feat(opfs): implement missing OPFS features and add tests#8
Merged
Conversation
Owner
jurerotar
commented
Nov 7, 2025
- Compare handles by identity (same underlying entry), not by name/kind.
- Add queryPermission() and requestPermission() on file and directory handles; always resolve to "granted".
- getFile() returns snapshots with lastModified set; snapshots remain immutable after subsequent writes.
- Use a real WritableStream sink so both stream.write() and stream.getWriter().write() modify file content.
- Support all createWritable write() variants: raw USVString/Blob/ArrayBuffer/ArrayBufferView.
- Support all createWritable write() variants: { type: 'write', data, position? }.
- Support all createWritable write() variants: { type: 'seek', position }.
- Support all createWritable write() variants: { type: 'truncate', size }.
- Validate write/seek/truncate parameters: negative truncate size -> TypeError (write-params) / DOMException('IndexSizeError') (truncate method).
- Validate write/seek parameters: negative position -> TypeError; stream.seek(-1) -> DOMException('IndexSizeError').
- Reject undefined data with TypeError.
- Ensure binary correctness for Blob using arrayBuffer() (no text coercion).
- Preserve and expose seek()/truncate() methods on the returned writable stream.
- Abort semantics: abort(reason) causes subsequent write() to reject with the reason; close() rejects with a standardized errored-state message.
- createSyncAccessHandle: enforce exclusive file lock; opening a second handle throws InvalidStateError until the first is closed.
- createSyncAccessHandle: closed-state errors for getSize/read/write/truncate/flush throw DOMException('InvalidStateError').
- createSyncAccessHandle: read() at or beyond EOF returns 0; writes grow and pad file as needed; truncate() grows/shrinks and updates lastModified.
- Directory semantics: getFileHandle/getDirectoryHandle throw TypeMismatchError if opposite kind exists with same name.
- Directory removeEntry: deleting a file succeeds (regardless of recursive flag).
- Directory removeEntry: deleting an empty directory without recursive succeeds.
- Directory removeEntry: deleting a non-empty directory without recursive throws InvalidModificationError.
- Directory removeEntry: missing entry throws NotFoundError.
- Directory iteration APIs (entries/keys/values/[Symbol.asyncIterator]) yield consistent sets.
- Normalize DOMException creation to new DOMException(message, name) with standard names/messages.
- Add ambient declarations for queryPermission/requestPermission on FileSystemFileHandle and FileSystemDirectoryHandle.
- Tests: writable stream lifecycle and error paths, including getWriter().write() and getWriter().close().
- Tests: createWritable({ keepExistingData: true }) appends at end and persists content.
- Tests: abort semantics — write() rejects with reason; close() rejects with errored-state message; stream.write(undefined) rejects with TypeError.
- Tests: write() parameter variants and validation (seek/write/truncate; negative sizes/positions; legacy { data, position } and invalid data types).
- Tests: Blob binary correctness; DataView offset/length writes.
- Tests: sync handle exclusive lock, closed-state errors, flush() resolves when open, EOF reads return 0, growth/padding/truncation behaviors.
- Tests: directory and resolve semantics — NotFoundError for missing handles; name-clash TypeMismatchError; empty directory iteration; positive and negative resolve() cases.
- Tests: identity stability for navigator.storage.getDirectory() within a session; identity changes after resetMockOPFS().
- Tests: StorageManager.estimate() aggregates base usage and computed sizes.
- Compare handles by identity (same underlying entry), not by name/kind.
- Add queryPermission() and requestPermission() on file and directory handles; always resolve to "granted".
- getFile() returns snapshots with lastModified set; snapshots remain immutable after subsequent writes.
- Use a real WritableStream sink so both stream.write() and stream.getWriter().write() modify file content.
- Support all createWritable write() variants: raw USVString/Blob/ArrayBuffer/ArrayBufferView.
- Support all createWritable write() variants: { type: 'write', data, position? }.
- Support all createWritable write() variants: { type: 'seek', position }.
- Support all createWritable write() variants: { type: 'truncate', size }.
- Validate write/seek/truncate parameters: negative truncate size -> TypeError (write-params) / DOMException('IndexSizeError') (truncate method).
- Validate write/seek parameters: negative position -> TypeError; stream.seek(-1) -> DOMException('IndexSizeError').
- Reject undefined data with TypeError.
- Ensure binary correctness for Blob using arrayBuffer() (no text coercion).
- Preserve and expose seek()/truncate() methods on the returned writable stream.
- Abort semantics: abort(reason) causes subsequent write() to reject with the reason; close() rejects with a standardized errored-state message.
- createSyncAccessHandle: enforce exclusive file lock; opening a second handle throws InvalidStateError until the first is closed.
- createSyncAccessHandle: closed-state errors for getSize/read/write/truncate/flush throw DOMException('InvalidStateError').
- createSyncAccessHandle: read() at or beyond EOF returns 0; writes grow and pad file as needed; truncate() grows/shrinks and updates lastModified.
- Directory semantics: getFileHandle/getDirectoryHandle throw TypeMismatchError if opposite kind exists with same name.
- Directory removeEntry: deleting a file succeeds (regardless of recursive flag).
- Directory removeEntry: deleting an empty directory without recursive succeeds.
- Directory removeEntry: deleting a non-empty directory without recursive throws InvalidModificationError.
- Directory removeEntry: missing entry throws NotFoundError.
- Directory iteration APIs (entries/keys/values/[Symbol.asyncIterator]) yield consistent sets.
- Normalize DOMException creation to new DOMException(message, name) with standard names/messages.
- Add ambient declarations for queryPermission/requestPermission on FileSystemFileHandle and FileSystemDirectoryHandle.
- Tests: writable stream lifecycle and error paths, including getWriter().write() and getWriter().close().
- Tests: createWritable({ keepExistingData: true }) appends at end and persists content.
- Tests: abort semantics — write() rejects with reason; close() rejects with errored-state message; stream.write(undefined) rejects with TypeError.
- Tests: write() parameter variants and validation (seek/write/truncate; negative sizes/positions; legacy { data, position } and invalid data types).
- Tests: Blob binary correctness; DataView offset/length writes.
- Tests: sync handle exclusive lock, closed-state errors, flush() resolves when open, EOF reads return 0, growth/padding/truncation behaviors.
- Tests: directory and resolve semantics — NotFoundError for missing handles; name-clash TypeMismatchError; empty directory iteration; positive and negative resolve() cases.
- Tests: identity stability for navigator.storage.getDirectory() within a session; identity changes after resetMockOPFS().
- Tests: StorageManager.estimate() aggregates base usage and computed sizes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.