-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: support typed arrays in indexeddb #34949
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Overview
This pull request adds support for typed arrays in IndexedDB storage by extending the serialization and deserialization logic, updating relevant tests, and removing outdated documentation.
- Introduces new types, functions, and handling for converting typed arrays to/from base64 strings.
- Updates tests to store and retrieve typed arrays instead of regular strings.
- Removes the documentation note that previously mentioned a lack of support for typed arrays.
Reviewed Changes
File | Description |
---|---|
packages/playwright-core/src/server/isomorphic/utilityScriptSerializers.ts | Adds typed array type definitions, conversion utilities, and updates parser logic. |
tests/library/browsercontext-storage-state.spec.ts | Modifies test cases to use typed arrays for IndexedDB operations. |
docs/src/api/class-browsercontext.md | Removes outdated note about lack of typed array support. |
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
0133258
to
1837b1b
Compare
This comment has been minimized.
This comment has been minimized.
}; | ||
|
||
function typedArrayToBase64(array: any) { | ||
if (globalThis.Buffer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why have Node-specific code? It seems like btoa/atob
should work both in the browser and in the Node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good question! I mostly copied from @pavelfeldman's gist. Pavel, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like it works just fine without: dfd44ee
packages/playwright-core/src/server/isomorphic/utilityScriptSerializers.ts
Outdated
Show resolved
Hide resolved
packages/playwright-core/src/server/isomorphic/utilityScriptSerializers.ts
Outdated
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
||
function typedArrayToBase64(array: any) { | ||
/** | ||
* Firefox does not support iterating over typed arrays, so we use `.toBase64`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps instead of Array.from()
use a for loop? This should be supported everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried that, but doesn't work. It looks like any kind of iteration is forbidden:
https://searchfox.org/mozilla-central/source/js/xpconnect/wrappers/XrayWrapper.cpp#576
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exactly does this mean? You should be able to iterate arrays and use Array.from on them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But not inside the utility world, apparently 🤷
*/ | ||
if ('toBase64' in array) | ||
return array.toBase64(); | ||
const binary = Array.from(new Uint8Array(array.buffer)).map(b => String.fromCharCode(b)).join(''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is incorrect to serialize array.buffer
without looking at array.byteOffset
and array.byteLength
, because underlying buffer may be longer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch! fixed in 769fda6
This comment has been minimized.
This comment has been minimized.
90ac23a
to
37f1f9f
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Test results for "tests 1"5 flaky38629 passed, 796 skipped Merge workflow run. |
@@ -186,6 +233,10 @@ export function source() { | |||
return { u: value.toJSON() }; | |||
if (isRegExp(value)) | |||
return { r: { p: value.source, f: value.flags } }; | |||
for (const [k, ctor] of Object.entries(typedArrayConstructors) as [TypedArrayKind, Function][]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd start with looking up constructor.name in a set instead of iterating
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that won't work on Firefox, see impl of isTypedArray
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does work for me, are you saying this is also due to utility worlds? Something is fishy here. Do we have a bug in the way we initialize utility context? It needs to be proper JS context.
|
||
function typedArrayToBase64(array: any) { | ||
/** | ||
* Firefox does not support iterating over typed arrays, so we use `.toBase64`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exactly does this mean? You should be able to iterate arrays and use Array.from on them?
@@ -25,7 +27,8 @@ export type SerializedValue = | |||
{ a: SerializedValue[], id: number } | | |||
{ o: { k: string, v: SerializedValue }[], id: number } | | |||
{ ref: number } | | |||
{ h: number }; | |||
{ h: number } | | |||
{ ta: { b: string, k: TypedArrayKind } }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like we need a bunch of page.evaluate tests for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests in page-evaluate.spec.ts
all go through the protocol serializer, which also doesn't yet have support. Do we test the server-side of page.evaluate
in isolation?
I was planning to add support to the protocol serializer in a follow-up, happy to add page.evaluate tests in there.
Based on https://gist.github.com/pavelfeldman/4c7826893182ac9f85cc60ddbd7b2d11