1import * as Effect from "effect/Effect";
2import * as Stream from "effect/Stream";
3import * as crypto from "node:crypto";
4import type * as Bundle from "../../../Bundle/Bundle.ts";
5import type { SourceProvider } from "../Source.ts";
6import { bundleSource } from "./shared.ts";
7
8/**
9 * Source provider for `props.script` workers: the raw module source is
10 * uploaded as a single ESM module (`main.js`), bypassing bundling
11 * entirely. The bundle hash is `sha256(script)` — identical to the
12 * pre-SourceProvider `hashScript` slot, so persisted state diffs cleanly
13 * across the refactor.
14 */
15export const makeInlineScriptSource = (script: string): SourceProvider => {
16 const bundle = Effect.sync(() =>
17 crypto.createHash("sha256").update(script).digest("hex"),
18 ).pipe(
19 Effect.map((hash): Bundle.BundleOutput => ({
20 files: [{ path: "main.js", content: script, hash }],
21 hash,
22 })),
23 );
24 return bundleSource({
25 build: () => bundle,
26 // Local dev: a single-element stream — script changes arrive as new
27 // props, which restart the instance via `structuralSignature`.
28 watch: () =>
29 bundle.pipe(
30 Effect.map((output) =>
31 Stream.make({ _tag: "Success", output } as Bundle.BundleWatchEvent),
32 ),
33 ),
34 });
35};