Transactions

Note: This feature is available for Web and Worker environments only!

With persistence enabled, browser runtimes synchronize their mounted IDBFS storage while holding the php-wasm-fs-lock Web Lock.

When Web Locks are unavailable, such as on a plain HTTP origin reached by a LAN IP address, browser runtimes fall back to a FIFO lock within the current page or worker. That fallback coordinates runtimes in the same JavaScript realm only. Use HTTPS, where Web Locks are available, when tabs or workers share persistent storage.

Browser CGI

Queued filesystem calls share a transaction. After the queue becomes idle, the wrapper waits up to 25 ms for more work. Storage is refreshed once per batch. A batch containing only analyzePath, readdir, readFile, or stat does not flush; any mutation makes the batch writable. Every call waits for the shared commit before its promise resolves or the service worker replies. A commit failure rejects every call in the batch. A callback failure still allows possible partial writes to be committed and later calls to run. The wait keeps the wrapper transaction open, not an IndexedDB transaction. IDBFS opens its own database transactions while hydrating or flushing.

Calls submitted together, including through Promise.all, can share a batch. Sequentially awaited calls create separate batches. Batches commit after 64 operations or a 250 ms processing window, checked between operations, so sustained traffic cannot defer acknowledgments indefinitely. A single slow callback is not interrupted. HTTP CGI requests use a separate path and still flush after each successful PHP request.

For a directory’s names and types, request readdir(path, {withFileTypes: true}): all metadata is read in one operation. File Bus uses this option for VS Code directory expansion and recursive file search when the host supports it.

Browser CGI tracks PHP and filesystem API mutations and commits only changed IDBFS records. This includes file contents, metadata, renamed directory trees and deletions. A clean mount needs no write transaction. The database format stays compatible with existing storage and older IDBFS readers. Hydration still reconciles remote changes and uses a direct local-node walk; nested mounts use ordinary reconciliation. Failed commits keep their pending changes and retry them before a later hydration can replace local state. Symlinks restore their own metadata without following or changing their targets.

Embedded browser runtimes

PhpWeb and PhpWorker retain their batched queues. Their operation results can become available before the shared transaction commits. The per-call persistence acknowledgment described above applies to browser CGI filesystem methods.

Manual Control of FS Mirroring

With {autoTransaction: false}, the caller owns transaction boundaries and serialization across runtimes. startTransaction() loads persisted storage; commitTransaction() flushes changes. These methods do not hold a Web Lock across a sequence of public calls. Do not acquire php-wasm-fs-lock and then await a public queued method that needs the same lock. Prefer automatic transactions unless you provide coordination for the complete operation.

php.startTransaction

await php.startTransaction();

php.commitTransaction

await php.commitTransaction();

For a manually managed transaction that performed only reads, use await php.commitTransaction(true) to close it without flushing. Never pass true after a mutation that must be persisted.