Skip to content

feat: move persistence off LocalStorage 5MB cap (File System API / OPFS / IndexedDB) #32

Description

@pskillen

Problem

Planned persistence (#9) targets browser LocalStorage, which is capped at roughly 5 MB per origin (and is synchronous/string-only). Once we persist whole codeplugs — and especially multiple codeplug projects (#31) — we will hit that ceiling. We need a larger, more robust storage backend.

Naming clarification (the "File System API" confusion)

The term covers two distinct APIs with very different support, which is why sources appear to contradict each other:

  1. File System Access API — user pickers (showOpenFilePicker, showSaveFilePicker, showDirectoryPicker): lets the app read/write files on the user's real filesystem. Chromium only (Chrome/Edge/Opera). Not Firefox, not Safari. This is what caniuse tracks: https://caniuse.com/native-filesystem-api
  2. Origin Private File System (OPFS) (navigator.storage.getDirectory() + FileSystemSyncAccessHandle): a sandboxed, origin-scoped filesystem with a large quota, available in a secure context across Chrome/Edge, Safari, and Firefox. This is what Mozilla's docs refer to when they say it's available — so both sources are correct about different things.

There is also a third, lowest-friction option:

  1. IndexedDB: universally supported (incl. Firefox + Safari), async, structured, quota far above LocalStorage's 5 MB. Simplest cross-browser path off the cap.

Intended outcome

Migrate persisted state off the LocalStorage 5 MB cap to a backend that scales to multi-project codeplugs, while keeping the small key/value prefs (e.g. Mapbox token, active project id) wherever is simplest.

  • Introduce a storage abstraction (async get/set/delete/list over codeplug projects) so the backend is swappable and tools/state don't hard-code LocalStorage.
  • Pick the backend after a compatibility spike (see below) — likely IndexedDB as the cross-browser default, with OPFS considered for large blobs, and the File System Access pickers used (where available) for explicit "save codeplug to disk" / "open codeplug from disk" round-trips that complement export (feat: CPS export support (internal models → vendor format) #8).
  • Graceful feature detection + fallback chain (File System Access → OPFS → IndexedDB) rather than assuming any one API.
  • Document the chosen backend, its quota behaviour, and per-browser limits.

Compatibility spike (do not trust docs alone)

Reported support conflicts and cannot be trusted blind; verify empirically on target browsers at implementation time:

  • Latest Chrome, Edge, Firefox, Safari (desktop) + Safari iOS + Chrome Android.
  • For each: secure-context behaviour, actual quota, persistence across reloads, and whether FileSystemSyncAccessHandle / pickers are truly available.
  • Capture findings in docs/features/<topic>/ before committing to a backend.

Affected tool(s)

  • Shared state/storage layer consumed by all tools/ (map first; report/export/CRUD later).

Notes / dependencies

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions