| 1 | import * as Cloudflare from "@/Cloudflare/index.ts"; |
| 2 | import * as Alchemy from "@/index.ts"; |
| 3 | import * as Neon from "@/Neon/index.ts"; |
| 4 | import * as Effect from "effect/Effect"; |
| 5 | import * as Layer from "effect/Layer"; |
| 6 | import * as pathe from "pathe"; |
| 7 | import HyperdriveEffectWorker from "./effect-worker.ts"; |
| 8 | |
| 9 | /** |
| 10 | * Async Worker that binds the shared Hyperdrive Connection via `env`. The |
| 11 | * Connection (and its Neon Postgres origin) share the same logical IDs as |
| 12 | * the ones the effect-worker binds, so the engine dedupes them to a single |
| 13 | * deployed resource that both workers observe. |
| 14 | */ |
| 15 | export const AsyncWorker = Cloudflare.Worker("HyperdriveAsyncWorker", { |
| 16 | main: pathe.resolve(import.meta.dirname, "async-worker.ts"), |
| 17 | env: { |
| 18 | HD: Effect.gen(function* () { |
| 19 | const project = yield* Neon.Project("HyperdriveBindingProject"); |
| 20 | return yield* Cloudflare.Hyperdrive.Connection( |
| 21 | "HyperdriveBindingConnection", |
| 22 | { origin: project.origin }, |
| 23 | ); |
| 24 | }), |
| 25 | }, |
| 26 | }); |
| 27 | |
| 28 | export type AsyncWorkerEnv = Cloudflare.InferEnv<typeof AsyncWorker>; |
| 29 | |
| 30 | /** |
| 31 | * Deploys two Workers that bind ONE shared Hyperdrive Connection — the |
| 32 | * effect-worker (via `Cloudflare.Hyperdrive.Connect`) and the async-worker |
| 33 | * (via `env: { HD: connection }`). Extracted into its own stack file so it |
| 34 | * can also be inspected directly, e.g. |
| 35 | * |
| 36 | * ```sh |
| 37 | * alchemy logs --tail --stage test --config ./test/Cloudflare/Hyperdrive/fixtures/stack.ts |
| 38 | * ``` |
| 39 | */ |
| 40 | export default Alchemy.Stack( |
| 41 | "HyperdriveBindingStack", |
| 42 | { |
| 43 | providers: Layer.merge(Cloudflare.providers(), Neon.providers()), |
| 44 | state: Cloudflare.state(), |
| 45 | }, |
| 46 | Effect.gen(function* () { |
| 47 | const effectWorker = yield* HyperdriveEffectWorker; |
| 48 | const asyncWorker = yield* AsyncWorker; |
| 49 | return { |
| 50 | effectWorkerUrl: effectWorker.url.as<string>(), |
| 51 | asyncWorkerUrl: asyncWorker.url.as<string>(), |
| 52 | }; |
| 53 | }), |
| 54 | ); |