| 1 | import * as Effect from "effect/Effect"; |
| 2 | import * as Stream from "effect/Stream"; |
| 3 | import * as crypto from "node:crypto"; |
| 4 | import type * as Bundle from "../../../Bundle/Bundle.ts"; |
| 5 | import type { SourceProvider } from "../Source.ts"; |
| 6 | import { 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 | */ |
| 15 | export 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 | }; |