🚀 demo page workerize load
This commit is contained in:
@@ -1,18 +1,17 @@
|
||||
import { getBestRoute } from "@snk/solver/getBestRoute";
|
||||
import { Color, copyGrid, Grid } from "@snk/types/grid";
|
||||
import { step } from "@snk/solver/step";
|
||||
import { isStableAndBound, stepSpring } from "./springUtils";
|
||||
import { Res } from "@snk/github-user-contribution";
|
||||
import { Snake } from "@snk/types/snake";
|
||||
import type { Res } from "@snk/github-user-contribution";
|
||||
import type { Snake } from "@snk/types/snake";
|
||||
import {
|
||||
drawLerpWorld,
|
||||
getCanvasWorldSize,
|
||||
Options,
|
||||
} from "@snk/draw/drawWorld";
|
||||
import { userContributionToGrid } from "../action/userContributionToGrid";
|
||||
import { snake4 as snake } from "@snk/types/__fixtures__/snake";
|
||||
import { getPathToPose } from "@snk/solver/getPathToPose";
|
||||
import { userContributionToGrid } from "@snk/action/userContributionToGrid";
|
||||
import { createSvg } from "@snk/svg-creator";
|
||||
import { createRpcClient } from "./worker-utils";
|
||||
import type { API as WorkerAPI } from "./demo.interactive.worker";
|
||||
|
||||
const createForm = ({
|
||||
onSubmit,
|
||||
@@ -47,15 +46,24 @@ const createForm = ({
|
||||
|
||||
form.addEventListener("submit", (event) => {
|
||||
event.preventDefault();
|
||||
onSubmit(input.value).catch((err) => {
|
||||
label.innerText = "error :(";
|
||||
throw err;
|
||||
});
|
||||
|
||||
onSubmit(input.value)
|
||||
.finally(() => {
|
||||
clearTimeout(timeout);
|
||||
})
|
||||
.catch((err) => {
|
||||
label.innerText = "error :(";
|
||||
throw err;
|
||||
});
|
||||
|
||||
input.disabled = true;
|
||||
submit.disabled = true;
|
||||
form.appendChild(label);
|
||||
label.innerText = "loading ...";
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
label.innerText = "loading ( it might take a while ) ... ";
|
||||
}, 5000);
|
||||
});
|
||||
|
||||
//
|
||||
@@ -75,6 +83,7 @@ const createGithubProfile = () => {
|
||||
container.style.opacity = "0";
|
||||
container.style.display = "flex";
|
||||
container.style.flexDirection = "column";
|
||||
container.style.height = "120px";
|
||||
container.style.alignItems = "flex-start";
|
||||
const image = document.createElement("img");
|
||||
image.style.width = "100px";
|
||||
@@ -232,13 +241,24 @@ const onSubmit = async (userName: string) => {
|
||||
};
|
||||
|
||||
const grid = userContributionToGrid(cells, colorScheme);
|
||||
const chain = getBestRoute(grid, snake)!;
|
||||
chain.push(...getPathToPose(chain.slice(-1)[0], snake)!);
|
||||
|
||||
const chain = await getChain(grid);
|
||||
|
||||
dispose();
|
||||
|
||||
createViewer({ grid0: grid, chain, drawOptions });
|
||||
};
|
||||
|
||||
const worker = new Worker(
|
||||
new URL(
|
||||
"./demo.interactive.worker.ts",
|
||||
// @ts-ignore
|
||||
import.meta.url
|
||||
)
|
||||
);
|
||||
|
||||
const { getChain } = createRpcClient<WorkerAPI>(worker);
|
||||
|
||||
const profile = createGithubProfile();
|
||||
const { dispose } = createForm({
|
||||
onSubmit,
|
||||
|
||||
17
packages/demo/demo.interactive.worker.ts
Normal file
17
packages/demo/demo.interactive.worker.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { getBestRoute } from "@snk/solver/getBestRoute";
|
||||
import { getPathToPose } from "@snk/solver/getPathToPose";
|
||||
import { snake4 as snake } from "@snk/types/__fixtures__/snake";
|
||||
import type { Grid } from "@snk/types/grid";
|
||||
import { createRpcServer } from "./worker-utils";
|
||||
|
||||
const getChain = (grid: Grid) => {
|
||||
const chain = getBestRoute(grid, snake)!;
|
||||
chain.push(...getPathToPose(chain.slice(-1)[0], snake)!);
|
||||
|
||||
return chain;
|
||||
};
|
||||
|
||||
const api = { getChain };
|
||||
export type API = typeof api;
|
||||
|
||||
createRpcServer(api);
|
||||
@@ -2,6 +2,7 @@
|
||||
"name": "@snk/demo",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@snk/action": "1.0.0",
|
||||
"@snk/draw": "1.0.0",
|
||||
"@snk/github-user-contribution": "1.0.0",
|
||||
"@snk/solver": "1.0.0",
|
||||
|
||||
59
packages/demo/worker-utils.ts
Normal file
59
packages/demo/worker-utils.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
type API = Record<string, (...args: any[]) => any>;
|
||||
|
||||
const symbol = "worker-rpc__";
|
||||
|
||||
export const createRpcServer = (api: API) =>
|
||||
self.addEventListener("message", async (event) => {
|
||||
if (event.data?.symbol === symbol) {
|
||||
try {
|
||||
const res = await api[event.data.methodName](...event.data.args);
|
||||
self.postMessage({ symbol, key: event.data.key, res });
|
||||
} catch (error: any) {
|
||||
postMessage({ symbol, key: event.data.key, error: error.message });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const createRpcClient = <API_ extends API>(worker: Worker) => {
|
||||
const originalTerminate = worker.terminate;
|
||||
worker.terminate = () => {
|
||||
worker.dispatchEvent(new Event("terminate"));
|
||||
originalTerminate.call(worker);
|
||||
};
|
||||
|
||||
return new Proxy(
|
||||
{} as {
|
||||
[K in keyof API_]: (
|
||||
...args: Parameters<API_[K]>
|
||||
) => Promise<Awaited<ReturnType<API_[K]>>>;
|
||||
},
|
||||
{
|
||||
get:
|
||||
(_, methodName) =>
|
||||
(...args: any[]) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const key = Math.random().toString();
|
||||
|
||||
const onTerminate = () => {
|
||||
worker.removeEventListener("terminate", onTerminate);
|
||||
worker.removeEventListener("message", onMessageHandler);
|
||||
reject(new Error("worker terminated"));
|
||||
};
|
||||
|
||||
const onMessageHandler = (event: MessageEvent) => {
|
||||
if (event.data?.symbol === symbol && event.data.key === key) {
|
||||
if (event.data.error) reject(event.data.error);
|
||||
else if (event.data.res) resolve(event.data.res);
|
||||
|
||||
worker.removeEventListener("terminate", onTerminate);
|
||||
worker.removeEventListener("message", onMessageHandler);
|
||||
}
|
||||
};
|
||||
|
||||
worker.addEventListener("message", onMessageHandler);
|
||||
worker.addEventListener("terminate", onTerminate);
|
||||
worker.postMessage({ symbol, key, methodName, args });
|
||||
}),
|
||||
}
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user