Skip to content
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

polyfill Worker in chrome runtime #190

Closed
wants to merge 9 commits into from

Conversation

turbocrime
Copy link
Contributor

@turbocrime turbocrime commented Sep 5, 2024

references penumbra-zone/web#1795

this PR creates a package implementing a polyfill of the DOM Worker interface for chrome extension workers, and applies that polyfill to consumed packages from penumbra-zone.

pending penumbra-zone/web#1769

@turbocrime turbocrime requested review from TalDerei and a team September 5, 2024 05:11
@turbocrime turbocrime marked this pull request as draft September 5, 2024 05:16
@turbocrime
Copy link
Contributor Author

managed to discover some lies within the chrome runtime api about the offscreen lifecycle, so i have to work around that, but this is nearly ready for review.

Copy link
Contributor Author

@turbocrime turbocrime left a comment

Choose a reason for hiding this comment

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

presently a draft, uploaded to show wip

Comment on lines 34 to 37
"background": {
"service_worker": "service-worker.js"
"service_worker": "service-worker.js",
"type": "module"
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this change is necessary due to some webpack reconfiguration.

Comment on lines 46 to 54
import { OffscreenWorker } from '@repo/chrome-offscreen-worker/worker';

globalThis.Worker = OffscreenWorker;
OffscreenWorker.configure(
chrome.runtime.getURL(
'offscreen.html',
) as `chrome-extension://${typeof chrome.runtime.id}/${'offscreen.html'}`,
);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the offscreen worker polyfill is applied to the global here. any packages bundled into this entry calling new Worker will actually be calling new OffscreenWorker

@@ -31,6 +31,7 @@
"@bufbuild/protobuf": "^1.10.0",
"@connectrpc/connect": "^1.4.0",
"@connectrpc/connect-web": "^1.4.0",
"@tsconfig/strictest": "^2.0.5",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

import { OffscreenWorkerPort } from './messages/worker-event.js';
import { OffscreenRootPort, WorkerConstructorParamsPrimitive } from './messages/root-control.js';

const attempts: string[] = [];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

todo: remove debug

Suggested change
const attempts: string[] = [];

packages/chrome-offscreen-worker/src/control.ts Outdated Show resolved Hide resolved
Comment on lines 3 to 6
export type WorkerConstructorParamsPrimitive =
Required<ConstructorParameters<typeof Worker>> extends [infer S, infer O]
? [S extends string ? S : never, { [k in keyof O]: O[k] & string }]
: never;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

mostly this just excludes URL from the worker path url parameter, but it also types the WorkerOptions structure as primitives to indicate jsonifiability

packages/chrome-offscreen-worker/src/worker.ts Outdated Show resolved Hide resolved
packages/chrome-offscreen-worker/src/worker.ts Outdated Show resolved Hide resolved
Comment on lines 64 to 66
this.internalTarget.addEventListener('error', this.parentListener);
this.internalTarget.addEventListener('message', this.parentListener);
this.internalTarget.addEventListener('messageerror', this.parentListener);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

each item of WorkerEventMap is listened

const data: unknown = args[0];
const { transfer } = Array.isArray(args[1]) ? { transfer: args[1] } : { ...args[1] };

this.externalTarget.postMessage(data, { transfer });
Copy link
Contributor Author

Choose a reason for hiding this comment

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

transferrable objects are accepted, but are likely to not serialize properly in parentListener

this doesn't matter for prax's use, where only json is sent.

@turbocrime turbocrime marked this pull request as ready for review September 6, 2024 02:36
@turbocrime
Copy link
Contributor Author

this is pretty close, but i had other tasks today and now i'm out of time. tl;dr:

a transaction build can take place successfully, but it seems like sessions live a bit too long.

workers should be redesigned to terminate themselves when possible.

be aware that when the createDocument method returns, offscreen is not ready.

this does not yet support use from multiple scripts - different global contexts will track offscreen use independently, and kill the shared document early.

it might be good to check if terminating the offscreen document actually kills the web workers, or if it's cleaned up too fast to issue termination commands.

this tool when complete would be incredibly useful to extension developers in general, so i'm likely to publish this polyfill independently to NPM.

@TalDerei
Copy link
Contributor

chrome-offscreen-worker package in this PR will be replaced with https://github.com/turbocrime/chrome-offscreen-worker/tree/main/package

@TalDerei
Copy link
Contributor

advocating to close the intermediate polyfill step in favor of proceeding directly with the migration.

@TalDerei TalDerei closed this Sep 30, 2024
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.

2 participants