Split out of #726 (review note) so it doesn't get lost.
handleDelete in packages/editor/src/components/ui/sidebar/panels/site-panel/index.tsx only routes http(s) URLs to onDeleteAsset. Assets persisted locally through saveAsset (packages/core/src/lib/asset-storage.ts, asset://<id> URLs) are never removed from IndexedDB when the referencing node is deleted.
Guide images have had this gap since local guide storage landed; with #726 the same path now stores scans, which are up to 200 MB each, so the orphaned data is no longer trivia.
Two layers to it:
- Immediate: when a node holding the last reference to an
asset:// URL is deleted, delete the IDB entry (mind undo — a deleted node can come back with history, so eager deletion needs either a grace period or resurrection re-save).
- Structural:
loadAssetUrl's module-level urlCache never revokes object URLs either. A small ref-counted asset lifecycle in asset-storage.ts would cover both.
An interim mitigation could be a sweep on scene load: drop IDB entries whose ids appear in no loaded node.
Split out of #726 (review note) so it doesn't get lost.
handleDeleteinpackages/editor/src/components/ui/sidebar/panels/site-panel/index.tsxonly routeshttp(s)URLs toonDeleteAsset. Assets persisted locally throughsaveAsset(packages/core/src/lib/asset-storage.ts,asset://<id>URLs) are never removed from IndexedDB when the referencing node is deleted.Guide images have had this gap since local guide storage landed; with #726 the same path now stores scans, which are up to 200 MB each, so the orphaned data is no longer trivia.
Two layers to it:
asset://URL is deleted, delete the IDB entry (mind undo — a deleted node can come back with history, so eager deletion needs either a grace period or resurrection re-save).loadAssetUrl's module-levelurlCachenever revokes object URLs either. A small ref-counted asset lifecycle inasset-storage.tswould cover both.An interim mitigation could be a sweep on scene load: drop IDB entries whose ids appear in no loaded node.