Skip to content

Commit 594a5bb

Browse files
create and execute worker with effect
1 parent 27f5542 commit 594a5bb

7 files changed

Lines changed: 95 additions & 3 deletions

File tree

apps/client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
},
2222
"dependencies": {
2323
"@effect/platform": "^0.77.2",
24+
"@effect/platform-browser": "^0.56.2",
2425
"@local/sync": "workspace:*",
2526
"@tanstack/react-router": "^1.105.0",
2627
"dexie": "^4.0.11",

apps/client/src/routes/$workspaceId.tsx

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
import { Worker } from "@effect/platform";
2+
import { BrowserWorker } from "@effect/platform-browser";
13
import { createFileRoute } from "@tanstack/react-router";
4+
import { Effect } from "effect";
5+
import { startTransition } from "react";
26
import { RuntimeClient } from "../lib/runtime-client";
37
import { WorkspaceManager } from "../lib/services/workspace-manager";
8+
import { useActionEffect } from "../lib/use-action-effect";
9+
import { Bootstrap } from "../workers/schema";
410

511
export const Route = createFileRoute("/$workspaceId")({
612
component: RouteComponent,
@@ -10,5 +16,38 @@ export const Route = createFileRoute("/$workspaceId")({
1016

1117
function RouteComponent() {
1218
const workspace = Route.useLoaderData();
13-
return <div>Hello {workspace.workspaceId}</div>;
19+
20+
const [, bootstrap] = useActionEffect(
21+
({ workspaceId }: { workspaceId: string }) =>
22+
Effect.gen(function* () {
23+
const pool = yield* Worker.makePoolSerialized({ size: 1 });
24+
return yield* pool.broadcast(new Bootstrap({ workspaceId }));
25+
}).pipe(
26+
Effect.scoped,
27+
Effect.provide(
28+
BrowserWorker.layer(
29+
() =>
30+
new globalThis.Worker(
31+
new URL("./src/workers/sync.ts", globalThis.origin),
32+
{ type: "module" }
33+
)
34+
)
35+
)
36+
)
37+
);
38+
39+
return (
40+
<div>
41+
<p>{workspace.workspaceId}</p>
42+
<button
43+
onClick={() =>
44+
startTransition(() =>
45+
bootstrap({ workspaceId: workspace.workspaceId })
46+
)
47+
}
48+
>
49+
Bootstrap
50+
</button>
51+
</div>
52+
);
1453
}

apps/client/src/workers/schema.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Schema } from "effect";
2+
3+
export class Bootstrap extends Schema.TaggedRequest<Bootstrap>()("Bootstrap", {
4+
failure: Schema.Never,
5+
payload: { workspaceId: Schema.String },
6+
success: Schema.Boolean,
7+
}) {}
8+
9+
export const WorkerMessage = Schema.Union(Bootstrap);

apps/client/src/workers/sync.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { WorkerRunner } from "@effect/platform";
2+
import { BrowserWorkerRunner } from "@effect/platform-browser";
3+
import { Effect, Layer } from "effect";
4+
import { WorkerMessage } from "./schema";
5+
6+
const WorkerLive = WorkerRunner.layerSerialized(WorkerMessage, {
7+
Bootstrap: ({ workspaceId }) =>
8+
Effect.gen(function* () {
9+
yield* Effect.log(`Bootstrapping workspace ${workspaceId}`);
10+
return true;
11+
}),
12+
}).pipe(Layer.provide(BrowserWorkerRunner.layer));
13+
14+
Effect.runFork(WorkerRunner.launch(WorkerLive));

apps/client/tsconfig.json

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@
66
"target": "ESNext",
77
"module": "ESNext",
88
"moduleResolution": "Bundler",
9-
"skipLibCheck": true
10-
}
9+
"skipLibCheck": true,
10+
"allowJs": true,
11+
"resolveJsonModule": true,
12+
"moduleDetection": "force",
13+
"isolatedModules": true,
14+
"verbatimModuleSyntax": true,
15+
"noUncheckedIndexedAccess": true,
16+
// "exactOptionalPropertyTypes": true,
17+
"noImplicitOverride": true,
18+
"noEmit": true,
19+
"lib": ["es2022", "dom", "dom.iterable"],
20+
"types": ["vite/client"]
21+
},
22+
"include": ["**/*.ts", "**/*.tsx"],
23+
"exclude": ["node_modules"]
1124
}

apps/client/vite.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ import wasm from "vite-plugin-wasm";
77
// https://vitejs.dev/config/
88
export default defineConfig({
99
plugins: [TanStackRouterVite({}), react(), wasm(), topLevelAwait()],
10+
worker: { format: "es" },
1011
});

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)