Deduplicate stored upload files and retain adoption bytes until their Root is durable
This commit is contained in:
@@ -209,3 +209,42 @@ NodeNext type check excludes DOM libraries. A separate peer consumer renders a
|
||||
registered component, verifies its command context, and checks typed NodeProps and
|
||||
EdgeProps with the declared peers. Browser tests still execute the compiled ESM
|
||||
storage and Worker artifacts independently of Next.js/TypeScript stripping.
|
||||
|
||||
|
||||
Workspace asset depot and file storage:
|
||||
|
||||
`createWorkspaceRuntime` owns one depot when `StoragePort.assetDepot` is provided.
|
||||
`await engine.adoptResource(id, (resource, tx) => { ... }, {signal})` obtains fresh
|
||||
server permission, verifies the original bytes, and runs a synchronous editor
|
||||
transaction. The callback uses the existing `resource.id` / canonical `resource.src`
|
||||
in a newly allocated element; it also receives server dimensions in `resource.asset`.
|
||||
The project stores a `SharedAssetBinding`, not a second upload. Binding, document,
|
||||
history, ledger, shared bytes and pins cross the same durable barrier. The returned
|
||||
local `Result` does not imply durability or backend completion. Async or failed
|
||||
callbacks leave no partial binding. The Foundry authority requires the matching
|
||||
permission-checked asset metadata endpoint; cached metadata is not an authorization.
|
||||
|
||||
Bindings use recovery envelope 13 (including partial loading v6); readers retain
|
||||
formats 1–12 and reject unknown future formats. A reopened binding can display
|
||||
shared local bytes, and undo/redo reuse the asset without uploading again. The
|
||||
workspace closes projects before its depot; retiring the identity fences late work.
|
||||
|
||||
The browser adapter uses IndexedDB version 4. After a proven stored-upload cut, a
|
||||
project's `files` row holds an opaque pointer to digest-addressed `asset-bytes`.
|
||||
Unconfirmed uploads and import source files keep their original Blob rows. Use
|
||||
`readFile` / `scanFiles`; direct assumptions that every raw files-store row is a
|
||||
Blob are invalid. Logical reads preserve the original local MIME, even if the
|
||||
server detected another MIME. Existing v3 databases upgrade without dropping
|
||||
checkpoints or original files and promote on a subsequent matching Root commit
|
||||
(or an idempotent reindex). Older DB readers reject v4. Blob URLs and already
|
||||
returned Blob objects live independently of a later persistent eviction; actual
|
||||
disk reclamation remains the browser's responsibility.
|
||||
|
||||
Resource identities retain immutable metadata after byte eviction. Complete,
|
||||
revision-matched durable manifests from every project in the workspace protect
|
||||
closed editors; missing/stale/opaque coverage prevents shared deletion. Distinct
|
||||
resource IDs may own the same digest; the shared byte row disappears only when
|
||||
its last live identity is retired. An older Root cannot release temporary bytes
|
||||
that belong to a newer adoption revision. Collection is explicit and local; this
|
||||
preview does not enable background deletion on Foundry or claim the full retention,
|
||||
permission-race and product acceptance matrix is finished.
|
||||
|
||||
Reference in New Issue
Block a user