Browser usage
In the browser, you usually only need the read path — Space plus a way to turn blob entries into <img src> URLs. @dreamlake/dreamdb works directly against any S3-compatible HTTP endpoint with no app server in between.
Open a Space
Read URIs come in two flavors:
| URI form | Semantics |
|---|---|
…/refs/<name> | Mutable. Resolves the named ref to a Manifest at fetch time (no-cache). |
…/manifests/<hash> | Pinned. The Manifest is content-addressed — cached forever, safe to share. |
Render a blob field as <img>
For an image / video / audio field on a Sample, fetch the bytes and wrap them in a same-origin object URL:
blobUrlFor handles:
- Direct fragments
- FragmentPack-style packed blobs (one HTTP GET per pack, then byte-slicing)
- HLS playlists for
video.hls.*fields
It returns null if the field has no entry for that sample.
Why object URLs?
Browsers won't render <img src="https://cross-origin.s3..."> if the bucket lacks Access-Control-Allow-Origin. URL.createObjectURL sidesteps CORS by giving the <img> a same-origin blob: URL backed by bytes you already fetched.
The trade-off is lifecycle: object URLs leak until revoked. With >10K thumbnails on a page that adds up fast. Always revokeBlobUrl on element removal.
React idiom
The revoked flag handles the late-arrival case (fetch resolves after unmount) — without it you'd revoke a URL that was never set.
See the React example for a full grid component.
Time-travel
Every commit is a free, immutable snapshot you can open forever.
Service workers + chunked items
Very large blobs are sometimes split across multiple object-store rows ("chunked Items" / "Item Manifests"). The current blobBytesAsync throws on these — full streaming reassembly is on the v0.2 roadmap. Until then, use service-worker-based stitching (browser-side reassembly via intercepted GETs) or stick to packed Fragments.