effect-cf 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # effect-cf
2
+
3
+ Effect-native primitives for Cloudflare Workers and bindings.
4
+
5
+ ## Design Goal
6
+
7
+ Cloudflare services should be described as `Context`, `Layer`, and `Effect` values and executed through package-owned Cloudflare entrypoint/runtime boundaries. Consumer code should stay in `Effect`; bindings and storage helpers wrap Promise-returning Cloudflare APIs so applications do not call `Effect.runPromise` or manually bridge Promises.
8
+
9
+ The low-level Worker entrypoint factory is exported as `Worker.make`. It returns a `WorkerEntrypoint` class with a `fetch` handler and optional typed RPC methods. Durable Object support starts with `DurableObject.make`, which routes Durable Object lifecycle methods and RPC handlers through one managed runtime for each Durable Object instance.
10
+
11
+ RPC contracts can be described as classes with `Worker.Tag` and `DurableObject.Tag`. Contract classes expose `.make(...)` for runtime entrypoint creation and `.Binding(...)` / `.Namespace(...)` for typed bindings. Bindings infer call types from the same code-owned contract classes. Definition-backed calls encode/decode arguments and success values with their Effect schemas at Worker and Durable Object boundaries.
12
+
13
+ Binding helpers expose two RPC paths:
14
+
15
+ - `call(...)` awaits one RPC result inside `Effect`. Use it for ordinary structured-cloneable values.
16
+ - `rpc(...)` returns Cloudflare's native RPC thenable/stub without awaiting it, preserving promise pipelining.
17
+ - `scopedCall(...)` awaits the result and registers any `Symbol.dispose` disposer with the current Effect `Scope`.
18
+
19
+ Client APIs use Cloudflare-style provider types, so object results expose pipelined property and method access. `ServerApi` remains available when a plain implementation-shaped `(...args) => Promise<A>` contract is needed.
20
+
21
+ ## Current Exports
22
+
23
+ - `Worker` - WorkerEntrypoint class factory, schema-backed RPC contract tags, and service binding helpers
24
+ - `DurableObject` - Durable Object class factory, schema-backed RPC contract tags, and namespace helpers
25
+ - `WorkerDefinition`, `DurableObjectDefinition` - compatibility exports for the lower-level definition modules
26
+ - `DurableObjectNamespace` - typed Durable Object namespace binding helper
27
+ - `DurableObjectState`, `DurableObjectStorage` - small Effect wrappers for Durable Object state, alarms, SQL, and embedded KV storage
28
+ - `DurableObjectWebSocket` - Durable Object WebSocket upgrade helpers built on `WebSocketPair` and `acceptWebSocket`
29
+ - `Binding` - low-level binding service helper
30
+ - `Kv` - typed KV namespace helper
31
+ - `Rpc` - Cloudflare RPC type helpers, `RpcTarget` / `RpcStub` re-exports, and scoped disposal utilities
32
+ - `ServiceBinding` - typed Worker-to-Worker service binding helper
33
+ - `WorkerEnvironment` - request environment service
34
+
35
+ ## RPC Values
36
+
37
+ Definition-backed RPC methods are intended for schema-backed structured values. If a Cloudflare RPC method returns a lifecycle-managed RPC object or stub, expose that through a lower-level binding API instead of a `WorkerDefinition` / `DurableObjectDefinition` method so disposal remains explicit.
38
+
39
+ ## Durable Object WebSocket Example
40
+
41
+ ```ts
42
+ const request = yield * Worker.NativeRequest;
43
+
44
+ if (!Worker.isWebSocketUpgrade(request)) {
45
+ return new Response("Expected WebSocket upgrade", { status: 426 });
46
+ }
47
+
48
+ const upgrade =
49
+ yield *
50
+ DurableObjectWebSocket.acceptUpgrade({
51
+ tags: ["room:general"],
52
+ attachment: { roomId: "general" },
53
+ });
54
+
55
+ return upgrade.response;
56
+ ```
57
+
58
+ ## Durable Object Example
59
+
60
+ ```ts
61
+ export class Counter extends DurableObject.Tag<Counter>()("Counter", {
62
+ get: DurableObject.method({ success: S.Number }),
63
+ }) {}
64
+
65
+ export const CounterDurableObject = Counter.make(Layer.empty, {
66
+ rpc: {
67
+ get: () =>
68
+ Effect.gen(function* () {
69
+ const state = yield* DurableObjectState.DurableObjectState;
70
+ const row = yield* (yield* state.storage.sql.exec<{ count: number }>(
71
+ "SELECT 0 AS count",
72
+ )).one();
73
+ return row.count;
74
+ }),
75
+ },
76
+ });
77
+ ```
78
+
79
+ Define the Wrangler binding and SQLite migration in the application. This package intentionally does not replace `wrangler.jsonc`.
@@ -0,0 +1,13 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ export { __exportAll as t };