Skip to content
QuireKit
Classic docs
Alpha · evolving API
Classic developmentView Markdown ↗

Images and durable media

Persist image bytes with canonical references for restoration, undo and DOCX conversion.

Document JSON stores image references; media services own their bytes. Downloading JSON alone does not guarantee images in another browser. Default memory media suits previews. Production products need durable identities, storage and restoration.

1. Prepare media before creating the instance

media is a creation-time service shared by mounted backends and file services:

InterfaceResponsibility
sink.put(asset)Synchronously register complete bytes and return { kind: 'asset', assetId }
resolver.resolve(reference)Resolve bytes synchronously or asynchronously
registrar.register(asset)Return an accept() / rollback() lease for fallible insertion
createAssetId(kind)Allocate an identity unique within durable storage

An asynchronous upload function cannot implement synchronous sink.put(). Restore assets into a synchronous working set first, or upload and then register/insert inside a guarded commit.

2. Build a saveable working set

The recipe wraps @quirekit/media memory storage and tracks accepted assets. The host supplies restored bytes and server-issued unique IDs through allocateId. For client-generated UUIDs, use v4 from uuid.

classic/media/session.tsts

Pass media: session.media at creation. snapshotAssets() returns independent byte copies for upload, rather than a binary encoding suitable for ordinary JSON. Store bytes in object storage or IndexedDB with a manifest of asset IDs, content types and storage locations.

Undo history can still reference accepted assets that are no longer visible. The recipe retains them; garbage collection follows the document/history storage policy. Never assign different bytes to an existing asset ID.

3. Save and restore in order

  1. Capture instance.getJSON() and session.snapshotAssets() together.
  2. Upload and confirm required assets. On failure, retain dirty state and do not publish references to missing bytes.
  3. Commit the document version and manifest. The host storage protocol owns conflicts and atomic publication.
  4. On reopening, restore bytes under their original IDs, then create Classic with the restored content and media services.

JSON.stringify(Uint8Array) does not produce a directly restorable media bundle. Browser object URLs are temporary resources, not durable document identities.

4. DOCX and failed operations

Official DOCX import stages new images while parsing. It registers them only when the operation can still write into the current document, rolling back new leases if the document commit fails. Providing a registrar establishes cleanup ownership. Custom sink-only implementations handle partial registration failures themselves.

Export requires the resolver to provide real bytes. Successful screen rendering does not prove export support. Hosts explicitly control external-reference fetching; verify cross-origin, expired-link and offline cases. See saving and files for conversion diagnostics and errors.

Verify the complete lifecycle

Insert an image, save, destroy the product, restore through a fresh working set and export DOCX. The image must resolve under the same asset ID. Also test upload failure, cancelled imports, duplicate resources, deletion and undo. Inspect bytes and canonical structure as well as screenshots.

QuireKitQuireKit · Core, plugins and Classic docs