Skip to content

Save/open projects as a single .hyperaudio file (#403)#404

Open
scarsellifi wants to merge 3 commits into
mainfrom
403-hyperaudio-save
Open

Save/open projects as a single .hyperaudio file (#403)#404
scarsellifi wants to merge 3 commits into
mainfrom
403-hyperaudio-save

Conversation

@scarsellifi

@scarsellifi scarsellifi commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Closes #403.

Adds Save project / Open project: the whole working state — original media (byte for byte, never re-encoded), transcript with in-progress redactions, captions, options, and the machine transcription — travels in one portable .hyperaudio file (a renamed ZIP). The working copy lives in OPFS with autosave and is restored at boot; the user's filesystem is the project library.

Format v1.0 is specified in full (with a worked example) in the first comment of #403; js/hyperaudio-save.js carries a ten-line summary in its header.

Commits

  • Preserve struck words in the HTML/JSON round-trip; expose gap-removal settings — standalone bugfix too: JSON export/import silently resurrected every redaction.
  • Add .hyperaudio project save/open — one module in five layers (format and container are pure and node-tested; OPFS working copy; editor bridge; UI in the file menu). JSZip 3.10.1 vendored (MIT branch of its dual license) and precached.

Tests

  • 15 unit tests (__TEST__/unit/hyperaudio-save.test.mjs) on the pure format/container layers — all unit tests pass (22/22).
  • 4 e2e (__TEST__/e2e/project-save.spec.mjs): real download, open, manual-captions preservation, OPFS restore across reload.

Remote media (format v1.1)

For projects whose media was loaded from a URL, Save first tries to download and embed it (the server's CORS policy decides — #370); when it can't, the project is saved with a declared media.kind: "link". On open, an unreachable link URL (or an original-kind container missing its media entry) triggers a media-reconciliation offer per spec § 7.3: re-attach a local copy, verified heuristically (size/filename/duration), and the next save is self-contained again.

Known v1 limits

  • Dirty-work guard on Open only; native confirm/alert dialogs.

… settings (#403)

The converter dropped redactions (inline line-through) on both directions,
so any JSON export/import silently resurrected every cut. Words now carry
"struck": true (default not serialized). editor-audio-cut.js exposes
getGapRemovalSettings/applyGapRemovalSettings so a loaded project can
restore them through the normal UI path.
…py, UI (#403)

One module (js/hyperaudio-save.js) in five layers: format (build/validate
hyperaudio.json) and container (zip/unzip, whitelist-read) are pure and
node-tested; OPFS holds the single working copy with autosave; the bridge
gathers/applies editor state; the UI adds Save/Open project to the file menu
and restores the working copy at boot. JSZip 3.10.1 vendored (MIT branch of
its dual license) and precached. 15 unit tests + 4 e2e (real download,
OPFS restore across reload).
…ciliation (#403)

Format 1.1 (additive minor bump): media.kind "link" is now writable. Save on
a URL-mode project first tries to fetch and embed the media byte-for-byte
(the server's CORS policy decides); when refused, the project is saved with
a declared URL-only link descriptor after user confirmation. On open, an
unreachable link URL (playback needs no CORS, so the player's error event is
the only honest signal) or an original-kind container missing its media entry
offers reconciliation per spec 7.3: re-attach a local copy, verified
heuristically (size/filename, duration once metadata loads); the next save is
self-contained again.
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.

Save and open projects as a single portable .hyperaudio file

1 participant