feat: publish av-tools 0.1.0
This commit is contained in:
93
docs/STORAGE.md
Normal file
93
docs/STORAGE.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# Storage and cleanup
|
||||
|
||||
av-tools separates source bytes, engine files, derivatives and project
|
||||
metadata. The default policy is deliberately non-persistent for source media.
|
||||
|
||||
## Object URLs
|
||||
|
||||
Browser preview and result playback use `URL.createObjectURL(File|Blob)`.
|
||||
Object URLs reveal bytes only to the current browser context but retain the
|
||||
underlying object until revoked. Each owner revokes its previous URL when a
|
||||
source/result changes and all URLs on project close/unmount. A preview failure
|
||||
does not trigger an upload or external fallback.
|
||||
|
||||
## FFmpeg virtual filesystem
|
||||
|
||||
Every execution receives a generated job directory. Inputs are copied to the
|
||||
in-memory filesystem or mounted read-only through WORKERFS where browser/core
|
||||
support is verified. Outputs are always in generated paths. The runner reads
|
||||
only declared outputs, then deletes output/input/control files and unmounts.
|
||||
|
||||
WORKERFS can avoid an initial JavaScript byte copy; FFmpeg decoding and output
|
||||
still consume WASM/browser memory. Cancelling terminates the engine, so cleanup
|
||||
also discards that entire virtual filesystem.
|
||||
|
||||
Each probe/export records its actual input mode and byte accounting. A
|
||||
successful WORKERFS mount reports zero copied input bytes; if mounting fails,
|
||||
the bounded compatibility fallback reports the exact bytes copied into engine
|
||||
memory. This is runtime evidence rather than a speculative preflight claim.
|
||||
|
||||
## IndexedDB
|
||||
|
||||
The mounted application currently stores validated user presets in IndexedDB.
|
||||
The codebase also contains a durable job-metadata store, but the application
|
||||
queue described in the UI is deliberately in memory and does not instantiate
|
||||
that store. Project documents are validated, versioned JSON that the user
|
||||
explicitly saves and loads; they are not currently auto-saved to IndexedDB.
|
||||
Media source bytes are not written there by default.
|
||||
|
||||
Clearing site data removes these records. Private browsing and quota eviction
|
||||
may remove them earlier; the app must treat storage as recoverable cache, not
|
||||
the only copy of an important user preset.
|
||||
|
||||
## Origin-private file system
|
||||
|
||||
OPFS is optional for bounded preview proxies, waveform peaks, thumbnails and
|
||||
other regenerable derivatives. The current implementation uses asynchronous
|
||||
origin-private file handles and falls back to a 128 MiB least-recently-used
|
||||
in-memory cache if OPFS is unavailable or fails. A derivative key includes a
|
||||
source fingerprint, operation, relevant settings and a cache-schema version;
|
||||
waveform keys additionally identify the selected stream and analysis settings.
|
||||
|
||||
Preview-proxy settings are part of that identity. The current UI validates a
|
||||
1–300 second maximum duration and a 480, 720, 960, 1280 or 1920 pixel maximum
|
||||
width. A matching local derivative is reused without FFmpeg execution; changing
|
||||
the source or either setting produces a different cache lookup. A cache miss or
|
||||
cache failure falls back to generation and never mutates/persists the source.
|
||||
|
||||
The application works without OPFS. The storage panel reports the browser's
|
||||
origin-wide quota estimate when available and offers per-entry or global cache
|
||||
deletion. The current OPFS layer relies on browser quota enforcement rather
|
||||
than pre-reserving space; a failed cache write switches subsequent cache work
|
||||
to the bounded in-memory fallback. OPFS writes close their
|
||||
`FileSystemWritableFileStream` on success and abort it on error.
|
||||
|
||||
OPFS is private to the current **origin**. Moving an app from one hostname,
|
||||
scheme or port to another does not move cached data. Toolbox and standalone
|
||||
deployments at different origins have different caches even if their files are
|
||||
identical.
|
||||
|
||||
## Source persistence policy
|
||||
|
||||
Normal import retains the user-selected `File` only in the active page. Saved
|
||||
projects contain source descriptors/fingerprints and prompt for reattachment;
|
||||
they do not embed source bytes. If a later UI offers “keep source on this
|
||||
device,” it must be explicit, show estimated/quota usage, identify the origin,
|
||||
allow per-source deletion and never be silently enabled by a project import.
|
||||
|
||||
Downloads are explicit user actions. The File System Access API, when
|
||||
available, writes only after the user selects a target; Blob download remains
|
||||
the fallback.
|
||||
|
||||
## Cleanup matrix
|
||||
|
||||
| Resource | Normal completion | Cancellation/error | User control |
|
||||
| ------------------------ | ---------------------------------------------------- | -------------------------------------------------------- | ----------------------- |
|
||||
| source/result object URL | retained only while displayed, then revoked | revoked when owning state clears | clear source/result |
|
||||
| FFmpeg job files/mount | delete/unmount in finalization | engine termination discards FS; stale generation ignored | cancel job/reset engine |
|
||||
| result Blob | retained until replaced/cleared/download page closes | failed partial output is not published | clear result |
|
||||
| IndexedDB user presets | retained intentionally | transaction rollback | delete/reset presets |
|
||||
| OPFS derivative | retained until expiry or explicit deletion | failed write is not indexed; cache switches to memory | delete item/clear all |
|
||||
|
||||
The storage screen reports approximate usage; browser quota figures remain
|
||||
estimates and are not a durability promise.
|
||||
Reference in New Issue
Block a user