1/// <reference types="@cloudflare/workers-types" />
2
3import * as Effect from "effect/Effect";
4import * as Layer from "effect/Layer";
5import { Worker, WorkerEnvironment } from "../Workers/Worker.ts";
6import type { DispatchNamespace as DispatchNamespaceResource } from "./DispatchNamespace.ts";
7import {
8 type DispatchNamespaceClient,
9 DispatchNamespaceError,
10 Get,
11} from "./Get.ts";
12
13/**
14 * Implementation of the {@link Get} binding that uses a native
15 * `dispatch_namespace` Worker binding.
16 */
17export const GetBinding = Layer.effect(
18 Get,
19 Effect.gen(function* () {
20 const env = yield* WorkerEnvironment;
21 const host = yield* Worker;
22
23 return Effect.fn(function* (namespace: DispatchNamespaceResource) {
24 if (!globalThis.__ALCHEMY_RUNTIME__) {
25 yield* host.bind`${namespace}`({
26 bindings: [
27 {
28 type: "dispatch_namespace",
29 name: namespace.LogicalId,
30 namespace: namespace.name,
31 },
32 ],
33 });
34 }
35
36 const raw = Effect.sync(
37 // Lazy — the WorkerEnvironment binding is not populated until runtime.
38 () => (env as Record<string, DispatchNamespace>)[namespace.LogicalId]!,
39 );
40
41 const self: DispatchNamespaceClient = {
42 raw,
43 get: (name, args, options) =>
44 raw.pipe(
45 Effect.flatMap((ns) =>
46 Effect.try({
47 try: () => ns.get(name, args, options),
48 catch: (error) =>
49 new DispatchNamespaceError({
50 message:
51 error instanceof Error
52 ? error.message
53 : "Unknown dispatch namespace runtime error",
54 cause: error,
55 }),
56 }),
57 ),
58 ),
59 };
60 return self;
61 });
62 }),
63);