On this page
Overview
Provides app-scoped OPFS tables, committed-change subscriptions with targeted cache freshness, explicit non-recursive empty-table removal, worker I/O, backup/restore, compression, and CRUD/batch APIs.
- Artifact
DBOPFS.js· esm - Classification
public first party - Availability
Browser / native WebView - Normalization
App scope and recognized file parsing are normalized; nonblank unreadable JSONL rows remain complete raw strings, empty-table removal reports removed, absent, or not-empty after a create:false directory lookup and without scanning or recursively clearing a directory, same-named files are preserved, aliases and cached handles are invalidated only when the directory is gone, and unexpected DOM/storage errors are preserved.
Import and lifecycle
import * as module from '/node_modules/arcane-os/runtime/arcane/modules/DBOPFS.js';
Browser import installs window.dbopfs, asynchronously opens or creates only the app OPFS scope, and emits dbopfs-ready. No table directory is created until a caller requests it; clearAllStorage leaves the emptied app scope without recreating product directories. CRUD and backup methods read, write, delete, download, or restore files. Successful mutations publish committed-change metadata through the existing event source and one app-scoped native BroadcastChannel. pagehide closes the channel; pageshow reopens it and clears only memory caches without fabricating a change.
Application-facing behavior: default DBOPFS; installs window.dbopfs, emits dbopfs-ready; subscribeChanges(listener,{signal,once}) observes DBOPFSEVENTTYPES.change (dbopfs-change), returns idempotent unsubscribe/.dispose, and publishes metadata {applicationId,storagePath,tableName,directoryName,fileName,action,originId,sequence,changeId,remote} after successful storage commits only. Actions are write/append/delete/table-delete; batches preserve partial success, remote receipts invalidate targeted aliases before local publication and never rebroadcast, and pagehide/pageshow closes/reopens the native channel and clears memory caches without replay or fabricated changes. Local subscription/storage continue when BroadcastChannel is unavailable. Table/file/backup APIs include getTableHandle(tableName='',{create=true}={}), readFile(tableName='',fileName='',{createTable=true}={}), get(tableName='',fileName='',force=false,{createTable=true}={}), and removeEmptyTable(tableName). Explicit create:false/createTable:false reads existing tables without creation or joining pending create work; default lazy creation remains unchanged. Low-level missing tables/files reject NotFoundError; get retains parsed caching/force semantics and resolves null only for NotFoundError, propagating other failures. Worker fallback reads already use existing app/table/file handles. createCompressedPNG({tableNames,additionalTables,signal}) returns a PNG Blob without download or record writes; omitted names select all, [] none, and supplied tables replace matching saved tables in the export. downloadCompressedPNG(name,options) reuses the same preparation and initiates one download; cancellation prevents it. restoreFromPNG(file,{selectTables}) closes the decoded image after pixel extraction, awaits the optional caller selection/projection before any writes, and rejects DBOPFSRESTOREWRITEFAILED AggregateError after all selected table batches settle when records fail, preserving original errors and failures {tableName,fileName,reason}; successful writes remain. No-options restore and setMany retain their contracts.
Protocol and host implementation
OPFS, DBOPFSWorker, Compression Streams, per-realm globalThis.arcaneEvents authority, and native BroadcastChannel for live same-app/storage-partition committed changes This detail does not widen the application-facing API or grant authority.
Exports, signatures, parameters, and results
| Binding | Form | Declaration or signature | Parameter syntax |
|---|---|---|---|
DBOPFS_EVENT_TYPES | variable · value | variable DBOPFS_EVENT_TYPES | — |
DBOPFS_REASONS | variable · value | variable DBOPFS_REASONS | — |
default | default · class | class DBOPFS | — |
| Member | Kind | Exact public declaration | Parameter syntax |
|---|---|---|---|
DBOPFS.constructor | constructor | constructor(options={}) | options={} |
DBOPFS.ready | field | ready=false; | — |
DBOPFS.readyPromise | field | readyPromise=Promise.resolve(); | — |
DBOPFS.applicationId | get | get applicationId() | — |
DBOPFS.storagePath | get | get storagePath() | — |
DBOPFS.subscribeChanges | method | subscribeChanges(listener,options={}) | listener,options={} |
DBOPFS.tables | get | get tables() | — |
DBOPFS.tables | set | set tables(update={tableName:'',fileName:'',value:''}) | update={tableName:'',fileName:'',value:''} |
DBOPFS.getTableHandle | async method | async getTableHandle(tableName='',{create=true}={}) | tableName='',{create=true}={} |
DBOPFS.set | async method | async set(tableName='',fileName='',value={}, append=false) | tableName='',fileName='',value={}, append=false |
DBOPFS.writeFile | async method | async writeFile(tableName='',fileName='',fileData='',append=false) | tableName='',fileName='',fileData='',append=false |
DBOPFS.readFile | async method | async readFile(tableName='',fileName='',{createTable=true}={}) | tableName='',fileName='',{createTable=true}={} |
DBOPFS.getFileMetadata | async method | async getFileMetadata(tableName='',fileName='') | tableName='',fileName='' |
DBOPFS.setMany | async method | async setMany(tableName,items) | tableName,items |
DBOPFS.get | async method | async get(tableName='',fileName='',force=false,{createTable=true}={}) | tableName='',fileName='',force=false,{createTable=true}={} |
DBOPFS.getMany | async method | async getMany(tableName,items) | tableName,items |
DBOPFS.getAll | async method | async getAll(tableName='',force=false) | tableName='',force=false |
DBOPFS.delete | async method | async delete(tableName='',fileName='') | tableName='',fileName='' |
DBOPFS.deleteMany | async method | async deleteMany(tableName,fileNames) | tableName,fileNames |
DBOPFS.deleteTable | async method | async deleteTable(tableName) | tableName |
DBOPFS.removeEmptyTable | async method | async removeEmptyTable(tableName) | tableName |
DBOPFS.clearAllStorage | async method | async clearAllStorage() | — |
DBOPFS.clear | async method | async clear(tableName) | tableName |
DBOPFS.getAllKeys | async method | async getAllKeys(tableName) | tableName |
DBOPFS.getTableNames | async method | async getTableNames(discover=false) | discover=false |
DBOPFS.filterKeyIncludes | async method | async filterKeyIncludes(tableName,subString='') | tableName,subString='' |
DBOPFS.hasKey | async method | async hasKey(tableName,key) | tableName,key |
DBOPFS.count | async method | async count(tableName) | tableName |
DBOPFS.createCompressedPNG | async method | async createCompressedPNG({tableNames, additionalTables = {}, signal} = {}) | {tableNames, additionalTables = {}, signal} = {} |
DBOPFS.downloadCompressedPNG | async method | async downloadCompressedPNG(name = 'DBOPFS-backup', options = {}) | name = 'DBOPFS-backup', options = {} |
DBOPFS.restoreFromPNG | async method | async restoreFromPNG(file, {selectTables} = {}) | file, {selectTables} = {} |
Parameter meanings and results
subscribeChanges(listener,{signal,once}) observes DBOPFS_EVENT_TYPES.change (dbopfs-change), returns idempotent unsubscribe/.dispose, and receives event.detail {applicationId,storagePath,tableName,directoryName,fileName,action,originId,sequence,changeId,remote}. Actions are write, append, delete and table-delete; fileName is null for table removal. Successful close/flush/removal precedes notification, and targeted caches and aliases are invalidated before listeners run. Partial batches publish each successful mutation without claiming a transaction; reads, missing targets and failed writes emit no change. Cross-document receivers invalidate before local publication and never rebroadcast. Subscriptions are live-only: subscribe before the initial read; application-owned refresh handles missed events after suspension. No bodies are included or reread, and outside-DBOPFS writes are not observed. Storage remains functional without BroadcastChannel; notification failures remain separate from committed storage outcomes. After readyPromise, getTableHandle(tableName='',{create=true}={}) lazily opens or creates one requested table and coalesces concurrent create requests for the same physical directory. Explicit create:false only opens an existing table and does not join a pending create; missing tables reject with NotFoundError. readFile(tableName='',fileName='',{createTable=true}={}) forwards the table selection and returns the complete raw file, rejecting missing tables/files with NotFoundError. get(tableName='',fileName='',force=false,{createTable=true}={}) retains parsed-value caching and force semantics, forwards createTable on actual reads, resolves null only for NotFoundError, and propagates other errors. force:true with createTable:false reads existing storage without earlier cached values or table creation. Defaults, app-scope initialization, and write behavior remain unchanged. Worker fallback reads already open app/table/file handles with create:false. removeEmptyTable(tableName) resolves the target through getDirectoryHandle(name,{create:false}), then asks OPFS to remove that directory non-recursively and resolves {status:'removed'|'absent'|'not-empty',removed,tableName,directoryName}. It never creates, scans, clears, or recursively removes the target; a same-named file and unexpected platform errors reject without removal. The logical memories table retains its physical memory directory and cache aliases are invalidated when that directory is removed or absent. Existing directories remain discoverable. createCompressedPNG({tableNames,additionalTables,signal}) returns a PNG Blob without download or record writes; omitted tableNames selects all saved tables, [] selects none, absent selected tables stay empty without directory creation, and each caller-owned additionalTables table replaces the same saved table in this export only. downloadCompressedPNG(name,options) reuses that method and downloads once. Cancellation stops further preparation and prevents a later download; in-flight browser file/canvas work cannot be interrupted. restoreFromPNG(file,{selectTables}) decodes once, awaits the optional application callback on the complete table/file map, then writes only its returned map; callback errors precede writes, and omitted callback retains all-table restoration. setMany and same-key write serialization remain unchanged. Storage is rooted at apps/<authoritative-app-id>, and worker fallback handles synchronous OPFS access.
Events, side effects, and errors
Source-literal CustomEvent dispatches
No source-literal CustomEvent dispatch is part of this artifact.
Lifecycle and event flow
- dbopfs-ready
- dbopfs-change through DBOPFS_EVENT_TYPES.change; committed local and remote storage metadata
Direct coded failures
DBOPFS_RESTORE_WRITE_FAILED
Exported Error subclasses
This artifact exports no Error subclass.
Documented failure behavior
- APP_DATA_SCOPE_INVALID
- APP_DATA_SCOPE_MISMATCH
- APP_DATA_SCOPE_REQUIRED
- APP_DATA_STORAGE_UNAVAILABLE
- DBOPFS_RESTORE_WRITE_FAILED: AggregateError.errors preserves original rejected writes; failures contains tableName, fileName, and reason after every table batch settles; successful writes remain saved
- DOM, OPFS, worker, serialization, compression, and backup validation failures
Availability and capabilities
Browser / native WebView. App scope and recognized file parsing are normalized; nonblank unreadable JSONL rows remain complete raw strings, empty-table removal reports removed, absent, or not-empty after a create:false directory lookup and without scanning or recursively clearing a directory, same-named files are preserved, aliases and cached handles are invalidated only when the directory is gone, and unexpected DOM/storage errors are preserved.
Normalized app-scoped browser and native-WebView persistence; Arcane.app.current supplies authoritative identity when native, but Core is not a database service.
Contract example
import '/node_modules/arcane-os/runtime/arcane/modules/DBOPFS.js';
await window.dbopfs.readyPromise;
await window.dbopfs.set('notes','welcome',{text:'Hello'});
console.log(await window.dbopfs.get('notes','welcome',true));
Related reference
No direct Core call is claimed for this artifact. Any injected provider or consuming module retains its own documented authority.