Skip to main content

Assets

Binary assets โ€” images and other file bytes โ€” live once in Scene.files as BinaryFile records keyed by FileId. Shapes that reference an asset (such as an ImageElement) carry only a fileId and resolve the bytes through this registry at render time, so the same image used by many shapes is stored a single time.

A BinaryFile holds the mime type, the data (an ArrayBuffer, which serialises cleanly through structuredClone, IndexedDB, and postMessage), an optional original name, and a createdAt timestamp.

import { createBinaryFile, addBinaryFile, getBinaryFile } from "@oh-just-another/scene";
import { fileId } from "@oh-just-another/types";

const id = fileId("logo");
const file = createBinaryFile(id, bytes, { mime: "image/png", name: "logo.png" });
const next = addBinaryFile(scene, file);
const resolved = getBinaryFile(next, id);

Use removeBinaryFile to drop an entry. On a live editor, editor.addBinaryFile(blob, name?) reads a Blob and registers it in one async call, returning the new FileId. When you drop or paste an image into the editor, the built-in image handler stores the bytes via this registry and inserts an ImageElement for you (see External Content).

The serializer writes files to a separate sidecar (serializeFiles / stringifyFiles / parseFiles in @oh-just-another/serialization, base64-encoded data) so the text scene JSON stays small; on import the host re-attaches the sidecar and shapes resolve their fileId lookups again.

Planned โ€” not yet available: a managed asset store with remote/CDN upload, content-hash deduplication, and lazy fetching of large blobs. Today asset bytes are held in memory on the scene and persisted by the host.