try to fix broken expressions

(in production) - fixes #2059
also type
and log worker error early
stores
Mikael Finstad 2024-08-06 16:04:27 +02:00
rodzic 0a3839882e
commit 6e60133ef7
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 25AB36E3E81CBC26
3 zmienionych plików z 43 dodań i 12 usunięć

Wyświetl plik

@ -1,8 +1,28 @@
const workerUrl = new URL('evalWorker.js', import.meta.url); import invariant from 'tiny-invariant';
// https://github.com/vitejs/vite/issues/11823#issuecomment-1407277242
// https://github.com/mifi/lossless-cut/issues/2059
import Worker from './evalWorker?worker';
export interface RequestMessageData {
code: string,
id: number,
context: string // json
}
export type ResponseMessageData = { id: number } & ({
error: string,
} | {
data: unknown,
})
// https://v3.vitejs.dev/guide/features.html#web-workers // https://v3.vitejs.dev/guide/features.html#web-workers
// todo terminate() and recreate in case of error? // todo terminate() and recreate in case of error?
const worker = new Worker(workerUrl); const worker = new Worker();
worker.addEventListener('error', (err) => {
console.error('evalWorker error', err);
});
let lastRequestId = 0; let lastRequestId = 0;
@ -22,13 +42,17 @@ export default async function safeishEval(code: string, context: Record<string,
worker.removeEventListener('error', onError); worker.removeEventListener('error', onError);
} }
function onMessage({ data: { id: responseId, error, data } }) { function onMessage(response: { data: ResponseMessageData }) {
// console.log('message', { responseId, error, data }) // console.log('message', { responseId, error, data })
if (responseId === id) { if (response.data.id === id) {
cleanup(); cleanup();
if (error) reject(new Error(error)); if ('error' in response.data) {
else resolve(data); reject(new Error(response.data.error));
} else {
invariant('data' in response.data);
resolve(response.data.data);
}
} }
} }
@ -46,6 +70,6 @@ export default async function safeishEval(code: string, context: Record<string,
worker.addEventListener('messageerror', onMessageerror); worker.addEventListener('messageerror', onMessageerror);
worker.addEventListener('error', onError); worker.addEventListener('error', onError);
worker.postMessage({ id, code, context: JSON.stringify(context) }); worker.postMessage({ id, code, context: JSON.stringify(context) } satisfies RequestMessageData);
}); });
} }

Wyświetl plik

@ -1,10 +1,15 @@
// eslint-disable-next-line unicorn/no-this-assignment, @typescript-eslint/no-this-alias import type { RequestMessageData, ResponseMessageData } from './eval';
const myGlobal = this;
// https://stackoverflow.com/a/10796616/6519037 // https://stackoverflow.com/a/10796616/6519037
// https://github.com/Zirak/SO-ChatBot/blob/master/source/eval.js // https://github.com/Zirak/SO-ChatBot/blob/master/source/eval.js
// https://github.com/Zirak/SO-ChatBot/blob/master/source/codeWorker.js // https://github.com/Zirak/SO-ChatBot/blob/master/source/codeWorker.js
// `this` doesn't seem to work when transpiling, so use globalThis instead
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis
const myGlobal = globalThis;
const wl = { const wl = {
self: 1, self: 1,
onmessage: 1, onmessage: 1,
@ -119,7 +124,7 @@ myGlobal.fetch = undefined;
// eslint-disable-next-line wrap-iife, func-names // eslint-disable-next-line wrap-iife, func-names
(function () { (function () {
onmessage = (event) => { onmessage = (event: MessageEvent<RequestMessageData>) => {
// eslint-disable-next-line strict, lines-around-directive // eslint-disable-next-line strict, lines-around-directive
'use strict'; 'use strict';
@ -130,9 +135,9 @@ myGlobal.fetch = undefined;
// https://stackoverflow.com/questions/8403108/calling-eval-in-particular-context // https://stackoverflow.com/questions/8403108/calling-eval-in-particular-context
// eslint-disable-next-line unicorn/new-for-builtins, no-new-func // eslint-disable-next-line unicorn/new-for-builtins, no-new-func
const result = Function(`\nwith (this) { return (${code}); }`).call(context); const result = Function(`\nwith (this) { return (${code}); }`).call(context);
postMessage({ id, data: result }); postMessage({ id, data: result } satisfies ResponseMessageData);
} catch (e) { } catch (e) {
postMessage({ id, error: `${e}` }); postMessage({ id, error: `${e}` } satisfies ResponseMessageData);
} }
}; };
})(); })();

Wyświetl plik

@ -5,6 +5,8 @@
"noEmit": true, "noEmit": true,
"noImplicitAny": false, // todo "noImplicitAny": false, // todo
"types": ["vite/client"],
}, },
"references": [ "references": [
{ "path": "./tsconfig.main.json" }, { "path": "./tsconfig.main.json" },