-
Notifications
You must be signed in to change notification settings - Fork 2
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
Changes from 1 commit
0bb49ca
51b6b07
6ae673c
a0172f3
5d625aa
092272c
c1379d9
0c48f8e
1d6bfa2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1 @@ | ||
import { ConnectError } from '@connectrpc/connect'; | ||
import { errorToJson } from '@connectrpc/connect/protocol-connect'; | ||
import { | ||
ActionBuildRequest, | ||
ActionBuildResponse, | ||
isActionBuildRequest, | ||
isOffscreenRequest, | ||
} from '@penumbra-zone/types/internal-msg/offscreen'; | ||
|
||
chrome.runtime.onMessage.addListener((req, _sender, respond) => { | ||
if (!isOffscreenRequest(req)) { | ||
return false; | ||
} | ||
const { type, request } = req; | ||
if (isActionBuildRequest(request)) { | ||
void (async () => { | ||
try { | ||
// propagate errors that occur in unawaited promises | ||
const unhandled = Promise.withResolvers<never>(); | ||
self.addEventListener('unhandledrejection', unhandled.reject, { | ||
once: true, | ||
}); | ||
|
||
const data = await Promise.race([ | ||
spawnActionBuildWorker(request), | ||
unhandled.promise, | ||
]).finally(() => self.removeEventListener('unhandledrejection', unhandled.reject)); | ||
|
||
respond({ type, data }); | ||
} catch (e) { | ||
const error = errorToJson( | ||
// note that any given promise rejection event probably doesn't | ||
// actually involve the specific request it ends up responding to. | ||
ConnectError.from(e instanceof PromiseRejectionEvent ? e.reason : e), | ||
undefined, | ||
); | ||
respond({ type, error }); | ||
} | ||
})(); | ||
return true; | ||
} | ||
return false; | ||
}); | ||
|
||
const spawnActionBuildWorker = (req: ActionBuildRequest) => { | ||
const { promise, resolve, reject } = Promise.withResolvers<ActionBuildResponse>(); | ||
|
||
const worker = new Worker(new URL('../wasm-build-action.ts', import.meta.url)); | ||
void promise.finally(() => worker.terminate()); | ||
|
||
const onWorkerMessage = (e: MessageEvent) => resolve(e.data as ActionBuildResponse); | ||
|
||
const onWorkerError = ({ error, filename, lineno, colno, message }: ErrorEvent) => | ||
reject( | ||
error instanceof Error | ||
? error | ||
: new Error(`Worker ErrorEvent ${filename}:${lineno}:${colno} ${message}`), | ||
); | ||
|
||
const onWorkerMessageError = (ev: MessageEvent) => reject(ConnectError.from(ev.data ?? ev)); | ||
|
||
worker.addEventListener('message', onWorkerMessage, { once: true }); | ||
worker.addEventListener('error', onWorkerError, { once: true }); | ||
worker.addEventListener('messageerror', onWorkerMessageError, { once: true }); | ||
|
||
// Send data to web worker | ||
worker.postMessage(req); | ||
|
||
return promise; | ||
}; | ||
import '@repo/chrome-offscreen-worker/entry'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,15 @@ import { walletIdCtx } from '@penumbra-zone/services/ctx/wallet-id'; | |
|
||
import { backOff } from 'exponential-backoff'; | ||
|
||
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'}`, | ||
); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
const initHandler = async () => { | ||
const walletServices = startWalletServices(); | ||
const rpcImpls = await getRpcImpls(); | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
"tsx": "^4.16.2" | ||
}, | ||
"devDependencies": { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { penumbraEslintConfig } from '@repo/eslint-config'; | ||
import { config, parser } from 'typescript-eslint'; | ||
|
||
export default config( | ||
{ | ||
...penumbraEslintConfig, | ||
languageOptions: { | ||
parser, | ||
parserOptions: { project: true, tsconfigRootDir: import.meta.dirname }, | ||
}, | ||
}, | ||
{ rules: { '@typescript-eslint/no-unnecessary-type-arguments': 'off' } }, | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"name": "@repo/chrome-offscreen-worker", | ||
"version": "0.0.0", | ||
"type": "module", | ||
"private": true, | ||
"scripts": { | ||
"lint": "eslint src" | ||
}, | ||
"exports": { | ||
"./worker": "./src/worker.ts", | ||
"./entry": "./src/entry.ts" | ||
}, | ||
"devDependencies": { | ||
"@types/chrome": "^0.0.270" | ||
} | ||
} |
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.
this change is necessary due to some webpack reconfiguration.