Skip to content

feat(storageState): add OPFS support#41420

Draft
gwennlbh wants to merge 2 commits into
microsoft:mainfrom
gwennlbh:storagestate-opfs
Draft

feat(storageState): add OPFS support#41420
gwennlbh wants to merge 2 commits into
microsoft:mainfrom
gwennlbh:storagestate-opfs

Conversation

@gwennlbh

Copy link
Copy Markdown
Contributor

Closes #41400

@gwennlbh gwennlbh force-pushed the storagestate-opfs branch from 6f6684c to 18b71cc Compare June 23, 2026 08:53
Comment thread packages/injected/src/storageScript.ts

@gwennlbh gwennlbh left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll wait for an answer on the comment i added since if baseline 2025 is not acceptable and neither is putting the script in a web worker, i don't wanna spend time on writing tests 😅

Comment thread packages/injected/src/storageScript.ts Outdated
}

// Getting a File object's contents requires async
export async function serializeFile(value: File): Promise<Extract<SerializedValue, { f: any; }>> {

This comment was marked as outdated.

Comment thread packages/injected/src/storageScript.ts
Comment thread packages/injected/src/storageScript.ts Outdated
};

type OPFSTree = Array<
[name: string, contents: Extract<SerializedValue, {f: any}> | OPFSTree]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use conservative types:

type FSEntry {
  type: 'file' | 'folder';
  name: string;
  lastModified: number;
}

type File = FSEntry & {
  type: 'file';
  base64: string;
}

type Folder = FSEntry & {
  type: 'folder';
  entries: (File | Folder)[];
}

{ ta: { b: string, k: TypedArrayKind } } |
{ ab: { b: string } };
{ ab: { b: string } } |
{ f: { b: string, n: string, t: string, m: number } };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to serialize and restore opfs without this.

return base64ToTypedArray(value.ta.b, typedArrayConstructors[value.ta.k]);
if ('ab' in value)
return base64ToTypedArray(value.ab.b, Uint8Array).buffer;
if ('f' in value) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it like this so that we would get File object support in IndexedDB as a side effect of the PR, but yeah it's not strictly necessary


async storageState(params: channels.BrowserContextStorageStateParams, progress: Progress): Promise<channels.BrowserContextStorageStateResult> {
return await this._context.storageState(progress, params.indexedDB, params.credentials);
return await this._context.storageState(progress, params.indexedDB, params.credentials, params.opfs);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pass params as object

@gwennlbh gwennlbh force-pushed the storagestate-opfs branch 2 times, most recently from bac24d8 to e9d3564 Compare June 25, 2026 19:29
@gwennlbh gwennlbh force-pushed the storagestate-opfs branch from e9d3564 to 2040049 Compare June 25, 2026 19:34
@gwennlbh

gwennlbh commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

i just realized, i don't think there's anyway to set the lastModified or content type of the file when writing it into OPFS. Maybe we should just leave them out of the serialized data :/ Unfortunate cuz tests can't rely on these things (esp. the last modified date could be useful, i feel like)

I mean, they have a solution: mocking FileSystemFileHandle#getFile i guess

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Capture OPFS in storageState

2 participants