Skip to content

Commit

Permalink
offscreen worker package
Browse files Browse the repository at this point in the history
  • Loading branch information
turbocrime committed Sep 5, 2024
1 parent b14f093 commit 0bb49ca
Show file tree
Hide file tree
Showing 17 changed files with 942 additions and 474 deletions.
3 changes: 2 additions & 1 deletion apps/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@penumbra-zone/types": "^22.0.0",
"@penumbra-zone/wasm": "^27.0.0",
"@radix-ui/react-icons": "^1.3.0",
"@repo/chrome-offscreen-worker": "workspace:*",
"@repo/context": "workspace:*",
"@repo/ui": "workspace:*",
"@tanstack/react-query": "4.36.1",
Expand All @@ -49,7 +50,7 @@
"zustand": "^4.5.2"
},
"devDependencies": {
"@types/chrome": "0.0.268",
"@types/chrome": "^0.0.270",
"@types/firefox-webext-browser": "^120.0.3",
"@types/lodash": "^4.17.4",
"@types/react": "^18.3.2",
Expand Down
3 changes: 2 additions & 1 deletion apps/extension/public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"open_in_tab": true
},
"background": {
"service_worker": "service-worker.js"
"service_worker": "service-worker.js",
"type": "module"
},
"web_accessible_resources": [
{
Expand Down
71 changes: 1 addition & 70 deletions apps/extension/src/entry/offscreen-handler.ts
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';
9 changes: 9 additions & 0 deletions apps/extension/src/service-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'}`,
);

const initHandler = async () => {
const walletServices = startWalletServices();
const rpcImpls = await getRpcImpls();
Expand Down
73 changes: 0 additions & 73 deletions apps/extension/src/wasm-build-action.ts

This file was deleted.

36 changes: 21 additions & 15 deletions apps/extension/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import WatchExternalFilesPlugin from 'webpack-watch-external-files-plugin';
// Loads default vars from `.env` file in this directory.
dotenv.config({ path: '.env' });

const keysPackage = path.dirname(url.fileURLToPath(import.meta.resolve('@penumbra-zone/keys')));
//const keysPackage = path.dirname(url.fileURLToPath(import.meta.resolve('@penumbra-zone/keys')));
//const servicesPackage = path.dirname(url.fileURLToPath(import.meta.resolve('@penumbra-zone/services')));

const localPackages = [
...Object.values(rootPackageJson.dependencies),
Expand Down Expand Up @@ -120,24 +121,29 @@ export default ({
'page-root': path.join(entryDir, 'page-root.tsx'),
'popup-root': path.join(entryDir, 'popup-root.tsx'),
'service-worker': path.join(srcDir, 'service-worker.ts'),
'wasm-build-action': path.join(srcDir, 'wasm-build-action.ts'),
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
module: true,
chunkFormat: 'module',
scriptType: 'module',
},
optimization: {
splitChunks: {
chunks: 'async',

/*
chunks: chunk => {
const filesNotToChunk = [
'injected-connection-port',
'injected-penumbra-global',
'injected-request-listner',
'service-worker',
'wasm-build-action',
];
return chunk.name ? !filesNotToChunk.includes(chunk.name) : false;
},
*/
},
},
module: {
Expand Down Expand Up @@ -176,13 +182,17 @@ export default ({
filename: 'videos/[hash][ext][query]',
},
},
/*
{
test: /\.bin$/,
type: 'asset/resource',
generator: { filename: 'keys/[name][ext]' },
},
*/
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
alias: {
'@ui': path.resolve(__dirname, '../../packages/ui'),
},
},
plugins: [
new webpack.CleanPlugin(),
Expand All @@ -197,41 +207,37 @@ export default ({
},
}),
DefinePlugin,
new CopyPlugin({
patterns: [
'public',
{
from: path.join(keysPackage, 'keys', '*_pk.bin'),
to: 'keys/[name][ext]',
},
],
}),
new CopyPlugin({ patterns: ['public'] }),
// html entry points
new HtmlWebpackPlugin({
favicon: 'public/favicon/icon128.png',
title: 'Prax Wallet',
template: 'react-root.html',
filename: 'page.html',
chunks: ['page-root'],
scriptLoading: 'module',
}),
new HtmlWebpackPlugin({
title: 'Prax Wallet',
template: 'react-root.html',
rootId: 'popup-root',
filename: 'popup.html',
chunks: ['popup-root'],
scriptLoading: 'module',
}),
new HtmlWebpackPlugin({
title: 'Penumbra Offscreen',
filename: 'offscreen.html',
chunks: ['offscreen-handler'],
scriptLoading: 'module',
}),
// watch tarballs for changes
WEBPACK_WATCH && new WatchExternalFilesPlugin({ files: localPackages }),
WEBPACK_WATCH && PnpmInstallPlugin,
CHROMIUM_PROFILE && WebExtReloadPlugin,
],
experiments: {
outputModule: true,
asyncWebAssembly: true,
},
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
"tsx": "^4.16.2"
},
"devDependencies": {
Expand Down
13 changes: 13 additions & 0 deletions packages/chrome-offscreen-worker/eslint.config.mjs
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' } },
);
16 changes: 16 additions & 0 deletions packages/chrome-offscreen-worker/package.json
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"
}
}
Loading

0 comments on commit 0bb49ca

Please sign in to comment.