effect-cf 0.39.1 → 0.40.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/CHANGELOG.md +18 -0
- package/README.md +9 -1
- package/dist/AiGateway.d.mts +86 -0
- package/dist/AiGateway.mjs +178 -0
- package/dist/AnalyticsEngine.d.mts +170 -0
- package/dist/AnalyticsEngine.mjs +275 -0
- package/dist/{Artifacts-B3r3RuTB.d.mts → Artifacts.d.mts} +8 -5
- package/dist/{Artifacts-CBxWGeZB.mjs → Artifacts.mjs} +9 -5
- package/dist/Binding.d.mts +45 -0
- package/dist/{Binding-C82jRhdr.mjs → Binding.mjs} +8 -4
- package/dist/BrowserRendering.d.mts +85 -0
- package/dist/BrowserRendering.mjs +81 -0
- package/dist/Cache.d.mts +40 -0
- package/dist/Cache.mjs +51 -0
- package/dist/CloudflareOtlp.d.mts +95 -0
- package/dist/CloudflareOtlp.mjs +125 -0
- package/dist/CloudflareTracer.d.mts +20 -0
- package/dist/CloudflareTracer.mjs +69 -0
- package/dist/ComputerArtifacts.d.mts +2 -2
- package/dist/ComputerArtifacts.mjs +3 -2
- package/dist/ComputerWorkspace.d.mts +36 -31
- package/dist/ComputerWorkspace.mjs +8 -3
- package/dist/ComputerWorkspaceHost.d.mts +1 -1
- package/dist/ComputerWorkspaceHost.mjs +1 -1
- package/dist/{ContainerNamespace-DbLaeFhN.d.mts → ContainerNamespace.d.mts} +16 -12
- package/dist/ContainerNamespace.mjs +165 -0
- package/dist/D1.d.mts +33 -0
- package/dist/D1.mjs +32 -0
- package/dist/DurableObject.d.mts +103 -0
- package/dist/DurableObject.mjs +77 -0
- package/dist/DurableObjectAlarm.d.mts +187 -0
- package/dist/DurableObjectAlarm.mjs +344 -0
- package/dist/DurableObjectDefinition.d.mts +87 -0
- package/dist/DurableObjectDefinition.mjs +125 -0
- package/dist/DurableObjectNamespace.d.mts +154 -0
- package/dist/DurableObjectNamespace.mjs +144 -0
- package/dist/DurableObjectRpcWebSocket.d.mts +112 -0
- package/dist/DurableObjectRpcWebSocket.mjs +547 -0
- package/dist/DurableObjectSqlite.d.mts +11 -0
- package/dist/DurableObjectSqlite.mjs +16 -0
- package/dist/DurableObjectState.d.mts +65 -0
- package/dist/DurableObjectState.mjs +47 -0
- package/dist/DurableObjectStorage.d.mts +112 -0
- package/dist/{DurableObjectState-DLL0YgBd.mjs → DurableObjectStorage.mjs} +19 -157
- package/dist/DurableObjectWebSocket.d.mts +83 -0
- package/dist/DurableObjectWebSocket.mjs +120 -0
- package/dist/Email.d.mts +106 -0
- package/dist/Email.mjs +247 -0
- package/dist/Environment.d.mts +59 -0
- package/dist/{ErrorMessage-Byx2OgNd.mjs → Environment.mjs} +7 -18
- package/dist/{Hyperdrive-HrwFlZ6x.d.mts → Hyperdrive.d.mts} +8 -5
- package/dist/Hyperdrive.mjs +32 -0
- package/dist/HyperdrivePg.d.mts +4 -3
- package/dist/HyperdrivePg.mjs +3 -1
- package/dist/Images.d.mts +191 -0
- package/dist/Images.mjs +112 -0
- package/dist/Kv.d.mts +84 -0
- package/dist/Kv.mjs +132 -0
- package/dist/Mcp.d.mts +5 -3
- package/dist/Mcp.mjs +13 -4
- package/dist/Queue.d.mts +68 -0
- package/dist/Queue.mjs +54 -0
- package/dist/QueueBinding.d.mts +42 -0
- package/dist/QueueBinding.mjs +69 -0
- package/dist/QueueDefinition.d.mts +48 -0
- package/dist/QueueDefinition.mjs +63 -0
- package/dist/R2.d.mts +89 -0
- package/dist/R2.mjs +117 -0
- package/dist/Rpc.d.mts +29 -0
- package/dist/Rpc.mjs +28 -0
- package/dist/RpcDefinition.d.mts +116 -0
- package/dist/RpcDefinition.mjs +184 -0
- package/dist/RpcTracing.d.mts +52 -0
- package/dist/RpcTracing.mjs +77 -0
- package/dist/Sandbox.d.mts +10 -5
- package/dist/Sandbox.mjs +9 -3
- package/dist/ServiceBinding.d.mts +112 -0
- package/dist/ServiceBinding.mjs +145 -0
- package/dist/Vectorize.d.mts +68 -0
- package/dist/Vectorize.mjs +76 -0
- package/dist/Vitest.d.mts +6 -4
- package/dist/Vitest.mjs +8 -4
- package/dist/WebTransport.d.mts +66 -0
- package/dist/WebTransport.mjs +63 -0
- package/dist/Worker.d.mts +139 -0
- package/dist/Worker.mjs +141 -0
- package/dist/WorkerDefinition.d.mts +100 -0
- package/dist/WorkerDefinition.mjs +103 -0
- package/dist/WorkersAi.d.mts +84 -0
- package/dist/WorkersAi.mjs +84 -0
- package/dist/Workflow.d.mts +91 -0
- package/dist/Workflow.mjs +139 -0
- package/dist/{WorkflowBinding-DtVykUCz.d.mts → WorkflowBinding.d.mts} +14 -10
- package/dist/WorkflowBinding.mjs +100 -0
- package/dist/WorkflowDefinition.d.mts +51 -0
- package/dist/WorkflowDefinition.mjs +69 -0
- package/dist/{rolldown-runtime-D7D4PA-g.mjs → _virtual/_rolldown/runtime.mjs} +1 -1
- package/dist/index.d.mts +40 -1800
- package/dist/index.mjs +40 -3123
- package/dist/{ComputerWorkspaceHostRegistry-CY5Fv4Ng.mjs → internal/ComputerWorkspaceHostRegistry.mjs} +1 -1
- package/dist/internal/Entrypoint.mjs +37 -0
- package/dist/internal/ErrorMessage.mjs +17 -0
- package/dist/internal/NativeCallback.mjs +33 -0
- package/dist/internal/RpcInvocation.d.mts +13 -0
- package/dist/internal/RpcInvocation.mjs +34 -0
- package/dist/internal/Runtime.mjs +31 -0
- package/dist/internal/Telemetry.mjs +20 -0
- package/dist/{WorkerContext-Yobnfw-K.mjs → internal/WorkerContext.mjs} +4 -31
- package/package.json +1 -1
- package/src/AiGateway.ts +5 -1
- package/src/AnalyticsEngine.ts +14 -19
- package/src/Artifacts.ts +6 -1
- package/src/Binding.ts +5 -1
- package/src/BrowserRendering.ts +5 -1
- package/src/Cache.ts +5 -1
- package/src/CloudflareOtlp.ts +12 -10
- package/src/CloudflareTracer.ts +7 -1
- package/src/ComputerArtifacts.ts +2 -1
- package/src/ComputerWorkspace.ts +7 -1
- package/src/ContainerNamespace.ts +6 -1
- package/src/D1.ts +4 -1
- package/src/DurableObject.ts +122 -29
- package/src/DurableObjectAlarm.ts +185 -52
- package/src/DurableObjectDefinition.ts +22 -22
- package/src/DurableObjectNamespace.ts +4 -1
- package/src/DurableObjectRpcWebSocket.ts +7 -1
- package/src/DurableObjectSqlite.ts +2 -1
- package/src/DurableObjectState.ts +4 -1
- package/src/DurableObjectStorage.ts +11 -13
- package/src/DurableObjectWebSocket.ts +5 -1
- package/src/Email.ts +5 -1
- package/src/Environment.ts +6 -1
- package/src/Hyperdrive.ts +4 -1
- package/src/HyperdrivePg.ts +3 -1
- package/src/Images.ts +7 -1
- package/src/Kv.ts +7 -1
- package/src/Mcp.ts +13 -13
- package/src/Queue.ts +3 -1
- package/src/QueueBinding.ts +5 -1
- package/src/QueueDefinition.ts +4 -1
- package/src/R2.ts +7 -1
- package/src/Rpc.ts +4 -1
- package/src/RpcDefinition.ts +4 -1
- package/src/RpcTracing.ts +9 -1
- package/src/Sandbox.ts +7 -1
- package/src/ServiceBinding.ts +6 -1
- package/src/Vectorize.ts +7 -1
- package/src/Vitest.ts +5 -1
- package/src/WebTransport.ts +6 -1
- package/src/Worker.ts +10 -16
- package/src/WorkerDefinition.ts +3 -1
- package/src/WorkersAi.ts +7 -1
- package/src/Workflow.ts +8 -11
- package/src/WorkflowBinding.ts +6 -1
- package/src/WorkflowDefinition.ts +4 -1
- package/src/internal/Entrypoint.ts +3 -1
- package/src/internal/ErrorMessage.ts +1 -1
- package/src/internal/NativeCallback.ts +3 -1
- package/src/internal/RpcInvocation.ts +5 -1
- package/src/internal/Runtime.ts +5 -1
- package/src/internal/Telemetry.ts +4 -3
- package/src/internal/WorkerContext.ts +3 -1
- package/dist/Binding-DKcLrQCM.d.mts +0 -94
- package/dist/DurableObjectState-DJ0K-zyd.d.mts +0 -244
- package/dist/Worker-XsGJsCJX.mjs +0 -885
- package/dist/Worker-gV4mDqIs.d.mts +0 -641
package/dist/index.mjs
CHANGED
|
@@ -1,3124 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
const tryWorkersAiPromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
42
|
-
try: evaluate,
|
|
43
|
-
catch: (cause) => workersAiError(binding, operation, cause)
|
|
44
|
-
});
|
|
45
|
-
const tryWorkersAiSync = (binding, operation, evaluate) => Effect.try({
|
|
46
|
-
try: evaluate,
|
|
47
|
-
catch: (cause) => workersAiError(binding, operation, cause)
|
|
48
|
-
});
|
|
49
|
-
const WorkersAiBindingSchema = Schema.declare((value) => Predicate.hasProperty(value, "run") && Predicate.isFunction(value.run) && Predicate.hasProperty(value, "gateway") && Predicate.isFunction(value.gateway) && Predicate.hasProperty(value, "models") && Predicate.isFunction(value.models));
|
|
50
|
-
const decodeWorkersAiBinding = Schema.decodeUnknownOption(WorkersAiBindingSchema);
|
|
51
|
-
const isWorkersAiBinding = (value) => Option.isSome(decodeWorkersAiBinding(value));
|
|
52
|
-
const embeddingResponse = (value) => ({
|
|
53
|
-
data: value.data ?? [],
|
|
54
|
-
[embeddingDimensionsKey]: value[embeddingDimensionsKey] ?? []
|
|
55
|
-
});
|
|
56
|
-
const decodeEmbeddingResponse = Schema.decodeUnknownEffect(Schema.Struct({
|
|
57
|
-
data: Schema.optional(Schema.Array(Schema.Array(Schema.Number))),
|
|
58
|
-
[embeddingDimensionsKey]: Schema.optional(Schema.Array(Schema.Number))
|
|
59
|
-
}));
|
|
60
|
-
const makeClient$13 = (definition) => (ai) => {
|
|
61
|
-
const run = Effect.fn("WorkersAi.run")((model, input, options) => tryWorkersAiPromise(definition.binding, "run", () => {
|
|
62
|
-
return ai.run(model, input, options);
|
|
63
|
-
}));
|
|
64
|
-
return {
|
|
65
|
-
definition,
|
|
66
|
-
aiGatewayLogId: tryWorkersAiSync(definition.binding, "aiGatewayLogId", () => ai.aiGatewayLogId),
|
|
67
|
-
run,
|
|
68
|
-
runEmbedding: Effect.fn("WorkersAi.runEmbedding")(function* (model, input, options) {
|
|
69
|
-
const response = yield* run(model, input, options);
|
|
70
|
-
const decoded = yield* decodeEmbeddingResponse(response).pipe(Effect.mapError((cause) => new WorkersAiOperationError({
|
|
71
|
-
binding: definition.binding,
|
|
72
|
-
operation: "runEmbedding",
|
|
73
|
-
cause
|
|
74
|
-
})));
|
|
75
|
-
return embeddingResponse(decoded);
|
|
76
|
-
}),
|
|
77
|
-
models: Effect.fn("WorkersAi.models")((params) => tryWorkersAiPromise(definition.binding, "models", () => ai.models(params))),
|
|
78
|
-
gateway: (gatewayId) => tryWorkersAiSync(definition.binding, "gateway", () => ai.gateway(gatewayId)),
|
|
79
|
-
rawUnsafe: Effect.succeed(ai)
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
const layer$17 = (tag, definition) => layer$18(tag, definition.binding, (value) => isWorkersAiBinding(value), makeClient$13(definition), { expected: expectedWorkersAiBinding });
|
|
83
|
-
const make$14 = (id) => Tag$13()(id);
|
|
84
|
-
const Tag$13 = () => (id) => {
|
|
85
|
-
const tag = Context.Service()(id);
|
|
86
|
-
const makeLayer = (definition) => layer$17(tag, definition);
|
|
87
|
-
return Object.assign(tag, {
|
|
88
|
-
id,
|
|
89
|
-
layer: makeLayer
|
|
90
|
-
});
|
|
91
|
-
};
|
|
92
|
-
//#endregion
|
|
93
|
-
//#region src/AiGateway.ts
|
|
94
|
-
var AiGateway_exports = /* @__PURE__ */ __exportAll({
|
|
95
|
-
AiGatewayOperationError: () => AiGatewayOperationError,
|
|
96
|
-
Tag: () => Tag$12,
|
|
97
|
-
isAiGatewayBinding: () => isAiGatewayBinding,
|
|
98
|
-
layer: () => layer$16,
|
|
99
|
-
make: () => make$13,
|
|
100
|
-
makeClient: () => makeClient$12,
|
|
101
|
-
makeClientFromAi: () => makeClientFromAi,
|
|
102
|
-
makeHttpClient: () => makeHttpClient
|
|
103
|
-
});
|
|
104
|
-
const expectedAiGatewayBinding = "Workers AI binding with gateway()";
|
|
105
|
-
var AiGatewayOperationError = class extends Data.TaggedError("AiGatewayOperationError") {
|
|
106
|
-
get message() {
|
|
107
|
-
return `AI Gateway ${this.operation} failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
const AiGatewayMetadata = Schema.Record(Schema.String, Schema.Union([
|
|
111
|
-
Schema.String,
|
|
112
|
-
Schema.Number,
|
|
113
|
-
Schema.Boolean,
|
|
114
|
-
Schema.Null
|
|
115
|
-
]));
|
|
116
|
-
const AiGatewayHttpMetadata = Schema.Union([AiGatewayMetadata, Schema.fromJsonString(AiGatewayMetadata)]);
|
|
117
|
-
const AiGatewayLogResponse = Schema.Struct({
|
|
118
|
-
success: Schema.Literal(true),
|
|
119
|
-
result: Schema.Struct({
|
|
120
|
-
id: Schema.String,
|
|
121
|
-
provider: Schema.String,
|
|
122
|
-
model: Schema.String,
|
|
123
|
-
model_type: Schema.optional(Schema.String),
|
|
124
|
-
path: Schema.String,
|
|
125
|
-
duration: Schema.Number,
|
|
126
|
-
request_type: Schema.optional(Schema.String),
|
|
127
|
-
request_content_type: Schema.optional(Schema.String),
|
|
128
|
-
status_code: Schema.Number,
|
|
129
|
-
response_content_type: Schema.optional(Schema.String),
|
|
130
|
-
success: Schema.Boolean,
|
|
131
|
-
cached: Schema.Boolean,
|
|
132
|
-
tokens_in: Schema.optional(Schema.Number),
|
|
133
|
-
tokens_out: Schema.optional(Schema.Number),
|
|
134
|
-
metadata: Schema.optional(AiGatewayHttpMetadata),
|
|
135
|
-
step: Schema.optional(Schema.Number),
|
|
136
|
-
cost: Schema.optional(Schema.Number),
|
|
137
|
-
custom_cost: Schema.optional(Schema.Boolean),
|
|
138
|
-
request_size: Schema.Number,
|
|
139
|
-
request_head: Schema.optional(Schema.String),
|
|
140
|
-
request_head_complete: Schema.Boolean,
|
|
141
|
-
response_size: Schema.Number,
|
|
142
|
-
response_head: Schema.optional(Schema.String),
|
|
143
|
-
response_head_complete: Schema.Boolean,
|
|
144
|
-
created_at: Schema.DateFromString
|
|
145
|
-
})
|
|
146
|
-
});
|
|
147
|
-
const AiGatewayPatchLogResponse = Schema.Struct({
|
|
148
|
-
success: Schema.Literal(true),
|
|
149
|
-
result: Schema.Unknown
|
|
150
|
-
});
|
|
151
|
-
const decodeAiGatewayLogResponse = Schema.decodeUnknownPromise(AiGatewayLogResponse);
|
|
152
|
-
const decodeAiGatewayPatchLogResponse = Schema.decodeUnknownPromise(AiGatewayPatchLogResponse);
|
|
153
|
-
const aiGatewayError = (binding, operation, cause) => new AiGatewayOperationError({
|
|
154
|
-
binding,
|
|
155
|
-
operation,
|
|
156
|
-
cause
|
|
157
|
-
});
|
|
158
|
-
const tryAiGatewayPromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
159
|
-
try: evaluate,
|
|
160
|
-
catch: (cause) => aiGatewayError(binding, operation, cause)
|
|
161
|
-
});
|
|
162
|
-
const mergeAbortSignals = (userSignal, signal) => userSignal === null || userSignal === void 0 ? signal : AbortSignal.any([userSignal, signal]);
|
|
163
|
-
const tryAiGatewaySync = (binding, operation, evaluate) => Effect.try({
|
|
164
|
-
try: evaluate,
|
|
165
|
-
catch: (cause) => aiGatewayError(binding, operation, cause)
|
|
166
|
-
});
|
|
167
|
-
const providerUrl = (baseUrl, path = "") => {
|
|
168
|
-
const url = new URL(baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
|
|
169
|
-
const normalizedPath = path.replace(/^\/+/, "");
|
|
170
|
-
return normalizedPath === "" ? url : new URL(normalizedPath, url);
|
|
171
|
-
};
|
|
172
|
-
const gatewayUrl = (definition) => `https://gateway.ai.cloudflare.com/v1/${definition.accountId}/${definition.gatewayId}/`;
|
|
173
|
-
const ensureSuccessfulResponse = (response) => {
|
|
174
|
-
if (!response.ok) throw new Error(`AI Gateway HTTP request failed with status ${response.status}`);
|
|
175
|
-
};
|
|
176
|
-
const isAiGatewayBinding = (value) => isWorkersAiBinding(value);
|
|
177
|
-
const makeClient$12 = (definition, gateway) => ({
|
|
178
|
-
definition,
|
|
179
|
-
run: Effect.fn("AiGateway.run")((data, options) => tryAiGatewayPromise(definition.binding, "run", () => gateway.run(Array.isArray(data) ? [...data] : data, options))),
|
|
180
|
-
getUrl: Effect.fn("AiGateway.getUrl")((provider) => tryAiGatewayPromise(definition.binding, "getUrl", () => gateway.getUrl(provider))),
|
|
181
|
-
fetch: Effect.fn("AiGateway.fetch")(function* (options) {
|
|
182
|
-
const baseUrl = yield* tryAiGatewayPromise(definition.binding, "getUrl", () => gateway.getUrl(options.provider));
|
|
183
|
-
return yield* tryAiGatewayPromise(definition.binding, "fetch", (signal) => fetch(providerUrl(baseUrl, options.path).href, {
|
|
184
|
-
...options.init,
|
|
185
|
-
signal: mergeAbortSignals(options.init?.signal, signal)
|
|
186
|
-
}));
|
|
187
|
-
}),
|
|
188
|
-
patchLog: Effect.fn("AiGateway.patchLog")((logId, data) => tryAiGatewayPromise(definition.binding, "patchLog", () => gateway.patchLog(logId, data))),
|
|
189
|
-
getLog: Effect.fn("AiGateway.getLog")((logId) => tryAiGatewayPromise(definition.binding, "getLog", () => gateway.getLog(logId))),
|
|
190
|
-
rawUnsafe: Effect.succeed(gateway)
|
|
191
|
-
});
|
|
192
|
-
const makeClientFromAi = (definition, ai) => {
|
|
193
|
-
const gateway = tryAiGatewaySync(definition.binding, "gateway", () => ai.gateway(definition.gatewayId));
|
|
194
|
-
const withGateway = (operation) => gateway.pipe(Effect.flatMap(operation));
|
|
195
|
-
return {
|
|
196
|
-
definition,
|
|
197
|
-
run: (data, options) => withGateway((raw) => makeClient$12(definition, raw).run(data, options)),
|
|
198
|
-
getUrl: (provider) => withGateway((raw) => makeClient$12(definition, raw).getUrl(provider)),
|
|
199
|
-
fetch: (options) => withGateway((raw) => makeClient$12(definition, raw).fetch(options)),
|
|
200
|
-
patchLog: (logId, data) => withGateway((raw) => makeClient$12(definition, raw).patchLog(logId, data)),
|
|
201
|
-
getLog: (logId) => withGateway((raw) => makeClient$12(definition, raw).getLog(logId)),
|
|
202
|
-
rawUnsafe: gateway
|
|
203
|
-
};
|
|
204
|
-
};
|
|
205
|
-
const makeHttpClient = (definition, request = fetch) => {
|
|
206
|
-
const binding = definition.binding ?? "AI_GATEWAY";
|
|
207
|
-
const clientDefinition = {
|
|
208
|
-
binding,
|
|
209
|
-
gatewayId: definition.gatewayId,
|
|
210
|
-
accountId: definition.accountId
|
|
211
|
-
};
|
|
212
|
-
const getUrl = (provider) => Effect.succeed(provider === void 0 ? gatewayUrl(definition) : providerUrl(gatewayUrl(definition), provider).href.replace(/\/$/, ""));
|
|
213
|
-
const extraHeaders = (options) => {
|
|
214
|
-
if (options?.extraHeaders === void 0 || Array.isArray(options.extraHeaders) || options.extraHeaders instanceof Headers) return options?.extraHeaders;
|
|
215
|
-
return Object.fromEntries(Object.entries(options.extraHeaders).map(([key, value]) => [key, String(value)]));
|
|
216
|
-
};
|
|
217
|
-
return {
|
|
218
|
-
definition: clientDefinition,
|
|
219
|
-
run: Effect.fn("AiGateway.run")((data, options) => tryAiGatewayPromise(binding, "run", (signal) => request(gatewayUrl(definition), {
|
|
220
|
-
method: "POST",
|
|
221
|
-
body: JSON.stringify(data),
|
|
222
|
-
headers: new Headers({
|
|
223
|
-
"content-type": "application/json",
|
|
224
|
-
...Object.fromEntries(new Headers(extraHeaders(options)).entries())
|
|
225
|
-
}),
|
|
226
|
-
signal: mergeAbortSignals(options?.signal, signal)
|
|
227
|
-
}))),
|
|
228
|
-
getUrl,
|
|
229
|
-
fetch: Effect.fn("AiGateway.fetch")((options) => getUrl(options.provider).pipe(Effect.flatMap((baseUrl) => tryAiGatewayPromise(binding, "fetch", (signal) => request(providerUrl(baseUrl, options.path).href, {
|
|
230
|
-
...options.init,
|
|
231
|
-
signal: mergeAbortSignals(options.init?.signal, signal)
|
|
232
|
-
}))))),
|
|
233
|
-
patchLog: Effect.fn("AiGateway.patchLog")((logId, data) => tryAiGatewayPromise(binding, "patchLog", async (signal) => {
|
|
234
|
-
const response = await request(providerUrl(gatewayUrl(definition), `logs/${logId}`).href, {
|
|
235
|
-
method: "PATCH",
|
|
236
|
-
body: JSON.stringify(data),
|
|
237
|
-
headers: { "content-type": "application/json" },
|
|
238
|
-
signal
|
|
239
|
-
});
|
|
240
|
-
ensureSuccessfulResponse(response);
|
|
241
|
-
await decodeAiGatewayPatchLogResponse(await response.json());
|
|
242
|
-
})),
|
|
243
|
-
getLog: Effect.fn("AiGateway.getLog")((logId) => tryAiGatewayPromise(binding, "getLog", async (signal) => {
|
|
244
|
-
const response = await request(providerUrl(gatewayUrl(definition), `logs/${logId}`).href, { signal });
|
|
245
|
-
ensureSuccessfulResponse(response);
|
|
246
|
-
return (await decodeAiGatewayLogResponse(await response.json())).result;
|
|
247
|
-
})),
|
|
248
|
-
rawUnsafe: Effect.fail(aiGatewayError(binding, "rawUnsafe", /* @__PURE__ */ new TypeError("HTTP AI Gateway clients have no raw binding")))
|
|
249
|
-
};
|
|
250
|
-
};
|
|
251
|
-
const layer$16 = (tag, definition) => layer$18(tag, definition.binding, isAiGatewayBinding, (ai) => makeClientFromAi(definition, ai), { expected: expectedAiGatewayBinding });
|
|
252
|
-
const make$13 = (id) => Tag$12()(id);
|
|
253
|
-
const Tag$12 = () => (id) => {
|
|
254
|
-
const tag = Context.Service()(id);
|
|
255
|
-
const makeLayer = (definition) => layer$16(tag, definition);
|
|
256
|
-
return Object.assign(tag, {
|
|
257
|
-
id,
|
|
258
|
-
layer: makeLayer
|
|
259
|
-
});
|
|
260
|
-
};
|
|
261
|
-
//#endregion
|
|
262
|
-
//#region src/AnalyticsEngine.ts
|
|
263
|
-
var AnalyticsEngine_exports = /* @__PURE__ */ __exportAll({
|
|
264
|
-
AnalyticsEngineDataPointSchema: () => AnalyticsEngineDataPointSchema,
|
|
265
|
-
AnalyticsEngineFieldValueSchema: () => AnalyticsEngineFieldValueSchema,
|
|
266
|
-
AnalyticsEngineOperationError: () => AnalyticsEngineOperationError,
|
|
267
|
-
AnalyticsEngineQueryError: () => AnalyticsEngineQueryError,
|
|
268
|
-
AnalyticsEngineWriteValidationError: () => AnalyticsEngineWriteValidationError,
|
|
269
|
-
QueryTag: () => QueryTag,
|
|
270
|
-
Tag: () => Tag$11,
|
|
271
|
-
isAnalyticsEngineDataset: () => isAnalyticsEngineDataset,
|
|
272
|
-
layer: () => layer$15,
|
|
273
|
-
layerFetch: () => layerFetch,
|
|
274
|
-
layerFetchConfig: () => layerFetchConfig,
|
|
275
|
-
make: () => make$12,
|
|
276
|
-
makeClient: () => makeClient$11,
|
|
277
|
-
makeQuery: () => makeQuery,
|
|
278
|
-
makeQueryClient: () => makeQueryClient,
|
|
279
|
-
queryConfig: () => queryConfig,
|
|
280
|
-
queryLayer: () => queryLayer,
|
|
281
|
-
queryLayerConfig: () => queryLayerConfig,
|
|
282
|
-
writeLimits: () => writeLimits
|
|
283
|
-
});
|
|
284
|
-
const expectedAnalyticsEngineDataset = "Analytics Engine dataset binding with writeDataPoint()";
|
|
285
|
-
const defaultQueryApiBaseUrl = "https://api.cloudflare.com/client/v4";
|
|
286
|
-
const textEncoder$1 = new TextEncoder();
|
|
287
|
-
const writeLimits = {
|
|
288
|
-
maxBlobs: 20,
|
|
289
|
-
maxDoubles: 20,
|
|
290
|
-
maxIndexes: 1,
|
|
291
|
-
maxBlobBytes: 16384,
|
|
292
|
-
maxIndexBytes: 96,
|
|
293
|
-
maxDataPointsPerInvocation: 250
|
|
294
|
-
};
|
|
295
|
-
const queryColumnSchema = Schema.Struct({
|
|
296
|
-
name: Schema.String,
|
|
297
|
-
type: Schema.String
|
|
298
|
-
});
|
|
299
|
-
const queryRowSchema = Schema.Record(Schema.String, Schema.Unknown);
|
|
300
|
-
const queryResponseSchema = Schema.Struct({
|
|
301
|
-
meta: Schema.Array(queryColumnSchema),
|
|
302
|
-
data: Schema.Array(queryRowSchema),
|
|
303
|
-
rows: Schema.Number
|
|
304
|
-
});
|
|
305
|
-
const AnalyticsEngineFieldValueSchema = Schema.NullOr(Schema.Union([Schema.String, Schema.instanceOf(ArrayBuffer)]));
|
|
306
|
-
const AnalyticsEngineDataPointSchema = Schema.Struct({
|
|
307
|
-
indexes: Schema.optional(Schema.Array(AnalyticsEngineFieldValueSchema)),
|
|
308
|
-
doubles: Schema.optional(Schema.Array(Schema.Finite)),
|
|
309
|
-
blobs: Schema.optional(Schema.Array(AnalyticsEngineFieldValueSchema))
|
|
310
|
-
});
|
|
311
|
-
const decodeQueryResponse = Schema.decodeUnknownEffect(queryResponseSchema);
|
|
312
|
-
const decodeDataPoint = Schema.decodeUnknownEffect(AnalyticsEngineDataPointSchema);
|
|
313
|
-
var AnalyticsEngineOperationError = class extends Data.TaggedError("AnalyticsEngineOperationError") {
|
|
314
|
-
get message() {
|
|
315
|
-
return `Analytics Engine ${this.operation} failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
var AnalyticsEngineWriteValidationError = class extends Data.TaggedError("AnalyticsEngineWriteValidationError") {
|
|
319
|
-
get message() {
|
|
320
|
-
return `Analytics Engine ${this.operation} for binding "${this.binding}" failed validation: ${violationsMessage(this.violations)}`;
|
|
321
|
-
}
|
|
322
|
-
};
|
|
323
|
-
var AnalyticsEngineQueryError = class extends Data.TaggedError("AnalyticsEngineQueryError") {};
|
|
324
|
-
const analyticsEngineError = (binding, operation, cause) => new AnalyticsEngineOperationError({
|
|
325
|
-
binding,
|
|
326
|
-
operation,
|
|
327
|
-
cause
|
|
328
|
-
});
|
|
329
|
-
const analyticsEngineWriteValidationError = (binding, operation, violations, cause) => new AnalyticsEngineWriteValidationError({
|
|
330
|
-
binding,
|
|
331
|
-
operation,
|
|
332
|
-
violations,
|
|
333
|
-
cause
|
|
334
|
-
});
|
|
335
|
-
const analyticsEngineQueryError = (definition, operation, message, options) => new AnalyticsEngineQueryError({
|
|
336
|
-
operation,
|
|
337
|
-
accountId: definition.accountId,
|
|
338
|
-
message,
|
|
339
|
-
status: options?.status,
|
|
340
|
-
body: options?.body,
|
|
341
|
-
cause: options?.cause
|
|
342
|
-
});
|
|
343
|
-
const tryAnalyticsEngineSync = (binding, operation, evaluate) => Effect.try({
|
|
344
|
-
try: evaluate,
|
|
345
|
-
catch: (cause) => analyticsEngineError(binding, operation, cause)
|
|
346
|
-
});
|
|
347
|
-
const resolveWritePolicy = (defaults, options) => ({ onInvalid: options?.onInvalid ?? defaults?.onInvalid ?? "error" });
|
|
348
|
-
const fieldPath = (prefix, field) => prefix === "" ? field : `${prefix}.${field}`;
|
|
349
|
-
const indexedPath = (prefix, field, index) => `${fieldPath(prefix, field)}[${index}]`;
|
|
350
|
-
const byteLength$1 = (value) => {
|
|
351
|
-
if (value === null) return 0;
|
|
352
|
-
return Predicate.isString(value) ? textEncoder$1.encode(value).byteLength : value.byteLength;
|
|
353
|
-
};
|
|
354
|
-
const lengthViolation = (path, label, actual, limit) => ({
|
|
355
|
-
path,
|
|
356
|
-
message: `${label} exceeds Cloudflare Analytics Engine limit`,
|
|
357
|
-
actual,
|
|
358
|
-
limit
|
|
359
|
-
});
|
|
360
|
-
const validateDataPointLimits = (dataPoint, pathPrefix = "") => {
|
|
361
|
-
const violations = [];
|
|
362
|
-
if (dataPoint.blobs !== void 0 && dataPoint.blobs.length > writeLimits.maxBlobs) violations.push(lengthViolation(fieldPath(pathPrefix, "blobs"), "blobs", dataPoint.blobs.length, writeLimits.maxBlobs));
|
|
363
|
-
if (dataPoint.doubles !== void 0 && dataPoint.doubles.length > writeLimits.maxDoubles) violations.push(lengthViolation(fieldPath(pathPrefix, "doubles"), "doubles", dataPoint.doubles.length, writeLimits.maxDoubles));
|
|
364
|
-
if (dataPoint.indexes !== void 0 && dataPoint.indexes.length > writeLimits.maxIndexes) violations.push(lengthViolation(fieldPath(pathPrefix, "indexes"), "indexes", dataPoint.indexes.length, writeLimits.maxIndexes));
|
|
365
|
-
if (dataPoint.blobs !== void 0) {
|
|
366
|
-
const blobBytes = dataPoint.blobs.reduce((total, value) => total + byteLength$1(value), 0);
|
|
367
|
-
if (blobBytes > writeLimits.maxBlobBytes) violations.push(lengthViolation(fieldPath(pathPrefix, "blobs"), "blob bytes", blobBytes, writeLimits.maxBlobBytes));
|
|
368
|
-
}
|
|
369
|
-
if (dataPoint.indexes !== void 0) for (let index = 0; index < dataPoint.indexes.length; index++) {
|
|
370
|
-
const indexBytes = byteLength$1(dataPoint.indexes[index] ?? null);
|
|
371
|
-
if (indexBytes > writeLimits.maxIndexBytes) violations.push(lengthViolation(indexedPath(pathPrefix, "indexes", index), "index bytes", indexBytes, writeLimits.maxIndexBytes));
|
|
372
|
-
}
|
|
373
|
-
return violations;
|
|
374
|
-
};
|
|
375
|
-
const schemaViolation = (pathPrefix, cause) => ({
|
|
376
|
-
path: pathPrefix === "" ? "$" : pathPrefix,
|
|
377
|
-
message: cause.message
|
|
378
|
-
});
|
|
379
|
-
const toAnalyticsEngineDataPoint = (dataPoint) => {
|
|
380
|
-
const result = {};
|
|
381
|
-
if (dataPoint.indexes !== void 0) result.indexes = [...dataPoint.indexes];
|
|
382
|
-
if (dataPoint.doubles !== void 0) result.doubles = [...dataPoint.doubles];
|
|
383
|
-
if (dataPoint.blobs !== void 0) result.blobs = [...dataPoint.blobs];
|
|
384
|
-
return result;
|
|
385
|
-
};
|
|
386
|
-
const validateDataPoint = (binding, operation, dataPoint, pathPrefix = "") => Effect.gen(function* () {
|
|
387
|
-
const decoded = yield* decodeDataPoint(dataPoint).pipe(Effect.mapError((cause) => analyticsEngineWriteValidationError(binding, operation, [schemaViolation(pathPrefix, cause)], cause)));
|
|
388
|
-
const validated = toAnalyticsEngineDataPoint(decoded);
|
|
389
|
-
const violations = validateDataPointLimits(validated, pathPrefix);
|
|
390
|
-
if (violations.length > 0) return yield* Effect.fail(analyticsEngineWriteValidationError(binding, operation, violations));
|
|
391
|
-
return validated;
|
|
392
|
-
});
|
|
393
|
-
const validateOptionalDataPoint = (binding, operation, dataPoint) => dataPoint === void 0 ? Effect.succeed(void 0) : validateDataPoint(binding, operation, dataPoint);
|
|
394
|
-
const validateDataPoints = (binding, operation, dataPoints, policy) => Effect.gen(function* () {
|
|
395
|
-
const points = dataPoints.length > writeLimits.maxDataPointsPerInvocation && policy.onInvalid === "drop" ? dataPoints.slice(0, writeLimits.maxDataPointsPerInvocation) : dataPoints;
|
|
396
|
-
const violations = [];
|
|
397
|
-
if (dataPoints.length > writeLimits.maxDataPointsPerInvocation && policy.onInvalid === "error") violations.push(lengthViolation("dataPoints", "data points per Worker invocation", dataPoints.length, writeLimits.maxDataPointsPerInvocation));
|
|
398
|
-
const validPoints = [];
|
|
399
|
-
for (let index = 0; index < points.length; index++) {
|
|
400
|
-
const result = yield* Effect.result(validateDataPoint(binding, operation, points[index], `dataPoints[${index}]`));
|
|
401
|
-
if (Result.isSuccess(result)) validPoints.push(result.success);
|
|
402
|
-
else if (policy.onInvalid === "error") violations.push(...result.failure.violations);
|
|
403
|
-
}
|
|
404
|
-
if (violations.length > 0) return yield* Effect.fail(analyticsEngineWriteValidationError(binding, operation, violations));
|
|
405
|
-
return validPoints;
|
|
406
|
-
});
|
|
407
|
-
const writeChunks = (binding, operation, dataset, dataPoints) => Effect.gen(function* () {
|
|
408
|
-
for (const point of dataPoints) yield* tryAnalyticsEngineSync(binding, operation, () => dataset.writeDataPoint(point));
|
|
409
|
-
});
|
|
410
|
-
const queryApiUrl = (definition) => {
|
|
411
|
-
const baseUrl = new URL(definition.apiBaseUrl ?? defaultQueryApiBaseUrl);
|
|
412
|
-
baseUrl.pathname = `${baseUrl.pathname.replace(/\/+$/, "")}/accounts/${definition.accountId}/analytics_engine/sql`;
|
|
413
|
-
return baseUrl.href;
|
|
414
|
-
};
|
|
415
|
-
const queryRequest = (definition, sql, options) => {
|
|
416
|
-
let request = HttpClientRequest.post(queryApiUrl(definition)).pipe(HttpClientRequest.bodyText(sql, "text/plain;charset=UTF-8"));
|
|
417
|
-
if (options?.headers !== void 0) request = HttpClientRequest.setHeaders(request, options.headers);
|
|
418
|
-
return HttpClientRequest.bearerToken(request, definition.apiToken);
|
|
419
|
-
};
|
|
420
|
-
const responseText = (definition, response, operation) => response.text.pipe(Effect.catch((cause) => Effect.fail(analyticsEngineQueryError(definition, operation, "Failed to read Analytics Engine SQL API response body", { cause }))));
|
|
421
|
-
const executeQueryRequest = (definition, httpClient, sql, options) => Effect.gen(function* () {
|
|
422
|
-
const request = yield* Effect.try({
|
|
423
|
-
try: () => queryRequest(definition, sql, options),
|
|
424
|
-
catch: (cause) => analyticsEngineQueryError(definition, "query", "Invalid Analytics Engine SQL API URL", { cause })
|
|
425
|
-
});
|
|
426
|
-
const response = yield* httpClient.execute(request).pipe(Effect.mapError((cause) => analyticsEngineQueryError(definition, "query", "Analytics Engine SQL API request failed", { cause })));
|
|
427
|
-
if (response.status < 200 || response.status >= 300) {
|
|
428
|
-
const body = yield* responseText(definition, response, "queryErrorBody");
|
|
429
|
-
return yield* Effect.fail(analyticsEngineQueryError(definition, "query", `Analytics Engine SQL API returned HTTP ${response.status}`, {
|
|
430
|
-
status: response.status,
|
|
431
|
-
body
|
|
432
|
-
}));
|
|
433
|
-
}
|
|
434
|
-
return response;
|
|
435
|
-
});
|
|
436
|
-
const makeQueryClientWith = (definition, httpClient) => {
|
|
437
|
-
const raw = Effect.fn("AnalyticsEngine.raw")((sql, options) => executeQueryRequest(definition, httpClient, sql, options));
|
|
438
|
-
const query = Effect.fn("AnalyticsEngine.query")(function* (sql, options) {
|
|
439
|
-
const json = yield* (yield* raw(sql, options)).json.pipe(Effect.catch((cause) => Effect.fail(analyticsEngineQueryError(definition, "json", "Failed to read Analytics Engine SQL API JSON response body", { cause }))));
|
|
440
|
-
return yield* decodeQueryResponse(json);
|
|
441
|
-
});
|
|
442
|
-
const queryResult = (row, sql, options) => Effect.gen(function* () {
|
|
443
|
-
const result = yield* query(sql, options);
|
|
444
|
-
const decodeRow = Schema.decodeUnknownEffect(row);
|
|
445
|
-
const data = [];
|
|
446
|
-
for (const value of result.data) data.push(yield* decodeRow(value));
|
|
447
|
-
return {
|
|
448
|
-
...result,
|
|
449
|
-
data,
|
|
450
|
-
rows: result.rows
|
|
451
|
-
};
|
|
452
|
-
}).pipe(Effect.withSpan("AnalyticsEngine.queryResult"));
|
|
453
|
-
return {
|
|
454
|
-
definition,
|
|
455
|
-
raw,
|
|
456
|
-
query,
|
|
457
|
-
queryResult,
|
|
458
|
-
queryRows: (row, sql, options) => queryResult(row, sql, options).pipe(Effect.map((result) => result.data), Effect.withSpan("AnalyticsEngine.queryRows")),
|
|
459
|
-
queryOne: (row, sql, options) => queryResult(row, sql, options).pipe(Effect.map((result) => result.data[0] === void 0 ? Option.none() : Option.some(result.data[0])), Effect.withSpan("AnalyticsEngine.queryOne")),
|
|
460
|
-
queryText: Effect.fn("AnalyticsEngine.queryText")((sql, options) => raw(sql, options).pipe(Effect.flatMap((response) => responseText(definition, response, "text"))))
|
|
461
|
-
};
|
|
462
|
-
};
|
|
463
|
-
const makeQueryClient = (definition) => Effect.map(HttpClient.HttpClient, (httpClient) => makeQueryClientWith(definition, httpClient));
|
|
464
|
-
const isAnalyticsEngineDataset = (value) => Predicate.hasProperty(value, "writeDataPoint") && Predicate.isFunction(value.writeDataPoint);
|
|
465
|
-
const makeClient$11 = (definition, defaults) => (dataset) => {
|
|
466
|
-
return {
|
|
467
|
-
definition,
|
|
468
|
-
writeDataPoint: Effect.fn("AnalyticsEngine.writeDataPoint")((dataPoint, options) => {
|
|
469
|
-
const policy = resolveWritePolicy(defaults, options);
|
|
470
|
-
return validateOptionalDataPoint(definition.binding, "writeDataPoint", dataPoint).pipe(Effect.matchEffect({
|
|
471
|
-
onFailure: (error) => policy.onInvalid === "drop" ? Effect.succeed(void 0) : Effect.fail(error),
|
|
472
|
-
onSuccess: (point) => tryAnalyticsEngineSync(definition.binding, "writeDataPoint", () => dataset.writeDataPoint(point))
|
|
473
|
-
}));
|
|
474
|
-
}),
|
|
475
|
-
writeDataPoints: Effect.fn("AnalyticsEngine.writeDataPoints")(function* (dataPoints, options) {
|
|
476
|
-
const policy = resolveWritePolicy(defaults, options);
|
|
477
|
-
const validPoints = yield* validateDataPoints(definition.binding, "writeDataPoints", dataPoints, policy);
|
|
478
|
-
yield* writeChunks(definition.binding, "writeDataPoints", dataset, validPoints);
|
|
479
|
-
}),
|
|
480
|
-
rawUnsafe: Effect.succeed(dataset)
|
|
481
|
-
};
|
|
482
|
-
};
|
|
483
|
-
const queryConfig = (options) => Config.all({
|
|
484
|
-
accountId: options?.accountId ?? Config.string("CLOUDFLARE_ACCOUNT_ID"),
|
|
485
|
-
apiToken: options?.apiToken ?? Config.redacted("CLOUDFLARE_API_TOKEN"),
|
|
486
|
-
apiBaseUrl: options?.apiBaseUrl ?? Config.string("CLOUDFLARE_API_BASE_URL").pipe(Config.withDefault(defaultQueryApiBaseUrl))
|
|
487
|
-
});
|
|
488
|
-
const queryLayer = (tag, definition) => Layer.effect(tag, makeQueryClient(definition));
|
|
489
|
-
const layerFetch = (tag, definition) => queryLayer(tag, definition).pipe(Layer.provide(FetchHttpClient.layer));
|
|
490
|
-
const queryLayerConfig = (tag, config = queryConfig()) => Layer.effect(tag, Effect.gen(function* () {
|
|
491
|
-
const definition = yield* config;
|
|
492
|
-
return yield* makeQueryClient(definition);
|
|
493
|
-
}));
|
|
494
|
-
const layerFetchConfig = (tag, config = queryConfig()) => queryLayerConfig(tag, config).pipe(Layer.provide(FetchHttpClient.layer));
|
|
495
|
-
const layer$15 = (tag, definition) => layer$18(tag, definition.binding, isAnalyticsEngineDataset, makeClient$11(definition, definition.write), { expected: expectedAnalyticsEngineDataset });
|
|
496
|
-
const make$12 = (id) => Tag$11()(id);
|
|
497
|
-
const makeQuery = (id) => QueryTag()(id);
|
|
498
|
-
const Tag$11 = () => (id) => {
|
|
499
|
-
const tag = Context.Service()(id);
|
|
500
|
-
const makeLayer = (definition) => layer$15(tag, definition);
|
|
501
|
-
return Object.assign(tag, {
|
|
502
|
-
id,
|
|
503
|
-
layer: makeLayer
|
|
504
|
-
});
|
|
505
|
-
};
|
|
506
|
-
const QueryTag = () => (id) => {
|
|
507
|
-
const tag = Context.Service()(id);
|
|
508
|
-
const makeLayer = (definition) => queryLayer(tag, definition);
|
|
509
|
-
const makeLayerFetch = (definition) => layerFetch(tag, definition);
|
|
510
|
-
const makeLayerConfig = (config) => queryLayerConfig(tag, config);
|
|
511
|
-
const makeLayerFetchConfig = (config) => layerFetchConfig(tag, config);
|
|
512
|
-
return Object.assign(tag, {
|
|
513
|
-
id,
|
|
514
|
-
layer: makeLayer,
|
|
515
|
-
layerFetch: makeLayerFetch,
|
|
516
|
-
layerConfig: makeLayerConfig,
|
|
517
|
-
layerFetchConfig: makeLayerFetchConfig
|
|
518
|
-
});
|
|
519
|
-
};
|
|
520
|
-
//#endregion
|
|
521
|
-
//#region src/BrowserRendering.ts
|
|
522
|
-
var BrowserRendering_exports = /* @__PURE__ */ __exportAll({
|
|
523
|
-
BrowserRenderingOperationError: () => BrowserRenderingOperationError,
|
|
524
|
-
Tag: () => Tag$10,
|
|
525
|
-
isBrowserRenderingBinding: () => isBrowserRenderingBinding,
|
|
526
|
-
layer: () => layer$14,
|
|
527
|
-
make: () => make$11,
|
|
528
|
-
makeClient: () => makeClient$10
|
|
529
|
-
});
|
|
530
|
-
const expectedBrowserRenderingBinding = "Browser Rendering binding resource";
|
|
531
|
-
var BrowserRenderingOperationError = class extends Data.TaggedError("BrowserRenderingOperationError") {
|
|
532
|
-
get message() {
|
|
533
|
-
return `Browser Rendering ${this.operation} failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
534
|
-
}
|
|
535
|
-
};
|
|
536
|
-
const browserRenderingError = (binding, operation, cause) => new BrowserRenderingOperationError({
|
|
537
|
-
binding,
|
|
538
|
-
operation,
|
|
539
|
-
cause
|
|
540
|
-
});
|
|
541
|
-
const tryBrowserRenderingPromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
542
|
-
try: evaluate,
|
|
543
|
-
catch: (cause) => browserRenderingError(binding, operation, cause)
|
|
544
|
-
});
|
|
545
|
-
const tryBrowserRenderingSync = (binding, operation, evaluate) => Effect.try({
|
|
546
|
-
try: evaluate,
|
|
547
|
-
catch: (cause) => browserRenderingError(binding, operation, cause)
|
|
548
|
-
});
|
|
549
|
-
const missingMethod = (binding, operation) => Effect.fail(browserRenderingError(binding, operation, /* @__PURE__ */ new TypeError(`Browser Rendering object does not expose ${operation}()`)));
|
|
550
|
-
const wrapPage = (binding, page) => ({
|
|
551
|
-
raw: page,
|
|
552
|
-
goto: (url, options) => page.goto === void 0 ? missingMethod(binding, "goto") : tryBrowserRenderingPromise(binding, "goto", () => page.goto(url, options)),
|
|
553
|
-
setContent: (html, options) => page.setContent === void 0 ? missingMethod(binding, "setContent") : tryBrowserRenderingPromise(binding, "setContent", () => page.setContent(html, options)),
|
|
554
|
-
content: page.content === void 0 ? missingMethod(binding, "content") : tryBrowserRenderingPromise(binding, "content", () => page.content()),
|
|
555
|
-
screenshot: (options) => {
|
|
556
|
-
const screenshot = page.screenshot?.bind(page);
|
|
557
|
-
return screenshot === void 0 ? missingMethod(binding, "screenshot") : tryBrowserRenderingPromise(binding, "screenshot", () => screenshot(options));
|
|
558
|
-
},
|
|
559
|
-
pdf: (options) => {
|
|
560
|
-
const pdf = page.pdf?.bind(page);
|
|
561
|
-
return pdf === void 0 ? missingMethod(binding, "pdf") : tryBrowserRenderingPromise(binding, "pdf", () => pdf(options));
|
|
562
|
-
},
|
|
563
|
-
evaluate: (pageFunction, ...args) => {
|
|
564
|
-
const evaluate = page.evaluate?.bind(page);
|
|
565
|
-
return evaluate === void 0 ? missingMethod(binding, "evaluate") : tryBrowserRenderingPromise(binding, "evaluate", () => evaluate(pageFunction, ...args));
|
|
566
|
-
},
|
|
567
|
-
close: (options) => page.close === void 0 ? Effect.void : tryBrowserRenderingPromise(binding, "closePage", () => page.close(options))
|
|
568
|
-
});
|
|
569
|
-
const wrapBrowser = (binding, browser) => ({
|
|
570
|
-
raw: browser,
|
|
571
|
-
newPage: tryBrowserRenderingPromise(binding, "newPage", () => browser.newPage()).pipe(Effect.map((page) => wrapPage(binding, page))),
|
|
572
|
-
version: browser.version === void 0 ? missingMethod(binding, "version") : tryBrowserRenderingPromise(binding, "version", () => browser.version()),
|
|
573
|
-
close: browser.close === void 0 ? Effect.void : tryBrowserRenderingPromise(binding, "closeBrowser", () => browser.close()),
|
|
574
|
-
disconnect: browser.disconnect === void 0 ? Effect.void : tryBrowserRenderingSync(binding, "disconnect", () => browser.disconnect())
|
|
575
|
-
});
|
|
576
|
-
const isBrowserRenderingBinding = (value) => Predicate.isObjectOrArray(value) || Predicate.isFunction(value);
|
|
577
|
-
const makeClient$10 = (definition) => (binding) => ({
|
|
578
|
-
definition,
|
|
579
|
-
launchWith: (launch, options) => tryBrowserRenderingPromise(definition.binding, "launch", () => launch(binding, options)).pipe(Effect.map((browser) => wrapBrowser(definition.binding, browser)), Effect.withSpan("BrowserRendering.launchWith")),
|
|
580
|
-
connectWith: (connect, options) => tryBrowserRenderingPromise(definition.binding, "connect", () => connect(binding, options)).pipe(Effect.map((browser) => wrapBrowser(definition.binding, browser)), Effect.withSpan("BrowserRendering.connectWith")),
|
|
581
|
-
rawUnsafe: Effect.succeed(binding)
|
|
582
|
-
});
|
|
583
|
-
const layer$14 = (tag, definition) => layer$18(tag, definition.binding, isBrowserRenderingBinding, makeClient$10(definition), { expected: expectedBrowserRenderingBinding });
|
|
584
|
-
const make$11 = (id) => Tag$10()(id);
|
|
585
|
-
const Tag$10 = () => (id) => {
|
|
586
|
-
const tag = Context.Service()(id);
|
|
587
|
-
const makeLayer = (definition) => layer$14(tag, definition);
|
|
588
|
-
return Object.assign(tag, {
|
|
589
|
-
id,
|
|
590
|
-
layer: makeLayer
|
|
591
|
-
});
|
|
592
|
-
};
|
|
593
|
-
//#endregion
|
|
594
|
-
//#region src/Cache.ts
|
|
595
|
-
var Cache_exports = /* @__PURE__ */ __exportAll({
|
|
596
|
-
CacheOperationError: () => CacheOperationError,
|
|
597
|
-
CacheStorage: () => CacheStorage,
|
|
598
|
-
layer: () => layer$13,
|
|
599
|
-
layerFrom: () => layerFrom,
|
|
600
|
-
makeCacheClient: () => makeCacheClient,
|
|
601
|
-
makeClient: () => makeClient$9
|
|
602
|
-
});
|
|
603
|
-
var CacheOperationError = class extends Data.TaggedError("CacheOperationError") {
|
|
604
|
-
get message() {
|
|
605
|
-
return `Cache ${this.operation} failed for cache "${this.cache}": ${causeMessage(this.cause)}`;
|
|
606
|
-
}
|
|
607
|
-
};
|
|
608
|
-
var CacheStorage = class extends Context.Service()("effect-cf/CacheStorage") {};
|
|
609
|
-
const cacheError = (cache, operation, cause) => new CacheOperationError({
|
|
610
|
-
cache,
|
|
611
|
-
operation,
|
|
612
|
-
cause
|
|
613
|
-
});
|
|
614
|
-
const tryCachePromise = (cache, operation, evaluate) => Effect.tryPromise({
|
|
615
|
-
try: evaluate,
|
|
616
|
-
catch: (cause) => cacheError(cache, operation, cause)
|
|
617
|
-
});
|
|
618
|
-
const spanOptions$2 = (cache, operation) => ({ attributes: {
|
|
619
|
-
cache,
|
|
620
|
-
operation
|
|
621
|
-
} });
|
|
622
|
-
const makeCacheClient = (cache, name = "default") => ({
|
|
623
|
-
name,
|
|
624
|
-
match: Effect.fn("Cache.match", spanOptions$2(name, "match"))((request, options) => tryCachePromise(name, "match", () => cache.match(request, options)).pipe(Effect.map(Option.fromUndefinedOr))),
|
|
625
|
-
put: Effect.fn("Cache.put", spanOptions$2(name, "put"))((request, response) => tryCachePromise(name, "put", () => cache.put(request, response))),
|
|
626
|
-
delete: Effect.fn("Cache.delete", spanOptions$2(name, "delete"))((request, options) => tryCachePromise(name, "delete", () => cache.delete(request, options))),
|
|
627
|
-
rawUnsafe: Effect.succeed(cache)
|
|
628
|
-
});
|
|
629
|
-
const makeClient$9 = (storage) => ({
|
|
630
|
-
default: makeCacheClient(storage.default),
|
|
631
|
-
open: (name) => tryCachePromise(name, "open", () => storage.open(name)).pipe(Effect.map((cache) => makeCacheClient(cache, name)), Effect.withSpan("Cache.open", spanOptions$2(name, "open"))),
|
|
632
|
-
rawUnsafe: Effect.succeed(storage)
|
|
633
|
-
});
|
|
634
|
-
const layerFrom = (storage) => Layer.succeed(CacheStorage, makeClient$9(storage));
|
|
635
|
-
const layer$13 = Layer.sync(CacheStorage, () => makeClient$9(caches));
|
|
636
|
-
//#endregion
|
|
637
|
-
//#region src/CloudflareOtlp.ts
|
|
638
|
-
/**
|
|
639
|
-
* Worker fetch/queue/RPC and Durable Object alarm/RPC handlers schedule a
|
|
640
|
-
* best-effort flusher. It settles within two seconds; other lifecycles must
|
|
641
|
-
* flush explicitly. Scheduled flush failures cannot fail user events. Exporter
|
|
642
|
-
* layer finalizers run separately and follow their configured shutdown timeout.
|
|
643
|
-
*/
|
|
644
|
-
var CloudflareOtlp_exports = /* @__PURE__ */ __exportAll({
|
|
645
|
-
layer: () => layer$12,
|
|
646
|
-
layerDurableObject: () => layerDurableObject,
|
|
647
|
-
layerJson: () => layerJson,
|
|
648
|
-
layerProtobuf: () => layerProtobuf,
|
|
649
|
-
layerWorker: () => layerWorker
|
|
650
|
-
});
|
|
651
|
-
const allSignals = [
|
|
652
|
-
"logs",
|
|
653
|
-
"traces",
|
|
654
|
-
"metrics"
|
|
655
|
-
];
|
|
656
|
-
const emptyConfigProvider = ConfigProvider.fromUnknown({});
|
|
657
|
-
const cloudflareConfigProviderLayer = ConfigProvider.layerAdd(Effect.map(Effect.serviceOption(WorkerEnvironment), (env) => Option.isSome(env) ? WorkerConfig.providerFromEnv(env.value) : emptyConfigProvider), { asPrimary: true });
|
|
658
|
-
const selectedSignals = (signals) => new Set(signals ?? allSignals);
|
|
659
|
-
const withDefinedAttributes = (attributes) => {
|
|
660
|
-
const out = {};
|
|
661
|
-
for (const [key, value] of Object.entries(attributes)) if (value !== void 0) out[key] = value;
|
|
662
|
-
return out;
|
|
663
|
-
};
|
|
664
|
-
const makeResource = (options, runtimeAttributes) => ({
|
|
665
|
-
serviceName: options.resource?.serviceName,
|
|
666
|
-
serviceVersion: options.resource?.serviceVersion,
|
|
667
|
-
attributes: {
|
|
668
|
-
...withDefinedAttributes(runtimeAttributes),
|
|
669
|
-
...options.resource?.attributes
|
|
670
|
-
}
|
|
671
|
-
});
|
|
672
|
-
const serializationLayer = (serialization) => serialization === "json" ? OtlpSerialization.layerJson : OtlpSerialization.layerProtobuf;
|
|
673
|
-
const mergeSignalLayers = (layers) => {
|
|
674
|
-
let merged = layers[0];
|
|
675
|
-
for (let index = 1; index < layers.length; index++) merged = Layer.mergeAll(merged, layers[index]);
|
|
676
|
-
return merged;
|
|
677
|
-
};
|
|
678
|
-
const makeLayer = (options = {}, runtimeAttributes = {}) => {
|
|
679
|
-
const signals = selectedSignals(options.signals);
|
|
680
|
-
const resource = makeResource(options, runtimeAttributes);
|
|
681
|
-
const layers = [];
|
|
682
|
-
if (signals.has("logs")) layers.push(OtlpLogger.layerFromConfig({
|
|
683
|
-
resource,
|
|
684
|
-
headers: options.headers,
|
|
685
|
-
excludeLogSpans: options.loggerExcludeLogSpans,
|
|
686
|
-
mergeWithExisting: options.loggerMergeWithExisting
|
|
687
|
-
}));
|
|
688
|
-
if (signals.has("traces")) layers.push(OtlpTracer.layerFromConfig({
|
|
689
|
-
resource,
|
|
690
|
-
headers: options.headers,
|
|
691
|
-
context: options.tracerContext
|
|
692
|
-
}));
|
|
693
|
-
if (signals.has("metrics")) layers.push(OtlpMetrics.layerFromConfig({
|
|
694
|
-
resource,
|
|
695
|
-
headers: options.headers
|
|
696
|
-
}));
|
|
697
|
-
if (layers.length === 0) return OtlpExporter.layerFlusher;
|
|
698
|
-
return mergeSignalLayers(layers).pipe(Layer.provide(cloudflareConfigProviderLayer), Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer));
|
|
699
|
-
};
|
|
700
|
-
/**
|
|
701
|
-
* Base OTLP telemetry layer for Cloudflare-compatible runtimes.
|
|
702
|
-
*
|
|
703
|
-
* Standard OpenTelemetry environment variables are resolved by Effect's OTLP
|
|
704
|
-
* layers. In Cloudflare Workers and Durable Objects, the current `env` object is
|
|
705
|
-
* installed as the primary `ConfigProvider`; outside Cloudflare, the ambient
|
|
706
|
-
* Effect `ConfigProvider` remains the fallback.
|
|
707
|
-
*
|
|
708
|
-
* The layer provides {@link OtlpExporter.Flusher} for draining buffered
|
|
709
|
-
* telemetry before the isolate freezes.
|
|
710
|
-
*/
|
|
711
|
-
const layer$12 = (options = {}) => makeLayer(options);
|
|
712
|
-
/** Base OTLP telemetry layer forced to JSON serialization. */
|
|
713
|
-
const layerJson = (options = {}) => layer$12({
|
|
714
|
-
...options,
|
|
715
|
-
serialization: "json"
|
|
716
|
-
});
|
|
717
|
-
/** Base OTLP telemetry layer forced to protobuf serialization. */
|
|
718
|
-
const layerProtobuf = (options = {}) => layer$12({
|
|
719
|
-
...options,
|
|
720
|
-
serialization: "protobuf"
|
|
721
|
-
});
|
|
722
|
-
/**
|
|
723
|
-
* OTLP layer with Cloudflare Worker resource attributes.
|
|
724
|
-
*
|
|
725
|
-
* Provide this layer at runtime scope for long-lived metrics aggregation, or at
|
|
726
|
-
* handler scope when traces/logs should flush as the Cloudflare event finishes.
|
|
727
|
-
* A handler-scoped exporter can delay scope closure while its own finalizer
|
|
728
|
-
* flushes; the two-second background flush limit does not bound layer shutdown.
|
|
729
|
-
*/
|
|
730
|
-
const layerWorker = (options = {}) => makeLayer(options, {
|
|
731
|
-
"cloudflare.resource_type": "worker",
|
|
732
|
-
"cloudflare.worker.name": options.workerName
|
|
733
|
-
});
|
|
734
|
-
/**
|
|
735
|
-
* OTLP layer with Cloudflare Durable Object resource attributes.
|
|
736
|
-
*
|
|
737
|
-
* The layer reads {@link DurableObjectState} so it can optionally include the
|
|
738
|
-
* Durable Object id. Prefer leaving `includeObjectId` disabled unless the
|
|
739
|
-
* backend can tolerate high-cardinality resource attributes.
|
|
740
|
-
*/
|
|
741
|
-
const layerDurableObject = (options = {}) => Layer.unwrap(Effect.map(DurableObjectState, (state) => makeLayer(options, {
|
|
742
|
-
"cloudflare.resource_type": "durable_object",
|
|
743
|
-
"cloudflare.durable_object.class": options.className,
|
|
744
|
-
"cloudflare.durable_object.id": options.includeObjectId ? state.id.toString() : void 0
|
|
745
|
-
})));
|
|
746
|
-
//#endregion
|
|
747
|
-
//#region src/CloudflareTracer.ts
|
|
748
|
-
var CloudflareTracer_exports = /* @__PURE__ */ __exportAll({ layer: () => layer$11 });
|
|
749
|
-
var Span = class extends Tracer.NativeSpan {
|
|
750
|
-
runInContext;
|
|
751
|
-
cloudflareSpan;
|
|
752
|
-
constructor(options, runInContext, cloudflareSpan) {
|
|
753
|
-
super({
|
|
754
|
-
...options,
|
|
755
|
-
sampled: options.sampled && (cloudflareSpan?.isTraced ?? false)
|
|
756
|
-
});
|
|
757
|
-
this.runInContext = runInContext;
|
|
758
|
-
this.cloudflareSpan = cloudflareSpan;
|
|
759
|
-
}
|
|
760
|
-
attribute(key, value) {
|
|
761
|
-
super.attribute(key, value);
|
|
762
|
-
if (Predicate.isString(value) || Predicate.isNumber(value) || Predicate.isBoolean(value)) this.cloudflareSpan?.setAttribute(key, value);
|
|
763
|
-
}
|
|
764
|
-
end(endTime, exit) {
|
|
765
|
-
if (this.status._tag === "Ended") return;
|
|
766
|
-
super.end(endTime, exit);
|
|
767
|
-
this.cloudflareSpan?.setAttribute("effect.exit", Exit.isSuccess(exit) ? "success" : Cause.hasInterruptsOnly(exit.cause) ? "interrupted" : "failure");
|
|
768
|
-
this.cloudflareSpan?.end();
|
|
769
|
-
}
|
|
770
|
-
};
|
|
771
|
-
/**
|
|
772
|
-
* Sends Effect spans to Cloudflare Workers Observability using the runtime's
|
|
773
|
-
* custom span API. Build this layer inside each invocation, for example with
|
|
774
|
-
* `Worker.make(Services, { eventLayer: CloudflareTracer.layer, fetch })`.
|
|
775
|
-
* It captures the invocation's async context and must not be cached across requests.
|
|
776
|
-
*
|
|
777
|
-
* Enable `observability.traces.enabled` in Wrangler. Cloudflare owns sampling
|
|
778
|
-
* and export; no OTLP exporter or flush is required. Scalar attributes are
|
|
779
|
-
* forwarded; other attributes, events, and links remain Effect-local. Completion
|
|
780
|
-
* is recorded as `effect.exit`, since Cloudflare has no outcome-setting API.
|
|
781
|
-
* Effect trace/span IDs remain independent of Cloudflare's opaque IDs. External
|
|
782
|
-
* parents and `root: true` cannot override the invocation's Cloudflare trace.
|
|
783
|
-
*/
|
|
784
|
-
const layer$11 = Layer.effect(Tracer.Tracer, Effect.sync(() => {
|
|
785
|
-
const invocationContext = AsyncLocalStorage.snapshot();
|
|
786
|
-
const contextFor = (span) => {
|
|
787
|
-
while (span?._tag === "Span") {
|
|
788
|
-
if (span instanceof Span) return span.runInContext;
|
|
789
|
-
span = Option.getOrUndefined(span.parent);
|
|
790
|
-
}
|
|
791
|
-
return invocationContext;
|
|
792
|
-
};
|
|
793
|
-
return Tracer.make({
|
|
794
|
-
span(options) {
|
|
795
|
-
const parentContext = options.root ? invocationContext : contextFor(Option.getOrUndefined(options.parent));
|
|
796
|
-
if (!options.sampled) return new Span(options, parentContext);
|
|
797
|
-
return parentContext(() => tracing.startActiveSpan(options.name, (span) => new Span(options, AsyncLocalStorage.snapshot(), span)));
|
|
798
|
-
},
|
|
799
|
-
context(primitive, fiber) {
|
|
800
|
-
return contextFor(fiber.currentSpan)(() => primitive["~effect/Effect/evaluate"](fiber));
|
|
801
|
-
}
|
|
802
|
-
});
|
|
803
|
-
}));
|
|
804
|
-
//#endregion
|
|
805
|
-
//#region src/ContainerNamespace.ts
|
|
806
|
-
var ContainerNamespace_exports = /* @__PURE__ */ __exportAll({
|
|
807
|
-
ContainerNamespace: () => ContainerNamespace,
|
|
808
|
-
ContainerOperationError: () => ContainerOperationError,
|
|
809
|
-
ContainerState: () => ContainerState,
|
|
810
|
-
Tag: () => Tag$9,
|
|
811
|
-
isContainerNamespaceResource: () => isContainerNamespaceResource,
|
|
812
|
-
layer: () => layer$10,
|
|
813
|
-
make: () => make$10,
|
|
814
|
-
makeClient: () => makeClient$8
|
|
815
|
-
});
|
|
816
|
-
const expectedContainerNamespace = "Container namespace binding with getByName()";
|
|
817
|
-
/** Serializable state reported by a Cloudflare Container instance. */
|
|
818
|
-
const ContainerState = Schema.Union([Schema.Struct({
|
|
819
|
-
lastChange: Schema.Finite,
|
|
820
|
-
status: Schema.Literals([
|
|
821
|
-
"running",
|
|
822
|
-
"stopping",
|
|
823
|
-
"stopped",
|
|
824
|
-
"healthy"
|
|
825
|
-
])
|
|
826
|
-
}), Schema.Struct({
|
|
827
|
-
lastChange: Schema.Finite,
|
|
828
|
-
status: Schema.Literal("stopped_with_code"),
|
|
829
|
-
exitCode: Schema.optionalKey(Schema.Int)
|
|
830
|
-
})]);
|
|
831
|
-
var ContainerOperationError = class extends Data.TaggedError("ContainerOperationError") {
|
|
832
|
-
get message() {
|
|
833
|
-
return `Container ${this.operation} failed for binding "${this.binding}" instance "${this.instance}": ${causeMessage(this.cause)}`;
|
|
834
|
-
}
|
|
835
|
-
};
|
|
836
|
-
const tryContainerPromise = (definition, instance, operation, evaluate) => Effect.tryPromise({
|
|
837
|
-
try: evaluate,
|
|
838
|
-
catch: (cause) => new ContainerOperationError({
|
|
839
|
-
binding: definition.binding,
|
|
840
|
-
instance,
|
|
841
|
-
operation,
|
|
842
|
-
cause
|
|
843
|
-
})
|
|
844
|
-
});
|
|
845
|
-
const makeInstanceClient = (definition, instance, stub) => {
|
|
846
|
-
const spanOptions = (operation) => ({ attributes: {
|
|
847
|
-
binding: definition.binding,
|
|
848
|
-
instance,
|
|
849
|
-
operation
|
|
850
|
-
} });
|
|
851
|
-
const hostListOperation = (operation) => Effect.fn(`ContainerNamespace.${operation}`, spanOptions(operation))(function* (hosts) {
|
|
852
|
-
return yield* tryContainerPromise(definition, instance, operation, () => stub[operation]([...hosts]));
|
|
853
|
-
});
|
|
854
|
-
const hostnameOperation = (operation) => Effect.fn(`ContainerNamespace.${operation}`, spanOptions(operation))(function* (hostname) {
|
|
855
|
-
return yield* tryContainerPromise(definition, instance, operation, () => stub[operation](hostname));
|
|
856
|
-
});
|
|
857
|
-
return {
|
|
858
|
-
rawUnsafe: Effect.succeed(stub),
|
|
859
|
-
state: tryContainerPromise(definition, instance, "state", () => stub.getState()).pipe(Effect.flatMap(Schema.decodeUnknownEffect(ContainerState)), Effect.mapError((cause) => cause instanceof ContainerOperationError ? cause : new ContainerOperationError({
|
|
860
|
-
binding: definition.binding,
|
|
861
|
-
instance,
|
|
862
|
-
operation: "state",
|
|
863
|
-
cause
|
|
864
|
-
})), Effect.withSpan("ContainerNamespace.state", spanOptions("state"))),
|
|
865
|
-
fetch: Effect.fn("ContainerNamespace.fetch", spanOptions("fetch"))(function* (input, init) {
|
|
866
|
-
return yield* tryContainerPromise(definition, instance, "fetch", () => stub.fetch(input, init));
|
|
867
|
-
}),
|
|
868
|
-
start: Effect.fn("ContainerNamespace.start", spanOptions("start"))(function* (options, waitOptions) {
|
|
869
|
-
return yield* tryContainerPromise(definition, instance, "start", () => stub.start(options, waitOptions));
|
|
870
|
-
}),
|
|
871
|
-
startAndWaitForPorts: Effect.fn("ContainerNamespace.startAndWaitForPorts", spanOptions("startAndWaitForPorts"))(function* (options) {
|
|
872
|
-
return yield* tryContainerPromise(definition, instance, "startAndWaitForPorts", () => stub.startAndWaitForPorts(options));
|
|
873
|
-
}),
|
|
874
|
-
waitForPort: Effect.fn("ContainerNamespace.waitForPort", spanOptions("waitForPort"))(function* (options) {
|
|
875
|
-
return yield* tryContainerPromise(definition, instance, "waitForPort", () => stub.waitForPort(options));
|
|
876
|
-
}),
|
|
877
|
-
stop: Effect.fn("ContainerNamespace.stop", spanOptions("stop"))(function* (signal) {
|
|
878
|
-
return yield* tryContainerPromise(definition, instance, "stop", () => stub.stop(signal));
|
|
879
|
-
}),
|
|
880
|
-
destroy: tryContainerPromise(definition, instance, "destroy", () => stub.destroy()).pipe(Effect.withSpan("ContainerNamespace.destroy", spanOptions("destroy"))),
|
|
881
|
-
setAllowedHosts: hostListOperation("setAllowedHosts"),
|
|
882
|
-
setDeniedHosts: hostListOperation("setDeniedHosts"),
|
|
883
|
-
allowHost: hostnameOperation("allowHost"),
|
|
884
|
-
denyHost: hostnameOperation("denyHost"),
|
|
885
|
-
removeAllowedHost: hostnameOperation("removeAllowedHost"),
|
|
886
|
-
removeDeniedHost: hostnameOperation("removeDeniedHost")
|
|
887
|
-
};
|
|
888
|
-
};
|
|
889
|
-
const isContainerNamespaceResource = (value) => Predicate.hasProperty(value, "getByName") && Predicate.isFunction(value.getByName);
|
|
890
|
-
const makeClient$8 = (definition) => (namespace) => {
|
|
891
|
-
const getByName = (name, options) => Effect.try({
|
|
892
|
-
try: () => makeInstanceClient(definition, name, namespace.getByName(name, options)),
|
|
893
|
-
catch: (cause) => new ContainerOperationError({
|
|
894
|
-
binding: definition.binding,
|
|
895
|
-
instance: name,
|
|
896
|
-
operation: "getByName",
|
|
897
|
-
cause
|
|
898
|
-
})
|
|
899
|
-
});
|
|
900
|
-
const byName = (name, options) => {
|
|
901
|
-
const instance = getByName(name, options);
|
|
902
|
-
return {
|
|
903
|
-
rawUnsafe: Effect.flatMap(instance, (client) => client.rawUnsafe),
|
|
904
|
-
state: Effect.flatMap(instance, (client) => client.state),
|
|
905
|
-
fetch: (input, init) => Effect.flatMap(instance, (client) => client.fetch(input, init)),
|
|
906
|
-
start: (startOptions, waitOptions) => Effect.flatMap(instance, (client) => client.start(startOptions, waitOptions)),
|
|
907
|
-
startAndWaitForPorts: (startOptions) => Effect.flatMap(instance, (client) => client.startAndWaitForPorts(startOptions)),
|
|
908
|
-
waitForPort: (waitOptions) => Effect.flatMap(instance, (client) => client.waitForPort(waitOptions)),
|
|
909
|
-
stop: (signal) => Effect.flatMap(instance, (client) => client.stop(signal)),
|
|
910
|
-
destroy: Effect.flatMap(instance, (client) => client.destroy),
|
|
911
|
-
setAllowedHosts: (hosts) => Effect.flatMap(instance, (client) => client.setAllowedHosts(hosts)),
|
|
912
|
-
setDeniedHosts: (hosts) => Effect.flatMap(instance, (client) => client.setDeniedHosts(hosts)),
|
|
913
|
-
allowHost: (hostname) => Effect.flatMap(instance, (client) => client.allowHost(hostname)),
|
|
914
|
-
denyHost: (hostname) => Effect.flatMap(instance, (client) => client.denyHost(hostname)),
|
|
915
|
-
removeAllowedHost: (hostname) => Effect.flatMap(instance, (client) => client.removeAllowedHost(hostname)),
|
|
916
|
-
removeDeniedHost: (hostname) => Effect.flatMap(instance, (client) => client.removeDeniedHost(hostname))
|
|
917
|
-
};
|
|
918
|
-
};
|
|
919
|
-
return {
|
|
920
|
-
definition,
|
|
921
|
-
getByName,
|
|
922
|
-
byName,
|
|
923
|
-
rawUnsafe: Effect.succeed(namespace)
|
|
924
|
-
};
|
|
925
|
-
};
|
|
926
|
-
const layer$10 = (tag, definition) => layer$18(tag, definition.binding, (value) => isContainerNamespaceResource(value), makeClient$8(definition), { expected: expectedContainerNamespace });
|
|
927
|
-
const make$10 = (id) => Tag$9()(id);
|
|
928
|
-
const Tag$9 = () => (id) => {
|
|
929
|
-
const tag = Context.Service()(`effect-cf/Container/${id}`);
|
|
930
|
-
const makeLayer = (definition) => layer$10(tag, definition);
|
|
931
|
-
const getByName = Effect.fnUntraced(function* (name, options) {
|
|
932
|
-
return yield* (yield* tag).getByName(name, options);
|
|
933
|
-
});
|
|
934
|
-
const byName = (name, options) => ({
|
|
935
|
-
state: Effect.flatMap(getByName(name, options), (instance) => instance.state),
|
|
936
|
-
fetch: (input, init) => Effect.flatMap(getByName(name, options), (instance) => instance.fetch(input, init)),
|
|
937
|
-
start: (startOptions, waitOptions) => Effect.flatMap(getByName(name, options), (instance) => instance.start(startOptions, waitOptions)),
|
|
938
|
-
startAndWaitForPorts: (startOptions) => Effect.flatMap(getByName(name, options), (instance) => instance.startAndWaitForPorts(startOptions)),
|
|
939
|
-
waitForPort: (waitOptions) => Effect.flatMap(getByName(name, options), (instance) => instance.waitForPort(waitOptions)),
|
|
940
|
-
stop: (signal) => Effect.flatMap(getByName(name, options), (instance) => instance.stop(signal)),
|
|
941
|
-
destroy: Effect.flatMap(getByName(name, options), (instance) => instance.destroy),
|
|
942
|
-
setAllowedHosts: (hosts) => Effect.flatMap(getByName(name, options), (instance) => instance.setAllowedHosts(hosts)),
|
|
943
|
-
setDeniedHosts: (hosts) => Effect.flatMap(getByName(name, options), (instance) => instance.setDeniedHosts(hosts)),
|
|
944
|
-
allowHost: (hostname) => Effect.flatMap(getByName(name, options), (instance) => instance.allowHost(hostname)),
|
|
945
|
-
denyHost: (hostname) => Effect.flatMap(getByName(name, options), (instance) => instance.denyHost(hostname)),
|
|
946
|
-
removeAllowedHost: (hostname) => Effect.flatMap(getByName(name, options), (instance) => instance.removeAllowedHost(hostname)),
|
|
947
|
-
removeDeniedHost: (hostname) => Effect.flatMap(getByName(name, options), (instance) => instance.removeDeniedHost(hostname)),
|
|
948
|
-
rawUnsafe: Effect.flatMap(getByName(name, options), (instance) => instance.rawUnsafe)
|
|
949
|
-
});
|
|
950
|
-
const rawUnsafe = Effect.flatMap(tag, (namespace) => namespace.rawUnsafe);
|
|
951
|
-
return Object.assign(tag, {
|
|
952
|
-
id,
|
|
953
|
-
layer: makeLayer,
|
|
954
|
-
getByName,
|
|
955
|
-
byName,
|
|
956
|
-
rawUnsafe
|
|
957
|
-
});
|
|
958
|
-
};
|
|
959
|
-
const ContainerNamespace = Tag$9;
|
|
960
|
-
//#endregion
|
|
961
|
-
//#region src/D1.ts
|
|
962
|
-
var D1_exports = /* @__PURE__ */ __exportAll({
|
|
963
|
-
Service: () => Service,
|
|
964
|
-
make: () => make$9
|
|
965
|
-
});
|
|
966
|
-
const TypeId$1 = "~effect-cf/D1";
|
|
967
|
-
const expectedD1Database = "D1 database binding with prepare(), batch(), and exec()";
|
|
968
|
-
const isD1Database = (value) => Predicate.hasProperty(value, "prepare") && Predicate.isFunction(value.prepare) && Predicate.hasProperty(value, "batch") && Predicate.isFunction(value.batch) && Predicate.hasProperty(value, "exec") && Predicate.isFunction(value.exec);
|
|
969
|
-
const make$9 = (id, definition) => Service()(id, definition);
|
|
970
|
-
const Service = () => (id, definition) => {
|
|
971
|
-
const tag = Service$1()(id, definition.binding, isD1Database, void 0, { expected: expectedD1Database });
|
|
972
|
-
const sqlLayer = (options) => Layer.unwrap(Effect.gen(function* () {
|
|
973
|
-
const db = yield* tag;
|
|
974
|
-
return D1Client.layer({
|
|
975
|
-
...options,
|
|
976
|
-
db
|
|
977
|
-
});
|
|
978
|
-
})).pipe(Layer.provide(tag.layer));
|
|
979
|
-
return Object.assign(tag, {
|
|
980
|
-
[TypeId$1]: TypeId$1,
|
|
981
|
-
definition,
|
|
982
|
-
sqlLayer
|
|
983
|
-
});
|
|
984
|
-
};
|
|
985
|
-
//#endregion
|
|
986
|
-
//#region src/DurableObjectNamespace.ts
|
|
987
|
-
var DurableObjectNamespace_exports = /* @__PURE__ */ __exportAll({
|
|
988
|
-
DurableObjectFetchError: () => DurableObjectFetchError,
|
|
989
|
-
DurableObjectRpcError: () => DurableObjectRpcError,
|
|
990
|
-
isDurableObjectNamespaceClient: () => isDurableObjectNamespaceClient,
|
|
991
|
-
layer: () => layer$9,
|
|
992
|
-
makeClient: () => makeClient$7,
|
|
993
|
-
makeDirectMethods: () => makeDirectMethods
|
|
994
|
-
});
|
|
995
|
-
const expectedDurableObjectNamespace = "Durable Object namespace binding with getByName(), get(), idFromName(), idFromString(), newUniqueId(), and jurisdiction()";
|
|
996
|
-
/**
|
|
997
|
-
* Failure raised when invoking an RPC method on a Durable Object stub.
|
|
998
|
-
*/
|
|
999
|
-
var DurableObjectRpcError = class extends Data.TaggedError("DurableObjectRpcError") {
|
|
1000
|
-
get message() {
|
|
1001
|
-
return `Durable Object RPC method "${this.method}" failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
1002
|
-
}
|
|
1003
|
-
};
|
|
1004
|
-
/**
|
|
1005
|
-
* Failure raised when forwarding a request to a Durable Object stub.
|
|
1006
|
-
*/
|
|
1007
|
-
var DurableObjectFetchError = class extends Data.TaggedError("DurableObjectFetchError") {
|
|
1008
|
-
get message() {
|
|
1009
|
-
return `Durable Object fetch failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
1010
|
-
}
|
|
1011
|
-
};
|
|
1012
|
-
const hasFunction$1 = (value, key) => Predicate.hasProperty(value, key) && Predicate.isFunction(value[key]);
|
|
1013
|
-
const isDurableObjectNamespaceClient = (value) => hasFunction$1(value, "getByName") && hasFunction$1(value, "get") && hasFunction$1(value, "idFromName") && hasFunction$1(value, "idFromString") && hasFunction$1(value, "newUniqueId") && hasFunction$1(value, "jurisdiction");
|
|
1014
|
-
const makeClient$7 = (definition) => {
|
|
1015
|
-
return (namespace) => {
|
|
1016
|
-
const newUniqueId = (options) => Effect.sync(() => namespace.newUniqueId(options));
|
|
1017
|
-
const idFromName = (name) => Effect.sync(() => namespace.idFromName(name));
|
|
1018
|
-
const idFromString = (id) => Effect.sync(() => namespace.idFromString(id));
|
|
1019
|
-
const get = (id, options) => Effect.sync(() => namespace.get(id, options));
|
|
1020
|
-
const getByName = (name, options) => Effect.sync(() => namespace.getByName(name, options));
|
|
1021
|
-
const jurisdiction = (value) => Effect.sync(() => namespace.jurisdiction(value));
|
|
1022
|
-
const fetch = (stub, input, init) => Effect.tryPromise({
|
|
1023
|
-
try: (signal) => {
|
|
1024
|
-
const callerSignal = init?.signal !== void 0 ? init.signal : input instanceof Request ? input.signal : void 0;
|
|
1025
|
-
return stub.fetch(input, {
|
|
1026
|
-
...init,
|
|
1027
|
-
signal: callerSignal === null || callerSignal === void 0 ? signal : AbortSignal.any([callerSignal, signal])
|
|
1028
|
-
});
|
|
1029
|
-
},
|
|
1030
|
-
catch: (cause) => new DurableObjectFetchError({
|
|
1031
|
-
binding: definition.binding,
|
|
1032
|
-
cause
|
|
1033
|
-
})
|
|
1034
|
-
});
|
|
1035
|
-
const rpc = Effect.fnUntraced(function* (stub, method, ...args) {
|
|
1036
|
-
const methodName = String(method);
|
|
1037
|
-
const encodedArgs = definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1038
|
-
binding: definition.binding,
|
|
1039
|
-
method: methodName,
|
|
1040
|
-
cause
|
|
1041
|
-
})));
|
|
1042
|
-
const nativeArgs = definition.rpcTracing ? yield* withRpcTraceContext(encodedArgs) : encodedArgs;
|
|
1043
|
-
return yield* invokeRpcMethod(stub, method, nativeArgs, (cause) => new DurableObjectRpcError({
|
|
1044
|
-
binding: definition.binding,
|
|
1045
|
-
method: methodName,
|
|
1046
|
-
cause
|
|
1047
|
-
}));
|
|
1048
|
-
});
|
|
1049
|
-
const decodeSuccess$1 = Effect.fnUntraced(function* (methodName, value) {
|
|
1050
|
-
if (definition.definition === void 0) return value;
|
|
1051
|
-
return yield* decodeSuccess(definition.definition, methodName, value).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1052
|
-
binding: definition.binding,
|
|
1053
|
-
method: methodName,
|
|
1054
|
-
cause
|
|
1055
|
-
})));
|
|
1056
|
-
});
|
|
1057
|
-
const call = Effect.fnUntraced(function* (stub, method, ...args) {
|
|
1058
|
-
const methodName = String(method);
|
|
1059
|
-
const value = yield* resolve(yield* rpc(stub, method, ...args)).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1060
|
-
binding: definition.binding,
|
|
1061
|
-
method: methodName,
|
|
1062
|
-
cause
|
|
1063
|
-
})));
|
|
1064
|
-
return yield* decodeSuccess$1(methodName, value);
|
|
1065
|
-
}, (effect, ...args) => withRpcClientSpan(effect, definition.binding, String(args[1])));
|
|
1066
|
-
const scopedCall = Effect.fnUntraced(function* (stub, method, ...args) {
|
|
1067
|
-
const methodName = String(method);
|
|
1068
|
-
const result = yield* rpc(stub, method, ...args);
|
|
1069
|
-
const value = yield* scoped(result).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1070
|
-
binding: definition.binding,
|
|
1071
|
-
method: methodName,
|
|
1072
|
-
cause
|
|
1073
|
-
})));
|
|
1074
|
-
return yield* decodeSuccess$1(methodName, value);
|
|
1075
|
-
}, (effect, ...args) => withRpcClientSpan(effect, definition.binding, String(args[1])));
|
|
1076
|
-
const directMethods = makeDirectMethods(definition.definition, {
|
|
1077
|
-
call,
|
|
1078
|
-
fetch,
|
|
1079
|
-
get,
|
|
1080
|
-
getByName
|
|
1081
|
-
});
|
|
1082
|
-
return Object.assign(directMethods, {
|
|
1083
|
-
newUniqueId,
|
|
1084
|
-
idFromName,
|
|
1085
|
-
idFromString,
|
|
1086
|
-
get,
|
|
1087
|
-
getByName,
|
|
1088
|
-
jurisdiction,
|
|
1089
|
-
fetch,
|
|
1090
|
-
rpc,
|
|
1091
|
-
call,
|
|
1092
|
-
scopedCall,
|
|
1093
|
-
rawUnsafe: Effect.succeed(namespace)
|
|
1094
|
-
});
|
|
1095
|
-
};
|
|
1096
|
-
};
|
|
1097
|
-
const layer$9 = (tag, definition) => layer$18(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$7(definition), { expected: expectedDurableObjectNamespace });
|
|
1098
|
-
const makeDirectMethods = (rpcDefinition, helpers) => {
|
|
1099
|
-
const methods = {};
|
|
1100
|
-
if (rpcDefinition !== void 0) {
|
|
1101
|
-
for (const methodName of Object.keys(rpcDefinition.methods)) methods[methodName] = (stub, ...args) => helpers.call(stub, methodName, ...args);
|
|
1102
|
-
const makeClient = (getStub) => {
|
|
1103
|
-
const client = { fetch: (input, init) => Effect.gen(function* () {
|
|
1104
|
-
const stub = yield* getStub();
|
|
1105
|
-
return yield* helpers.fetch(stub, input, init);
|
|
1106
|
-
}) };
|
|
1107
|
-
for (const methodName of Object.keys(rpcDefinition.methods)) client[methodName] = (...args) => Effect.gen(function* () {
|
|
1108
|
-
const stub = yield* getStub();
|
|
1109
|
-
return yield* helpers.call(stub, methodName, ...args);
|
|
1110
|
-
});
|
|
1111
|
-
return client;
|
|
1112
|
-
};
|
|
1113
|
-
methods.byName = (name, options) => makeClient(() => helpers.getByName(name, options));
|
|
1114
|
-
methods.byId = (id, options) => makeClient(() => helpers.get(id, options));
|
|
1115
|
-
}
|
|
1116
|
-
return methods;
|
|
1117
|
-
};
|
|
1118
|
-
//#endregion
|
|
1119
|
-
//#region src/DurableObjectDefinition.ts
|
|
1120
|
-
var DurableObjectDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
1121
|
-
DurableObject: () => DurableObject$1,
|
|
1122
|
-
Tag: () => Tag$8,
|
|
1123
|
-
implement: () => implement$2,
|
|
1124
|
-
make: () => make$8,
|
|
1125
|
-
method: () => method
|
|
1126
|
-
});
|
|
1127
|
-
const reservedMethodNames$1 = /* @__PURE__ */ new Set([
|
|
1128
|
-
"constructor",
|
|
1129
|
-
"dup",
|
|
1130
|
-
"fetch",
|
|
1131
|
-
"alarm",
|
|
1132
|
-
"webSocketMessage",
|
|
1133
|
-
"webSocketClose",
|
|
1134
|
-
"webSocketError"
|
|
1135
|
-
]);
|
|
1136
|
-
function method(definition) {
|
|
1137
|
-
return method$1(definition);
|
|
1138
|
-
}
|
|
1139
|
-
const makeDefinition$2 = (id, methods) => {
|
|
1140
|
-
assertNoReservedMethods("Durable Object", methods, reservedMethodNames$1);
|
|
1141
|
-
const definition = make$15(id, methods);
|
|
1142
|
-
return Object.assign(definition, { make: (layer, options) => make$7(layer, {
|
|
1143
|
-
...options,
|
|
1144
|
-
rpc: wrapHandlers(definition, options.rpc)
|
|
1145
|
-
}) });
|
|
1146
|
-
};
|
|
1147
|
-
const make$8 = (id, methods) => Tag$8()(id, methods);
|
|
1148
|
-
const Tag$8 = () => (id, methods) => {
|
|
1149
|
-
const definition = makeDefinition$2(id, methods);
|
|
1150
|
-
const serviceKey = `effect-cf/DurableObject/${id}`;
|
|
1151
|
-
const tag = Context.Service()(serviceKey);
|
|
1152
|
-
const bindingDefinition = (binding) => ({
|
|
1153
|
-
...binding,
|
|
1154
|
-
definition
|
|
1155
|
-
});
|
|
1156
|
-
const layer = (binding) => layer$9(tag, bindingDefinition(binding));
|
|
1157
|
-
const newUniqueId = Effect.fn("DurableObject.newUniqueId")(function* (options) {
|
|
1158
|
-
return yield* (yield* tag).newUniqueId(options);
|
|
1159
|
-
});
|
|
1160
|
-
const idFromName = Effect.fn("DurableObject.idFromName")(function* (name) {
|
|
1161
|
-
return yield* (yield* tag).idFromName(name);
|
|
1162
|
-
});
|
|
1163
|
-
const idFromString = Effect.fn("DurableObject.idFromString")(function* (value) {
|
|
1164
|
-
return yield* (yield* tag).idFromString(value);
|
|
1165
|
-
});
|
|
1166
|
-
const get = Effect.fn("DurableObject.get")(function* (objectId, options) {
|
|
1167
|
-
return yield* (yield* tag).get(objectId, options);
|
|
1168
|
-
});
|
|
1169
|
-
const getByName = Effect.fn("DurableObject.getByName")(function* (name, options) {
|
|
1170
|
-
return yield* (yield* tag).getByName(name, options);
|
|
1171
|
-
});
|
|
1172
|
-
const jurisdiction = Effect.fn("DurableObject.jurisdiction")(function* (value) {
|
|
1173
|
-
return yield* (yield* tag).jurisdiction(value);
|
|
1174
|
-
});
|
|
1175
|
-
const fetch = Effect.fn("DurableObject.fetch")(function* (stub, input, init) {
|
|
1176
|
-
return yield* (yield* tag).fetch(stub, input, init);
|
|
1177
|
-
});
|
|
1178
|
-
const rpc = Effect.fnUntraced(function* (stub, methodName, ...args) {
|
|
1179
|
-
const invokeRpc = (yield* tag).rpc;
|
|
1180
|
-
return yield* invokeRpc(stub, methodName, ...args);
|
|
1181
|
-
});
|
|
1182
|
-
const call = Effect.fnUntraced(function* (stub, methodName, ...args) {
|
|
1183
|
-
const invokeCall = (yield* tag).call;
|
|
1184
|
-
return yield* invokeCall(stub, methodName, ...args);
|
|
1185
|
-
});
|
|
1186
|
-
const scopedCall = Effect.fnUntraced(function* (stub, methodName, ...args) {
|
|
1187
|
-
const invokeScopedCall = (yield* tag).scopedCall;
|
|
1188
|
-
return yield* invokeScopedCall(stub, methodName, ...args);
|
|
1189
|
-
});
|
|
1190
|
-
const rawUnsafe = Effect.fnUntraced(function* () {
|
|
1191
|
-
return yield* (yield* tag).rawUnsafe;
|
|
1192
|
-
});
|
|
1193
|
-
const directMethods = makeDirectMethods(definition, {
|
|
1194
|
-
call,
|
|
1195
|
-
fetch,
|
|
1196
|
-
get,
|
|
1197
|
-
getByName
|
|
1198
|
-
});
|
|
1199
|
-
return Object.assign(tag, directMethods, {
|
|
1200
|
-
id: definition.id,
|
|
1201
|
-
methods: definition.methods,
|
|
1202
|
-
make: definition.make,
|
|
1203
|
-
layer,
|
|
1204
|
-
newUniqueId,
|
|
1205
|
-
idFromName,
|
|
1206
|
-
idFromString,
|
|
1207
|
-
get,
|
|
1208
|
-
getByName,
|
|
1209
|
-
jurisdiction,
|
|
1210
|
-
fetch,
|
|
1211
|
-
rpc,
|
|
1212
|
-
call,
|
|
1213
|
-
scopedCall,
|
|
1214
|
-
rawUnsafe
|
|
1215
|
-
});
|
|
1216
|
-
};
|
|
1217
|
-
const DurableObject$1 = Tag$8;
|
|
1218
|
-
const wrapHandlers = (definition, handlers) => {
|
|
1219
|
-
const wrapped = Object.create(Object.prototype);
|
|
1220
|
-
for (const key of Object.keys(definition.methods)) {
|
|
1221
|
-
const handler = handlers[key];
|
|
1222
|
-
wrapped[key] = (...args) => Effect.gen(function* () {
|
|
1223
|
-
const decodedArgs = yield* decodeArgs(definition, key, args);
|
|
1224
|
-
yield* recordDecodedArgs(decodedArgs);
|
|
1225
|
-
const value = yield* handler(...decodedArgs);
|
|
1226
|
-
return yield* encodeSuccess(definition, key, value);
|
|
1227
|
-
});
|
|
1228
|
-
}
|
|
1229
|
-
return wrapped;
|
|
1230
|
-
};
|
|
1231
|
-
/**
|
|
1232
|
-
* Helper for implementing handlers with the exact method shape of a definition.
|
|
1233
|
-
*/
|
|
1234
|
-
const implement$2 = (_definition, handlers) => handlers;
|
|
1235
|
-
//#endregion
|
|
1236
|
-
//#region src/DurableObject.ts
|
|
1237
|
-
var DurableObject_exports = /* @__PURE__ */ __exportAll({
|
|
1238
|
-
RunSymbol: () => RunSymbol,
|
|
1239
|
-
Tag: () => Tag$8,
|
|
1240
|
-
implement: () => implement$2,
|
|
1241
|
-
make: () => make$7,
|
|
1242
|
-
method: () => method
|
|
1243
|
-
});
|
|
1244
|
-
const reservedMethodNames = reservedMethodNames$2;
|
|
1245
|
-
/** Override to instrument the whole event, then call super[RunSymbol]. */
|
|
1246
|
-
const RunSymbol = Symbol.for("effect-cf/DurableObject/run");
|
|
1247
|
-
const scheduleTelemetryFlush = scheduleTelemetryFlush$1((flush) => Effect.flatMap(DurableObjectState, (state) => state.waitUntil(flush)));
|
|
1248
|
-
/**
|
|
1249
|
-
* Builds a Durable Object whose base `layer` lives for the in-memory instance.
|
|
1250
|
-
* Cloudflare does not expose an eviction or shutdown hook, so finalizers in
|
|
1251
|
-
* that layer are not guaranteed to run. Put resources that require timely
|
|
1252
|
-
* release in `eventLayer`, whose scope closes after each handled event.
|
|
1253
|
-
*/
|
|
1254
|
-
const make$7 = (layer, options = {}) => {
|
|
1255
|
-
class EffectDurableObject extends DurableObject {
|
|
1256
|
-
runtime;
|
|
1257
|
-
constructor(state, env) {
|
|
1258
|
-
super(state, env);
|
|
1259
|
-
this.runtime = makeEntrypointRuntime(layer, env, Layer.succeed(DurableObjectState, fromDurableObjectState(state)));
|
|
1260
|
-
const initialize = options.initialize;
|
|
1261
|
-
if (initialize !== void 0) state.waitUntil(this[RunSymbol](initialize, { eventLayer: false }));
|
|
1262
|
-
}
|
|
1263
|
-
[RunSymbol](effect, runOptions = {}) {
|
|
1264
|
-
const eventLayer = runOptions.eventLayer === false ? void 0 : options.eventLayer;
|
|
1265
|
-
const parent = runOptions.rpc?.parent;
|
|
1266
|
-
const parentSpan = parent === void 0 ? void 0 : Tracer.externalSpan(parent);
|
|
1267
|
-
if (eventLayer === void 0) return runEventPromise(this.runtime, effect, void 0, parentSpan);
|
|
1268
|
-
return runEventPromise(this.runtime, effect, eventLayer, parentSpan);
|
|
1269
|
-
}
|
|
1270
|
-
fetch(request) {
|
|
1271
|
-
const fetchHandler = options.fetch;
|
|
1272
|
-
if (fetchHandler === void 0) return Promise.resolve(new Response("Not Found", { status: 404 }));
|
|
1273
|
-
return this[RunSymbol](Effect.provideService(fetchHandler, NativeRequest, request), { event: "fetch" });
|
|
1274
|
-
}
|
|
1275
|
-
alarm(alarmInfo) {
|
|
1276
|
-
const logicalAlarms = options.alarms?.pipe(Effect.asVoid);
|
|
1277
|
-
const rawAlarm = options.alarm?.(alarmInfo);
|
|
1278
|
-
const alarmEffect = logicalAlarms !== void 0 && rawAlarm !== void 0 ? Effect.gen(function* () {
|
|
1279
|
-
yield* logicalAlarms;
|
|
1280
|
-
yield* rawAlarm;
|
|
1281
|
-
}) : logicalAlarms ?? rawAlarm;
|
|
1282
|
-
if (alarmEffect !== void 0) return this[RunSymbol](alarmEffect.pipe(Effect.onExit(() => scheduleTelemetryFlush)), { event: "alarm" });
|
|
1283
|
-
}
|
|
1284
|
-
webSocketMessage(socket, message) {
|
|
1285
|
-
if (options.webSocketMessage !== void 0) return this[RunSymbol](options.webSocketMessage(fromWebSocket(socket), message), { event: "webSocketMessage" });
|
|
1286
|
-
}
|
|
1287
|
-
webSocketClose(socket, code, reason, wasClean) {
|
|
1288
|
-
if (options.webSocketClose !== void 0) return this[RunSymbol](options.webSocketClose(fromWebSocket(socket), code, reason, wasClean), { event: "webSocketClose" });
|
|
1289
|
-
}
|
|
1290
|
-
webSocketError(socket, cause) {
|
|
1291
|
-
if (options.webSocketError !== void 0) return this[RunSymbol](options.webSocketError(fromWebSocket(socket), cause), { event: "webSocketError" });
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
defineEntrypointRpcMethods("Durable Object", EffectDurableObject.prototype, options.rpc, reservedMethodNames, (self, effect, rpc) => self[RunSymbol](effect, {
|
|
1295
|
-
event: "rpc",
|
|
1296
|
-
rpc
|
|
1297
|
-
}), () => scheduleTelemetryFlush, options.rpcTracing);
|
|
1298
|
-
return assumeEntrypointClass(EffectDurableObject);
|
|
1299
|
-
};
|
|
1300
|
-
//#endregion
|
|
1301
|
-
//#region src/DurableObjectAlarm.ts
|
|
1302
|
-
var DurableObjectAlarm_exports = /* @__PURE__ */ __exportAll({
|
|
1303
|
-
DurableObjectAlarm: () => DurableObjectAlarm,
|
|
1304
|
-
DurableObjectAlarmEvent: () => DurableObjectAlarmEvent,
|
|
1305
|
-
InvalidAlarmPayloadError: () => InvalidAlarmPayloadError,
|
|
1306
|
-
InvalidAlarmRefError: () => InvalidAlarmRefError,
|
|
1307
|
-
InvalidProcessDueAlarmsOptionsError: () => InvalidProcessDueAlarmsOptionsError,
|
|
1308
|
-
InvalidRepeatEveryError: () => InvalidRepeatEveryError,
|
|
1309
|
-
StoredAlarmDecodeError: () => StoredAlarmDecodeError,
|
|
1310
|
-
define: () => define,
|
|
1311
|
-
processDue: () => processDue
|
|
1312
|
-
});
|
|
1313
|
-
const INIT_TABLE_SQL = `
|
|
1314
|
-
CREATE TABLE IF NOT EXISTS effect_cf_scheduled_alarms (
|
|
1315
|
-
storage_id TEXT PRIMARY KEY,
|
|
1316
|
-
alarm_id TEXT NOT NULL,
|
|
1317
|
-
tag TEXT NOT NULL,
|
|
1318
|
-
run_at INTEGER NOT NULL,
|
|
1319
|
-
repeat_every_ms INTEGER,
|
|
1320
|
-
payload TEXT NOT NULL
|
|
1321
|
-
);
|
|
1322
|
-
CREATE INDEX IF NOT EXISTS idx_effect_cf_scheduled_alarms_run_at_storage_id
|
|
1323
|
-
ON effect_cf_scheduled_alarms (run_at, storage_id);
|
|
1324
|
-
`;
|
|
1325
|
-
const DEFAULT_PROCESS_DUE_ALARMS_LIMIT = 100;
|
|
1326
|
-
const DEFAULT_PROCESS_DUE_ALARMS_FAILURE_RESCHEDULE_AFTER = "30 seconds";
|
|
1327
|
-
const getScheduledEventId = (input) => `effect-cf-alarm:${encodeURIComponent(input.tag)}:${encodeURIComponent(input.id)}`;
|
|
1328
|
-
var InvalidAlarmRefError = class extends Data.TaggedError("InvalidAlarmRefError") {
|
|
1329
|
-
get message() {
|
|
1330
|
-
return `Invalid Durable Object alarm ref: ${causeMessage(this.cause)}`;
|
|
1331
|
-
}
|
|
1332
|
-
};
|
|
1333
|
-
var InvalidAlarmPayloadError = class extends Data.TaggedError("InvalidAlarmPayloadError") {
|
|
1334
|
-
get message() {
|
|
1335
|
-
return `Invalid Durable Object alarm payload: ${causeMessage(this.cause)}`;
|
|
1336
|
-
}
|
|
1337
|
-
};
|
|
1338
|
-
var InvalidRepeatEveryError = class extends Data.TaggedError("InvalidRepeatEveryError") {
|
|
1339
|
-
get message() {
|
|
1340
|
-
return `Invalid Durable Object alarm repeatEvery: ${causeMessage(this.cause)}`;
|
|
1341
|
-
}
|
|
1342
|
-
};
|
|
1343
|
-
var InvalidProcessDueAlarmsOptionsError = class extends Data.TaggedError("InvalidProcessDueAlarmsOptionsError") {
|
|
1344
|
-
get message() {
|
|
1345
|
-
return `Invalid processDueAlarms options: ${causeMessage(this.cause)}`;
|
|
1346
|
-
}
|
|
1347
|
-
};
|
|
1348
|
-
var StoredAlarmDecodeError = class extends Data.TaggedError("StoredAlarmDecodeError") {
|
|
1349
|
-
get message() {
|
|
1350
|
-
return `Failed to decode stored alarm "${this.storageId}": ${causeMessage(this.cause)}`;
|
|
1351
|
-
}
|
|
1352
|
-
};
|
|
1353
|
-
const DurableObjectAlarmEvent = Schema.TaggedUnion({ AlarmDue: {
|
|
1354
|
-
id: Schema.NonEmptyString,
|
|
1355
|
-
payload: Schema.Json,
|
|
1356
|
-
/** Persisted due time, which can differ from the invocation time during retries. */
|
|
1357
|
-
scheduledAt: Schema.DateTimeUtc,
|
|
1358
|
-
tag: Schema.NonEmptyString
|
|
1359
|
-
} });
|
|
1360
|
-
const AlarmRefSchema = Schema.Struct({
|
|
1361
|
-
id: Schema.NonEmptyString,
|
|
1362
|
-
tag: Schema.NonEmptyString
|
|
1363
|
-
});
|
|
1364
|
-
const decodeAlarmRef = (input) => Schema.decodeUnknownEffect(AlarmRefSchema)(input).pipe(Effect.mapError((cause) => new InvalidAlarmRefError({ cause })));
|
|
1365
|
-
const StoredPayloadString = Schema.fromJsonString(Schema.Json);
|
|
1366
|
-
const decodeStoredPayload = (row) => Schema.decodeUnknownEffect(StoredPayloadString)(row.payload).pipe(Effect.mapError((cause) => new StoredAlarmDecodeError({
|
|
1367
|
-
cause,
|
|
1368
|
-
storageId: row.storage_id
|
|
1369
|
-
})));
|
|
1370
|
-
const encodeStoredPayload = (payload) => Schema.encodeEffect(StoredPayloadString)(payload).pipe(Effect.mapError((cause) => new InvalidAlarmPayloadError({ cause })));
|
|
1371
|
-
const ensureTable = (state) => state.storage.sql.exec(INIT_TABLE_SQL).pipe(Effect.asVoid);
|
|
1372
|
-
const toRepeatEveryMillis = (input) => {
|
|
1373
|
-
if (input === void 0) return Effect.succeed(null);
|
|
1374
|
-
return Effect.try({
|
|
1375
|
-
try: () => {
|
|
1376
|
-
const millis = Duration.toMillis(input);
|
|
1377
|
-
if (!Number.isFinite(millis) || millis <= 0) throw new Error("Alarm repeatEvery must be a positive finite duration");
|
|
1378
|
-
return Math.ceil(millis);
|
|
1379
|
-
},
|
|
1380
|
-
catch: (cause) => new InvalidRepeatEveryError({ cause })
|
|
1381
|
-
});
|
|
1382
|
-
};
|
|
1383
|
-
const toAlarmDue = (row) => Effect.gen(function* () {
|
|
1384
|
-
if (!Number.isFinite(row.run_at)) return yield* Effect.fail(new StoredAlarmDecodeError({
|
|
1385
|
-
cause: /* @__PURE__ */ new Error("Stored alarm run_at must be a finite number"),
|
|
1386
|
-
storageId: row.storage_id
|
|
1387
|
-
}));
|
|
1388
|
-
return DurableObjectAlarmEvent.make({
|
|
1389
|
-
_tag: "AlarmDue",
|
|
1390
|
-
id: row.alarm_id,
|
|
1391
|
-
payload: yield* decodeStoredPayload(row),
|
|
1392
|
-
scheduledAt: DateTime.makeUnsafe(row.run_at),
|
|
1393
|
-
tag: row.tag
|
|
1394
|
-
});
|
|
1395
|
-
});
|
|
1396
|
-
const getProcessLimit = (options) => {
|
|
1397
|
-
const limit = options?.limit ?? DEFAULT_PROCESS_DUE_ALARMS_LIMIT;
|
|
1398
|
-
if (!Number.isSafeInteger(limit) || limit <= 0) return Effect.fail(new InvalidProcessDueAlarmsOptionsError({ cause: /* @__PURE__ */ new Error("processDueAlarms limit must be a positive safe integer") }));
|
|
1399
|
-
return Effect.succeed(limit);
|
|
1400
|
-
};
|
|
1401
|
-
const toFailureRescheduleMillis = (input) => Effect.try({
|
|
1402
|
-
try: () => {
|
|
1403
|
-
const millis = Duration.toMillis(input);
|
|
1404
|
-
if (!Number.isFinite(millis) || millis <= 0) throw new Error("Alarm failure rescheduleAfter must be a positive finite duration");
|
|
1405
|
-
return Math.ceil(millis);
|
|
1406
|
-
},
|
|
1407
|
-
catch: (cause) => new InvalidProcessDueAlarmsOptionsError({ cause })
|
|
1408
|
-
});
|
|
1409
|
-
const getFailureRetryDelay = (options) => toFailureRescheduleMillis(options?.retryFailedAfter ?? DEFAULT_PROCESS_DUE_ALARMS_FAILURE_RESCHEDULE_AFTER);
|
|
1410
|
-
const getFailureActionMode = (action) => Predicate.isString(action) ? action : action.mode;
|
|
1411
|
-
const getFailureActionRetryDelay = (action) => Predicate.isString(action) || action.mode !== "retry" ? void 0 : action.retryFailedAfter;
|
|
1412
|
-
const processDue = (handle, options = {}) => Effect.gen(function* () {
|
|
1413
|
-
return yield* (yield* DurableObjectAlarm).processDueAlarms(handle, options);
|
|
1414
|
-
});
|
|
1415
|
-
const isAlarmDefinitionConfig = (definition) => Predicate.isObject(definition) && "payload" in definition;
|
|
1416
|
-
const getAlarmDefinitionSchema = (definition) => isAlarmDefinitionConfig(definition) ? definition.payload : definition;
|
|
1417
|
-
const getAlarmDefinitionFailureAction = (definition) => {
|
|
1418
|
-
if (definition === void 0 || !isAlarmDefinitionConfig(definition)) return;
|
|
1419
|
-
if (definition.failure === void 0) return;
|
|
1420
|
-
return definition.failure === "retry" ? {
|
|
1421
|
-
mode: "retry",
|
|
1422
|
-
retryFailedAfter: definition.retry?.initialDelay
|
|
1423
|
-
} : { mode: definition.failure };
|
|
1424
|
-
};
|
|
1425
|
-
const define = (definitions) => ({ handlers: (handlers, options) => processDue((event) => Effect.gen(function* () {
|
|
1426
|
-
const definition = definitions[event.tag];
|
|
1427
|
-
if (definition === void 0) return;
|
|
1428
|
-
const schema = getAlarmDefinitionSchema(definition);
|
|
1429
|
-
const payload = yield* Schema.decodeUnknownEffect(schema)(event.payload).pipe(Effect.mapError((cause) => new StoredAlarmDecodeError({
|
|
1430
|
-
cause,
|
|
1431
|
-
storageId: getScheduledEventId(event)
|
|
1432
|
-
})));
|
|
1433
|
-
const handler = handlers[event.tag];
|
|
1434
|
-
yield* handler({
|
|
1435
|
-
...event,
|
|
1436
|
-
payload
|
|
1437
|
-
});
|
|
1438
|
-
}), {
|
|
1439
|
-
...options,
|
|
1440
|
-
onFailure: (failure) => Effect.gen(function* () {
|
|
1441
|
-
const action = getAlarmDefinitionFailureAction(definitions[failure.tag]);
|
|
1442
|
-
const optionAction = options?.onFailure === void 0 ? void 0 : yield* options.onFailure(failure);
|
|
1443
|
-
return action ?? optionAction;
|
|
1444
|
-
})
|
|
1445
|
-
}) });
|
|
1446
|
-
var DurableObjectAlarm = class DurableObjectAlarm extends Context.Service()("effect-cf/DurableObjectAlarm") {
|
|
1447
|
-
static layer = Layer.effect(DurableObjectAlarm, Effect.gen(function* () {
|
|
1448
|
-
const state = yield* DurableObjectState;
|
|
1449
|
-
const reconcileAlarm = Effect.fn("DurableObjectAlarm.reconcileAlarm")(function* () {
|
|
1450
|
-
const next = (yield* (yield* state.storage.sql.exec(`SELECT run_at FROM effect_cf_scheduled_alarms ORDER BY run_at ASC, storage_id ASC LIMIT 1`)).toArray())[0];
|
|
1451
|
-
if (next === void 0) {
|
|
1452
|
-
yield* state.storage.deleteAlarm();
|
|
1453
|
-
return;
|
|
1454
|
-
}
|
|
1455
|
-
yield* state.storage.setAlarm(next.run_at);
|
|
1456
|
-
});
|
|
1457
|
-
const rescheduleFailedAlarm = Effect.fn("DurableObjectAlarm.rescheduleFailedAlarm")(function* (row, retryDelayMillis) {
|
|
1458
|
-
const retryAt = (yield* Clock.currentTimeMillis) + retryDelayMillis;
|
|
1459
|
-
if (row.repeat_every_ms === null) {
|
|
1460
|
-
yield* (yield* state.storage.sql.exec(`UPDATE effect_cf_scheduled_alarms
|
|
1461
|
-
SET run_at = ?
|
|
1462
|
-
WHERE storage_id = ?
|
|
1463
|
-
AND run_at = ?
|
|
1464
|
-
AND repeat_every_ms IS NULL
|
|
1465
|
-
AND payload = ?`, retryAt, row.storage_id, row.run_at, row.payload)).rowsWritten;
|
|
1466
|
-
return;
|
|
1467
|
-
}
|
|
1468
|
-
yield* (yield* state.storage.sql.exec(`UPDATE effect_cf_scheduled_alarms
|
|
1469
|
-
SET run_at = ?
|
|
1470
|
-
WHERE storage_id = ?
|
|
1471
|
-
AND run_at = ?
|
|
1472
|
-
AND repeat_every_ms = ?
|
|
1473
|
-
AND payload = ?`, retryAt, row.storage_id, row.run_at, row.repeat_every_ms, row.payload)).rowsWritten;
|
|
1474
|
-
});
|
|
1475
|
-
const acknowledgeAlarm = Effect.fn("DurableObjectAlarm.acknowledgeAlarm")(function* (row) {
|
|
1476
|
-
if (row.repeat_every_ms === null) {
|
|
1477
|
-
yield* (yield* state.storage.sql.exec(`DELETE FROM effect_cf_scheduled_alarms
|
|
1478
|
-
WHERE storage_id = ?
|
|
1479
|
-
AND run_at = ?
|
|
1480
|
-
AND repeat_every_ms IS NULL
|
|
1481
|
-
AND payload = ?`, row.storage_id, row.run_at, row.payload)).rowsWritten;
|
|
1482
|
-
return;
|
|
1483
|
-
}
|
|
1484
|
-
const acknowledgedAt = yield* Clock.currentTimeMillis;
|
|
1485
|
-
yield* (yield* state.storage.sql.exec(`UPDATE effect_cf_scheduled_alarms
|
|
1486
|
-
SET run_at = ?
|
|
1487
|
-
WHERE storage_id = ?
|
|
1488
|
-
AND run_at = ?
|
|
1489
|
-
AND repeat_every_ms = ?
|
|
1490
|
-
AND payload = ?`, acknowledgedAt + row.repeat_every_ms, row.storage_id, row.run_at, row.repeat_every_ms, row.payload)).rowsWritten;
|
|
1491
|
-
});
|
|
1492
|
-
const cancelAlarm = Effect.fn("DurableObjectAlarm.cancelAlarm")(function* (input) {
|
|
1493
|
-
const ref = yield* decodeAlarmRef(input);
|
|
1494
|
-
yield* state.storage.sql.exec(`DELETE FROM effect_cf_scheduled_alarms WHERE storage_id = ?`, getScheduledEventId(ref));
|
|
1495
|
-
});
|
|
1496
|
-
const scheduleAlarm = Effect.fn("DurableObjectAlarm.scheduleAlarm")(function* (input) {
|
|
1497
|
-
const ref = yield* decodeAlarmRef(input);
|
|
1498
|
-
const repeatEveryMillis = yield* toRepeatEveryMillis(input.repeatEvery);
|
|
1499
|
-
const payload = yield* encodeStoredPayload(input.payload);
|
|
1500
|
-
const runAt = DateTime.toEpochMillis(input.runAt);
|
|
1501
|
-
yield* state.storage.sql.exec(`INSERT OR REPLACE INTO effect_cf_scheduled_alarms
|
|
1502
|
-
(storage_id, alarm_id, tag, run_at, repeat_every_ms, payload)
|
|
1503
|
-
VALUES (?, ?, ?, ?, ?, ?)`, getScheduledEventId(ref), ref.id, ref.tag, runAt, repeatEveryMillis, payload);
|
|
1504
|
-
});
|
|
1505
|
-
const transaction = (closure) => state.storage.transaction(() => Effect.withFiber((owner) => {
|
|
1506
|
-
let active = true;
|
|
1507
|
-
const requireActive = (effect) => Effect.withFiber((fiber) => active && fiber === owner ? effect : Effect.fail(new StorageOperationError({
|
|
1508
|
-
operation: "alarm.transaction",
|
|
1509
|
-
cause: /* @__PURE__ */ new Error("Alarm mutations require their active transaction callback")
|
|
1510
|
-
})));
|
|
1511
|
-
return Effect.gen(function* () {
|
|
1512
|
-
yield* ensureTable(state);
|
|
1513
|
-
const result = yield* Effect.suspend(() => closure({
|
|
1514
|
-
cancelAlarm: (input) => requireActive(cancelAlarm(input)),
|
|
1515
|
-
scheduleAlarm: (input) => requireActive(scheduleAlarm(input))
|
|
1516
|
-
})).pipe(Effect.ensuring(Effect.sync(() => {
|
|
1517
|
-
active = false;
|
|
1518
|
-
})));
|
|
1519
|
-
yield* reconcileAlarm();
|
|
1520
|
-
return result;
|
|
1521
|
-
});
|
|
1522
|
-
}));
|
|
1523
|
-
const processDueAlarms = Effect.fn("DurableObjectAlarm.processDueAlarms")(function* (handle, options) {
|
|
1524
|
-
yield* ensureTable(state);
|
|
1525
|
-
const mode = options?.mode ?? "isolated";
|
|
1526
|
-
const limit = yield* getProcessLimit(options);
|
|
1527
|
-
const now = yield* Clock.currentTimeMillis;
|
|
1528
|
-
const dueRows = yield* (yield* state.storage.sql.exec(`SELECT storage_id, alarm_id, tag, run_at, repeat_every_ms, payload
|
|
1529
|
-
FROM effect_cf_scheduled_alarms
|
|
1530
|
-
WHERE run_at <= ?
|
|
1531
|
-
ORDER BY run_at ASC, storage_id ASC
|
|
1532
|
-
LIMIT ?`, now, limit)).toArray();
|
|
1533
|
-
const handled = [];
|
|
1534
|
-
const failed = [];
|
|
1535
|
-
const handleFailure = function* (row, event, cause) {
|
|
1536
|
-
const failure = {
|
|
1537
|
-
cause,
|
|
1538
|
-
event,
|
|
1539
|
-
id: row.alarm_id,
|
|
1540
|
-
storageId: row.storage_id,
|
|
1541
|
-
tag: row.tag
|
|
1542
|
-
};
|
|
1543
|
-
failed.push(failure);
|
|
1544
|
-
const failureAction = options?.onFailure === void 0 ? void 0 : yield* options.onFailure(failure);
|
|
1545
|
-
const actionMode = failureAction === void 0 ? mode : getFailureActionMode(failureAction);
|
|
1546
|
-
if (actionMode === "retry" || actionMode === "isolated") {
|
|
1547
|
-
const actionRetryDelay = failureAction === void 0 ? void 0 : getFailureActionRetryDelay(failureAction);
|
|
1548
|
-
const retryDelay = actionRetryDelay === void 0 ? yield* getFailureRetryDelay(options) : yield* toFailureRescheduleMillis(actionRetryDelay);
|
|
1549
|
-
yield* rescheduleFailedAlarm(row, retryDelay);
|
|
1550
|
-
return "continue";
|
|
1551
|
-
}
|
|
1552
|
-
if (actionMode === "skip-and-advance-repeat") {
|
|
1553
|
-
yield* acknowledgeAlarm(row);
|
|
1554
|
-
return "continue";
|
|
1555
|
-
}
|
|
1556
|
-
yield* reconcileAlarm();
|
|
1557
|
-
return "stop";
|
|
1558
|
-
};
|
|
1559
|
-
for (const row of dueRows) {
|
|
1560
|
-
const eventExit = yield* Effect.exit(toAlarmDue(row));
|
|
1561
|
-
if (Exit.isFailure(eventExit)) {
|
|
1562
|
-
if ((yield* handleFailure(row, void 0, eventExit.cause)) === "stop") return yield* Effect.failCause(eventExit.cause);
|
|
1563
|
-
continue;
|
|
1564
|
-
}
|
|
1565
|
-
const event = eventExit.value;
|
|
1566
|
-
const handleExit = yield* Effect.exit(handle(event));
|
|
1567
|
-
if (Exit.isFailure(handleExit)) {
|
|
1568
|
-
if ((yield* handleFailure(row, event, handleExit.cause)) === "stop") return yield* Effect.failCause(handleExit.cause);
|
|
1569
|
-
continue;
|
|
1570
|
-
}
|
|
1571
|
-
yield* acknowledgeAlarm(row);
|
|
1572
|
-
handled.push(event);
|
|
1573
|
-
}
|
|
1574
|
-
yield* reconcileAlarm();
|
|
1575
|
-
return {
|
|
1576
|
-
failed,
|
|
1577
|
-
handled
|
|
1578
|
-
};
|
|
1579
|
-
});
|
|
1580
|
-
return DurableObjectAlarm.of({
|
|
1581
|
-
cancelAlarm: (input) => transaction((alarms) => alarms.cancelAlarm(input)),
|
|
1582
|
-
processDueAlarms,
|
|
1583
|
-
scheduleAlarm: (input) => transaction((alarms) => alarms.scheduleAlarm(input)),
|
|
1584
|
-
transaction
|
|
1585
|
-
});
|
|
1586
|
-
}).pipe(Effect.withSpan("DurableObjectAlarm.layer")));
|
|
1587
|
-
};
|
|
1588
|
-
//#endregion
|
|
1589
|
-
//#region src/DurableObjectRpcWebSocket.ts
|
|
1590
|
-
var DurableObjectRpcWebSocket_exports = /* @__PURE__ */ __exportAll({
|
|
1591
|
-
DurableObjectRpcWebSocket: () => DurableObjectRpcWebSocket,
|
|
1592
|
-
layer: () => layer$8,
|
|
1593
|
-
resumableStream: () => resumableStream
|
|
1594
|
-
});
|
|
1595
|
-
const defaultAttachmentKey = "effectCloudflareRpcClientId";
|
|
1596
|
-
const defaultTag = "effect-cf-rpc";
|
|
1597
|
-
const legacyAttachmentVersion = 1;
|
|
1598
|
-
const resumableAttachmentVersion = 2;
|
|
1599
|
-
const serviceRestartCode = 1012;
|
|
1600
|
-
const serviceRestartReason = "Durable Object RPC activation reset";
|
|
1601
|
-
/** Declares an explicitly resumable RPC stream. */
|
|
1602
|
-
const resumableStream = (declaration) => declaration;
|
|
1603
|
-
const PersistedPendingBatchSchema = Schema.Struct({ checkpointTokens: Schema.Array(Schema.String) });
|
|
1604
|
-
const PersistedSubscriptionSchema = Schema.Struct({
|
|
1605
|
-
definitionId: Schema.String,
|
|
1606
|
-
subscriptionKey: Schema.String,
|
|
1607
|
-
requestId: Schema.Union([Schema.String, Schema.Finite]),
|
|
1608
|
-
rpcTag: Schema.String,
|
|
1609
|
-
resumeDescriptor: Schema.Unknown,
|
|
1610
|
-
acknowledgedCheckpoint: Schema.Unknown,
|
|
1611
|
-
pending: Schema.optionalKey(PersistedPendingBatchSchema)
|
|
1612
|
-
});
|
|
1613
|
-
const ResumableAttachmentMetadataSchema = Schema.Struct({
|
|
1614
|
-
version: Schema.Literal(resumableAttachmentVersion),
|
|
1615
|
-
clientId: Schema.Finite,
|
|
1616
|
-
hasPendingRequests: Schema.Boolean,
|
|
1617
|
-
hasNonResumableRequests: Schema.Boolean,
|
|
1618
|
-
subscriptions: Schema.Array(PersistedSubscriptionSchema)
|
|
1619
|
-
});
|
|
1620
|
-
const decodeResumableAttachment = Schema.decodeUnknownOption(ResumableAttachmentMetadataSchema);
|
|
1621
|
-
var DurableObjectRpcWebSocket = class extends Context.Service()("effect-cf/DurableObjectRpcWebSocket") {};
|
|
1622
|
-
/**
|
|
1623
|
-
* Builds a hibernation-aware transport that bridges Durable Object websocket
|
|
1624
|
-
* events to `RpcServer.Protocol`.
|
|
1625
|
-
*
|
|
1626
|
-
* The layer restores idle tagged sockets and explicitly declared resumable
|
|
1627
|
-
* streams after constructor recreation. A socket that lost any other in-flight
|
|
1628
|
-
* request is closed with code 1012, which the stock Effect socket protocol
|
|
1629
|
-
* reports as an `RpcClientError` containing `SocketCloseError`.
|
|
1630
|
-
*/
|
|
1631
|
-
const layer$8 = (options = {}) => Layer.effectContext(Effect.gen(function* () {
|
|
1632
|
-
const tag = options.tag ?? defaultTag;
|
|
1633
|
-
const attachmentKey = options.attachmentKey ?? defaultAttachmentKey;
|
|
1634
|
-
const heartbeatPolicy = options.heartbeat ?? "auto-response";
|
|
1635
|
-
const declarations = options.resumableStreams ?? [];
|
|
1636
|
-
const durableObjectState = yield* DurableObjectState;
|
|
1637
|
-
const serialization = yield* RpcSerialization.RpcSerialization;
|
|
1638
|
-
const encodeDefect = Schema.encodeSync(serialization.codecFor(Schema.Defect()));
|
|
1639
|
-
const disconnects = yield* Queue.make();
|
|
1640
|
-
const connectionsBySocket = /* @__PURE__ */ new Map();
|
|
1641
|
-
const connectionsById = /* @__PURE__ */ new Map();
|
|
1642
|
-
const resetSockets = /* @__PURE__ */ new WeakSet();
|
|
1643
|
-
const declarationsById = /* @__PURE__ */ new Map();
|
|
1644
|
-
const declarationsByTag = /* @__PURE__ */ new Map();
|
|
1645
|
-
const replayRequests = [];
|
|
1646
|
-
let nextClientId = 0;
|
|
1647
|
-
let activeNonResumableRequestCount = 0;
|
|
1648
|
-
let writeRequest;
|
|
1649
|
-
for (const declaration of declarations) {
|
|
1650
|
-
if (declaration.id.length === 0 || declaration.rpcTag.length === 0) return yield* Effect.die(/* @__PURE__ */ new Error("Resumable RPC stream declaration ids and tags must be non-empty"));
|
|
1651
|
-
if (declarationsById.has(declaration.id)) return yield* Effect.die(/* @__PURE__ */ new Error(`Duplicate resumable RPC stream declaration id: ${declaration.id}`));
|
|
1652
|
-
if (declarationsByTag.has(declaration.rpcTag)) return yield* Effect.die(/* @__PURE__ */ new Error(`Duplicate resumable RPC stream tag: ${declaration.rpcTag}`));
|
|
1653
|
-
declarationsById.set(declaration.id, declaration);
|
|
1654
|
-
declarationsByTag.set(declaration.rpcTag, declaration);
|
|
1655
|
-
}
|
|
1656
|
-
const reserveClientId = (socket) => {
|
|
1657
|
-
const id = nextClientId++;
|
|
1658
|
-
const created = {
|
|
1659
|
-
version: legacyAttachmentVersion,
|
|
1660
|
-
clientId: id,
|
|
1661
|
-
hasPendingRequests: false
|
|
1662
|
-
};
|
|
1663
|
-
writeAttachment(socket.raw, attachmentKey, created);
|
|
1664
|
-
return created;
|
|
1665
|
-
};
|
|
1666
|
-
const addSubscription = (connection, subscription) => {
|
|
1667
|
-
if (connection.subscriptionsByRequestId.has(subscription.requestId)) return false;
|
|
1668
|
-
let byKey = connection.subscriptionsByDefinition.get(subscription.definitionId);
|
|
1669
|
-
if (byKey?.has(subscription.subscriptionKey) === true) return false;
|
|
1670
|
-
if (byKey === void 0) {
|
|
1671
|
-
byKey = /* @__PURE__ */ new Map();
|
|
1672
|
-
connection.subscriptionsByDefinition.set(subscription.definitionId, byKey);
|
|
1673
|
-
}
|
|
1674
|
-
byKey.set(subscription.subscriptionKey, subscription);
|
|
1675
|
-
connection.subscriptionsByRequestId.set(subscription.requestId, subscription);
|
|
1676
|
-
connection.requestIds.add(subscription.requestId);
|
|
1677
|
-
connection.metadataVersion = resumableAttachmentVersion;
|
|
1678
|
-
return true;
|
|
1679
|
-
};
|
|
1680
|
-
const removeSubscription = (connection, requestId) => {
|
|
1681
|
-
const subscription = connection.subscriptionsByRequestId.get(requestId);
|
|
1682
|
-
if (subscription === void 0) return;
|
|
1683
|
-
connection.subscriptionsByRequestId.delete(requestId);
|
|
1684
|
-
const byKey = connection.subscriptionsByDefinition.get(subscription.definitionId);
|
|
1685
|
-
byKey?.delete(subscription.subscriptionKey);
|
|
1686
|
-
if (byKey?.size === 0) connection.subscriptionsByDefinition.delete(subscription.definitionId);
|
|
1687
|
-
return subscription;
|
|
1688
|
-
};
|
|
1689
|
-
const register = (socket, restoredMetadata, restoredSubscriptions = []) => {
|
|
1690
|
-
const existing = connectionsBySocket.get(socket.raw);
|
|
1691
|
-
if (existing !== void 0) return existing;
|
|
1692
|
-
const metadata = restoredMetadata ?? reserveClientId(socket);
|
|
1693
|
-
const connection = {
|
|
1694
|
-
id: metadata.clientId,
|
|
1695
|
-
socket,
|
|
1696
|
-
parser: serialization.makeUnsafe(),
|
|
1697
|
-
requestIds: /* @__PURE__ */ new Set(),
|
|
1698
|
-
nonResumableRequestIds: /* @__PURE__ */ new Set(),
|
|
1699
|
-
subscriptionsByRequestId: /* @__PURE__ */ new Map(),
|
|
1700
|
-
subscriptionsByDefinition: /* @__PURE__ */ new Map(),
|
|
1701
|
-
suppressedAckRequestIds: /* @__PURE__ */ new Set(),
|
|
1702
|
-
currentPendingRequestIds: /* @__PURE__ */ new Set(),
|
|
1703
|
-
metadataVersion: metadata.version
|
|
1704
|
-
};
|
|
1705
|
-
if (connectionsById.has(connection.id)) throw new Error(`Duplicate Durable Object RPC websocket client id: ${connection.id}`);
|
|
1706
|
-
for (const subscription of restoredSubscriptions) if (!addSubscription(connection, subscription)) throw new Error("Duplicate restored resumable RPC stream subscription identity");
|
|
1707
|
-
connectionsBySocket.set(socket.raw, connection);
|
|
1708
|
-
connectionsById.set(connection.id, connection);
|
|
1709
|
-
nextClientId = Math.max(nextClientId, connection.id + 1);
|
|
1710
|
-
return connection;
|
|
1711
|
-
};
|
|
1712
|
-
const heartbeat = yield* makeHeartbeatController(durableObjectState, serialization, heartbeatPolicy);
|
|
1713
|
-
const syncHeartbeat = () => heartbeat.setEnabled(connectionsBySocket.size > 0 && activeNonResumableRequestCount === 0);
|
|
1714
|
-
const persistConnection = Effect.fn("DurableObjectRpcWebSocket.persistConnection")(function* (connection) {
|
|
1715
|
-
return yield* Effect.try({
|
|
1716
|
-
try: () => {
|
|
1717
|
-
if (connection.metadataVersion === legacyAttachmentVersion) {
|
|
1718
|
-
writeAttachment(connection.socket.raw, attachmentKey, {
|
|
1719
|
-
version: legacyAttachmentVersion,
|
|
1720
|
-
clientId: connection.id,
|
|
1721
|
-
hasPendingRequests: connection.requestIds.size > 0
|
|
1722
|
-
});
|
|
1723
|
-
return;
|
|
1724
|
-
}
|
|
1725
|
-
const subscriptions = Array.from(connection.subscriptionsByRequestId.values()).map(({ declaration: _, ...subscription }) => subscription);
|
|
1726
|
-
writeAttachment(connection.socket.raw, attachmentKey, {
|
|
1727
|
-
version: resumableAttachmentVersion,
|
|
1728
|
-
clientId: connection.id,
|
|
1729
|
-
hasPendingRequests: connection.requestIds.size > 0,
|
|
1730
|
-
hasNonResumableRequests: connection.nonResumableRequestIds.size > 0,
|
|
1731
|
-
subscriptions
|
|
1732
|
-
});
|
|
1733
|
-
},
|
|
1734
|
-
catch: (cause) => new DurableWebSocketAttachmentError({
|
|
1735
|
-
operation: "serialize",
|
|
1736
|
-
cause
|
|
1737
|
-
})
|
|
1738
|
-
});
|
|
1739
|
-
});
|
|
1740
|
-
const unregister = Effect.fn("DurableObjectRpcWebSocket.unregister")(function* (socket) {
|
|
1741
|
-
const connection = connectionsBySocket.get(socket.raw);
|
|
1742
|
-
if (connection === void 0) return;
|
|
1743
|
-
connectionsBySocket.delete(socket.raw);
|
|
1744
|
-
connectionsById.delete(connection.id);
|
|
1745
|
-
activeNonResumableRequestCount -= connection.nonResumableRequestIds.size;
|
|
1746
|
-
connection.requestIds.clear();
|
|
1747
|
-
connection.nonResumableRequestIds.clear();
|
|
1748
|
-
connection.subscriptionsByRequestId.clear();
|
|
1749
|
-
connection.subscriptionsByDefinition.clear();
|
|
1750
|
-
connection.suppressedAckRequestIds.clear();
|
|
1751
|
-
connection.currentPendingRequestIds.clear();
|
|
1752
|
-
Queue.offerUnsafe(disconnects, connection.id);
|
|
1753
|
-
yield* syncHeartbeat();
|
|
1754
|
-
});
|
|
1755
|
-
const resetSocket = Effect.fn("DurableObjectRpcWebSocket.resetSocket")(function* (socket, cause) {
|
|
1756
|
-
resetSockets.add(socket.raw);
|
|
1757
|
-
yield* unregister(socket).pipe(Effect.catchCause((unregisterCause) => Effect.logDebug("Failed to unregister Durable Object RPC websocket", unregisterCause)));
|
|
1758
|
-
if (cause !== void 0) yield* Effect.logDebug("Resetting Durable Object RPC websocket", cause);
|
|
1759
|
-
yield* socket.close(serviceRestartCode, serviceRestartReason).pipe(Effect.catch((closeError) => Effect.logDebug("Failed to close Durable Object RPC websocket", closeError)));
|
|
1760
|
-
});
|
|
1761
|
-
const persistOrReset = Effect.fn("DurableObjectRpcWebSocket.persistOrReset")(function* (connection) {
|
|
1762
|
-
return yield* persistConnection(connection).pipe(Effect.as(true), Effect.catch((cause) => resetSocket(connection.socket, cause).pipe(Effect.as(false))));
|
|
1763
|
-
});
|
|
1764
|
-
const trackRequest = Effect.fn("DurableObjectRpcWebSocket.trackRequest")(function* (connection, request) {
|
|
1765
|
-
if (connection.requestIds.has(request.id)) return true;
|
|
1766
|
-
const declaration = declarationsByTag.get(request.tag);
|
|
1767
|
-
const identified = declaration === void 0 ? Option.none() : yield* Effect.sync(() => declaration.identify(request));
|
|
1768
|
-
if (declaration !== void 0 && Option.isSome(identified)) {
|
|
1769
|
-
if (!addSubscription(connection, {
|
|
1770
|
-
declaration,
|
|
1771
|
-
definitionId: declaration.id,
|
|
1772
|
-
subscriptionKey: identified.value.subscriptionKey,
|
|
1773
|
-
requestId: request.id,
|
|
1774
|
-
rpcTag: declaration.rpcTag,
|
|
1775
|
-
resumeDescriptor: identified.value.resumeDescriptor,
|
|
1776
|
-
acknowledgedCheckpoint: identified.value.acknowledgedCheckpoint
|
|
1777
|
-
})) {
|
|
1778
|
-
yield* resetSocket(connection.socket, /* @__PURE__ */ new Error(`Duplicate resumable RPC stream subscription: ${declaration.id}`));
|
|
1779
|
-
return false;
|
|
1780
|
-
}
|
|
1781
|
-
} else {
|
|
1782
|
-
connection.requestIds.add(request.id);
|
|
1783
|
-
connection.nonResumableRequestIds.add(request.id);
|
|
1784
|
-
activeNonResumableRequestCount++;
|
|
1785
|
-
}
|
|
1786
|
-
if (!(yield* persistOrReset(connection))) return false;
|
|
1787
|
-
yield* syncHeartbeat();
|
|
1788
|
-
return true;
|
|
1789
|
-
});
|
|
1790
|
-
const completeRequest = Effect.fn("DurableObjectRpcWebSocket.completeRequest")(function* (connection, requestId, preserveAckFilter = false) {
|
|
1791
|
-
if (connection.requestIds.delete(requestId)) {
|
|
1792
|
-
if (connection.nonResumableRequestIds.delete(requestId)) activeNonResumableRequestCount--;
|
|
1793
|
-
const subscription = removeSubscription(connection, requestId);
|
|
1794
|
-
connection.currentPendingRequestIds.delete(requestId);
|
|
1795
|
-
if (preserveAckFilter && subscription !== void 0) connection.suppressedAckRequestIds.add(requestId);
|
|
1796
|
-
if (!(yield* persistOrReset(connection))) return;
|
|
1797
|
-
}
|
|
1798
|
-
if (!preserveAckFilter) connection.suppressedAckRequestIds.delete(requestId);
|
|
1799
|
-
yield* syncHeartbeat();
|
|
1800
|
-
});
|
|
1801
|
-
const completeAllRequests = Effect.fn("DurableObjectRpcWebSocket.completeAllRequests")(function* (connection) {
|
|
1802
|
-
const hadRequests = connection.requestIds.size > 0;
|
|
1803
|
-
if (connection.requestIds.size > 0) activeNonResumableRequestCount -= connection.nonResumableRequestIds.size;
|
|
1804
|
-
connection.requestIds.clear();
|
|
1805
|
-
connection.nonResumableRequestIds.clear();
|
|
1806
|
-
connection.subscriptionsByRequestId.clear();
|
|
1807
|
-
connection.subscriptionsByDefinition.clear();
|
|
1808
|
-
connection.suppressedAckRequestIds.clear();
|
|
1809
|
-
connection.currentPendingRequestIds.clear();
|
|
1810
|
-
if (hadRequests && !(yield* persistOrReset(connection))) return;
|
|
1811
|
-
yield* syncHeartbeat();
|
|
1812
|
-
});
|
|
1813
|
-
const restoredAttachments = (yield* durableObjectState.getWebSockets(tag)).map((socket) => ({
|
|
1814
|
-
socket,
|
|
1815
|
-
attachment: readAttachment(socket.raw, attachmentKey)
|
|
1816
|
-
}));
|
|
1817
|
-
for (const { attachment, socket } of restoredAttachments) {
|
|
1818
|
-
if (attachment._tag === "Invalid") {
|
|
1819
|
-
yield* resetSocket(socket);
|
|
1820
|
-
continue;
|
|
1821
|
-
}
|
|
1822
|
-
if (attachment._tag === "Missing") {
|
|
1823
|
-
yield* resetSocket(socket);
|
|
1824
|
-
continue;
|
|
1825
|
-
}
|
|
1826
|
-
const metadata = attachment.metadata;
|
|
1827
|
-
if (metadata.version === legacyAttachmentVersion) {
|
|
1828
|
-
if (metadata.hasPendingRequests) yield* resetSocket(socket);
|
|
1829
|
-
else if (connectionsById.has(metadata.clientId)) yield* resetSocket(socket);
|
|
1830
|
-
else yield* persistOrReset(register(socket, metadata));
|
|
1831
|
-
continue;
|
|
1832
|
-
}
|
|
1833
|
-
const prepared = yield* Effect.sync(() => {
|
|
1834
|
-
try {
|
|
1835
|
-
if (metadata.hasNonResumableRequests || metadata.hasPendingRequests !== (metadata.hasNonResumableRequests || metadata.subscriptions.length > 0)) throw new Error("Dirty resumable RPC websocket attachment metadata");
|
|
1836
|
-
const requestIds = /* @__PURE__ */ new Set();
|
|
1837
|
-
const subscriptionKeys = /* @__PURE__ */ new Map();
|
|
1838
|
-
const subscriptions = [];
|
|
1839
|
-
const requests = [];
|
|
1840
|
-
for (const persisted of metadata.subscriptions) {
|
|
1841
|
-
const declaration = declarationsById.get(persisted.definitionId);
|
|
1842
|
-
if (declaration === void 0 || declaration.rpcTag !== persisted.rpcTag) throw new Error("Missing resumable RPC stream declaration");
|
|
1843
|
-
let keys = subscriptionKeys.get(persisted.definitionId);
|
|
1844
|
-
if (keys === void 0) {
|
|
1845
|
-
keys = /* @__PURE__ */ new Set();
|
|
1846
|
-
subscriptionKeys.set(persisted.definitionId, keys);
|
|
1847
|
-
}
|
|
1848
|
-
if (requestIds.has(persisted.requestId) || keys.has(persisted.subscriptionKey)) throw new Error("Duplicate persisted resumable RPC stream subscription");
|
|
1849
|
-
requestIds.add(persisted.requestId);
|
|
1850
|
-
keys.add(persisted.subscriptionKey);
|
|
1851
|
-
if (persisted.pending !== void 0) {
|
|
1852
|
-
const { checkpointTokens } = persisted.pending;
|
|
1853
|
-
if (checkpointTokens.length === 0 || checkpointTokens.some((token) => token.length === 0) || new Set(checkpointTokens).size !== checkpointTokens.length) throw new Error("Invalid persisted resumable RPC stream pending batch");
|
|
1854
|
-
}
|
|
1855
|
-
const resumeDescriptor = Schema.decodeUnknownOption(declaration.resumeDescriptorSchema)(persisted.resumeDescriptor);
|
|
1856
|
-
const acknowledgedCheckpoint = Schema.decodeUnknownOption(declaration.checkpointSchema)(persisted.acknowledgedCheckpoint);
|
|
1857
|
-
if (Option.isNone(resumeDescriptor) || Option.isNone(acknowledgedCheckpoint)) throw new Error("Invalid persisted resumable RPC stream state");
|
|
1858
|
-
const rebuilt = declaration.rebuild({
|
|
1859
|
-
subscriptionKey: persisted.subscriptionKey,
|
|
1860
|
-
resumeDescriptor: resumeDescriptor.value,
|
|
1861
|
-
acknowledgedCheckpoint: acknowledgedCheckpoint.value
|
|
1862
|
-
});
|
|
1863
|
-
const request = {
|
|
1864
|
-
_tag: "Request",
|
|
1865
|
-
id: persisted.requestId,
|
|
1866
|
-
tag: declaration.rpcTag,
|
|
1867
|
-
payload: rebuilt.payload,
|
|
1868
|
-
headers: rebuilt.headers?.map(([name, value]) => [name, value]) ?? []
|
|
1869
|
-
};
|
|
1870
|
-
if (rebuilt.traceId !== void 0) Object.assign(request, { traceId: rebuilt.traceId });
|
|
1871
|
-
if (rebuilt.spanId !== void 0) Object.assign(request, { spanId: rebuilt.spanId });
|
|
1872
|
-
if (rebuilt.sampled !== void 0) Object.assign(request, { sampled: rebuilt.sampled });
|
|
1873
|
-
subscriptions.push({
|
|
1874
|
-
...persisted,
|
|
1875
|
-
resumeDescriptor: resumeDescriptor.value,
|
|
1876
|
-
acknowledgedCheckpoint: acknowledgedCheckpoint.value,
|
|
1877
|
-
declaration
|
|
1878
|
-
});
|
|
1879
|
-
requests.push(request);
|
|
1880
|
-
}
|
|
1881
|
-
return {
|
|
1882
|
-
_tag: "Success",
|
|
1883
|
-
requests,
|
|
1884
|
-
subscriptions
|
|
1885
|
-
};
|
|
1886
|
-
} catch (cause) {
|
|
1887
|
-
return {
|
|
1888
|
-
_tag: "Failure",
|
|
1889
|
-
cause
|
|
1890
|
-
};
|
|
1891
|
-
}
|
|
1892
|
-
});
|
|
1893
|
-
if (prepared._tag === "Failure") {
|
|
1894
|
-
yield* Effect.logDebug("Invalid resumable RPC websocket attachment", prepared.cause);
|
|
1895
|
-
yield* resetSocket(socket);
|
|
1896
|
-
continue;
|
|
1897
|
-
}
|
|
1898
|
-
if (connectionsById.has(metadata.clientId)) {
|
|
1899
|
-
yield* resetSocket(socket);
|
|
1900
|
-
continue;
|
|
1901
|
-
}
|
|
1902
|
-
const connection = register(socket, metadata, prepared.subscriptions);
|
|
1903
|
-
for (const request of prepared.requests) replayRequests.push({
|
|
1904
|
-
clientId: connection.id,
|
|
1905
|
-
request
|
|
1906
|
-
});
|
|
1907
|
-
}
|
|
1908
|
-
yield* syncHeartbeat();
|
|
1909
|
-
const send = (connection, response) => Effect.gen(function* () {
|
|
1910
|
-
let delivered = response;
|
|
1911
|
-
if (response._tag === "Chunk") {
|
|
1912
|
-
const subscription = connection.subscriptionsByRequestId.get(response.requestId);
|
|
1913
|
-
if (subscription !== void 0) {
|
|
1914
|
-
subscription.pending = { checkpointTokens: yield* Effect.sync(() => {
|
|
1915
|
-
const tokens = [];
|
|
1916
|
-
for (const value of response.values) {
|
|
1917
|
-
const checkpoint = subscription.declaration.checkpointFromValue(value);
|
|
1918
|
-
if (Option.isNone(checkpoint)) throw new Error(`Resumable RPC stream ${subscription.definitionId} did not identify a checkpoint`);
|
|
1919
|
-
const token = subscription.declaration.checkpointToken(checkpoint.value);
|
|
1920
|
-
if (token.length === 0 || tokens.includes(token)) throw new Error(`Resumable RPC stream ${subscription.definitionId} produced invalid checkpoint tokens`);
|
|
1921
|
-
tokens.push(token);
|
|
1922
|
-
}
|
|
1923
|
-
if (tokens.length === 0) throw new Error("Resumable RPC stream chunks must contain checkpointed values");
|
|
1924
|
-
return tokens;
|
|
1925
|
-
}) };
|
|
1926
|
-
connection.currentPendingRequestIds.add(subscription.requestId);
|
|
1927
|
-
if (!(yield* persistOrReset(connection))) return;
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
if (!(yield* Effect.sync(() => {
|
|
1931
|
-
try {
|
|
1932
|
-
const encoded = connection.parser.encode(response);
|
|
1933
|
-
if (encoded === void 0) return false;
|
|
1934
|
-
connection.socket.raw.send(encoded);
|
|
1935
|
-
return true;
|
|
1936
|
-
} catch (cause) {
|
|
1937
|
-
delivered = RpcMessage.ResponseDefectEncoded(encodeDefect(cause));
|
|
1938
|
-
const encoded = connection.parser.encode(delivered);
|
|
1939
|
-
if (encoded === void 0) return false;
|
|
1940
|
-
connection.socket.raw.send(encoded);
|
|
1941
|
-
return true;
|
|
1942
|
-
}
|
|
1943
|
-
}).pipe(Effect.catchCause((cause) => Effect.logDebug("Durable Object RPC websocket send failed", cause).pipe(Effect.as(false)))))) {
|
|
1944
|
-
resetSockets.add(connection.socket.raw);
|
|
1945
|
-
yield* connection.socket.close(serviceRestartCode, serviceRestartReason).pipe(Effect.ignore);
|
|
1946
|
-
yield* unregister(connection.socket);
|
|
1947
|
-
return;
|
|
1948
|
-
}
|
|
1949
|
-
if (delivered._tag === "Exit") yield* completeRequest(connection, delivered.requestId);
|
|
1950
|
-
else if (delivered._tag === "Defect" || delivered._tag === "ClientProtocolError") yield* completeAllRequests(connection);
|
|
1951
|
-
});
|
|
1952
|
-
const protocol = yield* RpcServer.Protocol.make((writeRequest_) => {
|
|
1953
|
-
writeRequest = writeRequest_;
|
|
1954
|
-
return Effect.succeed({
|
|
1955
|
-
disconnects,
|
|
1956
|
-
send: (clientId, response) => {
|
|
1957
|
-
const connection = connectionsById.get(clientId);
|
|
1958
|
-
return connection === void 0 ? Effect.void : send(connection, response);
|
|
1959
|
-
},
|
|
1960
|
-
end: (clientId) => Effect.sync(() => {
|
|
1961
|
-
connectionsById.get(clientId)?.socket.raw.close();
|
|
1962
|
-
}),
|
|
1963
|
-
clientIds: Effect.sync(() => new Set(connectionsById.keys())),
|
|
1964
|
-
initialMessage: Effect.succeedNone,
|
|
1965
|
-
supportsAck: true,
|
|
1966
|
-
supportsTransferables: false,
|
|
1967
|
-
supportsSpanPropagation: true,
|
|
1968
|
-
supportsNotifications: true,
|
|
1969
|
-
codecFor: serialization.codecFor
|
|
1970
|
-
});
|
|
1971
|
-
});
|
|
1972
|
-
const replay = writeRequest;
|
|
1973
|
-
if (replay === void 0) return yield* Effect.die(/* @__PURE__ */ new Error("RPC server protocol did not install its request writer"));
|
|
1974
|
-
for (const restoredRequest of replayRequests) yield* replay(restoredRequest.clientId, restoredRequest.request);
|
|
1975
|
-
const checkpoint = Effect.fn("DurableObjectRpcWebSocket.checkpoint")(function* (declaration, checkpointOptions) {
|
|
1976
|
-
const connection = connectionsById.get(checkpointOptions.clientId);
|
|
1977
|
-
const configured = declarationsById.get(declaration.id);
|
|
1978
|
-
const subscription = connection?.subscriptionsByDefinition.get(declaration.id)?.get(checkpointOptions.subscriptionKey);
|
|
1979
|
-
if (connection === void 0 || configured === void 0 || configured.rpcTag !== declaration.rpcTag || subscription === void 0 || subscription.pending === void 0) return false;
|
|
1980
|
-
const token = configured.checkpointToken(checkpointOptions.checkpoint);
|
|
1981
|
-
const checkpointIndex = subscription.pending.checkpointTokens.indexOf(token);
|
|
1982
|
-
if (token.length === 0 || checkpointIndex < 0) return false;
|
|
1983
|
-
const pending = subscription.pending;
|
|
1984
|
-
const isFinal = checkpointIndex === pending.checkpointTokens.length - 1;
|
|
1985
|
-
const shouldAck = isFinal && connection.currentPendingRequestIds.has(subscription.requestId);
|
|
1986
|
-
return yield* Effect.uninterruptible(Effect.gen(function* () {
|
|
1987
|
-
subscription.acknowledgedCheckpoint = checkpointOptions.checkpoint;
|
|
1988
|
-
if (isFinal) {
|
|
1989
|
-
connection.currentPendingRequestIds.delete(subscription.requestId);
|
|
1990
|
-
delete subscription.pending;
|
|
1991
|
-
} else subscription.pending = { checkpointTokens: pending.checkpointTokens.slice(checkpointIndex + 1) };
|
|
1992
|
-
yield* persistConnection(connection).pipe(Effect.catch((cause) => Effect.gen(function* () {
|
|
1993
|
-
yield* resetSocket(connection.socket, cause);
|
|
1994
|
-
return yield* cause;
|
|
1995
|
-
})));
|
|
1996
|
-
if (shouldAck) {
|
|
1997
|
-
const run = writeRequest;
|
|
1998
|
-
if (run === void 0) return yield* Effect.die(/* @__PURE__ */ new Error("RPC server is not ready to accept a checkpoint Ack"));
|
|
1999
|
-
yield* run(connection.id, {
|
|
2000
|
-
_tag: "Ack",
|
|
2001
|
-
requestId: subscription.requestId
|
|
2002
|
-
});
|
|
2003
|
-
}
|
|
2004
|
-
return true;
|
|
2005
|
-
}));
|
|
2006
|
-
});
|
|
2007
|
-
const service = DurableObjectRpcWebSocket.of({
|
|
2008
|
-
accept: (socket, tags = []) => Effect.gen(function* () {
|
|
2009
|
-
register(socket);
|
|
2010
|
-
yield* durableObjectState.acceptWebSocket(socket, Array.from(/* @__PURE__ */ new Set([tag, ...tags])));
|
|
2011
|
-
yield* syncHeartbeat();
|
|
2012
|
-
}),
|
|
2013
|
-
acceptUpgrade: (upgradeOptions = {}) => Effect.gen(function* () {
|
|
2014
|
-
const pair = new WebSocketPair();
|
|
2015
|
-
const client = pair[0];
|
|
2016
|
-
const server = fromWebSocket(pair[1]);
|
|
2017
|
-
if (upgradeOptions.attachment !== void 0) yield* server.serializeAttachment(upgradeOptions.attachment);
|
|
2018
|
-
yield* service.accept(server, upgradeOptions.tags);
|
|
2019
|
-
return {
|
|
2020
|
-
client,
|
|
2021
|
-
server,
|
|
2022
|
-
response: new Response(null, {
|
|
2023
|
-
status: 101,
|
|
2024
|
-
webSocket: client
|
|
2025
|
-
})
|
|
2026
|
-
};
|
|
2027
|
-
}),
|
|
2028
|
-
message: (socket, message) => Effect.gen(function* () {
|
|
2029
|
-
if (resetSockets.has(socket.raw)) return;
|
|
2030
|
-
const connection = register(socket);
|
|
2031
|
-
const decoded = yield* Effect.try({
|
|
2032
|
-
try: () => connection.parser.decode(normalizeMessage(message)),
|
|
2033
|
-
catch: (cause) => cause
|
|
2034
|
-
});
|
|
2035
|
-
const run = writeRequest;
|
|
2036
|
-
if (run === void 0) {
|
|
2037
|
-
yield* send(connection, RpcMessage.ResponseDefectEncoded(encodeDefect("RPC server is not ready")));
|
|
2038
|
-
return;
|
|
2039
|
-
}
|
|
2040
|
-
for (const current of decoded) {
|
|
2041
|
-
const request = current;
|
|
2042
|
-
if (request._tag === "Request" && request.isNotification !== true) {
|
|
2043
|
-
if (!(yield* trackRequest(connection, request))) return;
|
|
2044
|
-
}
|
|
2045
|
-
if (request._tag === "Ack" && (connection.subscriptionsByRequestId.has(request.requestId) || connection.suppressedAckRequestIds.has(request.requestId))) continue;
|
|
2046
|
-
if (request._tag === "Interrupt" && connection.subscriptionsByRequestId.has(request.requestId)) yield* completeRequest(connection, request.requestId, true);
|
|
2047
|
-
yield* run(connection.id, request);
|
|
2048
|
-
if (request._tag === "Interrupt" && !connection.suppressedAckRequestIds.has(request.requestId)) yield* completeRequest(connection, request.requestId);
|
|
2049
|
-
}
|
|
2050
|
-
}).pipe(Effect.catch((cause) => {
|
|
2051
|
-
const connection = register(socket);
|
|
2052
|
-
return Predicate.isTagged(cause, "MaxBufferSizeExceeded") ? Effect.ignore(connection.socket.close(1009, String(cause))) : send(connection, RpcMessage.ResponseDefectEncoded(encodeDefect(cause)));
|
|
2053
|
-
})),
|
|
2054
|
-
close: unregister,
|
|
2055
|
-
error: resetSocket,
|
|
2056
|
-
checkpoint
|
|
2057
|
-
});
|
|
2058
|
-
return Context.mergeAll(Context.make(RpcServer.Protocol, protocol), Context.make(DurableObjectRpcWebSocket, service));
|
|
2059
|
-
}));
|
|
2060
|
-
const normalizeMessage = (message) => Predicate.isString(message) ? message : new Uint8Array(message);
|
|
2061
|
-
const readAttachment = (socket, key) => {
|
|
2062
|
-
const value = socket.deserializeAttachment();
|
|
2063
|
-
if (value === null || value === void 0) return { _tag: "Missing" };
|
|
2064
|
-
if (!Predicate.isObject(value)) return { _tag: "Invalid" };
|
|
2065
|
-
if (!Predicate.hasProperty(value, key)) return { _tag: "Missing" };
|
|
2066
|
-
const metadata = value[key];
|
|
2067
|
-
if (Predicate.isNumber(metadata) && isClientId(metadata)) return {
|
|
2068
|
-
_tag: "Valid",
|
|
2069
|
-
metadata: {
|
|
2070
|
-
version: legacyAttachmentVersion,
|
|
2071
|
-
clientId: metadata,
|
|
2072
|
-
hasPendingRequests: false
|
|
2073
|
-
}
|
|
2074
|
-
};
|
|
2075
|
-
if (!Predicate.isObject(metadata)) return { _tag: "Invalid" };
|
|
2076
|
-
if (Predicate.hasProperty(metadata, "version") && metadata.version === resumableAttachmentVersion) {
|
|
2077
|
-
const decoded = decodeResumableAttachment(metadata);
|
|
2078
|
-
return Option.isSome(decoded) && isClientId(decoded.value.clientId) ? {
|
|
2079
|
-
_tag: "Valid",
|
|
2080
|
-
metadata: decoded.value
|
|
2081
|
-
} : { _tag: "Invalid" };
|
|
2082
|
-
}
|
|
2083
|
-
const hasPendingRequests = Predicate.hasProperty(metadata, "hasPendingRequests") ? metadata.hasPendingRequests : false;
|
|
2084
|
-
if ((!Predicate.hasProperty(metadata, "version") || metadata.version === legacyAttachmentVersion) && Predicate.hasProperty(metadata, "clientId") && Predicate.isNumber(metadata.clientId) && isClientId(metadata.clientId) && Predicate.isBoolean(hasPendingRequests)) return {
|
|
2085
|
-
_tag: "Valid",
|
|
2086
|
-
metadata: {
|
|
2087
|
-
version: legacyAttachmentVersion,
|
|
2088
|
-
clientId: metadata.clientId,
|
|
2089
|
-
hasPendingRequests
|
|
2090
|
-
}
|
|
2091
|
-
};
|
|
2092
|
-
return { _tag: "Invalid" };
|
|
2093
|
-
};
|
|
2094
|
-
const isClientId = (value) => Number.isSafeInteger(value) && value >= 0;
|
|
2095
|
-
const writeAttachment = (socket, key, metadata) => {
|
|
2096
|
-
const current = socket.deserializeAttachment();
|
|
2097
|
-
if (current !== null && current !== void 0 && !Predicate.isObject(current)) throw new Error("DurableObjectRpcWebSocket requires object-shaped websocket attachments so adapter metadata can preserve application fields");
|
|
2098
|
-
const attachment = Predicate.isObject(current) ? current : {};
|
|
2099
|
-
socket.serializeAttachment({
|
|
2100
|
-
...attachment,
|
|
2101
|
-
[key]: metadata
|
|
2102
|
-
});
|
|
2103
|
-
};
|
|
2104
|
-
const makeHeartbeatController = (state, serialization, policy) => Effect.gen(function* () {
|
|
2105
|
-
if (policy === "passthrough") return { setEnabled: () => Effect.void };
|
|
2106
|
-
const parser = serialization.makeUnsafe();
|
|
2107
|
-
const request = parser.encode(RpcMessage.constPing);
|
|
2108
|
-
const response = parser.encode(RpcMessage.constPong);
|
|
2109
|
-
if (!Predicate.isString(request) || !Predicate.isString(response)) return yield* Effect.die(/* @__PURE__ */ new Error("DurableObjectRpcWebSocket heartbeat auto-response requires a text RPC serialization; use heartbeat: \"passthrough\" to manage heartbeats externally"));
|
|
2110
|
-
const configured = yield* state.getWebSocketAutoResponse;
|
|
2111
|
-
if (configured !== null && (configured.request !== request || configured.response !== response)) return yield* Effect.die(/* @__PURE__ */ new Error("DurableObjectRpcWebSocket cannot replace the application WebSocket auto-response; use heartbeat: \"passthrough\" to preserve it"));
|
|
2112
|
-
const pair = new WebSocketRequestResponsePair(request, response);
|
|
2113
|
-
let enabled = configured !== null;
|
|
2114
|
-
return { setEnabled: (nextEnabled) => {
|
|
2115
|
-
if (enabled === nextEnabled) return Effect.void;
|
|
2116
|
-
return state.setWebSocketAutoResponse(nextEnabled ? pair : void 0).pipe(Effect.tap(() => Effect.sync(() => {
|
|
2117
|
-
enabled = nextEnabled;
|
|
2118
|
-
})));
|
|
2119
|
-
} };
|
|
2120
|
-
});
|
|
2121
|
-
//#endregion
|
|
2122
|
-
//#region src/DurableObjectSqlite.ts
|
|
2123
|
-
var DurableObjectSqlite_exports = /* @__PURE__ */ __exportAll({ layer: () => layer$7 });
|
|
2124
|
-
const layer$7 = (options) => Layer.unwrap(Effect.gen(function* () {
|
|
2125
|
-
const state = yield* DurableObjectState;
|
|
2126
|
-
return SqliteClient.layer({
|
|
2127
|
-
...options,
|
|
2128
|
-
storage: state.raw.storage
|
|
2129
|
-
});
|
|
2130
|
-
}));
|
|
2131
|
-
//#endregion
|
|
2132
|
-
//#region src/Email.ts
|
|
2133
|
-
var Email_exports = /* @__PURE__ */ __exportAll({
|
|
2134
|
-
EmailOperationError: () => EmailOperationError,
|
|
2135
|
-
EmailValidationError: () => EmailValidationError,
|
|
2136
|
-
Tag: () => Tag$7,
|
|
2137
|
-
emailErrorCodes: () => emailErrorCodes,
|
|
2138
|
-
isEmailBinding: () => isEmailBinding,
|
|
2139
|
-
layer: () => layer$6,
|
|
2140
|
-
make: () => make$6,
|
|
2141
|
-
makeClient: () => makeClient$6,
|
|
2142
|
-
sendLimits: () => sendLimits,
|
|
2143
|
-
validateMessage: () => validateMessage
|
|
2144
|
-
});
|
|
2145
|
-
const expectedSendEmailBinding = "Send Email binding with send()";
|
|
2146
|
-
const textEncoder = new TextEncoder();
|
|
2147
|
-
const sendLimits = {
|
|
2148
|
-
maxRecipients: 50,
|
|
2149
|
-
maxAttachments: 32,
|
|
2150
|
-
maxMessageBytes: 5242880,
|
|
2151
|
-
maxHeaderNameBytes: 100,
|
|
2152
|
-
maxHeaderValueBytes: 2048,
|
|
2153
|
-
maxHeadersBytes: 16384,
|
|
2154
|
-
maxAllowlistHeaders: 20
|
|
2155
|
-
};
|
|
2156
|
-
/**
|
|
2157
|
-
* Error codes reported by Cloudflare Email Sending.
|
|
2158
|
-
*
|
|
2159
|
-
* Surfaced on {@link EmailOperationError} `code` on a best-effort basis: the
|
|
2160
|
-
* runtime attaches them as a non-standard `code` property on thrown errors,
|
|
2161
|
-
* which may be missing depending on the runtime or dev-time proxying
|
|
2162
|
-
* (miniflare remote bindings serialize errors and can strip it).
|
|
2163
|
-
*/
|
|
2164
|
-
const emailErrorCodes = [
|
|
2165
|
-
"E_VALIDATION_ERROR",
|
|
2166
|
-
"E_FIELD_MISSING",
|
|
2167
|
-
"E_TOO_MANY_RECIPIENTS",
|
|
2168
|
-
"E_TOO_MANY_ATTACHMENTS",
|
|
2169
|
-
"E_SENDER_NOT_VERIFIED",
|
|
2170
|
-
"E_RECIPIENT_NOT_ALLOWED",
|
|
2171
|
-
"E_RECIPIENT_SUPPRESSED",
|
|
2172
|
-
"E_SENDER_DOMAIN_NOT_AVAILABLE",
|
|
2173
|
-
"E_CONTENT_TOO_LARGE",
|
|
2174
|
-
"E_DELIVERY_FAILED",
|
|
2175
|
-
"E_RATE_LIMIT_EXCEEDED",
|
|
2176
|
-
"E_DAILY_LIMIT_EXCEEDED",
|
|
2177
|
-
"E_INTERNAL_SERVER_ERROR",
|
|
2178
|
-
"E_HEADER_NOT_ALLOWED",
|
|
2179
|
-
"E_HEADER_USE_API_FIELD",
|
|
2180
|
-
"E_HEADER_VALUE_INVALID",
|
|
2181
|
-
"E_HEADER_VALUE_TOO_LONG",
|
|
2182
|
-
"E_HEADER_NAME_INVALID",
|
|
2183
|
-
"E_HEADERS_TOO_LARGE",
|
|
2184
|
-
"E_HEADERS_TOO_MANY"
|
|
2185
|
-
];
|
|
2186
|
-
var EmailOperationError = class extends Data.TaggedError("EmailOperationError") {
|
|
2187
|
-
get message() {
|
|
2188
|
-
const code = this.code === void 0 ? "" : ` (${this.code})`;
|
|
2189
|
-
return `Email ${this.operation} failed for binding "${this.binding}"${code}: ${causeMessage(this.cause)}`;
|
|
2190
|
-
}
|
|
2191
|
-
};
|
|
2192
|
-
var EmailValidationError = class extends Data.TaggedError("EmailValidationError") {
|
|
2193
|
-
get message() {
|
|
2194
|
-
return `Email ${this.operation} for binding "${this.binding}" failed validation: ${violationsMessage(this.violations)}`;
|
|
2195
|
-
}
|
|
2196
|
-
};
|
|
2197
|
-
/**
|
|
2198
|
-
* Best-effort extraction of the Cloudflare error `code` from a thrown error.
|
|
2199
|
-
* Returns `undefined` when the property is absent — e.g. when a dev-time
|
|
2200
|
-
* proxy such as a miniflare remote binding (`"remote": true`) serializes the
|
|
2201
|
-
* error and strips non-standard properties.
|
|
2202
|
-
*/
|
|
2203
|
-
const emailErrorCode = (cause) => {
|
|
2204
|
-
if (!Predicate.isObject(cause)) return;
|
|
2205
|
-
const code = Predicate.hasProperty(cause, "code") ? cause.code : void 0;
|
|
2206
|
-
return Predicate.isString(code) ? code : void 0;
|
|
2207
|
-
};
|
|
2208
|
-
const emailError = (binding, operation, cause) => new EmailOperationError({
|
|
2209
|
-
binding,
|
|
2210
|
-
operation,
|
|
2211
|
-
cause,
|
|
2212
|
-
code: emailErrorCode(cause)
|
|
2213
|
-
});
|
|
2214
|
-
const emailValidationError = (binding, operation, violations) => new EmailValidationError({
|
|
2215
|
-
binding,
|
|
2216
|
-
operation,
|
|
2217
|
-
violations
|
|
2218
|
-
});
|
|
2219
|
-
const tryEmailPromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
2220
|
-
try: evaluate,
|
|
2221
|
-
catch: (cause) => emailError(binding, operation, cause)
|
|
2222
|
-
});
|
|
2223
|
-
const byteLength = (value) => textEncoder.encode(value).byteLength;
|
|
2224
|
-
const limitViolation = (path, label, actual, limit) => ({
|
|
2225
|
-
path,
|
|
2226
|
-
message: `${label} exceeds Cloudflare Email Sending limit`,
|
|
2227
|
-
actual,
|
|
2228
|
-
limit
|
|
2229
|
-
});
|
|
2230
|
-
const addressList = (value) => {
|
|
2231
|
-
if (value === void 0) return [];
|
|
2232
|
-
return Array.isArray(value) ? value : [value];
|
|
2233
|
-
};
|
|
2234
|
-
const addressViolations = (path, value) => {
|
|
2235
|
-
if (Predicate.isString(value)) return value.includes("@") ? [] : [{
|
|
2236
|
-
path,
|
|
2237
|
-
message: "Email address must contain an @ symbol"
|
|
2238
|
-
}];
|
|
2239
|
-
if (!Predicate.isObject(value)) return [{
|
|
2240
|
-
path,
|
|
2241
|
-
message: "Email address must be a string or { name, email } object"
|
|
2242
|
-
}];
|
|
2243
|
-
const email = Predicate.hasProperty(value, "email") ? value.email : void 0;
|
|
2244
|
-
if (!Predicate.isString(email) || !email.includes("@")) return [{
|
|
2245
|
-
path: `${path}.email`,
|
|
2246
|
-
message: "Email address must contain an @ symbol"
|
|
2247
|
-
}];
|
|
2248
|
-
return [];
|
|
2249
|
-
};
|
|
2250
|
-
const recipientViolations = (field, value) => addressList(value).flatMap((address, index) => addressViolations(`${field}[${index}]`, address));
|
|
2251
|
-
const attachmentViolations = (attachments) => {
|
|
2252
|
-
const violations = [];
|
|
2253
|
-
if (attachments.length > sendLimits.maxAttachments) violations.push(limitViolation("attachments", "attachments", attachments.length, sendLimits.maxAttachments));
|
|
2254
|
-
for (let index = 0; index < attachments.length; index++) {
|
|
2255
|
-
const attachment = attachments[index];
|
|
2256
|
-
const path = `attachments[${index}]`;
|
|
2257
|
-
if (!Predicate.isObject(attachment)) {
|
|
2258
|
-
violations.push({
|
|
2259
|
-
path,
|
|
2260
|
-
message: "Attachment must be an object"
|
|
2261
|
-
});
|
|
2262
|
-
continue;
|
|
2263
|
-
}
|
|
2264
|
-
if (!Predicate.isString(attachment.filename) || attachment.filename === "") violations.push({
|
|
2265
|
-
path: `${path}.filename`,
|
|
2266
|
-
message: "Attachment filename is required"
|
|
2267
|
-
});
|
|
2268
|
-
if (!Predicate.isString(attachment.type) || attachment.type === "") violations.push({
|
|
2269
|
-
path: `${path}.type`,
|
|
2270
|
-
message: "Attachment MIME type is required"
|
|
2271
|
-
});
|
|
2272
|
-
if (attachment.content === void 0 || attachment.content === null) violations.push({
|
|
2273
|
-
path: `${path}.content`,
|
|
2274
|
-
message: "Attachment content is required"
|
|
2275
|
-
});
|
|
2276
|
-
if (attachment.disposition === "inline" && !Predicate.isString(attachment.contentId)) violations.push({
|
|
2277
|
-
path: `${path}.contentId`,
|
|
2278
|
-
message: "Inline attachments require a contentId"
|
|
2279
|
-
});
|
|
2280
|
-
}
|
|
2281
|
-
return violations;
|
|
2282
|
-
};
|
|
2283
|
-
const headerViolations = (headers) => {
|
|
2284
|
-
const violations = [];
|
|
2285
|
-
const entries = Object.entries(headers);
|
|
2286
|
-
let totalBytes = 0;
|
|
2287
|
-
let allowlistHeaders = 0;
|
|
2288
|
-
for (const [name, value] of entries) {
|
|
2289
|
-
const path = `headers["${name}"]`;
|
|
2290
|
-
const nameBytes = byteLength(name);
|
|
2291
|
-
if (nameBytes > sendLimits.maxHeaderNameBytes) violations.push(limitViolation(path, "header name bytes", nameBytes, sendLimits.maxHeaderNameBytes));
|
|
2292
|
-
if (!Predicate.isString(value)) {
|
|
2293
|
-
violations.push({
|
|
2294
|
-
path,
|
|
2295
|
-
message: "Header value must be a string"
|
|
2296
|
-
});
|
|
2297
|
-
continue;
|
|
2298
|
-
}
|
|
2299
|
-
const valueBytes = byteLength(value);
|
|
2300
|
-
if (valueBytes > sendLimits.maxHeaderValueBytes) violations.push(limitViolation(path, "header value bytes", valueBytes, sendLimits.maxHeaderValueBytes));
|
|
2301
|
-
totalBytes += nameBytes + valueBytes;
|
|
2302
|
-
if (!name.toLowerCase().startsWith("x-")) allowlistHeaders += 1;
|
|
2303
|
-
}
|
|
2304
|
-
if (totalBytes > sendLimits.maxHeadersBytes) violations.push(limitViolation("headers", "header bytes", totalBytes, sendLimits.maxHeadersBytes));
|
|
2305
|
-
if (allowlistHeaders > sendLimits.maxAllowlistHeaders) violations.push(limitViolation("headers", "allowlisted custom headers", allowlistHeaders, sendLimits.maxAllowlistHeaders));
|
|
2306
|
-
return violations;
|
|
2307
|
-
};
|
|
2308
|
-
/**
|
|
2309
|
-
* Validates a structured message against documented Cloudflare Email Sending
|
|
2310
|
-
* limits and returns every violation found. Total message size is not checked
|
|
2311
|
-
* because the encoded MIME size is only known once Cloudflare composes it.
|
|
2312
|
-
*/
|
|
2313
|
-
const validateMessage = (message) => {
|
|
2314
|
-
const violations = [];
|
|
2315
|
-
const fields = message;
|
|
2316
|
-
if (fields.from === void 0) violations.push({
|
|
2317
|
-
path: "from",
|
|
2318
|
-
message: "A from address is required"
|
|
2319
|
-
});
|
|
2320
|
-
else violations.push(...addressViolations("from", fields.from));
|
|
2321
|
-
if (fields.replyTo !== void 0) violations.push(...addressViolations("replyTo", fields.replyTo));
|
|
2322
|
-
if (!Predicate.isString(fields.subject) || fields.subject === "") violations.push({
|
|
2323
|
-
path: "subject",
|
|
2324
|
-
message: "A subject is required"
|
|
2325
|
-
});
|
|
2326
|
-
if (!Predicate.isString(fields.text) && !Predicate.isString(fields.html)) violations.push({
|
|
2327
|
-
path: "$",
|
|
2328
|
-
message: "A message requires either text or html content"
|
|
2329
|
-
});
|
|
2330
|
-
const recipients = addressList(fields.to).length + addressList(fields.cc).length + addressList(fields.bcc).length;
|
|
2331
|
-
if (recipients === 0) violations.push({
|
|
2332
|
-
path: "$",
|
|
2333
|
-
message: "A message requires at least one to, cc, or bcc address"
|
|
2334
|
-
});
|
|
2335
|
-
if (recipients > sendLimits.maxRecipients) violations.push(limitViolation("$", "combined to, cc, and bcc addresses", recipients, sendLimits.maxRecipients));
|
|
2336
|
-
violations.push(...recipientViolations("to", fields.to));
|
|
2337
|
-
violations.push(...recipientViolations("cc", fields.cc));
|
|
2338
|
-
violations.push(...recipientViolations("bcc", fields.bcc));
|
|
2339
|
-
if (fields.attachments !== void 0) violations.push(...attachmentViolations(fields.attachments));
|
|
2340
|
-
if (fields.headers !== void 0) violations.push(...headerViolations(fields.headers));
|
|
2341
|
-
return violations;
|
|
2342
|
-
};
|
|
2343
|
-
const validateSendInput = (binding, operation, message) => {
|
|
2344
|
-
const violations = validateMessage(message);
|
|
2345
|
-
return violations.length > 0 ? Effect.fail(emailValidationError(binding, operation, violations)) : Effect.succeed(message);
|
|
2346
|
-
};
|
|
2347
|
-
const isEmailBinding = (value) => Predicate.hasProperty(value, "send") && Predicate.isFunction(value.send);
|
|
2348
|
-
const makeClient$6 = (definition, options) => (email) => {
|
|
2349
|
-
const runtime = email;
|
|
2350
|
-
const validate = options?.validate ?? true;
|
|
2351
|
-
return {
|
|
2352
|
-
definition,
|
|
2353
|
-
send: Effect.fn("Email.send")(function* (message) {
|
|
2354
|
-
if (validate) yield* validateSendInput(definition.binding, "send", message);
|
|
2355
|
-
return yield* tryEmailPromise(definition.binding, "send", () => runtime.send(message));
|
|
2356
|
-
}),
|
|
2357
|
-
rawUnsafe: Effect.succeed(email)
|
|
2358
|
-
};
|
|
2359
|
-
};
|
|
2360
|
-
const layer$6 = (tag, definition) => layer$18(tag, definition.binding, isEmailBinding, makeClient$6(definition, definition.send), { expected: expectedSendEmailBinding });
|
|
2361
|
-
const make$6 = (id) => Tag$7()(id);
|
|
2362
|
-
const Tag$7 = () => (id) => {
|
|
2363
|
-
const tag = Context.Service()(id);
|
|
2364
|
-
const makeLayer = (definition) => layer$6(tag, definition);
|
|
2365
|
-
return Object.assign(tag, {
|
|
2366
|
-
id,
|
|
2367
|
-
layer: makeLayer
|
|
2368
|
-
});
|
|
2369
|
-
};
|
|
2370
|
-
//#endregion
|
|
2371
|
-
//#region src/Hyperdrive.ts
|
|
2372
|
-
var Hyperdrive_exports = /* @__PURE__ */ __exportAll({
|
|
2373
|
-
Tag: () => Tag$6,
|
|
2374
|
-
isHyperdrive: () => isHyperdrive,
|
|
2375
|
-
layer: () => layer$5,
|
|
2376
|
-
make: () => make$5,
|
|
2377
|
-
makeClient: () => makeClient$5
|
|
2378
|
-
});
|
|
2379
|
-
const expectedHyperdrive = "Hyperdrive binding with connectionString";
|
|
2380
|
-
const isHyperdrive = (value) => Predicate.hasProperty(value, "connectionString") && Predicate.isString(value.connectionString);
|
|
2381
|
-
const makeClient$5 = (definition) => (hyperdrive) => ({
|
|
2382
|
-
definition,
|
|
2383
|
-
connectionString: hyperdrive.connectionString,
|
|
2384
|
-
rawUnsafe: Effect.succeed(hyperdrive)
|
|
2385
|
-
});
|
|
2386
|
-
const layer$5 = (tag, definition) => layer$18(tag, definition.binding, isHyperdrive, makeClient$5(definition), { expected: expectedHyperdrive });
|
|
2387
|
-
const make$5 = (id) => Tag$6()(id);
|
|
2388
|
-
const Tag$6 = () => (id) => {
|
|
2389
|
-
const tag = Context.Service()(id);
|
|
2390
|
-
const makeLayer = (definition) => layer$5(tag, definition);
|
|
2391
|
-
return Object.assign(tag, {
|
|
2392
|
-
id,
|
|
2393
|
-
layer: makeLayer
|
|
2394
|
-
});
|
|
2395
|
-
};
|
|
2396
|
-
//#endregion
|
|
2397
|
-
//#region src/Images.ts
|
|
2398
|
-
var Images_exports = /* @__PURE__ */ __exportAll({
|
|
2399
|
-
ImagesOperationError: () => ImagesOperationError,
|
|
2400
|
-
Step: () => Step,
|
|
2401
|
-
Tag: () => Tag$5,
|
|
2402
|
-
draw: () => draw,
|
|
2403
|
-
empty: () => empty,
|
|
2404
|
-
isImagesBinding: () => isImagesBinding,
|
|
2405
|
-
layer: () => layer$4,
|
|
2406
|
-
make: () => make$4,
|
|
2407
|
-
makeClient: () => makeClient$4,
|
|
2408
|
-
transform: () => transform
|
|
2409
|
-
});
|
|
2410
|
-
const TypeId = "~effect-cf/Images/Steps";
|
|
2411
|
-
const expectedImagesBinding = "Images binding with info() and input()";
|
|
2412
|
-
var ImagesOperationError = class extends Data.TaggedError("ImagesOperationError") {
|
|
2413
|
-
get message() {
|
|
2414
|
-
return `Images ${this.operation} failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
2415
|
-
}
|
|
2416
|
-
};
|
|
2417
|
-
const Step = Data.taggedEnum();
|
|
2418
|
-
const makeSteps = (steps) => ({
|
|
2419
|
-
[TypeId]: TypeId,
|
|
2420
|
-
steps
|
|
2421
|
-
});
|
|
2422
|
-
const empty = makeSteps([]);
|
|
2423
|
-
const transform = Function$1.dual(2, (steps, transformValue) => makeSteps([...steps.steps, Step.Transform({ transform: transformValue })]));
|
|
2424
|
-
const draw = Function$1.dual(2, (steps, drawValue) => makeSteps([...steps.steps, Step.Draw(drawValue)]));
|
|
2425
|
-
const imagesError = (binding, operation, cause) => new ImagesOperationError({
|
|
2426
|
-
binding,
|
|
2427
|
-
operation,
|
|
2428
|
-
cause
|
|
2429
|
-
});
|
|
2430
|
-
const tryImagesPromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
2431
|
-
try: evaluate,
|
|
2432
|
-
catch: (cause) => imagesError(binding, operation, cause)
|
|
2433
|
-
});
|
|
2434
|
-
const tryImagesSync = (binding, operation, evaluate) => Effect.try({
|
|
2435
|
-
try: evaluate,
|
|
2436
|
-
catch: (cause) => imagesError(binding, operation, cause)
|
|
2437
|
-
});
|
|
2438
|
-
const maybe = (value) => value === null ? Option.none() : Option.some(value);
|
|
2439
|
-
const hasFunction = (value, key) => Predicate.hasProperty(value, key) && Predicate.isFunction(value[key]);
|
|
2440
|
-
const isHostedImagesBinding = (value) => hasFunction(value, "image") && hasFunction(value, "upload") && hasFunction(value, "list") && hasFunction(value, "createDirectUpload");
|
|
2441
|
-
const isImagesBinding = (value) => hasFunction(value, "info") && hasFunction(value, "input");
|
|
2442
|
-
const wrapResult = (binding, result) => ({
|
|
2443
|
-
raw: result,
|
|
2444
|
-
response: (options) => tryImagesSync(binding, "response", () => result.response(options)),
|
|
2445
|
-
contentType: tryImagesSync(binding, "contentType", () => result.contentType()),
|
|
2446
|
-
image: (options) => tryImagesSync(binding, "image", () => result.image(options))
|
|
2447
|
-
});
|
|
2448
|
-
const wrapHandle = (binding, handle) => ({
|
|
2449
|
-
raw: handle,
|
|
2450
|
-
details: tryImagesPromise(binding, "details", () => handle.details()).pipe(Effect.map(maybe), Effect.withSpan("Images.details")),
|
|
2451
|
-
bytes: tryImagesPromise(binding, "bytes", () => handle.bytes()).pipe(Effect.map(maybe), Effect.withSpan("Images.bytes")),
|
|
2452
|
-
signedUrl: Effect.fn("Images.signedUrl")((options) => tryImagesPromise(binding, "signedUrl", () => handle.signedUrl(options))),
|
|
2453
|
-
update: Effect.fn("Images.update")((options) => tryImagesPromise(binding, "update", () => handle.update(options))),
|
|
2454
|
-
delete: tryImagesPromise(binding, "delete", () => handle.delete()).pipe(Effect.withSpan("Images.delete"))
|
|
2455
|
-
});
|
|
2456
|
-
const wrapHosted = (binding, hosted) => ({
|
|
2457
|
-
image: (imageId) => wrapHandle(binding, hosted.image(imageId)),
|
|
2458
|
-
upload: Effect.fn("Images.upload")((image, options) => tryImagesPromise(binding, "upload", () => hosted.upload(image, options))),
|
|
2459
|
-
list: Effect.fn("Images.list")((options) => tryImagesPromise(binding, "list", () => hosted.list(options))),
|
|
2460
|
-
createDirectUpload: Effect.fn("Images.createDirectUpload")((options) => tryImagesPromise(binding, "createDirectUpload", () => hosted.createDirectUpload(options))),
|
|
2461
|
-
rawUnsafe: Effect.succeed(hosted)
|
|
2462
|
-
});
|
|
2463
|
-
const makeClient$4 = (definition) => (images) => {
|
|
2464
|
-
const input = (image, options) => tryImagesSync(definition.binding, "input", () => images.input(image, options));
|
|
2465
|
-
const text = (content, options) => tryImagesSync(definition.binding, "text", () => {
|
|
2466
|
-
if (!hasFunction(images, "text")) throw new Error("Images binding is missing text()");
|
|
2467
|
-
return images.text(content, options);
|
|
2468
|
-
});
|
|
2469
|
-
const process = Effect.fn("Images.process")(function* (steps, options) {
|
|
2470
|
-
let transformer = "text" in options ? yield* text(options.text, options.textOptions) : yield* input(options.stream, options.inputOptions);
|
|
2471
|
-
for (const step of steps.steps) transformer = yield* Step.$match(step, {
|
|
2472
|
-
Draw: (drawStep) => tryImagesSync(definition.binding, "draw", () => transformer.draw(drawStep.image, drawStep.options)),
|
|
2473
|
-
Transform: (transformStep) => tryImagesSync(definition.binding, "transform", () => transformer.transform(transformStep.transform))
|
|
2474
|
-
});
|
|
2475
|
-
const result = yield* tryImagesPromise(definition.binding, "output", () => transformer.output(options.outputOptions));
|
|
2476
|
-
return wrapResult(definition.binding, result);
|
|
2477
|
-
});
|
|
2478
|
-
return {
|
|
2479
|
-
definition,
|
|
2480
|
-
info: Effect.fn("Images.info")((image, options) => tryImagesPromise(definition.binding, "info", () => images.info(image, options))),
|
|
2481
|
-
input,
|
|
2482
|
-
text,
|
|
2483
|
-
process,
|
|
2484
|
-
hosted: isHostedImagesBinding(images.hosted) ? Option.some(wrapHosted(definition.binding, images.hosted)) : Option.none(),
|
|
2485
|
-
rawUnsafe: Effect.succeed(images)
|
|
2486
|
-
};
|
|
2487
|
-
};
|
|
2488
|
-
const layer$4 = (tag, definition) => layer$18(tag, definition.binding, isImagesBinding, makeClient$4(definition), { expected: expectedImagesBinding });
|
|
2489
|
-
const make$4 = (id) => Tag$5()(id);
|
|
2490
|
-
const Tag$5 = () => (id) => {
|
|
2491
|
-
const tag = Context.Service()(id);
|
|
2492
|
-
const makeLayer = (definition) => layer$4(tag, definition);
|
|
2493
|
-
return Object.assign(tag, {
|
|
2494
|
-
id,
|
|
2495
|
-
layer: makeLayer
|
|
2496
|
-
});
|
|
2497
|
-
};
|
|
2498
|
-
//#endregion
|
|
2499
|
-
//#region src/Kv.ts
|
|
2500
|
-
var Kv_exports = /* @__PURE__ */ __exportAll({
|
|
2501
|
-
KvOperationError: () => KvOperationError,
|
|
2502
|
-
Tag: () => Tag$4,
|
|
2503
|
-
isKvNamespace: () => isKvNamespace,
|
|
2504
|
-
layer: () => layer$3,
|
|
2505
|
-
makeClient: () => makeClient$3
|
|
2506
|
-
});
|
|
2507
|
-
const expectedKvNamespace = "KV namespace binding with get(), put(), delete(), getWithMetadata(), and list()";
|
|
2508
|
-
var KvOperationError = class extends Data.TaggedError("KvOperationError") {
|
|
2509
|
-
get message() {
|
|
2510
|
-
return `Kv ${this.operation} failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
2511
|
-
}
|
|
2512
|
-
};
|
|
2513
|
-
const kvError = (binding, operation, cause) => new KvOperationError({
|
|
2514
|
-
binding,
|
|
2515
|
-
operation,
|
|
2516
|
-
cause
|
|
2517
|
-
});
|
|
2518
|
-
const tryKvPromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
2519
|
-
try: evaluate,
|
|
2520
|
-
catch: (cause) => kvError(binding, operation, cause)
|
|
2521
|
-
});
|
|
2522
|
-
const isKvNamespace = (value) => Predicate.hasProperty(value, "get") && Predicate.isFunction(value.get) && Predicate.hasProperty(value, "put") && Predicate.isFunction(value.put) && Predicate.hasProperty(value, "delete") && Predicate.isFunction(value.delete) && Predicate.hasProperty(value, "getWithMetadata") && Predicate.isFunction(value.getWithMetadata) && Predicate.hasProperty(value, "list") && Predicate.isFunction(value.list);
|
|
2523
|
-
const makeClient$3 = (definition) => {
|
|
2524
|
-
const encodeKey = Schema.encodeEffect(definition.key);
|
|
2525
|
-
const decodeKey = Schema.decodeUnknownEffect(definition.key);
|
|
2526
|
-
const jsonValue = Schema.fromJsonString(Schema.toCodecJson(definition.value));
|
|
2527
|
-
const encodeValue = Schema.encodeEffect(jsonValue);
|
|
2528
|
-
const decodeValue = Schema.decodeUnknownEffect(jsonValue);
|
|
2529
|
-
return (kv) => ({
|
|
2530
|
-
definition,
|
|
2531
|
-
put: Effect.fn("Kv.put", { attributes: {
|
|
2532
|
-
binding: definition.binding,
|
|
2533
|
-
operation: "put"
|
|
2534
|
-
} })(function* (key, value, options) {
|
|
2535
|
-
const keyEncoded = yield* encodeKey(key);
|
|
2536
|
-
const valueEncoded = yield* encodeValue(value);
|
|
2537
|
-
yield* tryKvPromise(definition.binding, "put", () => kv.put(keyEncoded, valueEncoded, options));
|
|
2538
|
-
}),
|
|
2539
|
-
get: Effect.fn("Kv.get", { attributes: {
|
|
2540
|
-
binding: definition.binding,
|
|
2541
|
-
operation: "get"
|
|
2542
|
-
} })(function* (key) {
|
|
2543
|
-
const keyEncoded = yield* encodeKey(key);
|
|
2544
|
-
const valueEncoded = yield* tryKvPromise(definition.binding, "get", () => kv.get(keyEncoded));
|
|
2545
|
-
if (valueEncoded === null) return Option.none();
|
|
2546
|
-
return yield* decodeValue(valueEncoded).pipe(Effect.map(Option.some));
|
|
2547
|
-
}),
|
|
2548
|
-
getWithMetadata: Effect.fn("Kv.getWithMetadata", { attributes: {
|
|
2549
|
-
binding: definition.binding,
|
|
2550
|
-
operation: "getWithMetadata"
|
|
2551
|
-
} })(function* (key, metadataSchema) {
|
|
2552
|
-
const keyEncoded = yield* encodeKey(key);
|
|
2553
|
-
const result = yield* tryKvPromise(definition.binding, "getWithMetadata", () => kv.getWithMetadata(keyEncoded));
|
|
2554
|
-
if (result.value === null) return Option.none();
|
|
2555
|
-
const value = yield* decodeValue(result.value);
|
|
2556
|
-
const metadata = result.metadata === null ? Option.none() : Option.some(yield* Schema.decodeUnknownEffect(metadataSchema)(result.metadata));
|
|
2557
|
-
return Option.some({
|
|
2558
|
-
value,
|
|
2559
|
-
metadata,
|
|
2560
|
-
cacheStatus: Option.fromNullishOr(result.cacheStatus)
|
|
2561
|
-
});
|
|
2562
|
-
}),
|
|
2563
|
-
list: Effect.fn("Kv.list", { attributes: {
|
|
2564
|
-
binding: definition.binding,
|
|
2565
|
-
operation: "list"
|
|
2566
|
-
} })(function* (options) {
|
|
2567
|
-
const { metadataSchema, ...kvOptions } = options ?? {};
|
|
2568
|
-
const result = yield* tryKvPromise(definition.binding, "list", () => kv.list(kvOptions));
|
|
2569
|
-
const keys = [];
|
|
2570
|
-
for (const key of result.keys) {
|
|
2571
|
-
const decodedName = yield* decodeKey(key.name);
|
|
2572
|
-
const decodedMetadata = key.metadata === void 0 ? Option.none() : metadataSchema === void 0 ? Option.some(key.metadata) : Option.some(yield* Schema.decodeUnknownEffect(metadataSchema)(key.metadata));
|
|
2573
|
-
keys.push({
|
|
2574
|
-
name: decodedName,
|
|
2575
|
-
expiration: Option.fromUndefinedOr(key.expiration),
|
|
2576
|
-
metadata: decodedMetadata
|
|
2577
|
-
});
|
|
2578
|
-
}
|
|
2579
|
-
return {
|
|
2580
|
-
keys,
|
|
2581
|
-
listComplete: result.list_complete,
|
|
2582
|
-
cursor: Option.fromNullishOr("cursor" in result ? result.cursor : void 0),
|
|
2583
|
-
cacheStatus: Option.fromNullishOr(result.cacheStatus)
|
|
2584
|
-
};
|
|
2585
|
-
}),
|
|
2586
|
-
delete: Effect.fn("Kv.delete", { attributes: {
|
|
2587
|
-
binding: definition.binding,
|
|
2588
|
-
operation: "delete"
|
|
2589
|
-
} })(function* (key) {
|
|
2590
|
-
const keyEncoded = yield* encodeKey(key);
|
|
2591
|
-
yield* tryKvPromise(definition.binding, "delete", () => kv.delete(keyEncoded));
|
|
2592
|
-
}),
|
|
2593
|
-
rawUnsafe: Effect.succeed(kv)
|
|
2594
|
-
});
|
|
2595
|
-
};
|
|
2596
|
-
const layer$3 = (tag, definition) => layer$18(tag, definition.binding, isKvNamespace, makeClient$3(definition), { expected: expectedKvNamespace });
|
|
2597
|
-
const makeDefinition$1 = (id, definition) => {
|
|
2598
|
-
const kvDefinition = {
|
|
2599
|
-
id,
|
|
2600
|
-
key: definition.key,
|
|
2601
|
-
value: definition.value
|
|
2602
|
-
};
|
|
2603
|
-
return Object.assign(kvDefinition, { layer: (tag, binding) => layer$3(tag, {
|
|
2604
|
-
...binding,
|
|
2605
|
-
key: definition.key,
|
|
2606
|
-
value: definition.value
|
|
2607
|
-
}) });
|
|
2608
|
-
};
|
|
2609
|
-
const Tag$4 = () => (id, definition) => {
|
|
2610
|
-
const kvDefinition = makeDefinition$1(id, definition);
|
|
2611
|
-
const tag = Context.Service()(id);
|
|
2612
|
-
const makeLayer = (binding) => kvDefinition.layer(tag, binding);
|
|
2613
|
-
return Object.assign(tag, {
|
|
2614
|
-
id: kvDefinition.id,
|
|
2615
|
-
keySchema: kvDefinition.key,
|
|
2616
|
-
valueSchema: kvDefinition.value,
|
|
2617
|
-
layer: makeLayer
|
|
2618
|
-
});
|
|
2619
|
-
};
|
|
2620
|
-
//#endregion
|
|
2621
|
-
//#region src/R2.ts
|
|
2622
|
-
var R2_exports = /* @__PURE__ */ __exportAll({
|
|
2623
|
-
R2OperationError: () => R2OperationError,
|
|
2624
|
-
Tag: () => Tag$3,
|
|
2625
|
-
isR2Bucket: () => isR2Bucket,
|
|
2626
|
-
layer: () => layer$2,
|
|
2627
|
-
make: () => make$3,
|
|
2628
|
-
makeClient: () => makeClient$2
|
|
2629
|
-
});
|
|
2630
|
-
const expectedR2Bucket = "R2 bucket binding with head(), get(), put(), createMultipartUpload(), resumeMultipartUpload(), delete(), and list()";
|
|
2631
|
-
var R2OperationError = class extends Data.TaggedError("R2OperationError") {
|
|
2632
|
-
get message() {
|
|
2633
|
-
return `R2 ${this.operation} failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
2634
|
-
}
|
|
2635
|
-
};
|
|
2636
|
-
const r2Error = (binding, operation, cause) => new R2OperationError({
|
|
2637
|
-
binding,
|
|
2638
|
-
operation,
|
|
2639
|
-
cause
|
|
2640
|
-
});
|
|
2641
|
-
const tryR2Promise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
2642
|
-
try: evaluate,
|
|
2643
|
-
catch: (cause) => r2Error(binding, operation, cause)
|
|
2644
|
-
});
|
|
2645
|
-
const tryR2Sync = (binding, operation, evaluate) => Effect.try({
|
|
2646
|
-
try: evaluate,
|
|
2647
|
-
catch: (cause) => r2Error(binding, operation, cause)
|
|
2648
|
-
});
|
|
2649
|
-
const spanOptions$1 = (binding, operation) => ({ attributes: {
|
|
2650
|
-
binding,
|
|
2651
|
-
operation
|
|
2652
|
-
} });
|
|
2653
|
-
const isR2ObjectBody = (value) => "body" in value && Predicate.isFunction(value.arrayBuffer) && Predicate.isFunction(value.bytes) && Predicate.isFunction(value.text) && Predicate.isFunction(value.json) && Predicate.isFunction(value.blob);
|
|
2654
|
-
const wrapObjectBody = (binding, object) => ({
|
|
2655
|
-
key: object.key,
|
|
2656
|
-
version: object.version,
|
|
2657
|
-
size: object.size,
|
|
2658
|
-
etag: object.etag,
|
|
2659
|
-
httpEtag: object.httpEtag,
|
|
2660
|
-
checksums: object.checksums,
|
|
2661
|
-
uploaded: object.uploaded,
|
|
2662
|
-
httpMetadata: object.httpMetadata,
|
|
2663
|
-
customMetadata: object.customMetadata,
|
|
2664
|
-
range: object.range,
|
|
2665
|
-
storageClass: object.storageClass,
|
|
2666
|
-
ssecKeyMd5: object.ssecKeyMd5,
|
|
2667
|
-
writeHttpMetadata: (headers) => object.writeHttpMetadata(headers),
|
|
2668
|
-
raw: object,
|
|
2669
|
-
body: object.body,
|
|
2670
|
-
get bodyUsed() {
|
|
2671
|
-
return object.bodyUsed;
|
|
2672
|
-
},
|
|
2673
|
-
arrayBuffer: tryR2Promise(binding, "arrayBuffer", () => object.arrayBuffer()).pipe(Effect.withSpan("R2.arrayBuffer", spanOptions$1(binding, "arrayBuffer"))),
|
|
2674
|
-
bytes: tryR2Promise(binding, "bytes", () => object.bytes()).pipe(Effect.withSpan("R2.bytes", spanOptions$1(binding, "bytes"))),
|
|
2675
|
-
text: tryR2Promise(binding, "text", () => object.text()).pipe(Effect.withSpan("R2.text", spanOptions$1(binding, "text"))),
|
|
2676
|
-
json: () => tryR2Promise(binding, "json", () => object.json()).pipe(Effect.withSpan("R2.json", spanOptions$1(binding, "json"))),
|
|
2677
|
-
blob: tryR2Promise(binding, "blob", () => object.blob()).pipe(Effect.withSpan("R2.blob", spanOptions$1(binding, "blob")))
|
|
2678
|
-
});
|
|
2679
|
-
const wrapGetResult = (binding, object) => {
|
|
2680
|
-
if (object === null || !isR2ObjectBody(object)) return object;
|
|
2681
|
-
return wrapObjectBody(binding, object);
|
|
2682
|
-
};
|
|
2683
|
-
const R2BucketSchema = Schema.declare((value) => Predicate.hasProperty(value, "head") && Predicate.isFunction(value.head) && Predicate.hasProperty(value, "get") && Predicate.isFunction(value.get) && Predicate.hasProperty(value, "put") && Predicate.isFunction(value.put) && Predicate.hasProperty(value, "createMultipartUpload") && Predicate.isFunction(value.createMultipartUpload) && Predicate.hasProperty(value, "resumeMultipartUpload") && Predicate.isFunction(value.resumeMultipartUpload) && Predicate.hasProperty(value, "delete") && Predicate.isFunction(value.delete) && Predicate.hasProperty(value, "list") && Predicate.isFunction(value.list));
|
|
2684
|
-
const decodeR2Bucket = Schema.decodeUnknownOption(R2BucketSchema);
|
|
2685
|
-
const isR2Bucket = (value) => Option.isSome(decodeR2Bucket(value));
|
|
2686
|
-
const makeClient$2 = (definition) => {
|
|
2687
|
-
const wrapUpload = (upload) => ({
|
|
2688
|
-
raw: upload,
|
|
2689
|
-
key: upload.key,
|
|
2690
|
-
uploadId: upload.uploadId,
|
|
2691
|
-
uploadPart: Effect.fn("R2.uploadPart", spanOptions$1(definition.binding, "uploadPart"))((partNumber, value, options) => tryR2Promise(definition.binding, "uploadPart", () => upload.uploadPart(partNumber, value, options))),
|
|
2692
|
-
abort: tryR2Promise(definition.binding, "abortMultipartUpload", () => upload.abort()).pipe(Effect.withSpan("R2.abortMultipartUpload", spanOptions$1(definition.binding, "abortMultipartUpload"))),
|
|
2693
|
-
complete: Effect.fn("R2.completeMultipartUpload", spanOptions$1(definition.binding, "completeMultipartUpload"))((uploadedParts) => tryR2Promise(definition.binding, "completeMultipartUpload", () => upload.complete([...uploadedParts])))
|
|
2694
|
-
});
|
|
2695
|
-
return (bucket) => {
|
|
2696
|
-
const get = Effect.fn("R2.get", spanOptions$1(definition.binding, "get"))((key, options) => tryR2Promise(definition.binding, "get", () => bucket.get(key, options)).pipe(Effect.map((object) => Option.fromNullOr(wrapGetResult(definition.binding, object)))));
|
|
2697
|
-
return {
|
|
2698
|
-
definition,
|
|
2699
|
-
head: Effect.fn("R2.head", spanOptions$1(definition.binding, "head"))((key) => tryR2Promise(definition.binding, "head", () => bucket.head(key)).pipe(Effect.map(Option.fromNullOr))),
|
|
2700
|
-
get,
|
|
2701
|
-
put: Effect.fn("R2.put", spanOptions$1(definition.binding, "put"))((key, value, options) => tryR2Promise(definition.binding, "put", () => bucket.put(key, value, options)).pipe(Effect.map((object) => {
|
|
2702
|
-
if (object === null) return Option.none();
|
|
2703
|
-
if (options !== void 0 && "onlyIf" in options) return Option.some(object);
|
|
2704
|
-
return object;
|
|
2705
|
-
}))),
|
|
2706
|
-
createMultipartUpload: Effect.fn("R2.createMultipartUpload", spanOptions$1(definition.binding, "createMultipartUpload"))((key, options) => tryR2Promise(definition.binding, "createMultipartUpload", () => bucket.createMultipartUpload(key, options)).pipe(Effect.map(wrapUpload))),
|
|
2707
|
-
resumeMultipartUpload: Effect.fn("R2.resumeMultipartUpload", spanOptions$1(definition.binding, "resumeMultipartUpload"))((key, uploadId) => tryR2Sync(definition.binding, "resumeMultipartUpload", () => wrapUpload(bucket.resumeMultipartUpload(key, uploadId)))),
|
|
2708
|
-
delete: Effect.fn("R2.delete", spanOptions$1(definition.binding, "delete"))((keys) => {
|
|
2709
|
-
const nativeKeys = Predicate.isString(keys) ? keys : [...keys];
|
|
2710
|
-
return tryR2Promise(definition.binding, "delete", () => bucket.delete(nativeKeys));
|
|
2711
|
-
}),
|
|
2712
|
-
list: Effect.fn("R2.list", spanOptions$1(definition.binding, "list"))((options) => tryR2Promise(definition.binding, "list", () => bucket.list(options))),
|
|
2713
|
-
rawUnsafe: Effect.succeed(bucket)
|
|
2714
|
-
};
|
|
2715
|
-
};
|
|
2716
|
-
};
|
|
2717
|
-
const layer$2 = (tag, definition) => layer$18(tag, definition.binding, isR2Bucket, makeClient$2(definition), { expected: expectedR2Bucket });
|
|
2718
|
-
const make$3 = (id) => Tag$3()(id);
|
|
2719
|
-
const Tag$3 = () => (id) => {
|
|
2720
|
-
const tag = Context.Service()(id);
|
|
2721
|
-
const makeLayer = (definition) => layer$2(tag, definition);
|
|
2722
|
-
return Object.assign(tag, {
|
|
2723
|
-
id,
|
|
2724
|
-
layer: makeLayer
|
|
2725
|
-
});
|
|
2726
|
-
};
|
|
2727
|
-
//#endregion
|
|
2728
|
-
//#region src/Vectorize.ts
|
|
2729
|
-
var Vectorize_exports = /* @__PURE__ */ __exportAll({
|
|
2730
|
-
Tag: () => Tag$2,
|
|
2731
|
-
VectorizeOperationError: () => VectorizeOperationError,
|
|
2732
|
-
isVectorizeBinding: () => isVectorizeBinding,
|
|
2733
|
-
layer: () => layer$1,
|
|
2734
|
-
make: () => make$2,
|
|
2735
|
-
makeClient: () => makeClient$1
|
|
2736
|
-
});
|
|
2737
|
-
const expectedVectorizeBinding = "Vectorize index binding with describe(), query(), insert(), upsert(), deleteByIds(), and getByIds()";
|
|
2738
|
-
var VectorizeOperationError = class extends Data.TaggedError("VectorizeOperationError") {
|
|
2739
|
-
get message() {
|
|
2740
|
-
return `Vectorize ${this.operation} failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
2741
|
-
}
|
|
2742
|
-
};
|
|
2743
|
-
const vectorizeError = (binding, operation, cause) => new VectorizeOperationError({
|
|
2744
|
-
binding,
|
|
2745
|
-
operation,
|
|
2746
|
-
cause
|
|
2747
|
-
});
|
|
2748
|
-
const tryVectorizePromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
2749
|
-
try: evaluate,
|
|
2750
|
-
catch: (cause) => vectorizeError(binding, operation, cause)
|
|
2751
|
-
});
|
|
2752
|
-
const spanOptions = (binding, operation) => ({ attributes: {
|
|
2753
|
-
binding,
|
|
2754
|
-
operation
|
|
2755
|
-
} });
|
|
2756
|
-
const invokeVectorizeMethod = (method, receiver, args) => {
|
|
2757
|
-
return Function.prototype.apply.call(method, receiver, args);
|
|
2758
|
-
};
|
|
2759
|
-
const VectorizeBindingSchema = Schema.declare((value) => Predicate.hasProperty(value, "describe") && Predicate.isFunction(value.describe) && Predicate.hasProperty(value, "query") && Predicate.isFunction(value.query) && Predicate.hasProperty(value, "insert") && Predicate.isFunction(value.insert) && Predicate.hasProperty(value, "upsert") && Predicate.isFunction(value.upsert) && Predicate.hasProperty(value, "deleteByIds") && Predicate.isFunction(value.deleteByIds) && Predicate.hasProperty(value, "getByIds") && Predicate.isFunction(value.getByIds));
|
|
2760
|
-
const decodeVectorizeBinding = Schema.decodeUnknownOption(VectorizeBindingSchema);
|
|
2761
|
-
const isVectorizeBinding = (value) => Option.isSome(decodeVectorizeBinding(value));
|
|
2762
|
-
const makeClient$1 = (definition) => (index) => {
|
|
2763
|
-
const runtime = index;
|
|
2764
|
-
const deleteByIds = Effect.fn("Vectorize.deleteByIds", spanOptions(definition.binding, "deleteByIds"))((ids) => tryVectorizePromise(definition.binding, "deleteByIds", () => runtime.deleteByIds([...ids])));
|
|
2765
|
-
return {
|
|
2766
|
-
definition,
|
|
2767
|
-
describe: tryVectorizePromise(definition.binding, "describe", () => runtime.describe()).pipe(Effect.withSpan("Vectorize.describe", spanOptions(definition.binding, "describe"))),
|
|
2768
|
-
query: Effect.fn("Vectorize.query", spanOptions(definition.binding, "query"))((vector, options) => tryVectorizePromise(definition.binding, "query", () => {
|
|
2769
|
-
return runtime.query(vector, options);
|
|
2770
|
-
})),
|
|
2771
|
-
queryById: Effect.fn("Vectorize.queryById", spanOptions(definition.binding, "queryById"))((vectorId, options) => runtime.queryById !== void 0 ? tryVectorizePromise(definition.binding, "queryById", () => {
|
|
2772
|
-
const queryById = runtime.queryById;
|
|
2773
|
-
return queryById === void 0 ? Promise.reject(/* @__PURE__ */ new TypeError("Vectorize binding does not expose queryById()")) : invokeVectorizeMethod(queryById, runtime, [vectorId, options]);
|
|
2774
|
-
}) : Effect.fail(vectorizeError(definition.binding, "queryById", /* @__PURE__ */ new TypeError("Vectorize binding does not expose queryById()")))),
|
|
2775
|
-
insert: Effect.fn("Vectorize.insert", spanOptions(definition.binding, "insert"))((vectors) => tryVectorizePromise(definition.binding, "insert", () => runtime.insert([...vectors]))),
|
|
2776
|
-
upsert: Effect.fn("Vectorize.upsert", spanOptions(definition.binding, "upsert"))((vectors) => tryVectorizePromise(definition.binding, "upsert", () => runtime.upsert([...vectors]))),
|
|
2777
|
-
deleteByIds,
|
|
2778
|
-
delete: deleteByIds,
|
|
2779
|
-
getByIds: Effect.fn("Vectorize.getByIds", spanOptions(definition.binding, "getByIds"))((ids) => tryVectorizePromise(definition.binding, "getByIds", () => runtime.getByIds([...ids]))),
|
|
2780
|
-
rawUnsafe: Effect.succeed(index)
|
|
2781
|
-
};
|
|
2782
|
-
};
|
|
2783
|
-
const layer$1 = (tag, definition) => layer$18(tag, definition.binding, isVectorizeBinding, makeClient$1(definition), { expected: expectedVectorizeBinding });
|
|
2784
|
-
const make$2 = (id) => Tag$2()(id);
|
|
2785
|
-
const Tag$2 = () => (id) => {
|
|
2786
|
-
const tag = Context.Service()(id);
|
|
2787
|
-
const makeLayer = (definition) => layer$1(tag, definition);
|
|
2788
|
-
return Object.assign(tag, {
|
|
2789
|
-
id,
|
|
2790
|
-
layer: makeLayer
|
|
2791
|
-
});
|
|
2792
|
-
};
|
|
2793
|
-
//#endregion
|
|
2794
|
-
//#region src/WebTransport.ts
|
|
2795
|
-
var WebTransport_exports = /* @__PURE__ */ __exportAll({
|
|
2796
|
-
InboundTransport: () => InboundTransport,
|
|
2797
|
-
WebTransportUnsupportedError: () => WebTransportUnsupportedError,
|
|
2798
|
-
capabilities: () => capabilities,
|
|
2799
|
-
inboundSessionsUnsupported: () => inboundSessionsUnsupported,
|
|
2800
|
-
inboundTransport: () => inboundTransport,
|
|
2801
|
-
isHttp3: () => isHttp3
|
|
2802
|
-
});
|
|
2803
|
-
/**
|
|
2804
|
-
* Metadata Cloudflare's edge reports about the inbound client connection.
|
|
2805
|
-
*
|
|
2806
|
-
* `httpProtocol` and `clientTcpRtt` are declared in
|
|
2807
|
-
* `@cloudflare/workers-types`; `clientQuicRtt` is documented by Cloudflare
|
|
2808
|
-
* ("only present when the client connected over QUIC (HTTP/3)") but not yet
|
|
2809
|
-
* present in the published types, so it is decoded from the open
|
|
2810
|
-
* `Record<string, unknown>` side of `request.cf`.
|
|
2811
|
-
*/
|
|
2812
|
-
var InboundTransport = class extends Schema.Class("InboundTransport")({
|
|
2813
|
-
httpProtocol: Schema.String,
|
|
2814
|
-
clientQuicRtt: Schema.optional(Schema.Number),
|
|
2815
|
-
clientTcpRtt: Schema.optional(Schema.Number)
|
|
2816
|
-
}) {};
|
|
2817
|
-
const decodeInboundTransport = Schema.decodeUnknownResult(InboundTransport);
|
|
2818
|
-
/**
|
|
2819
|
-
* Decodes the inbound transport metadata from `request.cf`.
|
|
2820
|
-
*
|
|
2821
|
-
* Returns `None` when the metadata is absent (for example in local `wrangler
|
|
2822
|
-
* dev` or when a Worker invokes another Worker directly) or does not match
|
|
2823
|
-
* the expected shape.
|
|
2824
|
-
*/
|
|
2825
|
-
const inboundTransport = (request) => Result.getSuccess(decodeInboundTransport(request.cf));
|
|
2826
|
-
const isHttp3 = (transport) => transport.clientQuicRtt !== void 0 || transport.httpProtocol === "HTTP/3";
|
|
2827
|
-
const capabilities = Effect.sync(() => {
|
|
2828
|
-
const runtime = globalThis;
|
|
2829
|
-
return {
|
|
2830
|
-
inboundSessions: false,
|
|
2831
|
-
outboundSessions: Predicate.hasProperty(runtime, "WebTransport") && Predicate.isFunction(runtime["WebTransport"])
|
|
2832
|
-
};
|
|
2833
|
-
});
|
|
2834
|
-
var WebTransportUnsupportedError = class extends Data.TaggedError("WebTransportUnsupportedError") {
|
|
2835
|
-
get message() {
|
|
2836
|
-
return this.capability === "inbound-sessions" ? "Cloudflare Workers cannot accept inbound WebTransport sessions: the edge terminates QUIC and no runtime session API exists (cloudflare/workerd#6451). Use Durable Object WebSockets for bidirectional push." : "This Workers runtime provides no WebTransport client: workerd has no QUIC stack and cloudflare:sockets is TCP-only.";
|
|
2837
|
-
}
|
|
2838
|
-
};
|
|
2839
|
-
/**
|
|
2840
|
-
* The explicit typed boundary for inbound WebTransport sessions.
|
|
2841
|
-
*
|
|
2842
|
-
* Always fails with {@link WebTransportUnsupportedError} today. Route the
|
|
2843
|
-
* code path that would accept a session through this effect so the
|
|
2844
|
-
* limitation is visible in the type system and greppable when Cloudflare
|
|
2845
|
-
* ships a real API.
|
|
2846
|
-
*/
|
|
2847
|
-
const inboundSessionsUnsupported = Effect.fail(new WebTransportUnsupportedError({ capability: "inbound-sessions" }));
|
|
2848
|
-
//#endregion
|
|
2849
|
-
//#region src/WorkflowBinding.ts
|
|
2850
|
-
var WorkflowBinding_exports = /* @__PURE__ */ __exportAll({
|
|
2851
|
-
WorkflowOperationError: () => WorkflowOperationError,
|
|
2852
|
-
WorkflowResultDecodeError: () => WorkflowResultDecodeError,
|
|
2853
|
-
isWorkflow: () => isWorkflow,
|
|
2854
|
-
layer: () => layer,
|
|
2855
|
-
makeClient: () => makeClient
|
|
2856
|
-
});
|
|
2857
|
-
const expectedWorkflow = "Workflow binding with create(), createBatch(), and get()";
|
|
2858
|
-
var WorkflowOperationError = class extends Data.TaggedError("WorkflowOperationError") {
|
|
2859
|
-
get message() {
|
|
2860
|
-
return `Workflow ${this.operation} failed for binding "${this.binding}": ${causeMessage(this.cause)}`;
|
|
2861
|
-
}
|
|
2862
|
-
};
|
|
2863
|
-
var WorkflowResultDecodeError = class extends Data.TaggedError("WorkflowResultDecodeError") {
|
|
2864
|
-
get message() {
|
|
2865
|
-
return `Workflow result decode failed for binding "${this.binding}" instance "${this.instanceId}": ${causeMessage(this.cause)}`;
|
|
2866
|
-
}
|
|
2867
|
-
};
|
|
2868
|
-
const workflowError = (binding, operation, cause) => new WorkflowOperationError({
|
|
2869
|
-
binding,
|
|
2870
|
-
operation,
|
|
2871
|
-
cause
|
|
2872
|
-
});
|
|
2873
|
-
const tryWorkflowPromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
2874
|
-
try: evaluate,
|
|
2875
|
-
catch: (cause) => workflowError(binding, operation, cause)
|
|
2876
|
-
});
|
|
2877
|
-
const WorkflowBindingSchema = Schema.declare((value) => Predicate.hasProperty(value, "create") && Predicate.isFunction(value.create) && Predicate.hasProperty(value, "createBatch") && Predicate.isFunction(value.createBatch) && Predicate.hasProperty(value, "get") && Predicate.isFunction(value.get));
|
|
2878
|
-
const decodeWorkflowBinding = Schema.decodeUnknownOption(WorkflowBindingSchema);
|
|
2879
|
-
const isWorkflow = (value) => Option.isSome(decodeWorkflowBinding(value));
|
|
2880
|
-
const makeClient = (definition) => {
|
|
2881
|
-
const encodePayload = Schema.encodeEffect(definition.payload);
|
|
2882
|
-
const decodeResult = Schema.decodeUnknownEffect(definition.result);
|
|
2883
|
-
const wrapInstance = (raw) => {
|
|
2884
|
-
const operation = (name, evaluate) => tryWorkflowPromise(definition.binding, name, evaluate);
|
|
2885
|
-
return {
|
|
2886
|
-
raw,
|
|
2887
|
-
id: raw.id,
|
|
2888
|
-
pause: operation("pause", () => raw.pause()),
|
|
2889
|
-
resume: operation("resume", () => raw.resume()),
|
|
2890
|
-
terminate: (options) => operation("terminate", () => raw.terminate(options)),
|
|
2891
|
-
restart: (options) => operation("restart", () => raw.restart(options)),
|
|
2892
|
-
delete: operation("delete", () => raw.delete()),
|
|
2893
|
-
status: operation("status", () => raw.status()).pipe(Effect.flatMap((status) => Effect.gen(function* () {
|
|
2894
|
-
const output = status.output === void 0 || status.output === null && status.status !== "complete" ? Option.none() : Option.some(yield* decodeResult(status.output).pipe(Effect.mapError((cause) => new WorkflowResultDecodeError({
|
|
2895
|
-
binding: definition.binding,
|
|
2896
|
-
instanceId: raw.id,
|
|
2897
|
-
cause
|
|
2898
|
-
}))));
|
|
2899
|
-
return {
|
|
2900
|
-
status: status.status,
|
|
2901
|
-
output,
|
|
2902
|
-
error: status.error === null || status.error === void 0 ? Option.none() : Option.some(status.error)
|
|
2903
|
-
};
|
|
2904
|
-
}))),
|
|
2905
|
-
sendEvent: (event) => operation("sendEvent", () => raw.sendEvent(event))
|
|
2906
|
-
};
|
|
2907
|
-
};
|
|
2908
|
-
return (workflow) => ({
|
|
2909
|
-
create: Effect.fn("WorkflowBinding.create", { attributes: {
|
|
2910
|
-
binding: definition.binding,
|
|
2911
|
-
operation: "create"
|
|
2912
|
-
} })(function* (payload, options) {
|
|
2913
|
-
const encoded = yield* encodePayload(payload);
|
|
2914
|
-
const raw = yield* tryWorkflowPromise(definition.binding, "create", () => workflow.create({
|
|
2915
|
-
...options,
|
|
2916
|
-
params: encoded
|
|
2917
|
-
}));
|
|
2918
|
-
return wrapInstance(raw);
|
|
2919
|
-
}),
|
|
2920
|
-
createBatch: Effect.fn("WorkflowBinding.createBatch", { attributes: {
|
|
2921
|
-
binding: definition.binding,
|
|
2922
|
-
operation: "createBatch"
|
|
2923
|
-
} })(function* (batch) {
|
|
2924
|
-
const encodedBatch = [];
|
|
2925
|
-
for (const item of batch) {
|
|
2926
|
-
const { payload, ...options } = item;
|
|
2927
|
-
encodedBatch.push({
|
|
2928
|
-
...options,
|
|
2929
|
-
params: yield* encodePayload(payload)
|
|
2930
|
-
});
|
|
2931
|
-
}
|
|
2932
|
-
return (yield* tryWorkflowPromise(definition.binding, "createBatch", () => workflow.createBatch(encodedBatch))).map(wrapInstance);
|
|
2933
|
-
}),
|
|
2934
|
-
get: (instanceId) => tryWorkflowPromise(definition.binding, "get", () => workflow.get(instanceId)).pipe(Effect.map(wrapInstance)),
|
|
2935
|
-
rawUnsafe: Effect.succeed(workflow)
|
|
2936
|
-
});
|
|
2937
|
-
};
|
|
2938
|
-
const layer = (tag, definition) => layer$18(tag, definition.binding, (value) => isWorkflow(value), makeClient(definition), { expected: expectedWorkflow });
|
|
2939
|
-
//#endregion
|
|
2940
|
-
//#region src/WorkflowDefinition.ts
|
|
2941
|
-
var WorkflowDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
2942
|
-
Tag: () => Tag$1,
|
|
2943
|
-
Workflow: () => Workflow,
|
|
2944
|
-
implement: () => implement$1,
|
|
2945
|
-
make: () => make$1
|
|
2946
|
-
});
|
|
2947
|
-
const makeDefinition = (id, definition) => {
|
|
2948
|
-
const workflowDefinition = {
|
|
2949
|
-
id,
|
|
2950
|
-
payload: definition.payload,
|
|
2951
|
-
result: definition.result
|
|
2952
|
-
};
|
|
2953
|
-
return Object.assign(workflowDefinition, { make: (layer, options) => make(layer, { run: wrapHandler(workflowDefinition, options.run) }) });
|
|
2954
|
-
};
|
|
2955
|
-
const make$1 = (id, definition) => Tag$1()(id, definition);
|
|
2956
|
-
const Tag$1 = () => (id, definition) => {
|
|
2957
|
-
const workflowDefinition = makeDefinition(id, definition);
|
|
2958
|
-
const tag = Context.Service()(`effect-cf/Workflow/${id}`);
|
|
2959
|
-
const layer$19 = (binding) => layer(tag, {
|
|
2960
|
-
...binding,
|
|
2961
|
-
payload: definition.payload,
|
|
2962
|
-
result: definition.result
|
|
2963
|
-
});
|
|
2964
|
-
const create = Effect.fnUntraced(function* (payload, options) {
|
|
2965
|
-
return yield* (yield* tag).create(payload, options);
|
|
2966
|
-
});
|
|
2967
|
-
const createBatch = Effect.fnUntraced(function* (batch) {
|
|
2968
|
-
return yield* (yield* tag).createBatch(batch);
|
|
2969
|
-
});
|
|
2970
|
-
const get = Effect.fnUntraced(function* (instanceId) {
|
|
2971
|
-
return yield* (yield* tag).get(instanceId);
|
|
2972
|
-
});
|
|
2973
|
-
const rawUnsafe = Effect.flatMap(tag, (workflow) => workflow.rawUnsafe);
|
|
2974
|
-
return Object.assign(tag, {
|
|
2975
|
-
id: workflowDefinition.id,
|
|
2976
|
-
payload: workflowDefinition.payload,
|
|
2977
|
-
result: workflowDefinition.result,
|
|
2978
|
-
make: workflowDefinition.make,
|
|
2979
|
-
layer: layer$19,
|
|
2980
|
-
create,
|
|
2981
|
-
createBatch,
|
|
2982
|
-
get,
|
|
2983
|
-
rawUnsafe
|
|
2984
|
-
});
|
|
2985
|
-
};
|
|
2986
|
-
const Workflow = Tag$1;
|
|
2987
|
-
const wrapHandler = (definition, handler) => {
|
|
2988
|
-
const decodePayload = Schema.decodeUnknownEffect(definition.payload);
|
|
2989
|
-
const encodeResult = Schema.encodeEffect(definition.result);
|
|
2990
|
-
return Effect.fnUntraced(function* (payload) {
|
|
2991
|
-
const decodedPayload = yield* decodePayload(payload);
|
|
2992
|
-
const decodedEvent = {
|
|
2993
|
-
...yield* WorkflowEvent$1,
|
|
2994
|
-
payload: decodedPayload
|
|
2995
|
-
};
|
|
2996
|
-
const result = yield* handler(decodedPayload).pipe(Effect.provideService(WorkflowEvent$1, decodedEvent));
|
|
2997
|
-
return yield* encodeResult(result);
|
|
2998
|
-
});
|
|
2999
|
-
};
|
|
3000
|
-
const implement$1 = (_definition, handler) => handler;
|
|
3001
|
-
//#endregion
|
|
3002
|
-
//#region src/Workflow.ts
|
|
3003
|
-
var Workflow_exports = /* @__PURE__ */ __exportAll({
|
|
3004
|
-
Tag: () => Tag,
|
|
3005
|
-
WorkflowEvent: () => WorkflowEvent$1,
|
|
3006
|
-
WorkflowStep: () => WorkflowStep$1,
|
|
3007
|
-
WorkflowStepContext: () => WorkflowStepContext$1,
|
|
3008
|
-
WorkflowStepError: () => WorkflowStepError,
|
|
3009
|
-
WorkflowStepNonRetryableError: () => WorkflowStepNonRetryableError,
|
|
3010
|
-
implement: () => implement,
|
|
3011
|
-
make: () => make,
|
|
3012
|
-
sleep: () => sleep,
|
|
3013
|
-
sleepUntil: () => sleepUntil,
|
|
3014
|
-
step: () => step,
|
|
3015
|
-
waitForEvent: () => waitForEvent
|
|
3016
|
-
});
|
|
3017
|
-
var WorkflowEvent$1 = class extends Context.Service()("effect-cf/WorkflowEvent") {};
|
|
3018
|
-
var WorkflowStepError = class extends Data.TaggedError("WorkflowStepError") {
|
|
3019
|
-
get message() {
|
|
3020
|
-
const step = this.step === void 0 ? "" : ` in step "${this.step}"`;
|
|
3021
|
-
return `Workflow ${this.operation} failed${step}: ${causeMessage(this.cause)}`;
|
|
3022
|
-
}
|
|
3023
|
-
};
|
|
3024
|
-
/**
|
|
3025
|
-
* Typed step failure that Cloudflare must treat as terminal instead of retrying.
|
|
3026
|
-
*
|
|
3027
|
-
* The workflow boundary converts this value into Cloudflare's native
|
|
3028
|
-
* `NonRetryableError` while preserving the original cause and its message.
|
|
3029
|
-
*/
|
|
3030
|
-
var WorkflowStepNonRetryableError = class extends Data.TaggedError("WorkflowStepNonRetryableError") {
|
|
3031
|
-
get message() {
|
|
3032
|
-
return `Workflow step failed without retry: ${causeMessage(this.cause)}`;
|
|
3033
|
-
}
|
|
3034
|
-
};
|
|
3035
|
-
var WorkflowStep$1 = class extends Context.Service()("effect-cf/WorkflowStep") {};
|
|
3036
|
-
var WorkflowStepContext$1 = class extends Context.Service()("effect-cf/WorkflowStepContext") {};
|
|
3037
|
-
const fromWorkflowEvent = (event) => ({
|
|
3038
|
-
raw: event,
|
|
3039
|
-
payload: event.payload,
|
|
3040
|
-
timestamp: event.timestamp,
|
|
3041
|
-
instanceId: event.instanceId,
|
|
3042
|
-
workflowName: event.workflowName
|
|
3043
|
-
});
|
|
3044
|
-
const toCloudflareNonRetryableError = (error) => {
|
|
3045
|
-
const cloudflareError = new NonRetryableError(error.message);
|
|
3046
|
-
cloudflareError.cause = error.cause;
|
|
3047
|
-
return cloudflareError;
|
|
3048
|
-
};
|
|
3049
|
-
const exposeCloudflareNonRetryableError = (effect) => Effect.catchCause(effect, (cause) => {
|
|
3050
|
-
const error = Cause.findErrorOption(cause);
|
|
3051
|
-
return Option.isSome(error) && error.value instanceof WorkflowStepNonRetryableError ? Effect.die(toCloudflareNonRetryableError(error.value)) : Effect.failCause(cause);
|
|
3052
|
-
});
|
|
3053
|
-
const fromWorkflowStep = (step) => ({
|
|
3054
|
-
raw: step,
|
|
3055
|
-
do: (name, effect, config) => Effect.gen(function* () {
|
|
3056
|
-
const context = yield* Effect.context();
|
|
3057
|
-
return yield* Effect.scoped(Effect.gen(function* () {
|
|
3058
|
-
const runPromise = yield* FiberSet.makeRuntimePromise();
|
|
3059
|
-
return yield* Effect.tryPromise({
|
|
3060
|
-
try: () => {
|
|
3061
|
-
const run = (stepContext) => {
|
|
3062
|
-
const stepEffect = Effect.scoped(Effect.provideService(effect, WorkflowStepContext$1, stepContext));
|
|
3063
|
-
return runPromise(exposeCloudflareNonRetryableError(Effect.provideContext(stepEffect, context)));
|
|
3064
|
-
};
|
|
3065
|
-
const rawStep = step;
|
|
3066
|
-
return config === void 0 ? rawStep.do(name, run) : rawStep.do(name, config, run);
|
|
3067
|
-
},
|
|
3068
|
-
catch: (cause) => new WorkflowStepError({
|
|
3069
|
-
step: name,
|
|
3070
|
-
operation: "do",
|
|
3071
|
-
cause
|
|
3072
|
-
})
|
|
3073
|
-
});
|
|
3074
|
-
}));
|
|
3075
|
-
}),
|
|
3076
|
-
sleep: (name, duration) => Effect.tryPromise({
|
|
3077
|
-
try: () => step.sleep(name, duration),
|
|
3078
|
-
catch: (cause) => new WorkflowStepError({
|
|
3079
|
-
step: name,
|
|
3080
|
-
operation: "sleep",
|
|
3081
|
-
cause
|
|
3082
|
-
})
|
|
3083
|
-
}),
|
|
3084
|
-
sleepUntil: (name, timestamp) => Effect.tryPromise({
|
|
3085
|
-
try: () => step.sleepUntil(name, timestamp),
|
|
3086
|
-
catch: (cause) => new WorkflowStepError({
|
|
3087
|
-
step: name,
|
|
3088
|
-
operation: "sleepUntil",
|
|
3089
|
-
cause
|
|
3090
|
-
})
|
|
3091
|
-
}),
|
|
3092
|
-
waitForEvent: (name, options) => Effect.tryPromise({
|
|
3093
|
-
try: () => {
|
|
3094
|
-
return step.waitForEvent(name, options);
|
|
3095
|
-
},
|
|
3096
|
-
catch: (cause) => new WorkflowStepError({
|
|
3097
|
-
step: name,
|
|
3098
|
-
operation: "waitForEvent",
|
|
3099
|
-
cause
|
|
3100
|
-
})
|
|
3101
|
-
})
|
|
3102
|
-
});
|
|
3103
|
-
const make = (layer, options) => {
|
|
3104
|
-
class EffectWorkflow extends WorkflowEntrypoint {
|
|
3105
|
-
runtime;
|
|
3106
|
-
constructor(ctx, env) {
|
|
3107
|
-
super(ctx, env);
|
|
3108
|
-
this.runtime = makeEntrypointRuntime(layer, env, Layer.mergeAll(Layer.succeed(ExecutionContext, ctx), Layer.succeed(WorkerContext, fromExecutionContext(ctx))));
|
|
3109
|
-
}
|
|
3110
|
-
run(event, step) {
|
|
3111
|
-
const workflowServices = Layer.mergeAll(Layer.succeed(WorkflowEvent$1, fromWorkflowEvent(event)), Layer.succeed(WorkflowStep$1, fromWorkflowStep(step)));
|
|
3112
|
-
return runEventPromise(this.runtime, options.run(event.payload), workflowServices);
|
|
3113
|
-
}
|
|
3114
|
-
}
|
|
3115
|
-
return assumeEntrypointClass(EffectWorkflow);
|
|
3116
|
-
};
|
|
3117
|
-
const step = (name, effect, config) => Effect.flatMap(WorkflowStep$1, (workflowStep) => workflowStep.do(name, effect, config));
|
|
3118
|
-
const sleep = (name, duration) => Effect.flatMap(WorkflowStep$1, (workflowStep) => workflowStep.sleep(name, duration));
|
|
3119
|
-
const sleepUntil = (name, timestamp) => Effect.flatMap(WorkflowStep$1, (workflowStep) => workflowStep.sleepUntil(name, timestamp));
|
|
3120
|
-
const waitForEvent = (name, options) => Effect.flatMap(WorkflowStep$1, (workflowStep) => workflowStep.waitForEvent(name, options));
|
|
3121
|
-
const Tag = Tag$1;
|
|
3122
|
-
const implement = implement$1;
|
|
3123
|
-
//#endregion
|
|
1
|
+
import { Environment_exports, WorkerConfig, WorkerEnvironment } from "./Environment.mjs";
|
|
2
|
+
import { Binding_exports } from "./Binding.mjs";
|
|
3
|
+
import { WorkersAi_exports } from "./WorkersAi.mjs";
|
|
4
|
+
import { AiGateway_exports } from "./AiGateway.mjs";
|
|
5
|
+
import { AnalyticsEngine_exports } from "./AnalyticsEngine.mjs";
|
|
6
|
+
import { Artifacts_exports } from "./Artifacts.mjs";
|
|
7
|
+
import { BrowserRendering_exports } from "./BrowserRendering.mjs";
|
|
8
|
+
import { Cache_exports } from "./Cache.mjs";
|
|
9
|
+
import { DurableObjectStorage_exports } from "./DurableObjectStorage.mjs";
|
|
10
|
+
import { DurableObjectWebSocket_exports } from "./DurableObjectWebSocket.mjs";
|
|
11
|
+
import { DurableObjectState_exports } from "./DurableObjectState.mjs";
|
|
12
|
+
import { CloudflareOtlp_exports } from "./CloudflareOtlp.mjs";
|
|
13
|
+
import { CloudflareTracer_exports } from "./CloudflareTracer.mjs";
|
|
14
|
+
import { ContainerNamespace_exports } from "./ContainerNamespace.mjs";
|
|
15
|
+
import { D1_exports } from "./D1.mjs";
|
|
16
|
+
import { QueueBinding_exports } from "./QueueBinding.mjs";
|
|
17
|
+
import { QueueDefinition_exports } from "./QueueDefinition.mjs";
|
|
18
|
+
import { Queue_exports } from "./Queue.mjs";
|
|
19
|
+
import { RpcDefinition_exports } from "./RpcDefinition.mjs";
|
|
20
|
+
import { RpcTracing_exports } from "./RpcTracing.mjs";
|
|
21
|
+
import { Rpc_exports } from "./Rpc.mjs";
|
|
22
|
+
import { ServiceBinding_exports } from "./ServiceBinding.mjs";
|
|
23
|
+
import { WorkerDefinition_exports } from "./WorkerDefinition.mjs";
|
|
24
|
+
import { Worker_exports } from "./Worker.mjs";
|
|
25
|
+
import { DurableObjectAlarm_exports } from "./DurableObjectAlarm.mjs";
|
|
26
|
+
import { DurableObjectNamespace_exports } from "./DurableObjectNamespace.mjs";
|
|
27
|
+
import { DurableObjectDefinition_exports } from "./DurableObjectDefinition.mjs";
|
|
28
|
+
import { DurableObject_exports } from "./DurableObject.mjs";
|
|
29
|
+
import { DurableObjectRpcWebSocket_exports } from "./DurableObjectRpcWebSocket.mjs";
|
|
30
|
+
import { DurableObjectSqlite_exports } from "./DurableObjectSqlite.mjs";
|
|
31
|
+
import { Email_exports } from "./Email.mjs";
|
|
32
|
+
import { Hyperdrive_exports } from "./Hyperdrive.mjs";
|
|
33
|
+
import { Images_exports } from "./Images.mjs";
|
|
34
|
+
import { Kv_exports } from "./Kv.mjs";
|
|
35
|
+
import { R2_exports } from "./R2.mjs";
|
|
36
|
+
import { Vectorize_exports } from "./Vectorize.mjs";
|
|
37
|
+
import { WebTransport_exports } from "./WebTransport.mjs";
|
|
38
|
+
import { WorkflowBinding_exports } from "./WorkflowBinding.mjs";
|
|
39
|
+
import { WorkflowDefinition_exports } from "./WorkflowDefinition.mjs";
|
|
40
|
+
import { Workflow_exports } from "./Workflow.mjs";
|
|
3124
41
|
export { AiGateway_exports as AiGateway, AnalyticsEngine_exports as AnalyticsEngine, Artifacts_exports as Artifacts, Binding_exports as Binding, BrowserRendering_exports as BrowserRendering, Cache_exports as Cache, CloudflareOtlp_exports as CloudflareOtlp, CloudflareTracer_exports as CloudflareTracer, ContainerNamespace_exports as ContainerNamespace, D1_exports as D1, DurableObject_exports as DurableObject, DurableObjectAlarm_exports as DurableObjectAlarm, DurableObjectDefinition_exports as DurableObjectDefinition, DurableObjectNamespace_exports as DurableObjectNamespace, DurableObjectRpcWebSocket_exports as DurableObjectRpcWebSocket, DurableObjectSqlite_exports as DurableObjectSqlite, DurableObjectState_exports as DurableObjectState, DurableObjectStorage_exports as DurableObjectStorage, DurableObjectWebSocket_exports as DurableObjectWebSocket, Email_exports as Email, Environment_exports as Environment, Hyperdrive_exports as Hyperdrive, Images_exports as Images, Kv_exports as Kv, Queue_exports as Queue, QueueBinding_exports as QueueBinding, QueueDefinition_exports as QueueDefinition, R2_exports as R2, Rpc_exports as Rpc, RpcDefinition_exports as RpcDefinition, RpcTracing_exports as RpcTracing, ServiceBinding_exports as ServiceBinding, Vectorize_exports as Vectorize, WebTransport_exports as WebTransport, Worker_exports as Worker, WorkerConfig, WorkerDefinition_exports as WorkerDefinition, WorkerEnvironment, WorkersAi_exports as WorkersAi, Workflow_exports as Workflow, WorkflowBinding_exports as WorkflowBinding, WorkflowDefinition_exports as WorkflowDefinition };
|