1import * as Effect from "effect/Effect";
2import * as Layer from "effect/Layer";
3import { makeReadWriteKVClient } from "./ReadWriteNamespaceBinding.ts";
4import { makeLocalKVNamespaceBinding } from "./NamespaceLocal.ts";
5import { ReadWriteNamespace } from "./ReadWriteNamespace.ts";
6import { makeReadWriteKVHttpClient } from "./ReadWriteNamespaceHttp.ts";
7
8/**
9 * Local implementation of the {@link ReadWriteNamespace} binding — reads and
10 * writes KV values over the Cloudflare HTTP API using the **current
11 * credentials** instead of a native Worker binding
12 * (`ReadWriteNamespaceBinding`) or a scoped API token
13 * (`ReadWriteNamespaceHttp`).
14 *
15 * Provide it on an {@link Action} (or any deploy-time Effect) so you can talk
16 * to a namespace with the same `get`/`put`/`list`/`delete` client you'd use
17 * inside a Worker:
18 *
19 * @example Seeding a namespace from an Action
20 * ```typescript
21 * const Seed = Alchemy.Action(
22 * "Seed",
23 * Effect.gen(function* () {
24 * const kv = yield* Cloudflare.KV.ReadWriteNamespace(namespace);
25 * return Effect.fn(function* () {
26 * yield* kv.put("greeting", "hello world");
27 * return yield* kv.get("greeting");
28 * });
29 * }).pipe(Effect.provide(Cloudflare.KV.ReadWriteNamespaceLocal)),
30 * );
31 * ```
32 *
33 * The namespace id is resolved at apply time through the ambient
34 * {@link RuntimeContext} (in an Action, that's the resolve context the engine
35 * provides around the body), so `ReadWriteNamespace(namespace)` works even
36 * though the namespace is created in the same deploy.
37 */
38export const ReadWriteNamespaceLocal = Layer.effect(
39 ReadWriteNamespace,
40 Effect.suspend(() =>
41 makeLocalKVNamespaceBinding({
42 makeHttpClient: makeReadWriteKVHttpClient,
43 makeNativeClient: makeReadWriteKVClient,
44 }),
45 ),
46);