Skip to content

Fix project-review bugs, autosave and export issues, and code health - #1

Merged
pythonicode merged 15 commits into
mainfrom
fix/audit-bugs-and-code-health
Oct 14, 2026
Merged

pythonicode merged 15 commits into
mainfrom
fix/audit-bugs-and-code-health

Conversation

@pythonicode

@pythonicode pythonicode commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Summary

Fixes the bugs from the project review and adds the code-health and UX work
requested alongside them. Each change is its own commit so they can be reviewed
or reverted individually.

Bug fixes

  • Open Project no longer silently replaces your work. The file picker, drag-and-drop and the sample project all confirm first when there's content on screen. The New Project dialog is generalized to serve both.
  • VITE_ANALYTICS_HOSTNAME now takes effect. index.html hardcoded the domain, so the build-time token never matched.
  • Exports stay within the iOS canvas limit. On iOS, oversized maps are scaled down (and the modal says so) instead of silently failing. Desktop keeps full resolution. Export errors now show a message instead of an unhandled rejection.
  • Damaged .anal entries are rejected up front. Each track, drawing, annotation and map image is checked, and the error names the bad entry.
  • Map image replacement is undoable.

Performance

  • Autosave no longer re-encodes the map image. The image is stored as a Blob under its own IndexedDB key and written only when it changes. Projects saved by older builds still load and migrate on their next save.

UX

  • Autosave status in the status bar (Saving / Saved HH:MM / Autosave failed).
  • Close prompt only when an edit would be lost, i.e. one waiting to be written or after a failed write.

Code health

  • Lint is clean (the one Fast Refresh warning is fixed).
  • Escape-key handling is shared in useEscapeKey.
  • Project validation and export scaling moved into pure modules.
  • Vitest added (npm test) with 21 tests on those modules.
  • README rewritten; CI runs lint, tests and build.
  • Removed an unused deprecated export helper.

Testing

  • npm test, npm run lint, npm run build pass locally.
  • Verified in the browser: sample project autosaves the image as a Blob and restores it after reload; a legacy inline-image record still loads; dropping a project file shows the confirmation; a replacement image can be undone; the export preview renders; Escape and the New Project dialog still work.
  • Not verified: export on a real iOS device (the scaling is covered by unit tests only).

Notes for review

  • The project now uses Bun. package-lock.json was replaced by a regenerated bun.lock, and the README and CI use Bun commands.
  • Undo history now holds map image references, so replacing the map many times keeps the older images in memory until history is trimmed (max 100 steps).

🤖 Generated with Claude Code

pythonicode and others added 13 commits October 14, 2026 10:32
Open Project (picker, drag-and-drop and the sample project) loaded straight
over unsaved content. All opens now go through requestOpenProject, which asks
first via ReplaceProjectModal (the generalized New Project dialog).

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
index.html hardcoded the analytics hostname, so the __ODS_HOSTNAME__ token the
Vite plugin replaces never existed and the env setting was ignored.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Exports rendered the full map at native size with no pixel cap, and iOS
Safari silently fails to encode canvases above ~16.7M pixels. On iOS the
export is now scaled to fit, the modal says so, and encoding or render
failures show an error instead of an unhandled rejection. Desktop keeps
full resolution.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
validateProjectFile only checked that tracks, paths and annotations were
arrays, so a damaged entry got through and crashed rendering later. Each
entry is now checked for the fields and numeric coordinates the canvas needs,
and the error names the damaged entry.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Every autosave re-encoded the whole project, including the base64 map image
(up to ~27MB), on the main thread. The image is now written to its own
IndexedDB key only when it changes, and the project JSON keeps a placeholder.
Projects saved by older builds still load and are migrated on their next save.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
setMapImage sat outside the undo snapshot, so replacing or dropping in a new
map could not be undone. The image is now part of the snapshot and goes
through the same history recording as other edits.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Autosave was silent, so users could not tell whether their work was saved.
The status bar now shows Saving, Saved HH:MM or Autosave failed. A close
prompt appears only when an edit is still waiting to be written or the last
write failed.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Exporting a non-component function from TopBarMenu.tsx broke Fast Refresh and
caused the only lint warning in the project.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Six modals repeated the same window keydown listener. They now call one hook.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
The validator and the iOS export-scale rule lived inside modules that import
the store and canvas, so they could not be tested directly. Both are now
standalone, with the device passed in for export scaling.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…wport math

Adds npm test (vitest run) with Vitest 4.1.11. The first suite covers the
project file validator (including the bundled sample), iOS export scaling,
viewport clamping and text-scale helpers.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
The README was still the Vite template. It now covers setup, scripts, the env
setting, project layout and the .anal format. CI runs lint, tests and the
production build on pushes to main and on pull requests.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Nothing called it; export goes through ExportModal and downloadExport.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
analysis Ready Ready Preview Oct 14, 2026 8:47am UTC

pythonicode and others added 2 commits October 14, 2026 10:47
Replaces package-lock.json with bun.lock (regenerated with Bun 1.3.11) so the
repo has a single lockfile. The README and CI workflow now use bun install
(frozen lockfile), bun run lint, test and build.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
@pythonicode
pythonicode merged commit 3e5a40e into main Oct 14, 2026
4 checks passed

This branch was successfully deployed

1 active deployment
Preview — b2b367d6 Deployed Oct 14, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant