effect-cf 0.12.0 → 0.13.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 +15 -0
- package/dist/index.d.mts +1085 -1085
- package/dist/index.mjs +1489 -1519
- package/package.json +1 -1
- package/src/CloudflareOtlp.ts +0 -112
- package/src/DurableObject.ts +64 -21
- package/src/DurableObjectDefinition.ts +19 -9
- package/src/Worker.ts +90 -29
- package/src/WorkerDefinition.ts +16 -8
- package/src/internal/Clock.ts +28 -0
package/dist/index.mjs
CHANGED
|
@@ -1,1644 +1,1614 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
|
|
2
|
-
import { a as WorkerConfig, i as layer$
|
|
2
|
+
import { a as WorkerConfig, i as layer$11, n as Binding_exports, o as WorkerEnvironment, r as Service$2, t as Hyperdrive_exports } from "./Hyperdrive-89hg_Fck.mjs";
|
|
3
3
|
import { Cause, Clock, Config, ConfigProvider, Context, Data, DateTime, Duration, Effect, Exit, Layer, ManagedRuntime, Option, Queue, Schema } from "effect";
|
|
4
4
|
import { FetchHttpClient, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
|
|
5
5
|
import { Otlp, OtlpLogger, OtlpMetrics, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";
|
|
6
|
-
import { DurableObject, RpcStub, RpcTarget, WorkerEntrypoint, WorkflowEntrypoint } from "cloudflare:workers";
|
|
7
6
|
import { D1Client } from "@effect/sql-d1";
|
|
7
|
+
import { DurableObject, RpcStub, RpcTarget, WorkerEntrypoint, WorkflowEntrypoint } from "cloudflare:workers";
|
|
8
8
|
import * as RpcMessage from "effect/unstable/rpc/RpcMessage";
|
|
9
9
|
import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization";
|
|
10
10
|
import * as RpcServer from "effect/unstable/rpc/RpcServer";
|
|
11
11
|
import { SqliteClient } from "@effect/sql-sqlite-do";
|
|
12
|
-
//#region src/
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
layer: () => layer$9,
|
|
17
|
-
makeClient: () => makeClient$6
|
|
12
|
+
//#region src/DurableObjectStorage.ts
|
|
13
|
+
var DurableObjectStorage_exports = /* @__PURE__ */ __exportAll({
|
|
14
|
+
StorageOperationError: () => StorageOperationError,
|
|
15
|
+
fromDurableObjectStorage: () => fromDurableObjectStorage
|
|
18
16
|
});
|
|
19
|
-
|
|
20
|
-
var
|
|
21
|
-
const
|
|
17
|
+
/** Error type used when a storage operation throws or rejects. */
|
|
18
|
+
var StorageOperationError = class extends Data.TaggedError("StorageOperationError") {};
|
|
19
|
+
const storageError = (operation, cause) => new StorageOperationError({
|
|
20
|
+
operation,
|
|
21
|
+
cause
|
|
22
|
+
});
|
|
23
|
+
const tryStorageSync = (operation, evaluate) => Effect.try({
|
|
22
24
|
try: evaluate,
|
|
23
|
-
catch: (cause) =>
|
|
24
|
-
binding,
|
|
25
|
-
operation,
|
|
26
|
-
cause,
|
|
27
|
-
message: `Cloudflare queue binding "${binding}" operation "${operation}" failed`
|
|
28
|
-
})
|
|
25
|
+
catch: (cause) => storageError(operation, cause)
|
|
29
26
|
});
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
};
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
const tryStoragePromise = (operation, evaluate) => Effect.tryPromise({
|
|
28
|
+
try: evaluate,
|
|
29
|
+
catch: (cause) => storageError(operation, cause)
|
|
30
|
+
});
|
|
31
|
+
const fromSqlCursor = (cursor) => ({
|
|
32
|
+
next: () => tryStorageSync("sql.next", () => cursor.next()),
|
|
33
|
+
toArray: () => tryStorageSync("sql.toArray", () => cursor.toArray()),
|
|
34
|
+
one: () => tryStorageSync("sql.one", () => cursor.one()),
|
|
35
|
+
raw: () => tryStorageSync("sql.raw", () => cursor.raw()),
|
|
36
|
+
get columnNames() {
|
|
37
|
+
return cursor.columnNames;
|
|
38
|
+
},
|
|
39
|
+
rowsRead: tryStorageSync("sql.rowsRead", () => cursor.rowsRead),
|
|
40
|
+
rowsWritten: tryStorageSync("sql.rowsWritten", () => cursor.rowsWritten)
|
|
41
|
+
});
|
|
42
|
+
const fromSqlStorage = (sql) => ({
|
|
43
|
+
exec: (query, ...bindings) => tryStorageSync("sql.exec", () => fromSqlCursor(sql.exec(query, ...bindings))),
|
|
44
|
+
get databaseSize() {
|
|
45
|
+
return sql.databaseSize;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const schemaBackedSyncKvStorage = (kv, definition) => {
|
|
49
|
+
const encodeKey = Schema.encodeEffect(definition.key);
|
|
50
|
+
const decodeKey = Schema.decodeUnknownEffect(definition.key);
|
|
51
|
+
const encodeValue = Schema.encodeEffect(definition.value);
|
|
52
|
+
const decodeValue = Schema.decodeUnknownEffect(definition.value);
|
|
53
|
+
return {
|
|
54
|
+
get: (key) => Effect.gen(function* () {
|
|
55
|
+
const encodedKey = yield* encodeKey(key);
|
|
56
|
+
const encodedValue = yield* tryStorageSync("kv.get", () => kv.get(encodedKey));
|
|
57
|
+
if (encodedValue === void 0) return Option.none();
|
|
58
|
+
return yield* decodeValue(encodedValue).pipe(Effect.map(Option.some));
|
|
40
59
|
}),
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
body: yield* encodeMessage(message.body)
|
|
46
|
-
});
|
|
47
|
-
const sendBatch = queue.sendBatch;
|
|
48
|
-
if (sendBatch !== void 0) {
|
|
49
|
-
yield* tryQueuePromise(definition.binding, "sendBatch", () => sendBatch.call(queue, encodedMessages, options));
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
yield* tryQueuePromise(definition.binding, "sendBatch", async () => {
|
|
53
|
-
for (const message of encodedMessages) await queue.send(message.body, {
|
|
54
|
-
contentType: message.contentType,
|
|
55
|
-
delaySeconds: message.delaySeconds ?? options?.delaySeconds
|
|
56
|
-
});
|
|
57
|
-
});
|
|
60
|
+
put: (key, value) => Effect.gen(function* () {
|
|
61
|
+
const encodedKey = yield* encodeKey(key);
|
|
62
|
+
const encodedValue = yield* encodeValue(value);
|
|
63
|
+
yield* tryStorageSync("kv.put", () => kv.put(encodedKey, encodedValue));
|
|
58
64
|
}),
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return
|
|
68
|
-
}
|
|
69
|
-
unsafeRaw: Effect.succeed(queue)
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
const layer$9 = (tag, definition) => layer$10(tag, definition.binding, (value) => isQueue(value), makeClient$6(definition), { expected: expectedQueueProducer });
|
|
73
|
-
//#endregion
|
|
74
|
-
//#region src/QueueDefinition.ts
|
|
75
|
-
var QueueDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
76
|
-
Queue: () => Queue$1,
|
|
77
|
-
Tag: () => Tag$10,
|
|
78
|
-
implement: () => implement$7,
|
|
79
|
-
make: () => make$10
|
|
80
|
-
});
|
|
81
|
-
const makeDefinition$4 = (id, definition) => {
|
|
82
|
-
const queueDefinition = {
|
|
83
|
-
id,
|
|
84
|
-
message: definition.message
|
|
65
|
+
delete: (key) => Effect.gen(function* () {
|
|
66
|
+
const encodedKey = yield* encodeKey(key);
|
|
67
|
+
return yield* tryStorageSync("kv.delete", () => kv.delete(encodedKey));
|
|
68
|
+
}),
|
|
69
|
+
list: (options) => Effect.gen(function* () {
|
|
70
|
+
const entries = Array.from(yield* tryStorageSync("kv.list", () => kv.list(options)));
|
|
71
|
+
const decoded = [];
|
|
72
|
+
for (const [key, value] of entries) decoded.push([yield* decodeKey(key), yield* decodeValue(value)]);
|
|
73
|
+
return decoded;
|
|
74
|
+
})
|
|
85
75
|
};
|
|
86
|
-
return Object.assign(queueDefinition, { make: (layer, options) => make$7(layer, {
|
|
87
|
-
...options,
|
|
88
|
-
queue: wrapHandler$1(queueDefinition, options.queue)
|
|
89
|
-
}) });
|
|
90
|
-
};
|
|
91
|
-
const make$10 = (id, definition) => Tag$10()(id, definition);
|
|
92
|
-
const Tag$10 = () => (id, definition) => {
|
|
93
|
-
const queueDefinition = makeDefinition$4(id, definition);
|
|
94
|
-
const tag = Context.Service()(id);
|
|
95
|
-
const layer = (binding) => layer$9(tag, {
|
|
96
|
-
...binding,
|
|
97
|
-
message: definition.message
|
|
98
|
-
});
|
|
99
|
-
const send = Effect.fnUntraced(function* (message, options) {
|
|
100
|
-
yield* (yield* tag).send(message, options);
|
|
101
|
-
});
|
|
102
|
-
const sendBatch = Effect.fnUntraced(function* (messages, options) {
|
|
103
|
-
yield* (yield* tag).sendBatch(messages, options);
|
|
104
|
-
});
|
|
105
|
-
const metrics = Effect.fnUntraced(function* () {
|
|
106
|
-
return yield* (yield* tag).metrics();
|
|
107
|
-
});
|
|
108
|
-
const unsafeRaw = Effect.fnUntraced(function* () {
|
|
109
|
-
return yield* (yield* tag).unsafeRaw;
|
|
110
|
-
});
|
|
111
|
-
return Object.assign(tag, {
|
|
112
|
-
id: queueDefinition.id,
|
|
113
|
-
message: queueDefinition.message,
|
|
114
|
-
make: queueDefinition.make,
|
|
115
|
-
layer,
|
|
116
|
-
send,
|
|
117
|
-
sendBatch,
|
|
118
|
-
metrics,
|
|
119
|
-
unsafeRaw
|
|
120
|
-
});
|
|
121
76
|
};
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
};
|
|
129
|
-
const implement$7 = (_definition, handler) => handler;
|
|
130
|
-
//#endregion
|
|
131
|
-
//#region src/Queue.ts
|
|
132
|
-
var Queue_exports = /* @__PURE__ */ __exportAll({
|
|
133
|
-
QueueMessageDecodeError: () => QueueMessageDecodeError,
|
|
134
|
-
Tag: () => Tag$9,
|
|
135
|
-
decodeBatch: () => decodeBatch,
|
|
136
|
-
fromMessage: () => fromMessage,
|
|
137
|
-
fromMessageBatch: () => fromMessageBatch,
|
|
138
|
-
implement: () => implement$6
|
|
77
|
+
const fromSyncKvStorage = (kv) => ({
|
|
78
|
+
get: (key) => tryStorageSync("kv.get", () => kv.get(key)),
|
|
79
|
+
put: (key, value) => tryStorageSync("kv.put", () => kv.put(key, value)),
|
|
80
|
+
delete: (key) => tryStorageSync("kv.delete", () => kv.delete(key)),
|
|
81
|
+
list: (options) => tryStorageSync("kv.list", () => Array.from(kv.list(options))),
|
|
82
|
+
schema: (definition) => schemaBackedSyncKvStorage(kv, definition)
|
|
139
83
|
});
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
84
|
+
const fromDurableObjectTransaction = (txn) => ({
|
|
85
|
+
get: (keyOrKeys, options) => Array.isArray(keyOrKeys) ? tryStoragePromise("transaction.get", () => txn.get(keyOrKeys, options)) : tryStoragePromise("transaction.get", () => txn.get(keyOrKeys, options)),
|
|
86
|
+
list: (options) => tryStoragePromise("transaction.list", () => txn.list(options)),
|
|
87
|
+
put: (keyOrEntries, valueOrOptions, maybeOptions) => tryStoragePromise("transaction.put", () => typeof keyOrEntries === "string" ? txn.put(keyOrEntries, valueOrOptions, maybeOptions) : txn.put(keyOrEntries, valueOrOptions)),
|
|
88
|
+
delete: (keyOrKeys, options) => Array.isArray(keyOrKeys) ? tryStoragePromise("transaction.delete", () => txn.delete(keyOrKeys, options)) : tryStoragePromise("transaction.delete", () => txn.delete(keyOrKeys, options)),
|
|
89
|
+
rollback: () => tryStorageSync("transaction.rollback", () => txn.rollback()),
|
|
90
|
+
getAlarm: (options) => tryStoragePromise("transaction.getAlarm", () => txn.getAlarm(options)),
|
|
91
|
+
setAlarm: (scheduledTime, options) => tryStoragePromise("transaction.setAlarm", () => txn.setAlarm(scheduledTime, options)),
|
|
92
|
+
deleteAlarm: (options) => tryStoragePromise("transaction.deleteAlarm", () => txn.deleteAlarm(options))
|
|
149
93
|
});
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Wraps native Cloudflare storage APIs as Effect-returning helpers.
|
|
96
|
+
*/
|
|
97
|
+
const fromDurableObjectStorage = (storage) => ({
|
|
98
|
+
get: (key, options) => tryStoragePromise("get", () => storage.get(key, options)),
|
|
99
|
+
put: (key, value, options) => tryStoragePromise("put", () => storage.put(key, value, options)),
|
|
100
|
+
delete: (key, options) => tryStoragePromise("delete", () => storage.delete(key, options)),
|
|
101
|
+
deleteAll: (options) => tryStoragePromise("deleteAll", () => storage.deleteAll(options)),
|
|
102
|
+
getAlarm: (options) => tryStoragePromise("getAlarm", () => storage.getAlarm(options)),
|
|
103
|
+
setAlarm: (scheduledTime, options) => tryStoragePromise("setAlarm", () => storage.setAlarm(scheduledTime, options)),
|
|
104
|
+
deleteAlarm: (options) => tryStoragePromise("deleteAlarm", () => storage.deleteAlarm(options)),
|
|
105
|
+
transactionSync: (closure) => Effect.context().pipe(Effect.flatMap((context) => Effect.suspend(() => {
|
|
106
|
+
try {
|
|
107
|
+
return Effect.succeed(storage.transactionSync(() => {
|
|
108
|
+
const exit = Effect.runSyncExitWith(context)(closure());
|
|
109
|
+
if (Exit.isSuccess(exit)) return exit.value;
|
|
110
|
+
throw exit;
|
|
111
|
+
}));
|
|
112
|
+
} catch (cause) {
|
|
113
|
+
if (Exit.isExit(cause) && Exit.isFailure(cause)) return Effect.failCause(cause.cause);
|
|
114
|
+
return Effect.fail(storageError("transactionSync", cause));
|
|
115
|
+
}
|
|
116
|
+
}))),
|
|
117
|
+
transaction: (closure) => Effect.context().pipe(Effect.flatMap((context) => Effect.callback((resume) => {
|
|
118
|
+
storage.transaction(async (txn) => {
|
|
119
|
+
const exit = await Effect.runPromiseExitWith(context)(closure(fromDurableObjectTransaction(txn)));
|
|
120
|
+
if (Exit.isSuccess(exit)) return exit.value;
|
|
121
|
+
throw exit;
|
|
122
|
+
}).then((value) => resume(Effect.succeed(value)), (cause) => {
|
|
123
|
+
if (Exit.isExit(cause) && Exit.isFailure(cause)) resume(Effect.failCause(cause.cause));
|
|
124
|
+
else resume(Effect.fail(storageError("transaction", cause)));
|
|
125
|
+
});
|
|
126
|
+
}))),
|
|
127
|
+
sync: () => tryStoragePromise("sync", () => storage.sync()),
|
|
128
|
+
getCurrentBookmark: () => tryStoragePromise("getCurrentBookmark", () => storage.getCurrentBookmark()),
|
|
129
|
+
onNextSessionRestoreBookmark: (bookmark) => tryStoragePromise("onNextSessionRestoreBookmark", () => storage.onNextSessionRestoreBookmark(bookmark)),
|
|
130
|
+
sql: fromSqlStorage(storage.sql),
|
|
131
|
+
kv: fromSyncKvStorage(storage.kv)
|
|
157
132
|
});
|
|
158
|
-
const decodeBatch = (batch, decodeBody) => Effect.gen(function* () {
|
|
159
|
-
const messages = [];
|
|
160
|
-
for (let index = 0; index < batch.messages.length; index++) {
|
|
161
|
-
const message = batch.messages[index];
|
|
162
|
-
const body = yield* decodeBody(message.body).pipe(Effect.mapError((cause) => new QueueMessageDecodeError({
|
|
163
|
-
queue: batch.queue,
|
|
164
|
-
messageId: message.id,
|
|
165
|
-
index,
|
|
166
|
-
cause
|
|
167
|
-
})));
|
|
168
|
-
messages.push(fromMessage(message, body));
|
|
169
|
-
}
|
|
170
|
-
return fromMessageBatch(batch, messages);
|
|
171
|
-
});
|
|
172
|
-
const Tag$9 = Tag$10;
|
|
173
|
-
const implement$6 = implement$7;
|
|
174
133
|
//#endregion
|
|
175
|
-
//#region src/
|
|
176
|
-
var
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
assertNoReservedMethodNames: () => assertNoReservedMethodNames,
|
|
185
|
-
assertNoReservedMethods: () => assertNoReservedMethods,
|
|
186
|
-
decodeArgs: () => decodeArgs,
|
|
187
|
-
decodeSuccess: () => decodeSuccess,
|
|
188
|
-
encodeArgs: () => encodeArgs,
|
|
189
|
-
encodeSuccess: () => encodeSuccess,
|
|
190
|
-
make: () => make$9,
|
|
191
|
-
method: () => method$4,
|
|
192
|
-
reservedMethodNames: () => reservedMethodNames$4
|
|
134
|
+
//#region src/DurableObjectWebSocket.ts
|
|
135
|
+
var DurableObjectWebSocket_exports = /* @__PURE__ */ __exportAll({
|
|
136
|
+
DurableWebSocketAttachmentError: () => DurableWebSocketAttachmentError,
|
|
137
|
+
DurableWebSocketCloseError: () => DurableWebSocketCloseError,
|
|
138
|
+
DurableWebSocketSendError: () => DurableWebSocketSendError,
|
|
139
|
+
acceptUpgrade: () => acceptUpgrade,
|
|
140
|
+
attachment: () => attachment,
|
|
141
|
+
fromWebSocket: () => fromWebSocket,
|
|
142
|
+
handlers: () => handlers
|
|
193
143
|
});
|
|
194
|
-
|
|
195
|
-
var
|
|
196
|
-
|
|
197
|
-
var
|
|
198
|
-
|
|
199
|
-
var
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
144
|
+
/** Error raised when sending on a Durable Object websocket fails. */
|
|
145
|
+
var DurableWebSocketSendError = class extends Data.TaggedError("DurableWebSocketSendError") {};
|
|
146
|
+
/** Error raised when closing a Durable Object websocket fails. */
|
|
147
|
+
var DurableWebSocketCloseError = class extends Data.TaggedError("DurableWebSocketCloseError") {};
|
|
148
|
+
/** Error raised when serializing or deserializing a websocket attachment fails. */
|
|
149
|
+
var DurableWebSocketAttachmentError = class extends Data.TaggedError("DurableWebSocketAttachmentError") {};
|
|
150
|
+
const wrappers = /* @__PURE__ */ new WeakMap();
|
|
151
|
+
/** Wraps a native Cloudflare websocket in the Effect-native Durable Object API. */
|
|
152
|
+
const fromWebSocket = (raw) => {
|
|
153
|
+
const existing = wrappers.get(raw);
|
|
154
|
+
if (existing !== void 0) return existing;
|
|
155
|
+
const socket = {
|
|
156
|
+
raw,
|
|
157
|
+
send: (data) => Effect.try({
|
|
158
|
+
try: () => raw.send(data),
|
|
159
|
+
catch: (cause) => new DurableWebSocketSendError({ cause })
|
|
160
|
+
}),
|
|
161
|
+
close: (code, reason) => Effect.try({
|
|
162
|
+
try: () => raw.close(code, reason),
|
|
163
|
+
catch: (cause) => new DurableWebSocketCloseError({ cause })
|
|
164
|
+
}),
|
|
165
|
+
serializeAttachment: (value) => Effect.try({
|
|
166
|
+
try: () => raw.serializeAttachment(value),
|
|
167
|
+
catch: (cause) => new DurableWebSocketAttachmentError({
|
|
168
|
+
operation: "serialize",
|
|
169
|
+
cause
|
|
170
|
+
})
|
|
171
|
+
}),
|
|
172
|
+
deserializeAttachment: Effect.try({
|
|
173
|
+
try: () => raw.deserializeAttachment(),
|
|
174
|
+
catch: (cause) => new DurableWebSocketAttachmentError({
|
|
175
|
+
operation: "deserialize",
|
|
176
|
+
cause
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
};
|
|
180
|
+
wrappers.set(raw, socket);
|
|
181
|
+
return socket;
|
|
226
182
|
};
|
|
227
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Accepts a websocket upgrade and registers the server socket on `DurableObjectState`.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```ts
|
|
188
|
+
* const response = yield* DurableObjectWebSocket.acceptUpgrade({
|
|
189
|
+
* tags: ["room:general"],
|
|
190
|
+
* });
|
|
191
|
+
*
|
|
192
|
+
* return response.response;
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
const acceptUpgrade = (options = {}) => Effect.gen(function* () {
|
|
196
|
+
const state = yield* DurableObjectState;
|
|
197
|
+
const pair = new WebSocketPair();
|
|
198
|
+
const client = pair[0];
|
|
199
|
+
const server = fromWebSocket(pair[1]);
|
|
200
|
+
if (options.attachment !== void 0) server.raw.serializeAttachment(options.attachment);
|
|
201
|
+
yield* state.acceptWebSocket(server, options.tags === void 0 ? void 0 : [...options.tags]);
|
|
228
202
|
return {
|
|
229
|
-
|
|
230
|
-
|
|
203
|
+
client,
|
|
204
|
+
server,
|
|
205
|
+
response: new Response(null, {
|
|
206
|
+
status: 101,
|
|
207
|
+
webSocket: client
|
|
208
|
+
})
|
|
231
209
|
};
|
|
232
|
-
}
|
|
233
|
-
const assertNoReservedMethodNames = (definition) => Effect.forEach(Object.keys(definition.methods), (method) => reservedMethodNames$4.has(method) ? Effect.fail(new RpcReservedMethodNameError({
|
|
234
|
-
definition: definition.id,
|
|
235
|
-
method
|
|
236
|
-
})) : Effect.void).pipe(Effect.asVoid);
|
|
237
|
-
const decodeArgs = (definition, methodName, args) => Effect.gen(function* () {
|
|
238
|
-
const methodDefinition = definition.methods[methodName];
|
|
239
|
-
if (args.length !== methodDefinition.args.length) return yield* Effect.fail(new RpcArgumentCountError({
|
|
240
|
-
definition: definition.id,
|
|
241
|
-
method: methodName,
|
|
242
|
-
expected: methodDefinition.args.length,
|
|
243
|
-
actual: args.length
|
|
244
|
-
}));
|
|
245
|
-
const decoded = [];
|
|
246
|
-
for (let index = 0; index < methodDefinition.args.length; index++) {
|
|
247
|
-
const schema = methodDefinition.args[index];
|
|
248
|
-
decoded.push(yield* Schema.decodeUnknownEffect(schema)(args[index]).pipe(Effect.mapError((cause) => new RpcArgumentDecodeError({
|
|
249
|
-
definition: definition.id,
|
|
250
|
-
method: methodName,
|
|
251
|
-
index,
|
|
252
|
-
cause
|
|
253
|
-
}))));
|
|
254
|
-
}
|
|
255
|
-
return decoded;
|
|
256
210
|
});
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
encoded.push(yield* Schema.encodeEffect(schema)(args[index]).pipe(Effect.mapError((cause) => new RpcArgumentEncodeError({
|
|
269
|
-
definition: definition.id,
|
|
270
|
-
method: methodName,
|
|
271
|
-
index,
|
|
211
|
+
/** Creates typed attachment helpers for accepted and rehydrated sockets. */
|
|
212
|
+
const attachment = (schema) => {
|
|
213
|
+
const serialize = (socket, value) => Schema.encodeEffect(schema)(value).pipe(Effect.mapError((cause) => new DurableWebSocketAttachmentError({
|
|
214
|
+
operation: "serialize",
|
|
215
|
+
cause
|
|
216
|
+
})), Effect.flatMap((encoded) => socket.serializeAttachment(encoded)));
|
|
217
|
+
const deserialize = (socket) => Effect.gen(function* () {
|
|
218
|
+
const value = yield* socket.deserializeAttachment;
|
|
219
|
+
if (value == null) return Option.none();
|
|
220
|
+
return Option.some(yield* Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError((cause) => new DurableWebSocketAttachmentError({
|
|
221
|
+
operation: "deserialize",
|
|
272
222
|
cause
|
|
273
223
|
}))));
|
|
274
|
-
}
|
|
275
|
-
return encoded;
|
|
276
|
-
});
|
|
277
|
-
const encodeSuccess = (definition, methodName, value) => {
|
|
278
|
-
const methodDefinition = definition.methods[methodName];
|
|
279
|
-
return Schema.encodeEffect(methodDefinition.success)(value).pipe(Effect.mapError((cause) => new RpcSuccessEncodeError({
|
|
280
|
-
definition: definition.id,
|
|
281
|
-
method: methodName,
|
|
282
|
-
cause
|
|
283
|
-
})));
|
|
284
|
-
};
|
|
285
|
-
const decodeSuccess = (definition, methodName, value) => {
|
|
286
|
-
const methodDefinition = definition.methods[methodName];
|
|
287
|
-
return Schema.decodeUnknownEffect(methodDefinition.success)(value).pipe(Effect.mapError((cause) => new RpcSuccessDecodeError({
|
|
288
|
-
definition: definition.id,
|
|
289
|
-
method: methodName,
|
|
290
|
-
cause
|
|
291
|
-
})));
|
|
292
|
-
};
|
|
293
|
-
const make$9 = (id, methods) => {
|
|
294
|
-
const definition = {
|
|
295
|
-
id,
|
|
296
|
-
methods
|
|
297
|
-
};
|
|
298
|
-
const reserved = Object.keys(definition.methods).find((methodName) => reservedMethodNames$4.has(methodName));
|
|
299
|
-
if (reserved !== void 0) throw new RpcReservedMethodNameError({
|
|
300
|
-
definition: id,
|
|
301
|
-
method: reserved
|
|
302
224
|
});
|
|
303
|
-
|
|
225
|
+
const rehydrate = (options = {}) => Effect.gen(function* () {
|
|
226
|
+
const sockets = yield* (yield* DurableObjectState).getWebSockets(options.tag);
|
|
227
|
+
const restored = [];
|
|
228
|
+
const onInvalid = options.onInvalid ?? "ignore";
|
|
229
|
+
for (const socket of sockets) {
|
|
230
|
+
const decoded = yield* deserialize(socket).pipe(Effect.match({
|
|
231
|
+
onFailure: (error) => ({
|
|
232
|
+
_tag: "Failure",
|
|
233
|
+
error
|
|
234
|
+
}),
|
|
235
|
+
onSuccess: (value) => ({
|
|
236
|
+
_tag: "Success",
|
|
237
|
+
value
|
|
238
|
+
})
|
|
239
|
+
}));
|
|
240
|
+
if (decoded._tag === "Success" && Option.isSome(decoded.value)) {
|
|
241
|
+
restored.push({
|
|
242
|
+
socket,
|
|
243
|
+
attachment: decoded.value.value
|
|
244
|
+
});
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (decoded._tag === "Failure" && onInvalid === "fail") return yield* Effect.fail(decoded.error);
|
|
248
|
+
if (decoded._tag === "Failure" && onInvalid === "ignore-and-close") yield* socket.close(1008, "invalid websocket attachment").pipe(Effect.ignore);
|
|
249
|
+
}
|
|
250
|
+
return restored;
|
|
251
|
+
});
|
|
252
|
+
return {
|
|
253
|
+
serialize,
|
|
254
|
+
deserialize,
|
|
255
|
+
rehydrate,
|
|
256
|
+
schema
|
|
257
|
+
};
|
|
304
258
|
};
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
dispose: () => dispose,
|
|
311
|
-
isDisposable: () => isDisposable,
|
|
312
|
-
resolve: () => resolve,
|
|
313
|
-
scoped: () => scoped
|
|
314
|
-
});
|
|
315
|
-
const isDisposable = (value) => (typeof value === "object" || typeof value === "function") && value !== null && Symbol.dispose in value && typeof value[Symbol.dispose] === "function";
|
|
316
|
-
const dispose = (value) => Effect.sync(() => {
|
|
317
|
-
if (isDisposable(value)) value[Symbol.dispose]();
|
|
318
|
-
});
|
|
319
|
-
const resolve = (value) => isPromiseLike(value) ? Effect.tryPromise({
|
|
320
|
-
try: () => value,
|
|
321
|
-
catch: (cause) => cause
|
|
322
|
-
}) : Effect.sync(() => value);
|
|
323
|
-
const scoped = (value) => Effect.acquireRelease(resolve(value), (resolved) => dispose(resolved));
|
|
324
|
-
const isPromiseLike = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
325
|
-
//#endregion
|
|
326
|
-
//#region src/internal/RpcInvocation.ts
|
|
327
|
-
const isPropertyTarget = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
|
|
328
|
-
const lookupRpcMethod = (target, method, makeError) => Effect.try({
|
|
329
|
-
try: () => {
|
|
330
|
-
if (!isPropertyTarget(target)) throw new TypeError(`RPC target is not object-like`);
|
|
331
|
-
const value = Reflect.get(target, method);
|
|
332
|
-
if (typeof value !== "function") throw new TypeError(`RPC method "${String(method)}" is not callable`);
|
|
333
|
-
return ((...args) => Reflect.apply(value, target, args));
|
|
334
|
-
},
|
|
335
|
-
catch: makeError
|
|
336
|
-
});
|
|
337
|
-
const invokeRpcMethod = (target, method, args, makeError) => Effect.gen(function* () {
|
|
338
|
-
const fn = yield* lookupRpcMethod(target, method, makeError);
|
|
339
|
-
return yield* Effect.try({
|
|
340
|
-
try: () => fn(...args),
|
|
341
|
-
catch: makeError
|
|
342
|
-
});
|
|
259
|
+
/** Maps compact websocket lifecycle handler names to `DurableObject.make` options. */
|
|
260
|
+
const handlers = (options) => ({
|
|
261
|
+
webSocketMessage: options.message,
|
|
262
|
+
webSocketClose: options.close,
|
|
263
|
+
webSocketError: options.error
|
|
343
264
|
});
|
|
344
265
|
//#endregion
|
|
345
|
-
//#region src/
|
|
346
|
-
var
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
ServiceBindingRpcError: () => ServiceBindingRpcError,
|
|
350
|
-
isServiceBindingClient: () => isServiceBindingClient,
|
|
351
|
-
layer: () => layer$8,
|
|
352
|
-
makeClient: () => makeClient$5,
|
|
353
|
-
makeDirectMethods: () => makeDirectMethods$1
|
|
266
|
+
//#region src/DurableObjectState.ts
|
|
267
|
+
var DurableObjectState_exports = /* @__PURE__ */ __exportAll({
|
|
268
|
+
DurableObjectState: () => DurableObjectState,
|
|
269
|
+
fromDurableObjectState: () => fromDurableObjectState
|
|
354
270
|
});
|
|
355
|
-
const TypeId$2 = "effect-cf/ServiceBinding";
|
|
356
|
-
const expectedServiceBinding = "Worker service binding with fetch()";
|
|
357
271
|
/**
|
|
358
|
-
*
|
|
272
|
+
* Context tag for accessing the current Durable Object state service.
|
|
359
273
|
*/
|
|
360
|
-
var
|
|
274
|
+
var DurableObjectState = class extends Context.Service()("effect-cf/DurableObjectState") {};
|
|
361
275
|
/**
|
|
362
|
-
*
|
|
276
|
+
* Wraps a native Cloudflare `DurableObjectState` as a {@link DurableObjectStateService}.
|
|
363
277
|
*/
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}));
|
|
386
|
-
});
|
|
387
|
-
const decodeSuccess$2 = (methodName, value) => Effect.gen(function* () {
|
|
388
|
-
if (definition.definition === void 0) return value;
|
|
389
|
-
return yield* decodeSuccess(definition.definition, methodName, value).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
390
|
-
binding: definition.binding,
|
|
391
|
-
method: methodName,
|
|
392
|
-
cause
|
|
393
|
-
})));
|
|
394
|
-
});
|
|
395
|
-
const call = (method, ...args) => Effect.gen(function* () {
|
|
396
|
-
const methodName = String(method);
|
|
397
|
-
return yield* decodeSuccess$2(methodName, yield* resolve(yield* rpc(method, ...args)).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
398
|
-
binding: definition.binding,
|
|
399
|
-
method: methodName,
|
|
400
|
-
cause
|
|
401
|
-
}))));
|
|
402
|
-
});
|
|
403
|
-
const scopedCall = (method, ...args) => Effect.gen(function* () {
|
|
404
|
-
return yield* decodeSuccess$2(String(method), yield* scoped(yield* rpc(method, ...args)));
|
|
405
|
-
});
|
|
406
|
-
const directMethods = makeDirectMethods$1(definition.definition, call);
|
|
407
|
-
return Object.assign(directMethods, {
|
|
408
|
-
fetch,
|
|
409
|
-
rpc,
|
|
410
|
-
call,
|
|
411
|
-
scopedCall
|
|
412
|
-
});
|
|
413
|
-
};
|
|
278
|
+
const fromDurableObjectState = (state) => ({
|
|
279
|
+
raw: state,
|
|
280
|
+
id: state.id,
|
|
281
|
+
storage: fromDurableObjectStorage(state.storage),
|
|
282
|
+
waitUntil: (promise) => Effect.sync(() => state.waitUntil(promise)),
|
|
283
|
+
blockConcurrencyWhile: (effect) => Effect.context().pipe(Effect.flatMap((context) => Effect.promise(() => state.blockConcurrencyWhile(() => runPromiseExitPreservingTypedFailures(Effect.provideContext(effect, context))))), Effect.flatten),
|
|
284
|
+
blockConcurrencyWhileOrReset: (effect) => Effect.context().pipe(Effect.flatMap((context) => Effect.promise(() => state.blockConcurrencyWhile(() => Effect.runPromise(Effect.provideContext(effect, context)))))),
|
|
285
|
+
acceptWebSocket: (ws, tags) => Effect.sync(() => state.acceptWebSocket(ws.raw, tags)),
|
|
286
|
+
getWebSockets: (tag) => Effect.sync(() => state.getWebSockets(tag).map((socket) => fromWebSocket(socket))),
|
|
287
|
+
setWebSocketAutoResponse: (pair) => Effect.sync(() => state.setWebSocketAutoResponse(pair)),
|
|
288
|
+
getWebSocketAutoResponse: Effect.sync(() => state.getWebSocketAutoResponse()),
|
|
289
|
+
getWebSocketAutoResponseTimestamp: (ws) => Effect.sync(() => state.getWebSocketAutoResponseTimestamp(ws.raw)),
|
|
290
|
+
setHibernatableWebSocketEventTimeout: (timeoutMs) => Effect.sync(() => state.setHibernatableWebSocketEventTimeout(timeoutMs)),
|
|
291
|
+
getHibernatableWebSocketEventTimeout: Effect.sync(() => state.getHibernatableWebSocketEventTimeout()),
|
|
292
|
+
getTags: (ws) => Effect.sync(() => state.getTags(ws.raw)),
|
|
293
|
+
abort: (reason) => Effect.sync(() => state.abort(reason))
|
|
294
|
+
});
|
|
295
|
+
const runPromiseExitPreservingTypedFailures = async (effect) => {
|
|
296
|
+
const exit = await Effect.runPromiseExit(effect);
|
|
297
|
+
if (Exit.isFailure(exit) && (Cause.hasDies(exit.cause) || Cause.hasInterrupts(exit.cause))) throw Cause.squash(exit.cause);
|
|
298
|
+
return exit;
|
|
414
299
|
};
|
|
415
|
-
|
|
300
|
+
//#endregion
|
|
301
|
+
//#region src/CloudflareOtlp.ts
|
|
302
|
+
var CloudflareOtlp_exports = /* @__PURE__ */ __exportAll({
|
|
303
|
+
CloudflareOtlpSettings: () => CloudflareOtlpSettings,
|
|
304
|
+
durableObjectLayer: () => durableObjectLayer,
|
|
305
|
+
layer: () => layer$10,
|
|
306
|
+
layerJson: () => layerJson,
|
|
307
|
+
layerProtobuf: () => layerProtobuf,
|
|
308
|
+
settingsConfig: () => settingsConfig,
|
|
309
|
+
settingsLayer: () => settingsLayer,
|
|
310
|
+
workerLayer: () => workerLayer
|
|
311
|
+
});
|
|
416
312
|
/**
|
|
417
|
-
*
|
|
313
|
+
* Supported OpenTelemetry environment configuration for Cloudflare OTLP export.
|
|
418
314
|
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
* - `rpc(...)` for raw Cloudflare RPC results
|
|
423
|
-
* - `call(...)` for resolved and decoded RPC results
|
|
424
|
-
* - `scopedCall(...)` for scoped and decoded disposable RPC results
|
|
425
|
-
* - direct RPC methods when `definition` is provided
|
|
315
|
+
* This config intentionally uses the conventional `OTEL_*` variable names so
|
|
316
|
+
* deployments can share the same settings used by other OpenTelemetry SDKs.
|
|
317
|
+
* It covers the OTLP HTTP settings supported by the Effect OTLP layers:
|
|
426
318
|
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
319
|
+
* - `OTEL_EXPORTER_OTLP_ENDPOINT`
|
|
320
|
+
* - `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`
|
|
321
|
+
* - `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`
|
|
322
|
+
* - `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`
|
|
323
|
+
* - `OTEL_EXPORTER_OTLP_HEADERS`
|
|
324
|
+
* - `OTEL_EXPORTER_OTLP_LOGS_HEADERS`
|
|
325
|
+
* - `OTEL_EXPORTER_OTLP_TRACES_HEADERS`
|
|
326
|
+
* - `OTEL_EXPORTER_OTLP_METRICS_HEADERS`
|
|
327
|
+
* - `OTEL_SERVICE_NAME`
|
|
328
|
+
* - `OTEL_RESOURCE_ATTRIBUTES`
|
|
435
329
|
*
|
|
436
|
-
*
|
|
330
|
+
* `OTEL_SERVICE_VERSION` is also accepted as an effect-cf convenience alias.
|
|
331
|
+
* The standard OpenTelemetry way to configure service version is
|
|
332
|
+
* `OTEL_RESOURCE_ATTRIBUTES=service.version=...`.
|
|
437
333
|
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
* const next = yield* counter.increment(1);
|
|
441
|
-
* return next;
|
|
442
|
-
* });
|
|
443
|
-
* ```
|
|
334
|
+
* Consumers with non-standard binding names should map those names into
|
|
335
|
+
* {@link CloudflareOtlpSettings} rather than changing this config globally.
|
|
444
336
|
*/
|
|
445
|
-
const
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
return yield* (yield* tag).scopedCall(method, ...args);
|
|
458
|
-
});
|
|
459
|
-
const directMethods = makeDirectMethods$1(definition.definition, call);
|
|
460
|
-
return Object.assign(tag, directMethods, {
|
|
461
|
-
[TypeId$2]: TypeId$2,
|
|
462
|
-
definition,
|
|
463
|
-
fetch,
|
|
464
|
-
rpc,
|
|
465
|
-
call,
|
|
466
|
-
scopedCall
|
|
467
|
-
});
|
|
468
|
-
};
|
|
469
|
-
const makeDirectMethods$1 = (rpcDefinition, call) => {
|
|
470
|
-
const methods = {};
|
|
471
|
-
if (rpcDefinition !== void 0) for (const methodName of Object.keys(rpcDefinition.methods)) methods[methodName] = (...args) => call(methodName, ...args);
|
|
472
|
-
return methods;
|
|
473
|
-
};
|
|
474
|
-
//#endregion
|
|
475
|
-
//#region src/WorkerDefinition.ts
|
|
476
|
-
var WorkerDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
477
|
-
Tag: () => Tag$8,
|
|
478
|
-
Worker: () => Worker,
|
|
479
|
-
implement: () => implement$5,
|
|
480
|
-
make: () => make$8,
|
|
481
|
-
method: () => method$3
|
|
337
|
+
const settingsConfig = Config.all({
|
|
338
|
+
endpoint: Config.string("OTEL_EXPORTER_OTLP_ENDPOINT").pipe(Config.option),
|
|
339
|
+
logsEndpoint: Config.string("OTEL_EXPORTER_OTLP_LOGS_ENDPOINT").pipe(Config.option),
|
|
340
|
+
tracesEndpoint: Config.string("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT").pipe(Config.option),
|
|
341
|
+
metricsEndpoint: Config.string("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT").pipe(Config.option),
|
|
342
|
+
headers: Config.string("OTEL_EXPORTER_OTLP_HEADERS").pipe(Config.option),
|
|
343
|
+
logsHeaders: Config.string("OTEL_EXPORTER_OTLP_LOGS_HEADERS").pipe(Config.option),
|
|
344
|
+
tracesHeaders: Config.string("OTEL_EXPORTER_OTLP_TRACES_HEADERS").pipe(Config.option),
|
|
345
|
+
metricsHeaders: Config.string("OTEL_EXPORTER_OTLP_METRICS_HEADERS").pipe(Config.option),
|
|
346
|
+
serviceName: Config.string("OTEL_SERVICE_NAME").pipe(Config.option),
|
|
347
|
+
serviceVersion: Config.string("OTEL_SERVICE_VERSION").pipe(Config.option),
|
|
348
|
+
resourceAttributes: Config.schema(Config.Record(Schema.String, Schema.String), "OTEL_RESOURCE_ATTRIBUTES").pipe(Config.option)
|
|
482
349
|
});
|
|
483
|
-
const reservedMethodNames$3 = new Set([
|
|
484
|
-
"constructor",
|
|
485
|
-
"dup",
|
|
486
|
-
"fetch",
|
|
487
|
-
"connect",
|
|
488
|
-
"queue",
|
|
489
|
-
"scheduled",
|
|
490
|
-
"tail",
|
|
491
|
-
"tailStream",
|
|
492
|
-
"test",
|
|
493
|
-
"trace",
|
|
494
|
-
"alarm",
|
|
495
|
-
"webSocketMessage",
|
|
496
|
-
"webSocketClose",
|
|
497
|
-
"webSocketError"
|
|
498
|
-
]);
|
|
499
|
-
/**
|
|
500
|
-
* Defines a single RPC method schema in a worker definition.
|
|
501
|
-
*/
|
|
502
|
-
const method$3 = method$4;
|
|
503
350
|
/**
|
|
504
|
-
*
|
|
351
|
+
* Service carrying already-resolved Cloudflare OTLP settings.
|
|
352
|
+
*
|
|
353
|
+
* Provide this service directly when an application needs to map custom
|
|
354
|
+
* Cloudflare binding names, compute settings dynamically, or override settings
|
|
355
|
+
* in tests. When this service is present, the OTLP layers use it instead of
|
|
356
|
+
* reading {@link settingsConfig}.
|
|
505
357
|
*
|
|
506
358
|
* @example
|
|
507
359
|
* ```ts
|
|
508
|
-
* const
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
const
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const scopedCall = (method, ...args) => Effect.gen(function* () {
|
|
543
|
-
return yield* (yield* tag).scopedCall(method, ...args);
|
|
544
|
-
});
|
|
545
|
-
const directMethods = makeDirectMethods$1(definition, call);
|
|
546
|
-
return Object.assign(tag, directMethods, {
|
|
547
|
-
id: definition.id,
|
|
548
|
-
methods: definition.methods,
|
|
549
|
-
make: definition.make,
|
|
550
|
-
layer,
|
|
551
|
-
fetch,
|
|
552
|
-
rpc,
|
|
553
|
-
call,
|
|
554
|
-
scopedCall
|
|
555
|
-
});
|
|
556
|
-
};
|
|
557
|
-
const Worker = Tag$8;
|
|
558
|
-
const wrapHandlers$1 = (definition, handlers) => {
|
|
559
|
-
const wrapped = {};
|
|
560
|
-
for (const key of Object.keys(definition.methods)) {
|
|
561
|
-
const handler = handlers[key];
|
|
562
|
-
wrapped[key] = (...args) => Effect.gen(function* () {
|
|
563
|
-
return yield* encodeSuccess(definition, key, yield* handler(...yield* decodeArgs(definition, key, args)));
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
return wrapped;
|
|
567
|
-
};
|
|
360
|
+
* const CustomOtlpSettings = Layer.effect(
|
|
361
|
+
* CloudflareOtlp.CloudflareOtlpSettings,
|
|
362
|
+
* Config.all({
|
|
363
|
+
* ...CloudflareOtlp.settingsConfig,
|
|
364
|
+
* endpoint: Config.string("MY_OTLP_ENDPOINT").pipe(Config.option),
|
|
365
|
+
* }),
|
|
366
|
+
* ).pipe(Layer.provide(WorkerConfig.layer));
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
var CloudflareOtlpSettings = class extends Context.Service()("effect-cf/CloudflareOtlpSettings") {};
|
|
370
|
+
const allSignals = [
|
|
371
|
+
"logs",
|
|
372
|
+
"traces",
|
|
373
|
+
"metrics"
|
|
374
|
+
];
|
|
375
|
+
const optionToUndefined = (option) => Option.isSome(option) ? option.value : void 0;
|
|
376
|
+
const nonEmptyStringOption = (option) => Option.flatMap(option, (value) => {
|
|
377
|
+
const trimmed = value.trim();
|
|
378
|
+
return trimmed === "" ? Option.none() : Option.some(trimmed);
|
|
379
|
+
});
|
|
380
|
+
const nonEmptyRecordOption = (option) => Option.filter(option, (value) => Object.keys(value).length > 0);
|
|
381
|
+
const normalizeSettings = (settings) => ({
|
|
382
|
+
endpoint: nonEmptyStringOption(settings.endpoint),
|
|
383
|
+
logsEndpoint: nonEmptyStringOption(settings.logsEndpoint),
|
|
384
|
+
tracesEndpoint: nonEmptyStringOption(settings.tracesEndpoint),
|
|
385
|
+
metricsEndpoint: nonEmptyStringOption(settings.metricsEndpoint),
|
|
386
|
+
headers: nonEmptyStringOption(settings.headers),
|
|
387
|
+
logsHeaders: nonEmptyStringOption(settings.logsHeaders),
|
|
388
|
+
tracesHeaders: nonEmptyStringOption(settings.tracesHeaders),
|
|
389
|
+
metricsHeaders: nonEmptyStringOption(settings.metricsHeaders),
|
|
390
|
+
serviceName: nonEmptyStringOption(settings.serviceName),
|
|
391
|
+
serviceVersion: nonEmptyStringOption(settings.serviceVersion),
|
|
392
|
+
resourceAttributes: nonEmptyRecordOption(settings.resourceAttributes)
|
|
393
|
+
});
|
|
568
394
|
/**
|
|
569
|
-
*
|
|
395
|
+
* Layer that reads standard OpenTelemetry settings from the current Cloudflare
|
|
396
|
+
* `env` object.
|
|
397
|
+
*
|
|
398
|
+
* The layer depends on {@link WorkerEnvironment} and installs a
|
|
399
|
+
* Cloudflare-backed Effect `ConfigProvider`, so `settingsConfig` reads from
|
|
400
|
+
* Worker vars/secrets instead of Node process environment variables.
|
|
570
401
|
*/
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
const
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
assertNoReservedMethods(target, methods, reservedMethodNames);
|
|
578
|
-
for (const [key, method] of Object.entries(methods)) Object.defineProperty(prototype, key, {
|
|
579
|
-
enumerable: true,
|
|
580
|
-
value(...args) {
|
|
581
|
-
return run(this, Effect.suspend(() => method(...args)));
|
|
582
|
-
}
|
|
583
|
-
});
|
|
402
|
+
const settingsLayer = Layer.effect(CloudflareOtlpSettings, settingsConfig.pipe(Config.map(normalizeSettings))).pipe(Layer.provide(WorkerConfig.layer));
|
|
403
|
+
const selectedSignals = (signals) => new Set(signals ?? allSignals);
|
|
404
|
+
const withDefinedAttributes = (attributes) => {
|
|
405
|
+
const out = {};
|
|
406
|
+
for (const [key, value] of Object.entries(attributes)) if (value !== void 0) out[key] = value;
|
|
407
|
+
return out;
|
|
584
408
|
};
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
409
|
+
const parseHeaders = (input) => {
|
|
410
|
+
if (Option.isNone(input) || input.value.trim() === "") return;
|
|
411
|
+
const headers = {};
|
|
412
|
+
for (const part of input.value.split(",")) {
|
|
413
|
+
const index = part.indexOf("=");
|
|
414
|
+
if (index <= 0) continue;
|
|
415
|
+
const key = part.slice(0, index).trim();
|
|
416
|
+
const value = part.slice(index + 1).trim();
|
|
417
|
+
if (key !== "") headers[decodeHeaderComponent(key)] = decodeHeaderComponent(value);
|
|
418
|
+
}
|
|
419
|
+
return headers;
|
|
420
|
+
};
|
|
421
|
+
const mergeHeaders = (common, signalSpecific) => {
|
|
422
|
+
const commonHeaders = parseHeaders(common);
|
|
423
|
+
const signalHeaders = parseHeaders(signalSpecific);
|
|
424
|
+
if (commonHeaders === void 0 && signalHeaders === void 0) return;
|
|
601
425
|
return {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
waitUntilPropagating: (effect, options) => schedule(effect, options, "propagate"),
|
|
605
|
-
passThroughOnException: Effect.sync(() => ctx.passThroughOnException())
|
|
426
|
+
...commonHeaders,
|
|
427
|
+
...signalHeaders
|
|
606
428
|
};
|
|
607
429
|
};
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
Tag: () => Tag$7,
|
|
614
|
-
WorkerContext: () => WorkerContext,
|
|
615
|
-
implement: () => implement$4,
|
|
616
|
-
isWebSocketUpgrade: () => isWebSocketUpgrade,
|
|
617
|
-
make: () => make$7,
|
|
618
|
-
makeFetchHandler: () => makeFetchHandler,
|
|
619
|
-
method: () => method$2,
|
|
620
|
-
renderHttpResponse: () => renderHttpResponse
|
|
621
|
-
});
|
|
622
|
-
var ExecutionContext = class extends Context.Service()("effect-cf/ExecutionContext") {};
|
|
623
|
-
var WorkerContext = class extends Context.Service()("effect-cf/WorkerContext") {};
|
|
624
|
-
var NativeRequest = class extends Context.Service()("effect-cf/NativeRequest") {};
|
|
625
|
-
const isWebSocketUpgrade = (request) => request.headers.get("Upgrade")?.toLowerCase() === "websocket";
|
|
626
|
-
const reservedMethodNames$2 = new Set([
|
|
627
|
-
"constructor",
|
|
628
|
-
"dup",
|
|
629
|
-
"fetch",
|
|
630
|
-
"connect",
|
|
631
|
-
"queue",
|
|
632
|
-
"scheduled",
|
|
633
|
-
"tail",
|
|
634
|
-
"tailStream",
|
|
635
|
-
"test",
|
|
636
|
-
"trace",
|
|
637
|
-
"alarm",
|
|
638
|
-
"webSocketMessage",
|
|
639
|
-
"webSocketClose",
|
|
640
|
-
"webSocketError"
|
|
641
|
-
]);
|
|
642
|
-
const RunSymbol$1 = Symbol.for("effect-cf/Worker/run");
|
|
643
|
-
const renderHttpResponse = (effect) => Effect.flatMap(effect, (response) => Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
|
|
644
|
-
const renderFetchSuccess = (effect) => Effect.flatMap(effect, (response) => response instanceof Response ? Effect.succeed(response) : Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
|
|
645
|
-
const isWorkerOptions = (options) => typeof options === "object" && options !== null && ("fetch" in options || "queue" in options || "rpc" in options);
|
|
646
|
-
function make$7(layer, optionsOrFetch) {
|
|
647
|
-
const options = isWorkerOptions(optionsOrFetch) ? optionsOrFetch : { fetch: optionsOrFetch };
|
|
648
|
-
class EffectWorker extends WorkerEntrypoint {
|
|
649
|
-
runtime;
|
|
650
|
-
constructor(ctx, env) {
|
|
651
|
-
super(ctx, env);
|
|
652
|
-
let runWaitUntilEffect = () => Promise.reject(/* @__PURE__ */ new Error("WorkerContext runtime is not initialized"));
|
|
653
|
-
const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(Layer.succeed(ExecutionContext, ctx), ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(WorkerContext, fromExecutionContext(ctx, (effect) => runWaitUntilEffect(effect))), Layer.succeed(WorkerEnvironment, env)));
|
|
654
|
-
this.runtime = ManagedRuntime.make(runtimeLayer);
|
|
655
|
-
runWaitUntilEffect = (effect) => this.runtime.runPromiseExit(effect);
|
|
656
|
-
}
|
|
657
|
-
[RunSymbol$1](effect) {
|
|
658
|
-
return this.runtime.runPromise(Effect.scoped(effect));
|
|
659
|
-
}
|
|
660
|
-
fetch(request) {
|
|
661
|
-
const fetchHandler = options.fetch;
|
|
662
|
-
if (fetchHandler === void 0) return Promise.resolve(new Response("Not Found", { status: 404 }));
|
|
663
|
-
const requestServices = Layer.mergeAll(Layer.succeed(NativeRequest, request), Layer.succeed(HttpServerRequest.HttpServerRequest, HttpServerRequest.fromWeb(request)));
|
|
664
|
-
return this[RunSymbol$1](renderFetchSuccess(fetchHandler).pipe(Effect.provide(requestServices)));
|
|
665
|
-
}
|
|
666
|
-
queue(batch) {
|
|
667
|
-
const queueHandler = options.queue;
|
|
668
|
-
if (queueHandler === void 0) return Promise.resolve();
|
|
669
|
-
const messages = batch.messages.map((message) => fromMessage(message, message.body));
|
|
670
|
-
return this[RunSymbol$1](queueHandler(fromMessageBatch(batch, messages)));
|
|
671
|
-
}
|
|
430
|
+
const decodeHeaderComponent = (value) => {
|
|
431
|
+
try {
|
|
432
|
+
return decodeURIComponent(value);
|
|
433
|
+
} catch {
|
|
434
|
+
return value;
|
|
672
435
|
}
|
|
673
|
-
defineEntrypointRpcMethods("Worker", EffectWorker.prototype, options.rpc, reservedMethodNames$2, (self, effect) => self[RunSymbol$1](effect));
|
|
674
|
-
return assumeEntrypointClass(EffectWorker);
|
|
675
|
-
}
|
|
676
|
-
const makeFetchHandler = (layer, options) => {
|
|
677
|
-
const WorkerClass = make$7(layer, options);
|
|
678
|
-
return { fetch: (request, env, ctx) => Promise.resolve(new WorkerClass(ctx, env).fetch(request)) };
|
|
679
436
|
};
|
|
680
|
-
const
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
}
|
|
689
|
-
/** Error type used when a storage operation throws or rejects. */
|
|
690
|
-
var StorageOperationError = class extends Data.TaggedError("StorageOperationError") {};
|
|
691
|
-
const storageError = (operation, cause) => new StorageOperationError({
|
|
692
|
-
operation,
|
|
693
|
-
cause
|
|
437
|
+
const appendOtlpPath = (baseUrl, path) => `${baseUrl.replace(/\/+$/, "")}${path}`;
|
|
438
|
+
const makeResource = (settings, options, runtimeAttributes) => ({
|
|
439
|
+
serviceName: options.serviceName ?? optionToUndefined(settings.serviceName),
|
|
440
|
+
serviceVersion: options.serviceVersion ?? optionToUndefined(settings.serviceVersion),
|
|
441
|
+
attributes: {
|
|
442
|
+
...optionToUndefined(settings.resourceAttributes),
|
|
443
|
+
...withDefinedAttributes(runtimeAttributes),
|
|
444
|
+
...options.attributes
|
|
445
|
+
}
|
|
694
446
|
});
|
|
695
|
-
const
|
|
696
|
-
|
|
697
|
-
|
|
447
|
+
const commonOtlpOptions = (settings, options, runtimeAttributes) => ({
|
|
448
|
+
resource: makeResource(settings, options, runtimeAttributes),
|
|
449
|
+
maxBatchSize: options.maxBatchSize,
|
|
450
|
+
loggerExportInterval: options.loggerExportInterval,
|
|
451
|
+
loggerExcludeLogSpans: options.loggerExcludeLogSpans,
|
|
452
|
+
loggerMergeWithExisting: options.loggerMergeWithExisting,
|
|
453
|
+
tracerExportInterval: options.tracerExportInterval,
|
|
454
|
+
tracerContext: options.tracerContext,
|
|
455
|
+
metricsExportInterval: options.metricsExportInterval,
|
|
456
|
+
metricsTemporality: options.metricsTemporality,
|
|
457
|
+
shutdownTimeout: options.shutdownTimeout
|
|
698
458
|
});
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
const
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
one: () => tryStorageSync("sql.one", () => cursor.one()),
|
|
707
|
-
raw: () => tryStorageSync("sql.raw", () => cursor.raw()),
|
|
708
|
-
get columnNames() {
|
|
709
|
-
return cursor.columnNames;
|
|
710
|
-
},
|
|
711
|
-
rowsRead: tryStorageSync("sql.rowsRead", () => cursor.rowsRead),
|
|
712
|
-
rowsWritten: tryStorageSync("sql.rowsWritten", () => cursor.rowsWritten)
|
|
713
|
-
});
|
|
714
|
-
const fromSqlStorage = (sql) => ({
|
|
715
|
-
exec: (query, ...bindings) => tryStorageSync("sql.exec", () => fromSqlCursor(sql.exec(query, ...bindings))),
|
|
716
|
-
get databaseSize() {
|
|
717
|
-
return sql.databaseSize;
|
|
718
|
-
}
|
|
459
|
+
const serializationLayer = (serialization) => serialization === "json" ? OtlpSerialization.layerJson : OtlpSerialization.layerProtobuf;
|
|
460
|
+
const resolveSettings = Effect.gen(function* () {
|
|
461
|
+
const settings = yield* Effect.serviceOption(CloudflareOtlpSettings);
|
|
462
|
+
if (Option.isSome(settings)) return normalizeSettings(settings.value);
|
|
463
|
+
const env = yield* Effect.serviceOption(WorkerEnvironment);
|
|
464
|
+
if (Option.isSome(env)) return normalizeSettings(yield* settingsConfig.pipe(Effect.provide(ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env.value))))));
|
|
465
|
+
return normalizeSettings(yield* settingsConfig);
|
|
719
466
|
});
|
|
720
|
-
const
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
return {
|
|
726
|
-
get: (key) => Effect.gen(function* () {
|
|
727
|
-
const encodedKey = yield* encodeKey(key);
|
|
728
|
-
const encodedValue = yield* tryStorageSync("kv.get", () => kv.get(encodedKey));
|
|
729
|
-
if (encodedValue === void 0) return Option.none();
|
|
730
|
-
return yield* decodeValue(encodedValue).pipe(Effect.map(Option.some));
|
|
731
|
-
}),
|
|
732
|
-
put: (key, value) => Effect.gen(function* () {
|
|
733
|
-
const encodedKey = yield* encodeKey(key);
|
|
734
|
-
const encodedValue = yield* encodeValue(value);
|
|
735
|
-
yield* tryStorageSync("kv.put", () => kv.put(encodedKey, encodedValue));
|
|
736
|
-
}),
|
|
737
|
-
delete: (key) => Effect.gen(function* () {
|
|
738
|
-
const encodedKey = yield* encodeKey(key);
|
|
739
|
-
return yield* tryStorageSync("kv.delete", () => kv.delete(encodedKey));
|
|
740
|
-
}),
|
|
741
|
-
list: (options) => Effect.gen(function* () {
|
|
742
|
-
const entries = Array.from(yield* tryStorageSync("kv.list", () => kv.list(options)));
|
|
743
|
-
const decoded = [];
|
|
744
|
-
for (const [key, value] of entries) decoded.push([yield* decodeKey(key), yield* decodeValue(value)]);
|
|
745
|
-
return decoded;
|
|
746
|
-
})
|
|
747
|
-
};
|
|
467
|
+
const mergeSignalLayers = (layers) => {
|
|
468
|
+
if (layers.length === 0) return Layer.empty;
|
|
469
|
+
let merged = layers[0];
|
|
470
|
+
for (let index = 1; index < layers.length; index++) merged = Layer.mergeAll(merged, layers[index]);
|
|
471
|
+
return merged;
|
|
748
472
|
};
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
473
|
+
const emptyLayer = Layer.empty;
|
|
474
|
+
const makeLayerFromSettings = (options = {}, runtimeAttributes = {}) => Layer.unwrap(Effect.map(resolveSettings, (settings) => {
|
|
475
|
+
const signals = selectedSignals(options.signals);
|
|
476
|
+
const endpoint = optionToUndefined(settings.endpoint);
|
|
477
|
+
const logsEndpoint = optionToUndefined(settings.logsEndpoint);
|
|
478
|
+
const tracesEndpoint = optionToUndefined(settings.tracesEndpoint);
|
|
479
|
+
const metricsEndpoint = optionToUndefined(settings.metricsEndpoint);
|
|
480
|
+
const hasSpecificEndpoint = logsEndpoint !== void 0 || tracesEndpoint !== void 0 || metricsEndpoint !== void 0;
|
|
481
|
+
const hasSpecificHeaders = Option.isSome(settings.logsHeaders) || Option.isSome(settings.tracesHeaders) || Option.isSome(settings.metricsHeaders);
|
|
482
|
+
const common = commonOtlpOptions(settings, options, runtimeAttributes);
|
|
483
|
+
if (endpoint !== void 0 && !hasSpecificEndpoint && !hasSpecificHeaders && signals.size === 3) return Otlp.layer({
|
|
484
|
+
baseUrl: endpoint,
|
|
485
|
+
headers: parseHeaders(settings.headers),
|
|
486
|
+
...common
|
|
487
|
+
}).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer));
|
|
488
|
+
const layers = [];
|
|
489
|
+
if (signals.has("logs")) {
|
|
490
|
+
const url = logsEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/logs"));
|
|
491
|
+
if (url !== void 0) layers.push(OtlpLogger.layer({
|
|
492
|
+
url,
|
|
493
|
+
resource: common.resource,
|
|
494
|
+
headers: mergeHeaders(settings.headers, settings.logsHeaders),
|
|
495
|
+
exportInterval: common.loggerExportInterval,
|
|
496
|
+
maxBatchSize: common.maxBatchSize,
|
|
497
|
+
shutdownTimeout: common.shutdownTimeout,
|
|
498
|
+
excludeLogSpans: common.loggerExcludeLogSpans,
|
|
499
|
+
mergeWithExisting: common.loggerMergeWithExisting
|
|
500
|
+
}).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
|
|
501
|
+
}
|
|
502
|
+
if (signals.has("traces")) {
|
|
503
|
+
const url = tracesEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/traces"));
|
|
504
|
+
if (url !== void 0) layers.push(OtlpTracer.layer({
|
|
505
|
+
url,
|
|
506
|
+
resource: common.resource,
|
|
507
|
+
headers: mergeHeaders(settings.headers, settings.tracesHeaders),
|
|
508
|
+
exportInterval: common.tracerExportInterval,
|
|
509
|
+
maxBatchSize: common.maxBatchSize,
|
|
510
|
+
context: common.tracerContext,
|
|
511
|
+
shutdownTimeout: common.shutdownTimeout
|
|
512
|
+
}).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
|
|
513
|
+
}
|
|
514
|
+
if (signals.has("metrics")) {
|
|
515
|
+
const url = metricsEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/metrics"));
|
|
516
|
+
if (url !== void 0) layers.push(OtlpMetrics.layer({
|
|
517
|
+
url,
|
|
518
|
+
resource: common.resource,
|
|
519
|
+
headers: mergeHeaders(settings.headers, settings.metricsHeaders),
|
|
520
|
+
exportInterval: common.metricsExportInterval,
|
|
521
|
+
shutdownTimeout: common.shutdownTimeout,
|
|
522
|
+
temporality: common.metricsTemporality
|
|
523
|
+
}).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
|
|
524
|
+
}
|
|
525
|
+
return mergeSignalLayers(layers);
|
|
526
|
+
}).pipe(Effect.catch((error) => Effect.logWarning("CloudflareOtlp disabled because OTLP configuration is invalid", { error: String(error) }).pipe(Effect.as(emptyLayer)))));
|
|
527
|
+
const makeLayer = (options = {}, runtimeAttributes = {}) => makeLayerFromSettings(options, runtimeAttributes);
|
|
766
528
|
/**
|
|
767
|
-
*
|
|
529
|
+
* Base OTLP telemetry layer for Cloudflare-compatible runtimes.
|
|
530
|
+
*
|
|
531
|
+
* The layer reads {@link CloudflareOtlpSettings} when provided. Otherwise it
|
|
532
|
+
* reads standard OpenTelemetry config from `WorkerEnvironment` when available,
|
|
533
|
+
* then falls back to the ambient Effect `ConfigProvider`.
|
|
534
|
+
*
|
|
535
|
+
* When only `OTEL_EXPORTER_OTLP_ENDPOINT` is configured, per-signal paths are
|
|
536
|
+
* derived by appending `/v1/logs`, `/v1/traces`, and `/v1/metrics`. Signal
|
|
537
|
+
* specific endpoints are used as-is, matching the OpenTelemetry OTLP exporter
|
|
538
|
+
* convention.
|
|
768
539
|
*/
|
|
769
|
-
const
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
getAlarm: (options) => tryStoragePromise("getAlarm", () => storage.getAlarm(options)),
|
|
775
|
-
setAlarm: (scheduledTime, options) => tryStoragePromise("setAlarm", () => storage.setAlarm(scheduledTime, options)),
|
|
776
|
-
deleteAlarm: (options) => tryStoragePromise("deleteAlarm", () => storage.deleteAlarm(options)),
|
|
777
|
-
transactionSync: (closure) => Effect.context().pipe(Effect.flatMap((context) => Effect.suspend(() => {
|
|
778
|
-
try {
|
|
779
|
-
return Effect.succeed(storage.transactionSync(() => {
|
|
780
|
-
const exit = Effect.runSyncExitWith(context)(closure());
|
|
781
|
-
if (Exit.isSuccess(exit)) return exit.value;
|
|
782
|
-
throw exit;
|
|
783
|
-
}));
|
|
784
|
-
} catch (cause) {
|
|
785
|
-
if (Exit.isExit(cause) && Exit.isFailure(cause)) return Effect.failCause(cause.cause);
|
|
786
|
-
return Effect.fail(storageError("transactionSync", cause));
|
|
787
|
-
}
|
|
788
|
-
}))),
|
|
789
|
-
transaction: (closure) => Effect.context().pipe(Effect.flatMap((context) => Effect.callback((resume) => {
|
|
790
|
-
storage.transaction(async (txn) => {
|
|
791
|
-
const exit = await Effect.runPromiseExitWith(context)(closure(fromDurableObjectTransaction(txn)));
|
|
792
|
-
if (Exit.isSuccess(exit)) return exit.value;
|
|
793
|
-
throw exit;
|
|
794
|
-
}).then((value) => resume(Effect.succeed(value)), (cause) => {
|
|
795
|
-
if (Exit.isExit(cause) && Exit.isFailure(cause)) resume(Effect.failCause(cause.cause));
|
|
796
|
-
else resume(Effect.fail(storageError("transaction", cause)));
|
|
797
|
-
});
|
|
798
|
-
}))),
|
|
799
|
-
sync: () => tryStoragePromise("sync", () => storage.sync()),
|
|
800
|
-
getCurrentBookmark: () => tryStoragePromise("getCurrentBookmark", () => storage.getCurrentBookmark()),
|
|
801
|
-
onNextSessionRestoreBookmark: (bookmark) => tryStoragePromise("onNextSessionRestoreBookmark", () => storage.onNextSessionRestoreBookmark(bookmark)),
|
|
802
|
-
sql: fromSqlStorage(storage.sql),
|
|
803
|
-
kv: fromSyncKvStorage(storage.kv)
|
|
540
|
+
const layer$10 = (options = {}) => makeLayer(options);
|
|
541
|
+
/** Base OTLP telemetry layer forced to JSON serialization. */
|
|
542
|
+
const layerJson = (options = {}) => layer$10({
|
|
543
|
+
...options,
|
|
544
|
+
serialization: "json"
|
|
804
545
|
});
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
DurableWebSocketCloseError: () => DurableWebSocketCloseError,
|
|
810
|
-
DurableWebSocketSendError: () => DurableWebSocketSendError,
|
|
811
|
-
acceptUpgrade: () => acceptUpgrade,
|
|
812
|
-
attachment: () => attachment,
|
|
813
|
-
fromWebSocket: () => fromWebSocket,
|
|
814
|
-
handlers: () => handlers
|
|
546
|
+
/** Base OTLP telemetry layer forced to protobuf serialization. */
|
|
547
|
+
const layerProtobuf = (options = {}) => layer$10({
|
|
548
|
+
...options,
|
|
549
|
+
serialization: "protobuf"
|
|
815
550
|
});
|
|
816
|
-
/** Error raised when sending on a Durable Object websocket fails. */
|
|
817
|
-
var DurableWebSocketSendError = class extends Data.TaggedError("DurableWebSocketSendError") {};
|
|
818
|
-
/** Error raised when closing a Durable Object websocket fails. */
|
|
819
|
-
var DurableWebSocketCloseError = class extends Data.TaggedError("DurableWebSocketCloseError") {};
|
|
820
|
-
/** Error raised when serializing or deserializing a websocket attachment fails. */
|
|
821
|
-
var DurableWebSocketAttachmentError = class extends Data.TaggedError("DurableWebSocketAttachmentError") {};
|
|
822
|
-
const wrappers = /* @__PURE__ */ new WeakMap();
|
|
823
|
-
/** Wraps a native Cloudflare websocket in the Effect-native Durable Object API. */
|
|
824
|
-
const fromWebSocket = (raw) => {
|
|
825
|
-
const existing = wrappers.get(raw);
|
|
826
|
-
if (existing !== void 0) return existing;
|
|
827
|
-
const socket = {
|
|
828
|
-
raw,
|
|
829
|
-
send: (data) => Effect.try({
|
|
830
|
-
try: () => raw.send(data),
|
|
831
|
-
catch: (cause) => new DurableWebSocketSendError({ cause })
|
|
832
|
-
}),
|
|
833
|
-
close: (code, reason) => Effect.try({
|
|
834
|
-
try: () => raw.close(code, reason),
|
|
835
|
-
catch: (cause) => new DurableWebSocketCloseError({ cause })
|
|
836
|
-
}),
|
|
837
|
-
serializeAttachment: (value) => Effect.try({
|
|
838
|
-
try: () => raw.serializeAttachment(value),
|
|
839
|
-
catch: (cause) => new DurableWebSocketAttachmentError({
|
|
840
|
-
operation: "serialize",
|
|
841
|
-
cause
|
|
842
|
-
})
|
|
843
|
-
}),
|
|
844
|
-
deserializeAttachment: Effect.try({
|
|
845
|
-
try: () => raw.deserializeAttachment(),
|
|
846
|
-
catch: (cause) => new DurableWebSocketAttachmentError({
|
|
847
|
-
operation: "deserialize",
|
|
848
|
-
cause
|
|
849
|
-
})
|
|
850
|
-
})
|
|
851
|
-
};
|
|
852
|
-
wrappers.set(raw, socket);
|
|
853
|
-
return socket;
|
|
854
|
-
};
|
|
855
551
|
/**
|
|
856
|
-
*
|
|
552
|
+
* OTLP layer with Cloudflare Worker resource attributes.
|
|
857
553
|
*
|
|
858
|
-
*
|
|
859
|
-
*
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
554
|
+
* Provide this layer at runtime scope for long-lived metrics aggregation, or at
|
|
555
|
+
* handler scope when traces/logs should flush as the Cloudflare event finishes.
|
|
556
|
+
*/
|
|
557
|
+
const workerLayer = (options = {}) => makeLayer(options, {
|
|
558
|
+
"cloudflare.resource_type": "worker",
|
|
559
|
+
"cloudflare.worker.name": options.workerName
|
|
560
|
+
});
|
|
561
|
+
/**
|
|
562
|
+
* OTLP layer with Cloudflare Durable Object resource attributes.
|
|
863
563
|
*
|
|
864
|
-
*
|
|
865
|
-
*
|
|
564
|
+
* The layer reads {@link DurableObjectState} so it can optionally include the
|
|
565
|
+
* Durable Object id. Prefer leaving `includeObjectId` disabled unless the
|
|
566
|
+
* backend can tolerate high-cardinality resource attributes.
|
|
866
567
|
*/
|
|
867
|
-
const
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
if (options.attachment !== void 0) server.raw.serializeAttachment(options.attachment);
|
|
873
|
-
yield* state.acceptWebSocket(server, options.tags === void 0 ? void 0 : [...options.tags]);
|
|
874
|
-
return {
|
|
875
|
-
client,
|
|
876
|
-
server,
|
|
877
|
-
response: new Response(null, {
|
|
878
|
-
status: 101,
|
|
879
|
-
webSocket: client
|
|
880
|
-
})
|
|
881
|
-
};
|
|
882
|
-
});
|
|
883
|
-
/** Creates typed attachment helpers for accepted and rehydrated sockets. */
|
|
884
|
-
const attachment = (schema) => {
|
|
885
|
-
const serialize = (socket, value) => Schema.encodeEffect(schema)(value).pipe(Effect.mapError((cause) => new DurableWebSocketAttachmentError({
|
|
886
|
-
operation: "serialize",
|
|
887
|
-
cause
|
|
888
|
-
})), Effect.flatMap((encoded) => socket.serializeAttachment(encoded)));
|
|
889
|
-
const deserialize = (socket) => Effect.gen(function* () {
|
|
890
|
-
const value = yield* socket.deserializeAttachment;
|
|
891
|
-
if (value == null) return Option.none();
|
|
892
|
-
return Option.some(yield* Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError((cause) => new DurableWebSocketAttachmentError({
|
|
893
|
-
operation: "deserialize",
|
|
894
|
-
cause
|
|
895
|
-
}))));
|
|
896
|
-
});
|
|
897
|
-
const rehydrate = (options = {}) => Effect.gen(function* () {
|
|
898
|
-
const sockets = yield* (yield* DurableObjectState).getWebSockets(options.tag);
|
|
899
|
-
const restored = [];
|
|
900
|
-
const onInvalid = options.onInvalid ?? "ignore";
|
|
901
|
-
for (const socket of sockets) {
|
|
902
|
-
const decoded = yield* deserialize(socket).pipe(Effect.match({
|
|
903
|
-
onFailure: (error) => ({
|
|
904
|
-
_tag: "Failure",
|
|
905
|
-
error
|
|
906
|
-
}),
|
|
907
|
-
onSuccess: (value) => ({
|
|
908
|
-
_tag: "Success",
|
|
909
|
-
value
|
|
910
|
-
})
|
|
911
|
-
}));
|
|
912
|
-
if (decoded._tag === "Success" && Option.isSome(decoded.value)) {
|
|
913
|
-
restored.push({
|
|
914
|
-
socket,
|
|
915
|
-
attachment: decoded.value.value
|
|
916
|
-
});
|
|
917
|
-
continue;
|
|
918
|
-
}
|
|
919
|
-
if (decoded._tag === "Failure" && onInvalid === "fail") return yield* Effect.fail(decoded.error);
|
|
920
|
-
if (decoded._tag === "Failure" && onInvalid === "ignore-and-close") yield* socket.close(1008, "invalid websocket attachment").pipe(Effect.ignore);
|
|
921
|
-
}
|
|
922
|
-
return restored;
|
|
923
|
-
});
|
|
924
|
-
return {
|
|
925
|
-
serialize,
|
|
926
|
-
deserialize,
|
|
927
|
-
rehydrate,
|
|
928
|
-
schema
|
|
929
|
-
};
|
|
930
|
-
};
|
|
931
|
-
/** Maps compact websocket lifecycle handler names to `DurableObject.make` options. */
|
|
932
|
-
const handlers = (options) => ({
|
|
933
|
-
webSocketMessage: options.message,
|
|
934
|
-
webSocketClose: options.close,
|
|
935
|
-
webSocketError: options.error
|
|
936
|
-
});
|
|
937
|
-
//#endregion
|
|
938
|
-
//#region src/DurableObjectState.ts
|
|
939
|
-
var DurableObjectState_exports = /* @__PURE__ */ __exportAll({
|
|
940
|
-
DurableObjectState: () => DurableObjectState,
|
|
941
|
-
fromDurableObjectState: () => fromDurableObjectState
|
|
942
|
-
});
|
|
943
|
-
/**
|
|
944
|
-
* Context tag for accessing the current Durable Object state service.
|
|
945
|
-
*/
|
|
946
|
-
var DurableObjectState = class extends Context.Service()("effect-cf/DurableObjectState") {};
|
|
947
|
-
/**
|
|
948
|
-
* Wraps a native Cloudflare `DurableObjectState` as a {@link DurableObjectStateService}.
|
|
949
|
-
*/
|
|
950
|
-
const fromDurableObjectState = (state) => ({
|
|
951
|
-
raw: state,
|
|
952
|
-
id: state.id,
|
|
953
|
-
storage: fromDurableObjectStorage(state.storage),
|
|
954
|
-
waitUntil: (promise) => Effect.sync(() => state.waitUntil(promise)),
|
|
955
|
-
blockConcurrencyWhile: (effect) => Effect.context().pipe(Effect.flatMap((context) => Effect.promise(() => state.blockConcurrencyWhile(() => runPromiseExitPreservingTypedFailures(Effect.provideContext(effect, context))))), Effect.flatten),
|
|
956
|
-
blockConcurrencyWhileOrReset: (effect) => Effect.context().pipe(Effect.flatMap((context) => Effect.promise(() => state.blockConcurrencyWhile(() => Effect.runPromise(Effect.provideContext(effect, context)))))),
|
|
957
|
-
acceptWebSocket: (ws, tags) => Effect.sync(() => state.acceptWebSocket(ws.raw, tags)),
|
|
958
|
-
getWebSockets: (tag) => Effect.sync(() => state.getWebSockets(tag).map((socket) => fromWebSocket(socket))),
|
|
959
|
-
setWebSocketAutoResponse: (pair) => Effect.sync(() => state.setWebSocketAutoResponse(pair)),
|
|
960
|
-
getWebSocketAutoResponse: Effect.sync(() => state.getWebSocketAutoResponse()),
|
|
961
|
-
getWebSocketAutoResponseTimestamp: (ws) => Effect.sync(() => state.getWebSocketAutoResponseTimestamp(ws.raw)),
|
|
962
|
-
setHibernatableWebSocketEventTimeout: (timeoutMs) => Effect.sync(() => state.setHibernatableWebSocketEventTimeout(timeoutMs)),
|
|
963
|
-
getHibernatableWebSocketEventTimeout: Effect.sync(() => state.getHibernatableWebSocketEventTimeout()),
|
|
964
|
-
getTags: (ws) => Effect.sync(() => state.getTags(ws.raw)),
|
|
965
|
-
abort: (reason) => Effect.sync(() => state.abort(reason))
|
|
966
|
-
});
|
|
967
|
-
const runPromiseExitPreservingTypedFailures = async (effect) => {
|
|
968
|
-
const exit = await Effect.runPromiseExit(effect);
|
|
969
|
-
if (Exit.isFailure(exit) && (Cause.hasDies(exit.cause) || Cause.hasInterrupts(exit.cause))) throw Cause.squash(exit.cause);
|
|
970
|
-
return exit;
|
|
971
|
-
};
|
|
568
|
+
const durableObjectLayer = (options = {}) => Layer.unwrap(Effect.map(DurableObjectState, (state) => makeLayer(options, {
|
|
569
|
+
"cloudflare.resource_type": "durable_object",
|
|
570
|
+
"cloudflare.durable_object.class": options.className,
|
|
571
|
+
"cloudflare.durable_object.id": options.includeObjectId ? state.id.toString() : void 0
|
|
572
|
+
})));
|
|
972
573
|
//#endregion
|
|
973
|
-
//#region src/
|
|
974
|
-
var
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
isDurableObjectNamespaceClient: () => isDurableObjectNamespaceClient,
|
|
978
|
-
layer: () => layer$7,
|
|
979
|
-
makeClient: () => makeClient$4,
|
|
980
|
-
makeDirectMethods: () => makeDirectMethods
|
|
574
|
+
//#region src/D1.ts
|
|
575
|
+
var D1_exports = /* @__PURE__ */ __exportAll({
|
|
576
|
+
Service: () => Service$1,
|
|
577
|
+
make: () => make$10
|
|
981
578
|
});
|
|
982
|
-
const
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
* Failure raised when forwarding a request to a Durable Object stub.
|
|
989
|
-
*/
|
|
990
|
-
var DurableObjectFetchError = class extends Data.TaggedError("DurableObjectFetchError") {};
|
|
991
|
-
const hasFunction$1 = (value, key) => typeof Reflect.get(value, key) === "function";
|
|
992
|
-
const isDurableObjectNamespaceClient = (value) => typeof value === "object" && value !== null && hasFunction$1(value, "getByName") && hasFunction$1(value, "get") && hasFunction$1(value, "idFromName") && hasFunction$1(value, "idFromString") && hasFunction$1(value, "newUniqueId") && hasFunction$1(value, "jurisdiction");
|
|
993
|
-
const makeClient$4 = (definition) => {
|
|
994
|
-
return (namespace) => {
|
|
995
|
-
const newUniqueId = (options) => Effect.sync(() => namespace.newUniqueId(options));
|
|
996
|
-
const idFromName = (name) => Effect.sync(() => namespace.idFromName(name));
|
|
997
|
-
const idFromString = (id) => Effect.sync(() => namespace.idFromString(id));
|
|
998
|
-
const get = (id, options) => Effect.sync(() => namespace.get(id, options));
|
|
999
|
-
const getByName = (name, options) => Effect.sync(() => namespace.getByName(name, options));
|
|
1000
|
-
const jurisdiction = (value) => Effect.sync(() => namespace.jurisdiction(value));
|
|
1001
|
-
const fetch = (stub, input, init) => Effect.tryPromise({
|
|
1002
|
-
try: () => stub.fetch(input, init),
|
|
1003
|
-
catch: (cause) => new DurableObjectFetchError({
|
|
1004
|
-
binding: definition.binding,
|
|
1005
|
-
cause
|
|
1006
|
-
})
|
|
1007
|
-
});
|
|
1008
|
-
const rpc = (stub, method, ...args) => Effect.gen(function* () {
|
|
1009
|
-
const methodName = String(method);
|
|
1010
|
-
return yield* invokeRpcMethod(stub, method, definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1011
|
-
binding: definition.binding,
|
|
1012
|
-
method: methodName,
|
|
1013
|
-
cause
|
|
1014
|
-
}))), (cause) => new DurableObjectRpcError({
|
|
1015
|
-
binding: definition.binding,
|
|
1016
|
-
method: methodName,
|
|
1017
|
-
cause
|
|
1018
|
-
}));
|
|
1019
|
-
});
|
|
1020
|
-
const decodeSuccess$1 = (methodName, value) => Effect.gen(function* () {
|
|
1021
|
-
if (definition.definition === void 0) return value;
|
|
1022
|
-
return yield* decodeSuccess(definition.definition, methodName, value).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1023
|
-
binding: definition.binding,
|
|
1024
|
-
method: methodName,
|
|
1025
|
-
cause
|
|
1026
|
-
})));
|
|
1027
|
-
});
|
|
1028
|
-
const call = (stub, method, ...args) => Effect.gen(function* () {
|
|
1029
|
-
const methodName = String(method);
|
|
1030
|
-
return yield* decodeSuccess$1(methodName, yield* resolve(yield* rpc(stub, method, ...args)).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1031
|
-
binding: definition.binding,
|
|
1032
|
-
method: methodName,
|
|
1033
|
-
cause
|
|
1034
|
-
}))));
|
|
1035
|
-
});
|
|
1036
|
-
const scopedCall = (stub, method, ...args) => Effect.gen(function* () {
|
|
1037
|
-
return yield* decodeSuccess$1(String(method), yield* scoped(yield* rpc(stub, method, ...args)));
|
|
1038
|
-
});
|
|
1039
|
-
const directMethods = makeDirectMethods(definition.definition, {
|
|
1040
|
-
call,
|
|
1041
|
-
fetch,
|
|
1042
|
-
get,
|
|
1043
|
-
getByName
|
|
1044
|
-
});
|
|
1045
|
-
return Object.assign(directMethods, {
|
|
1046
|
-
newUniqueId,
|
|
1047
|
-
idFromName,
|
|
1048
|
-
idFromString,
|
|
1049
|
-
get,
|
|
1050
|
-
getByName,
|
|
1051
|
-
jurisdiction,
|
|
1052
|
-
fetch,
|
|
1053
|
-
rpc,
|
|
1054
|
-
call,
|
|
1055
|
-
scopedCall,
|
|
1056
|
-
unsafeRaw: Effect.succeed(namespace)
|
|
1057
|
-
});
|
|
1058
|
-
};
|
|
1059
|
-
};
|
|
1060
|
-
const layer$7 = (tag, definition) => layer$10(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$4(definition), { expected: expectedDurableObjectNamespace });
|
|
1061
|
-
const makeDirectMethods = (rpcDefinition, helpers) => {
|
|
1062
|
-
const methods = {};
|
|
1063
|
-
if (rpcDefinition !== void 0) {
|
|
1064
|
-
for (const methodName of Object.keys(rpcDefinition.methods)) methods[methodName] = (stub, ...args) => helpers.call(stub, methodName, ...args);
|
|
1065
|
-
const makeClient = (getStub) => {
|
|
1066
|
-
const client = { fetch: (input, init) => Effect.gen(function* () {
|
|
1067
|
-
const stub = yield* getStub();
|
|
1068
|
-
return yield* helpers.fetch(stub, input, init);
|
|
1069
|
-
}) };
|
|
1070
|
-
for (const methodName of Object.keys(rpcDefinition.methods)) client[methodName] = (...args) => Effect.gen(function* () {
|
|
1071
|
-
const stub = yield* getStub();
|
|
1072
|
-
return yield* helpers.call(stub, methodName, ...args);
|
|
1073
|
-
});
|
|
1074
|
-
return client;
|
|
1075
|
-
};
|
|
1076
|
-
methods.byName = (name, options) => makeClient(() => helpers.getByName(name, options));
|
|
1077
|
-
methods.byId = (id, options) => makeClient(() => helpers.get(id, options));
|
|
1078
|
-
}
|
|
1079
|
-
return methods;
|
|
579
|
+
const TypeId$2 = "effect-cf/D1";
|
|
580
|
+
const expectedD1Database = "D1 database binding with prepare(), batch(), and exec()";
|
|
581
|
+
const isD1Database = (value) => {
|
|
582
|
+
if (typeof value !== "object" || value === null) return false;
|
|
583
|
+
const resource = value;
|
|
584
|
+
return typeof resource.prepare === "function" && typeof resource.batch === "function" && typeof resource.exec === "function";
|
|
1080
585
|
};
|
|
1081
|
-
//#endregion
|
|
1082
|
-
//#region src/DurableObjectDefinition.ts
|
|
1083
|
-
var DurableObjectDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
1084
|
-
DurableObject: () => DurableObject$1,
|
|
1085
|
-
Tag: () => Tag$6,
|
|
1086
|
-
implement: () => implement$3,
|
|
1087
|
-
make: () => make$6,
|
|
1088
|
-
method: () => method$1
|
|
1089
|
-
});
|
|
1090
|
-
const reservedMethodNames$1 = new Set([
|
|
1091
|
-
"constructor",
|
|
1092
|
-
"dup",
|
|
1093
|
-
"fetch",
|
|
1094
|
-
"alarm",
|
|
1095
|
-
"webSocketMessage",
|
|
1096
|
-
"webSocketClose",
|
|
1097
|
-
"webSocketError"
|
|
1098
|
-
]);
|
|
1099
586
|
/**
|
|
1100
|
-
*
|
|
587
|
+
* Creates a typed D1 service tag plus Effect helpers.
|
|
1101
588
|
*/
|
|
1102
|
-
const
|
|
589
|
+
const make$10 = (id, definition) => Service$1()(id, definition);
|
|
1103
590
|
/**
|
|
1104
|
-
*
|
|
591
|
+
* Builds a D1 service around a Cloudflare D1 database binding.
|
|
592
|
+
*
|
|
593
|
+
* The returned service exposes the raw `D1Database` binding and `sqlLayer(...)`
|
|
594
|
+
* for providing `effect/unstable/sql` via `@effect/sql-d1`.
|
|
1105
595
|
*
|
|
1106
596
|
* @example
|
|
1107
597
|
* ```ts
|
|
1108
|
-
*
|
|
1109
|
-
*
|
|
1110
|
-
*
|
|
1111
|
-
*
|
|
1112
|
-
*
|
|
1113
|
-
* });
|
|
598
|
+
* class TodoDatabase extends D1.Service<TodoDatabase>()("TodoDatabase", {
|
|
599
|
+
* binding: "TODO_DB",
|
|
600
|
+
* }) {}
|
|
601
|
+
*
|
|
602
|
+
* const SqlLive = TodoDatabase.sqlLayer();
|
|
1114
603
|
* ```
|
|
1115
604
|
*/
|
|
1116
|
-
const
|
|
1117
|
-
|
|
1118
|
-
const
|
|
1119
|
-
|
|
605
|
+
const Service$1 = () => (id, definition) => {
|
|
606
|
+
const tag = Service$2()(id, definition.binding, isD1Database, void 0, { expected: expectedD1Database });
|
|
607
|
+
const sqlLayer = (options) => Layer.unwrap(Effect.gen(function* () {
|
|
608
|
+
const db = yield* tag;
|
|
609
|
+
return D1Client.layer({
|
|
610
|
+
...options,
|
|
611
|
+
db
|
|
612
|
+
});
|
|
613
|
+
})).pipe(Layer.provide(tag.layer));
|
|
614
|
+
return Object.assign(tag, {
|
|
615
|
+
[TypeId$2]: TypeId$2,
|
|
616
|
+
definition,
|
|
617
|
+
sqlLayer
|
|
618
|
+
});
|
|
619
|
+
};
|
|
620
|
+
//#endregion
|
|
621
|
+
//#region src/QueueBinding.ts
|
|
622
|
+
var QueueBinding_exports = /* @__PURE__ */ __exportAll({
|
|
623
|
+
QueueOperationError: () => QueueOperationError,
|
|
624
|
+
isQueue: () => isQueue,
|
|
625
|
+
layer: () => layer$9,
|
|
626
|
+
makeClient: () => makeClient$6
|
|
627
|
+
});
|
|
628
|
+
const expectedQueueProducer = "Queue producer binding with send(); optional sendBatch()/metrics()";
|
|
629
|
+
var QueueOperationError = class extends Data.TaggedError("QueueOperationError") {};
|
|
630
|
+
const tryQueuePromise = (binding, operation, evaluate) => Effect.tryPromise({
|
|
631
|
+
try: evaluate,
|
|
632
|
+
catch: (cause) => new QueueOperationError({
|
|
633
|
+
binding,
|
|
634
|
+
operation,
|
|
635
|
+
cause,
|
|
636
|
+
message: `Cloudflare queue binding "${binding}" operation "${operation}" failed`
|
|
637
|
+
})
|
|
638
|
+
});
|
|
639
|
+
const isQueue = (value) => {
|
|
640
|
+
if (typeof value !== "object" || value === null) return false;
|
|
641
|
+
return typeof value.send === "function";
|
|
642
|
+
};
|
|
643
|
+
const makeClient$6 = (definition) => {
|
|
644
|
+
const encodeMessage = Schema.encodeEffect(definition.message);
|
|
645
|
+
return (queue) => ({
|
|
646
|
+
send: Effect.fnUntraced(function* (message, options) {
|
|
647
|
+
const encoded = yield* encodeMessage(message);
|
|
648
|
+
yield* tryQueuePromise(definition.binding, "send", () => queue.send(encoded, options));
|
|
649
|
+
}),
|
|
650
|
+
sendBatch: Effect.fnUntraced(function* (messages, options) {
|
|
651
|
+
const encodedMessages = [];
|
|
652
|
+
for (const message of messages) encodedMessages.push({
|
|
653
|
+
...message,
|
|
654
|
+
body: yield* encodeMessage(message.body)
|
|
655
|
+
});
|
|
656
|
+
const sendBatch = queue.sendBatch;
|
|
657
|
+
if (sendBatch !== void 0) {
|
|
658
|
+
yield* tryQueuePromise(definition.binding, "sendBatch", () => sendBatch.call(queue, encodedMessages, options));
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
yield* tryQueuePromise(definition.binding, "sendBatch", async () => {
|
|
662
|
+
for (const message of encodedMessages) await queue.send(message.body, {
|
|
663
|
+
contentType: message.contentType,
|
|
664
|
+
delaySeconds: message.delaySeconds ?? options?.delaySeconds
|
|
665
|
+
});
|
|
666
|
+
});
|
|
667
|
+
}),
|
|
668
|
+
metrics: () => {
|
|
669
|
+
const metrics = queue.metrics;
|
|
670
|
+
if (metrics === void 0) return Effect.fail(new QueueOperationError({
|
|
671
|
+
binding: definition.binding,
|
|
672
|
+
operation: "metrics",
|
|
673
|
+
cause: /* @__PURE__ */ new Error(`Queue binding "${definition.binding}" does not provide metrics()`),
|
|
674
|
+
message: `Cloudflare queue binding "${definition.binding}" does not provide metrics()`
|
|
675
|
+
}));
|
|
676
|
+
return tryQueuePromise(definition.binding, "metrics", () => metrics.call(queue));
|
|
677
|
+
},
|
|
678
|
+
unsafeRaw: Effect.succeed(queue)
|
|
679
|
+
});
|
|
680
|
+
};
|
|
681
|
+
const layer$9 = (tag, definition) => layer$11(tag, definition.binding, (value) => isQueue(value), makeClient$6(definition), { expected: expectedQueueProducer });
|
|
682
|
+
//#endregion
|
|
683
|
+
//#region src/QueueDefinition.ts
|
|
684
|
+
var QueueDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
685
|
+
Queue: () => Queue$1,
|
|
686
|
+
Tag: () => Tag$10,
|
|
687
|
+
implement: () => implement$7,
|
|
688
|
+
make: () => make$9
|
|
689
|
+
});
|
|
690
|
+
const makeDefinition$4 = (id, definition) => {
|
|
691
|
+
const queueDefinition = {
|
|
692
|
+
id,
|
|
693
|
+
message: definition.message
|
|
694
|
+
};
|
|
695
|
+
return Object.assign(queueDefinition, { make: (layer, options) => make$6(layer, {
|
|
1120
696
|
...options,
|
|
1121
|
-
|
|
697
|
+
queue: wrapHandler$1(queueDefinition, options.queue)
|
|
1122
698
|
}) });
|
|
1123
699
|
};
|
|
1124
|
-
const make$
|
|
1125
|
-
const Tag$
|
|
1126
|
-
const
|
|
700
|
+
const make$9 = (id, definition) => Tag$10()(id, definition);
|
|
701
|
+
const Tag$10 = () => (id, definition) => {
|
|
702
|
+
const queueDefinition = makeDefinition$4(id, definition);
|
|
1127
703
|
const tag = Context.Service()(id);
|
|
1128
|
-
const
|
|
704
|
+
const layer = (binding) => layer$9(tag, {
|
|
1129
705
|
...binding,
|
|
1130
|
-
definition
|
|
1131
|
-
});
|
|
1132
|
-
const layer = (binding) => layer$7(tag, bindingDefinition(binding));
|
|
1133
|
-
const newUniqueId = Effect.fnUntraced(function* (options) {
|
|
1134
|
-
return yield* (yield* tag).newUniqueId(options);
|
|
1135
|
-
});
|
|
1136
|
-
const idFromName = Effect.fnUntraced(function* (name) {
|
|
1137
|
-
return yield* (yield* tag).idFromName(name);
|
|
1138
|
-
});
|
|
1139
|
-
const idFromString = Effect.fnUntraced(function* (value) {
|
|
1140
|
-
return yield* (yield* tag).idFromString(value);
|
|
1141
|
-
});
|
|
1142
|
-
const get = Effect.fnUntraced(function* (objectId, options) {
|
|
1143
|
-
return yield* (yield* tag).get(objectId, options);
|
|
1144
|
-
});
|
|
1145
|
-
const getByName = Effect.fnUntraced(function* (name, options) {
|
|
1146
|
-
return yield* (yield* tag).getByName(name, options);
|
|
1147
|
-
});
|
|
1148
|
-
const jurisdiction = Effect.fnUntraced(function* (value) {
|
|
1149
|
-
return yield* (yield* tag).jurisdiction(value);
|
|
1150
|
-
});
|
|
1151
|
-
const fetch = (stub, input, init) => Effect.gen(function* () {
|
|
1152
|
-
return yield* (yield* tag).fetch(stub, input, init);
|
|
706
|
+
message: definition.message
|
|
1153
707
|
});
|
|
1154
|
-
const
|
|
1155
|
-
|
|
708
|
+
const send = Effect.fnUntraced(function* (message, options) {
|
|
709
|
+
yield* (yield* tag).send(message, options);
|
|
1156
710
|
});
|
|
1157
|
-
const
|
|
1158
|
-
|
|
711
|
+
const sendBatch = Effect.fnUntraced(function* (messages, options) {
|
|
712
|
+
yield* (yield* tag).sendBatch(messages, options);
|
|
1159
713
|
});
|
|
1160
|
-
const
|
|
1161
|
-
return yield* (yield* tag).
|
|
714
|
+
const metrics = Effect.fnUntraced(function* () {
|
|
715
|
+
return yield* (yield* tag).metrics();
|
|
1162
716
|
});
|
|
1163
717
|
const unsafeRaw = Effect.fnUntraced(function* () {
|
|
1164
718
|
return yield* (yield* tag).unsafeRaw;
|
|
1165
719
|
});
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
getByName
|
|
1171
|
-
});
|
|
1172
|
-
return Object.assign(tag, directMethods, {
|
|
1173
|
-
id: definition.id,
|
|
1174
|
-
methods: definition.methods,
|
|
1175
|
-
make: definition.make,
|
|
720
|
+
return Object.assign(tag, {
|
|
721
|
+
id: queueDefinition.id,
|
|
722
|
+
message: queueDefinition.message,
|
|
723
|
+
make: queueDefinition.make,
|
|
1176
724
|
layer,
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
get,
|
|
1181
|
-
getByName,
|
|
1182
|
-
jurisdiction,
|
|
1183
|
-
fetch,
|
|
1184
|
-
rpc,
|
|
1185
|
-
call,
|
|
1186
|
-
scopedCall,
|
|
725
|
+
send,
|
|
726
|
+
sendBatch,
|
|
727
|
+
metrics,
|
|
1187
728
|
unsafeRaw
|
|
1188
729
|
});
|
|
1189
730
|
};
|
|
1190
|
-
const
|
|
1191
|
-
const
|
|
1192
|
-
const
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
return yield* encodeSuccess(definition, key, yield* handler(...yield* decodeArgs(definition, key, args)));
|
|
1197
|
-
});
|
|
1198
|
-
}
|
|
1199
|
-
return wrapped;
|
|
731
|
+
const Queue$1 = Tag$10;
|
|
732
|
+
const wrapHandler$1 = (definition, handler) => {
|
|
733
|
+
const decodeBody = Schema.decodeUnknownEffect(definition.message);
|
|
734
|
+
return (batch) => Effect.gen(function* () {
|
|
735
|
+
yield* handler(yield* decodeBatch(batch.raw, decodeBody));
|
|
736
|
+
});
|
|
1200
737
|
};
|
|
1201
|
-
|
|
1202
|
-
* Helper for implementing handlers with the exact method shape of a definition.
|
|
1203
|
-
*/
|
|
1204
|
-
const implement$3 = (_definition, handlers) => handlers;
|
|
738
|
+
const implement$7 = (_definition, handler) => handler;
|
|
1205
739
|
//#endregion
|
|
1206
|
-
//#region src/
|
|
1207
|
-
var
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
740
|
+
//#region src/Queue.ts
|
|
741
|
+
var Queue_exports = /* @__PURE__ */ __exportAll({
|
|
742
|
+
QueueMessageDecodeError: () => QueueMessageDecodeError,
|
|
743
|
+
Tag: () => Tag$9,
|
|
744
|
+
decodeBatch: () => decodeBatch,
|
|
745
|
+
fromMessage: () => fromMessage,
|
|
746
|
+
fromMessageBatch: () => fromMessageBatch,
|
|
747
|
+
implement: () => implement$6
|
|
1212
748
|
});
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
const RunSymbol = Symbol.for("effect-cf/DurableObject/run");
|
|
1223
|
-
/**
|
|
1224
|
-
* Creates a Durable Object class backed by a single managed Effect runtime.
|
|
1225
|
-
*/
|
|
1226
|
-
const make$5 = (layer, options = {}) => {
|
|
1227
|
-
class EffectDurableObject extends DurableObject {
|
|
1228
|
-
runtime;
|
|
1229
|
-
constructor(state, env) {
|
|
1230
|
-
super(state, env);
|
|
1231
|
-
const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(Layer.succeed(DurableObjectState, fromDurableObjectState(state)), Layer.succeed(WorkerEnvironment, env)));
|
|
1232
|
-
this.runtime = ManagedRuntime.make(runtimeLayer);
|
|
1233
|
-
const initialize = options.initialize;
|
|
1234
|
-
if (initialize !== void 0) state.waitUntil(this[RunSymbol](initialize));
|
|
1235
|
-
}
|
|
1236
|
-
[RunSymbol](effect) {
|
|
1237
|
-
return this.runtime.runPromise(Effect.scoped(effect));
|
|
1238
|
-
}
|
|
1239
|
-
fetch(request) {
|
|
1240
|
-
const fetchHandler = options.fetch;
|
|
1241
|
-
if (fetchHandler === void 0) return Promise.resolve(new Response("Not Found", { status: 404 }));
|
|
1242
|
-
return this[RunSymbol](Effect.provideService(fetchHandler, NativeRequest, request));
|
|
1243
|
-
}
|
|
1244
|
-
alarm(alarmInfo) {
|
|
1245
|
-
const logicalAlarms = options.alarms?.pipe(Effect.asVoid);
|
|
1246
|
-
const rawAlarm = options.alarm?.(alarmInfo);
|
|
1247
|
-
if (logicalAlarms !== void 0 && rawAlarm !== void 0) return this[RunSymbol](Effect.gen(function* () {
|
|
1248
|
-
yield* logicalAlarms;
|
|
1249
|
-
yield* rawAlarm;
|
|
1250
|
-
}));
|
|
1251
|
-
if (logicalAlarms !== void 0) return this[RunSymbol](logicalAlarms);
|
|
1252
|
-
if (rawAlarm !== void 0) return this[RunSymbol](rawAlarm);
|
|
1253
|
-
}
|
|
1254
|
-
webSocketMessage(socket, message) {
|
|
1255
|
-
if (options.webSocketMessage !== void 0) return this[RunSymbol](options.webSocketMessage(fromWebSocket(socket), message));
|
|
1256
|
-
}
|
|
1257
|
-
webSocketClose(socket, code, reason, wasClean) {
|
|
1258
|
-
if (options.webSocketClose !== void 0) return this[RunSymbol](options.webSocketClose(fromWebSocket(socket), code, reason, wasClean));
|
|
1259
|
-
}
|
|
1260
|
-
webSocketError(socket, error) {
|
|
1261
|
-
if (options.webSocketError !== void 0) return this[RunSymbol](options.webSocketError(fromWebSocket(socket), error));
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
defineEntrypointRpcMethods("Durable Object", EffectDurableObject.prototype, options.rpc, reservedMethodNames, (self, effect) => self[RunSymbol](effect));
|
|
1265
|
-
return assumeEntrypointClass(EffectDurableObject);
|
|
1266
|
-
};
|
|
1267
|
-
const Tag$5 = Tag$6;
|
|
1268
|
-
const method = method$1;
|
|
1269
|
-
const implement$2 = implement$3;
|
|
1270
|
-
//#endregion
|
|
1271
|
-
//#region src/CloudflareOtlp.ts
|
|
1272
|
-
var CloudflareOtlp_exports = /* @__PURE__ */ __exportAll({
|
|
1273
|
-
CloudflareOtlpSettings: () => CloudflareOtlpSettings,
|
|
1274
|
-
durableObjectLayer: () => durableObjectLayer,
|
|
1275
|
-
instrumentDurableObjectOptions: () => instrumentDurableObjectOptions,
|
|
1276
|
-
instrumentWorkerOptions: () => instrumentWorkerOptions,
|
|
1277
|
-
layer: () => layer$6,
|
|
1278
|
-
layerJson: () => layerJson,
|
|
1279
|
-
layerProtobuf: () => layerProtobuf,
|
|
1280
|
-
settingsConfig: () => settingsConfig,
|
|
1281
|
-
settingsLayer: () => settingsLayer,
|
|
1282
|
-
workerLayer: () => workerLayer
|
|
749
|
+
var QueueMessageDecodeError = class extends Data.TaggedError("QueueMessageDecodeError") {};
|
|
750
|
+
const fromMessage = (message, body) => ({
|
|
751
|
+
raw: message,
|
|
752
|
+
id: message.id,
|
|
753
|
+
timestamp: message.timestamp,
|
|
754
|
+
body,
|
|
755
|
+
attempts: message.attempts,
|
|
756
|
+
ack: Effect.sync(() => message.ack()),
|
|
757
|
+
retry: (options) => Effect.sync(() => message.retry(options))
|
|
1283
758
|
});
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
* - `OTEL_EXPORTER_OTLP_ENDPOINT`
|
|
1292
|
-
* - `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`
|
|
1293
|
-
* - `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`
|
|
1294
|
-
* - `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`
|
|
1295
|
-
* - `OTEL_EXPORTER_OTLP_HEADERS`
|
|
1296
|
-
* - `OTEL_EXPORTER_OTLP_LOGS_HEADERS`
|
|
1297
|
-
* - `OTEL_EXPORTER_OTLP_TRACES_HEADERS`
|
|
1298
|
-
* - `OTEL_EXPORTER_OTLP_METRICS_HEADERS`
|
|
1299
|
-
* - `OTEL_SERVICE_NAME`
|
|
1300
|
-
* - `OTEL_RESOURCE_ATTRIBUTES`
|
|
1301
|
-
*
|
|
1302
|
-
* `OTEL_SERVICE_VERSION` is also accepted as an effect-cf convenience alias.
|
|
1303
|
-
* The standard OpenTelemetry way to configure service version is
|
|
1304
|
-
* `OTEL_RESOURCE_ATTRIBUTES=service.version=...`.
|
|
1305
|
-
*
|
|
1306
|
-
* Consumers with non-standard binding names should map those names into
|
|
1307
|
-
* {@link CloudflareOtlpSettings} rather than changing this config globally.
|
|
1308
|
-
*/
|
|
1309
|
-
const settingsConfig = Config.all({
|
|
1310
|
-
endpoint: Config.string("OTEL_EXPORTER_OTLP_ENDPOINT").pipe(Config.option),
|
|
1311
|
-
logsEndpoint: Config.string("OTEL_EXPORTER_OTLP_LOGS_ENDPOINT").pipe(Config.option),
|
|
1312
|
-
tracesEndpoint: Config.string("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT").pipe(Config.option),
|
|
1313
|
-
metricsEndpoint: Config.string("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT").pipe(Config.option),
|
|
1314
|
-
headers: Config.string("OTEL_EXPORTER_OTLP_HEADERS").pipe(Config.option),
|
|
1315
|
-
logsHeaders: Config.string("OTEL_EXPORTER_OTLP_LOGS_HEADERS").pipe(Config.option),
|
|
1316
|
-
tracesHeaders: Config.string("OTEL_EXPORTER_OTLP_TRACES_HEADERS").pipe(Config.option),
|
|
1317
|
-
metricsHeaders: Config.string("OTEL_EXPORTER_OTLP_METRICS_HEADERS").pipe(Config.option),
|
|
1318
|
-
serviceName: Config.string("OTEL_SERVICE_NAME").pipe(Config.option),
|
|
1319
|
-
serviceVersion: Config.string("OTEL_SERVICE_VERSION").pipe(Config.option),
|
|
1320
|
-
resourceAttributes: Config.schema(Config.Record(Schema.String, Schema.String), "OTEL_RESOURCE_ATTRIBUTES").pipe(Config.option)
|
|
759
|
+
const fromMessageBatch = (batch, messages) => ({
|
|
760
|
+
raw: batch,
|
|
761
|
+
messages,
|
|
762
|
+
queue: batch.queue,
|
|
763
|
+
metadata: batch.metadata,
|
|
764
|
+
ackAll: Effect.sync(() => batch.ackAll()),
|
|
765
|
+
retryAll: (options) => Effect.sync(() => batch.retryAll(options))
|
|
1321
766
|
});
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
* ...CloudflareOtlp.settingsConfig,
|
|
1336
|
-
* endpoint: Config.string("MY_OTLP_ENDPOINT").pipe(Config.option),
|
|
1337
|
-
* }),
|
|
1338
|
-
* ).pipe(Layer.provide(WorkerConfig.layer));
|
|
1339
|
-
* ```
|
|
1340
|
-
*/
|
|
1341
|
-
var CloudflareOtlpSettings = class extends Context.Service()("effect-cf/CloudflareOtlpSettings") {};
|
|
1342
|
-
const allSignals = [
|
|
1343
|
-
"logs",
|
|
1344
|
-
"traces",
|
|
1345
|
-
"metrics"
|
|
1346
|
-
];
|
|
1347
|
-
const optionToUndefined = (option) => Option.isSome(option) ? option.value : void 0;
|
|
1348
|
-
const nonEmptyStringOption = (option) => Option.flatMap(option, (value) => {
|
|
1349
|
-
const trimmed = value.trim();
|
|
1350
|
-
return trimmed === "" ? Option.none() : Option.some(trimmed);
|
|
767
|
+
const decodeBatch = (batch, decodeBody) => Effect.gen(function* () {
|
|
768
|
+
const messages = [];
|
|
769
|
+
for (let index = 0; index < batch.messages.length; index++) {
|
|
770
|
+
const message = batch.messages[index];
|
|
771
|
+
const body = yield* decodeBody(message.body).pipe(Effect.mapError((cause) => new QueueMessageDecodeError({
|
|
772
|
+
queue: batch.queue,
|
|
773
|
+
messageId: message.id,
|
|
774
|
+
index,
|
|
775
|
+
cause
|
|
776
|
+
})));
|
|
777
|
+
messages.push(fromMessage(message, body));
|
|
778
|
+
}
|
|
779
|
+
return fromMessageBatch(batch, messages);
|
|
1351
780
|
});
|
|
1352
|
-
const
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
781
|
+
const Tag$9 = Tag$10;
|
|
782
|
+
const implement$6 = implement$7;
|
|
783
|
+
//#endregion
|
|
784
|
+
//#region src/RpcDefinition.ts
|
|
785
|
+
var RpcDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
786
|
+
ReservedMethodNameError: () => ReservedMethodNameError,
|
|
787
|
+
RpcArgumentCountError: () => RpcArgumentCountError,
|
|
788
|
+
RpcArgumentDecodeError: () => RpcArgumentDecodeError,
|
|
789
|
+
RpcArgumentEncodeError: () => RpcArgumentEncodeError,
|
|
790
|
+
RpcReservedMethodNameError: () => RpcReservedMethodNameError,
|
|
791
|
+
RpcSuccessDecodeError: () => RpcSuccessDecodeError,
|
|
792
|
+
RpcSuccessEncodeError: () => RpcSuccessEncodeError,
|
|
793
|
+
assertNoReservedMethodNames: () => assertNoReservedMethodNames,
|
|
794
|
+
assertNoReservedMethods: () => assertNoReservedMethods,
|
|
795
|
+
decodeArgs: () => decodeArgs,
|
|
796
|
+
decodeSuccess: () => decodeSuccess,
|
|
797
|
+
encodeArgs: () => encodeArgs,
|
|
798
|
+
encodeSuccess: () => encodeSuccess,
|
|
799
|
+
make: () => make$8,
|
|
800
|
+
method: () => method$4,
|
|
801
|
+
reservedMethodNames: () => reservedMethodNames$4
|
|
1365
802
|
});
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
803
|
+
var RpcReservedMethodNameError = class extends Data.TaggedError("RpcReservedMethodNameError") {};
|
|
804
|
+
var RpcArgumentCountError = class extends Data.TaggedError("RpcArgumentCountError") {};
|
|
805
|
+
var RpcArgumentDecodeError = class extends Data.TaggedError("RpcArgumentDecodeError") {};
|
|
806
|
+
var RpcArgumentEncodeError = class extends Data.TaggedError("RpcArgumentEncodeError") {};
|
|
807
|
+
var RpcSuccessDecodeError = class extends Data.TaggedError("RpcSuccessDecodeError") {};
|
|
808
|
+
var RpcSuccessEncodeError = class extends Data.TaggedError("RpcSuccessEncodeError") {};
|
|
809
|
+
const reservedMethodNames$4 = new Set([
|
|
810
|
+
"constructor",
|
|
811
|
+
"fetch",
|
|
812
|
+
"connect",
|
|
813
|
+
"alarm",
|
|
814
|
+
"webSocketMessage",
|
|
815
|
+
"webSocketClose",
|
|
816
|
+
"webSocketError",
|
|
817
|
+
"then",
|
|
818
|
+
"dup",
|
|
819
|
+
"dispose",
|
|
820
|
+
"serialize",
|
|
821
|
+
"deserialize"
|
|
822
|
+
]);
|
|
823
|
+
var ReservedMethodNameError = class extends Error {
|
|
824
|
+
method;
|
|
825
|
+
target;
|
|
826
|
+
constructor(target, method) {
|
|
827
|
+
super(`${target} RPC method "${method}" is reserved by Cloudflare Workers RPC`);
|
|
828
|
+
this.name = "ReservedMethodNameError";
|
|
829
|
+
this.target = target;
|
|
830
|
+
this.method = method;
|
|
1390
831
|
}
|
|
1391
|
-
return headers;
|
|
1392
832
|
};
|
|
1393
|
-
const
|
|
1394
|
-
const
|
|
1395
|
-
|
|
1396
|
-
|
|
833
|
+
const assertNoReservedMethods = (target, methods, reserved) => {
|
|
834
|
+
for (const method of Object.keys(methods)) if (reserved.has(method)) throw new ReservedMethodNameError(target, method);
|
|
835
|
+
};
|
|
836
|
+
function method$4(definition) {
|
|
1397
837
|
return {
|
|
1398
|
-
|
|
1399
|
-
|
|
838
|
+
args: definition.args ?? [],
|
|
839
|
+
success: definition.success
|
|
1400
840
|
};
|
|
1401
|
-
}
|
|
1402
|
-
const
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
841
|
+
}
|
|
842
|
+
const assertNoReservedMethodNames = (definition) => Effect.forEach(Object.keys(definition.methods), (method) => reservedMethodNames$4.has(method) ? Effect.fail(new RpcReservedMethodNameError({
|
|
843
|
+
definition: definition.id,
|
|
844
|
+
method
|
|
845
|
+
})) : Effect.void).pipe(Effect.asVoid);
|
|
846
|
+
const decodeArgs = (definition, methodName, args) => Effect.gen(function* () {
|
|
847
|
+
const methodDefinition = definition.methods[methodName];
|
|
848
|
+
if (args.length !== methodDefinition.args.length) return yield* Effect.fail(new RpcArgumentCountError({
|
|
849
|
+
definition: definition.id,
|
|
850
|
+
method: methodName,
|
|
851
|
+
expected: methodDefinition.args.length,
|
|
852
|
+
actual: args.length
|
|
853
|
+
}));
|
|
854
|
+
const decoded = [];
|
|
855
|
+
for (let index = 0; index < methodDefinition.args.length; index++) {
|
|
856
|
+
const schema = methodDefinition.args[index];
|
|
857
|
+
decoded.push(yield* Schema.decodeUnknownEffect(schema)(args[index]).pipe(Effect.mapError((cause) => new RpcArgumentDecodeError({
|
|
858
|
+
definition: definition.id,
|
|
859
|
+
method: methodName,
|
|
860
|
+
index,
|
|
861
|
+
cause
|
|
862
|
+
}))));
|
|
1407
863
|
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
const
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
864
|
+
return decoded;
|
|
865
|
+
});
|
|
866
|
+
const encodeArgs = (definition, methodName, args) => Effect.gen(function* () {
|
|
867
|
+
const methodDefinition = definition.methods[methodName];
|
|
868
|
+
if (args.length !== methodDefinition.args.length) return yield* Effect.fail(new RpcArgumentCountError({
|
|
869
|
+
definition: definition.id,
|
|
870
|
+
method: methodName,
|
|
871
|
+
expected: methodDefinition.args.length,
|
|
872
|
+
actual: args.length
|
|
873
|
+
}));
|
|
874
|
+
const encoded = [];
|
|
875
|
+
for (let index = 0; index < methodDefinition.args.length; index++) {
|
|
876
|
+
const schema = methodDefinition.args[index];
|
|
877
|
+
encoded.push(yield* Schema.encodeEffect(schema)(args[index]).pipe(Effect.mapError((cause) => new RpcArgumentEncodeError({
|
|
878
|
+
definition: definition.id,
|
|
879
|
+
method: methodName,
|
|
880
|
+
index,
|
|
881
|
+
cause
|
|
882
|
+
}))));
|
|
1417
883
|
}
|
|
884
|
+
return encoded;
|
|
1418
885
|
});
|
|
1419
|
-
const
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
886
|
+
const encodeSuccess = (definition, methodName, value) => {
|
|
887
|
+
const methodDefinition = definition.methods[methodName];
|
|
888
|
+
return Schema.encodeEffect(methodDefinition.success)(value).pipe(Effect.mapError((cause) => new RpcSuccessEncodeError({
|
|
889
|
+
definition: definition.id,
|
|
890
|
+
method: methodName,
|
|
891
|
+
cause
|
|
892
|
+
})));
|
|
893
|
+
};
|
|
894
|
+
const decodeSuccess = (definition, methodName, value) => {
|
|
895
|
+
const methodDefinition = definition.methods[methodName];
|
|
896
|
+
return Schema.decodeUnknownEffect(methodDefinition.success)(value).pipe(Effect.mapError((cause) => new RpcSuccessDecodeError({
|
|
897
|
+
definition: definition.id,
|
|
898
|
+
method: methodName,
|
|
899
|
+
cause
|
|
900
|
+
})));
|
|
901
|
+
};
|
|
902
|
+
const make$8 = (id, methods) => {
|
|
903
|
+
const definition = {
|
|
904
|
+
id,
|
|
905
|
+
methods
|
|
906
|
+
};
|
|
907
|
+
const reserved = Object.keys(definition.methods).find((methodName) => reservedMethodNames$4.has(methodName));
|
|
908
|
+
if (reserved !== void 0) throw new RpcReservedMethodNameError({
|
|
909
|
+
definition: id,
|
|
910
|
+
method: reserved
|
|
911
|
+
});
|
|
912
|
+
return definition;
|
|
913
|
+
};
|
|
914
|
+
//#endregion
|
|
915
|
+
//#region src/Rpc.ts
|
|
916
|
+
var Rpc_exports = /* @__PURE__ */ __exportAll({
|
|
917
|
+
RpcStub: () => RpcStub,
|
|
918
|
+
RpcTarget: () => RpcTarget,
|
|
919
|
+
dispose: () => dispose,
|
|
920
|
+
isDisposable: () => isDisposable,
|
|
921
|
+
resolve: () => resolve,
|
|
922
|
+
scoped: () => scoped
|
|
923
|
+
});
|
|
924
|
+
const isDisposable = (value) => (typeof value === "object" || typeof value === "function") && value !== null && Symbol.dispose in value && typeof value[Symbol.dispose] === "function";
|
|
925
|
+
const dispose = (value) => Effect.sync(() => {
|
|
926
|
+
if (isDisposable(value)) value[Symbol.dispose]();
|
|
927
|
+
});
|
|
928
|
+
const resolve = (value) => isPromiseLike(value) ? Effect.tryPromise({
|
|
929
|
+
try: () => value,
|
|
930
|
+
catch: (cause) => cause
|
|
931
|
+
}) : Effect.sync(() => value);
|
|
932
|
+
const scoped = (value) => Effect.acquireRelease(resolve(value), (resolved) => dispose(resolved));
|
|
933
|
+
const isPromiseLike = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
934
|
+
//#endregion
|
|
935
|
+
//#region src/internal/RpcInvocation.ts
|
|
936
|
+
const isPropertyTarget = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
|
|
937
|
+
const lookupRpcMethod = (target, method, makeError) => Effect.try({
|
|
938
|
+
try: () => {
|
|
939
|
+
if (!isPropertyTarget(target)) throw new TypeError(`RPC target is not object-like`);
|
|
940
|
+
const value = Reflect.get(target, method);
|
|
941
|
+
if (typeof value !== "function") throw new TypeError(`RPC method "${String(method)}" is not callable`);
|
|
942
|
+
return ((...args) => Reflect.apply(value, target, args));
|
|
943
|
+
},
|
|
944
|
+
catch: makeError
|
|
945
|
+
});
|
|
946
|
+
const invokeRpcMethod = (target, method, args, makeError) => Effect.gen(function* () {
|
|
947
|
+
const fn = yield* lookupRpcMethod(target, method, makeError);
|
|
948
|
+
return yield* Effect.try({
|
|
949
|
+
try: () => fn(...args),
|
|
950
|
+
catch: makeError
|
|
951
|
+
});
|
|
952
|
+
});
|
|
953
|
+
//#endregion
|
|
954
|
+
//#region src/ServiceBinding.ts
|
|
955
|
+
var ServiceBinding_exports = /* @__PURE__ */ __exportAll({
|
|
956
|
+
Service: () => Service,
|
|
957
|
+
ServiceBindingFetchError: () => ServiceBindingFetchError,
|
|
958
|
+
ServiceBindingRpcError: () => ServiceBindingRpcError,
|
|
959
|
+
isServiceBindingClient: () => isServiceBindingClient,
|
|
960
|
+
layer: () => layer$8,
|
|
961
|
+
makeClient: () => makeClient$5,
|
|
962
|
+
makeDirectMethods: () => makeDirectMethods$1
|
|
963
|
+
});
|
|
964
|
+
const TypeId$1 = "effect-cf/ServiceBinding";
|
|
965
|
+
const expectedServiceBinding = "Worker service binding with fetch()";
|
|
966
|
+
/**
|
|
967
|
+
* Failure raised when calling `fetch` on a service binding.
|
|
968
|
+
*/
|
|
969
|
+
var ServiceBindingFetchError = class extends Data.TaggedError("ServiceBindingFetchError") {};
|
|
970
|
+
/**
|
|
971
|
+
* Failure raised when invoking an RPC method on a service binding.
|
|
972
|
+
*/
|
|
973
|
+
var ServiceBindingRpcError = class extends Data.TaggedError("ServiceBindingRpcError") {};
|
|
974
|
+
const isServiceBindingClient = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "fetch") === "function";
|
|
975
|
+
const makeClient$5 = (definition) => {
|
|
976
|
+
return (service) => {
|
|
977
|
+
const fetch = (input, init) => Effect.tryPromise({
|
|
978
|
+
try: () => service.fetch(input, init),
|
|
979
|
+
catch: (cause) => new ServiceBindingFetchError({
|
|
980
|
+
binding: definition.binding,
|
|
981
|
+
cause
|
|
982
|
+
})
|
|
983
|
+
});
|
|
984
|
+
const rpc = (method, ...args) => Effect.gen(function* () {
|
|
985
|
+
const methodName = String(method);
|
|
986
|
+
return yield* invokeRpcMethod(service, method, definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
987
|
+
binding: definition.binding,
|
|
988
|
+
method: methodName,
|
|
989
|
+
cause
|
|
990
|
+
}))), (cause) => new ServiceBindingRpcError({
|
|
991
|
+
binding: definition.binding,
|
|
992
|
+
method: methodName,
|
|
993
|
+
cause
|
|
994
|
+
}));
|
|
995
|
+
});
|
|
996
|
+
const decodeSuccess$2 = (methodName, value) => Effect.gen(function* () {
|
|
997
|
+
if (definition.definition === void 0) return value;
|
|
998
|
+
return yield* decodeSuccess(definition.definition, methodName, value).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
999
|
+
binding: definition.binding,
|
|
1000
|
+
method: methodName,
|
|
1001
|
+
cause
|
|
1002
|
+
})));
|
|
1003
|
+
});
|
|
1004
|
+
const call = (method, ...args) => Effect.gen(function* () {
|
|
1005
|
+
const methodName = String(method);
|
|
1006
|
+
return yield* decodeSuccess$2(methodName, yield* resolve(yield* rpc(method, ...args)).pipe(Effect.mapError((cause) => new ServiceBindingRpcError({
|
|
1007
|
+
binding: definition.binding,
|
|
1008
|
+
method: methodName,
|
|
1009
|
+
cause
|
|
1010
|
+
}))));
|
|
1011
|
+
});
|
|
1012
|
+
const scopedCall = (method, ...args) => Effect.gen(function* () {
|
|
1013
|
+
return yield* decodeSuccess$2(String(method), yield* scoped(yield* rpc(method, ...args)));
|
|
1014
|
+
});
|
|
1015
|
+
const directMethods = makeDirectMethods$1(definition.definition, call);
|
|
1016
|
+
return Object.assign(directMethods, {
|
|
1017
|
+
fetch,
|
|
1018
|
+
rpc,
|
|
1019
|
+
call,
|
|
1020
|
+
scopedCall
|
|
1021
|
+
});
|
|
1022
|
+
};
|
|
1023
|
+
};
|
|
1024
|
+
const layer$8 = (tag, definition) => layer$11(tag, definition.binding, (value) => isServiceBindingClient(value), makeClient$5(definition), { expected: expectedServiceBinding });
|
|
1025
|
+
/**
|
|
1026
|
+
* Creates a typed Effect service for a Worker service binding.
|
|
1027
|
+
*
|
|
1028
|
+
* Returned value includes:
|
|
1029
|
+
* - a Context tag for dependency injection
|
|
1030
|
+
* - `fetch(...)` for raw HTTP forwarding
|
|
1031
|
+
* - `rpc(...)` for raw Cloudflare RPC results
|
|
1032
|
+
* - `call(...)` for resolved and decoded RPC results
|
|
1033
|
+
* - `scopedCall(...)` for scoped and decoded disposable RPC results
|
|
1034
|
+
* - direct RPC methods when `definition` is provided
|
|
1035
|
+
*
|
|
1036
|
+
* @example
|
|
1037
|
+
* ```ts
|
|
1038
|
+
* const Counter = WorkerDefinition.make("Counter", {
|
|
1039
|
+
* increment: WorkerDefinition.method({
|
|
1040
|
+
* args: [Schema.Number],
|
|
1041
|
+
* success: Schema.Number,
|
|
1042
|
+
* }),
|
|
1043
|
+
* });
|
|
1044
|
+
*
|
|
1045
|
+
* const CounterLive = Counter.layer({ binding: "COUNTER" });
|
|
1046
|
+
*
|
|
1047
|
+
* const program = Effect.gen(function* () {
|
|
1048
|
+
* const counter = yield* Counter;
|
|
1049
|
+
* const next = yield* counter.increment(1);
|
|
1050
|
+
* return next;
|
|
1051
|
+
* });
|
|
1052
|
+
* ```
|
|
1053
|
+
*/
|
|
1054
|
+
const Service = () => (id, definition) => {
|
|
1055
|
+
const tag = Service$2()(id, definition.binding, (value) => isServiceBindingClient(value), makeClient$5(definition));
|
|
1056
|
+
const fetch = (input, init) => Effect.gen(function* () {
|
|
1057
|
+
return yield* (yield* tag).fetch(input, init);
|
|
1058
|
+
});
|
|
1059
|
+
const rpc = (method, ...args) => Effect.gen(function* () {
|
|
1060
|
+
return yield* (yield* tag).rpc(method, ...args);
|
|
1061
|
+
});
|
|
1062
|
+
const call = (method, ...args) => Effect.gen(function* () {
|
|
1063
|
+
return yield* (yield* tag).call(method, ...args);
|
|
1064
|
+
});
|
|
1065
|
+
const scopedCall = (method, ...args) => Effect.gen(function* () {
|
|
1066
|
+
return yield* (yield* tag).scopedCall(method, ...args);
|
|
1067
|
+
});
|
|
1068
|
+
const directMethods = makeDirectMethods$1(definition.definition, call);
|
|
1069
|
+
return Object.assign(tag, directMethods, {
|
|
1070
|
+
[TypeId$1]: TypeId$1,
|
|
1071
|
+
definition,
|
|
1072
|
+
fetch,
|
|
1073
|
+
rpc,
|
|
1074
|
+
call,
|
|
1075
|
+
scopedCall
|
|
1076
|
+
});
|
|
1077
|
+
};
|
|
1078
|
+
const makeDirectMethods$1 = (rpcDefinition, call) => {
|
|
1079
|
+
const methods = {};
|
|
1080
|
+
if (rpcDefinition !== void 0) for (const methodName of Object.keys(rpcDefinition.methods)) methods[methodName] = (...args) => call(methodName, ...args);
|
|
1081
|
+
return methods;
|
|
1082
|
+
};
|
|
1083
|
+
//#endregion
|
|
1084
|
+
//#region src/WorkerDefinition.ts
|
|
1085
|
+
var WorkerDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
1086
|
+
Tag: () => Tag$8,
|
|
1087
|
+
Worker: () => Worker,
|
|
1088
|
+
implement: () => implement$5,
|
|
1089
|
+
make: () => make$7,
|
|
1090
|
+
method: () => method$3
|
|
1091
|
+
});
|
|
1092
|
+
const reservedMethodNames$3 = new Set([
|
|
1093
|
+
"constructor",
|
|
1094
|
+
"dup",
|
|
1095
|
+
"fetch",
|
|
1096
|
+
"connect",
|
|
1097
|
+
"queue",
|
|
1098
|
+
"scheduled",
|
|
1099
|
+
"tail",
|
|
1100
|
+
"tailStream",
|
|
1101
|
+
"test",
|
|
1102
|
+
"trace",
|
|
1103
|
+
"alarm",
|
|
1104
|
+
"webSocketMessage",
|
|
1105
|
+
"webSocketClose",
|
|
1106
|
+
"webSocketError"
|
|
1107
|
+
]);
|
|
1108
|
+
/**
|
|
1109
|
+
* Defines a single RPC method schema in a worker definition.
|
|
1110
|
+
*/
|
|
1111
|
+
const method$3 = method$4;
|
|
1112
|
+
/**
|
|
1113
|
+
* Creates a typed worker RPC definition plus helpers for implementation and bindings.
|
|
1114
|
+
*
|
|
1115
|
+
* @example
|
|
1116
|
+
* ```ts
|
|
1117
|
+
* const CounterWorker = WorkerDefinition.make("CounterWorker", {
|
|
1118
|
+
* increment: WorkerDefinition.method({
|
|
1119
|
+
* args: [Schema.Number],
|
|
1120
|
+
* success: Schema.Number,
|
|
1121
|
+
* }),
|
|
1122
|
+
* });
|
|
1123
|
+
* ```
|
|
1124
|
+
*/
|
|
1125
|
+
const makeDefinition$3 = (id, methods) => {
|
|
1126
|
+
assertNoReservedMethods("Worker", methods, reservedMethodNames$3);
|
|
1127
|
+
const definition = make$8(id, methods);
|
|
1128
|
+
return Object.assign(definition, { make: (layer, options) => make$6(layer, {
|
|
1129
|
+
...options,
|
|
1130
|
+
rpc: wrapHandlers$1(definition, options.rpc)
|
|
1131
|
+
}) });
|
|
1132
|
+
};
|
|
1133
|
+
const make$7 = (id, methods) => Tag$8()(id, methods);
|
|
1134
|
+
const Tag$8 = () => (id, methods) => {
|
|
1135
|
+
const definition = makeDefinition$3(id, methods);
|
|
1136
|
+
const tag = Context.Service()(id);
|
|
1137
|
+
const bindingDefinition = (binding) => ({
|
|
1138
|
+
...binding,
|
|
1139
|
+
definition
|
|
1140
|
+
});
|
|
1141
|
+
const layer = (binding) => layer$8(tag, bindingDefinition(binding));
|
|
1142
|
+
const fetch = (input, init) => Effect.gen(function* () {
|
|
1143
|
+
return yield* (yield* tag).fetch(input, init);
|
|
1144
|
+
});
|
|
1145
|
+
const rpc = (method, ...args) => Effect.gen(function* () {
|
|
1146
|
+
return yield* (yield* tag).rpc(method, ...args);
|
|
1147
|
+
});
|
|
1148
|
+
const call = (method, ...args) => Effect.gen(function* () {
|
|
1149
|
+
return yield* (yield* tag).call(method, ...args);
|
|
1150
|
+
});
|
|
1151
|
+
const scopedCall = (method, ...args) => Effect.gen(function* () {
|
|
1152
|
+
return yield* (yield* tag).scopedCall(method, ...args);
|
|
1153
|
+
});
|
|
1154
|
+
const directMethods = makeDirectMethods$1(definition, call);
|
|
1155
|
+
return Object.assign(tag, directMethods, {
|
|
1156
|
+
id: definition.id,
|
|
1157
|
+
methods: definition.methods,
|
|
1158
|
+
make: definition.make,
|
|
1159
|
+
layer,
|
|
1160
|
+
fetch,
|
|
1161
|
+
rpc,
|
|
1162
|
+
call,
|
|
1163
|
+
scopedCall
|
|
1164
|
+
});
|
|
1165
|
+
};
|
|
1166
|
+
const Worker = Tag$8;
|
|
1167
|
+
const wrapHandlers$1 = (definition, handlers) => {
|
|
1168
|
+
const wrapped = {};
|
|
1169
|
+
for (const key of Object.keys(definition.methods)) {
|
|
1170
|
+
const handler = handlers[key];
|
|
1171
|
+
wrapped[key] = (...args) => Effect.gen(function* () {
|
|
1172
|
+
return yield* encodeSuccess(definition, key, yield* handler(...yield* decodeArgs(definition, key, args)));
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
return wrapped;
|
|
1176
|
+
};
|
|
1177
|
+
/**
|
|
1178
|
+
* Helper for implementing handlers with the exact method shape of a definition.
|
|
1179
|
+
*/
|
|
1180
|
+
const implement$5 = (_definition, handlers) => handlers;
|
|
1181
|
+
//#endregion
|
|
1182
|
+
//#region src/internal/Clock.ts
|
|
1183
|
+
const maxTimerMillis = 2 ** 31 - 1;
|
|
1184
|
+
const nanosPerMilli = BigInt(1e6);
|
|
1185
|
+
const clock = {
|
|
1186
|
+
currentTimeMillisUnsafe: () => Date.now(),
|
|
1187
|
+
currentTimeMillis: Effect.sync(() => clock.currentTimeMillisUnsafe()),
|
|
1188
|
+
currentTimeNanosUnsafe: () => BigInt(Date.now()) * nanosPerMilli,
|
|
1189
|
+
currentTimeNanos: Effect.sync(() => clock.currentTimeNanosUnsafe()),
|
|
1190
|
+
sleep: (duration) => {
|
|
1191
|
+
const millis = Duration.toMillis(duration);
|
|
1192
|
+
if (millis <= 0) return Effect.yieldNow;
|
|
1193
|
+
return Effect.callback((resume) => {
|
|
1194
|
+
if (millis > maxTimerMillis) return;
|
|
1195
|
+
const handle = setTimeout(() => resume(Effect.void), millis);
|
|
1196
|
+
return Effect.sync(() => clearTimeout(handle));
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
};
|
|
1200
|
+
const layer$7 = Layer.effect(Clock.Clock, Effect.succeed(clock));
|
|
1201
|
+
//#endregion
|
|
1202
|
+
//#region src/internal/Entrypoint.ts
|
|
1203
|
+
const provideEntrypointServices = (layer, services) => layer.pipe(Layer.provideMerge(services));
|
|
1204
|
+
const defineEntrypointRpcMethods = (target, prototype, rpc, reservedMethodNames, run) => {
|
|
1205
|
+
const methods = rpc ?? {};
|
|
1206
|
+
assertNoReservedMethods(target, methods, reservedMethodNames);
|
|
1207
|
+
for (const [key, method] of Object.entries(methods)) Object.defineProperty(prototype, key, {
|
|
1208
|
+
enumerable: true,
|
|
1209
|
+
value(...args) {
|
|
1210
|
+
return run(this, Effect.suspend(() => method(...args)));
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1213
|
+
};
|
|
1214
|
+
const assumeEntrypointClass = (entrypoint) => entrypoint;
|
|
1215
|
+
//#endregion
|
|
1216
|
+
//#region src/internal/WorkerContext.ts
|
|
1217
|
+
const causeError = (cause) => new Error(Cause.pretty(cause));
|
|
1218
|
+
const failureHandler = (cause, options) => (options?.onFailure?.(cause) ?? Effect.logError("WorkerContext.waitUntil failed", Cause.pretty(cause))).pipe(Effect.catchCause((handlerCause) => Effect.logError("WorkerContext.waitUntil failure handler failed", Cause.pretty(cause), Cause.pretty(handlerCause))));
|
|
1219
|
+
const fromExecutionContext = (ctx, runPromiseExit) => {
|
|
1220
|
+
const schedule = (effect, options, mode) => Effect.context().pipe(Effect.flatMap((context) => Effect.sync(() => {
|
|
1221
|
+
const runHandler = (cause) => runPromiseExit(Effect.scoped(Effect.provideContext(failureHandler(cause, options), context))).then((exit) => {
|
|
1222
|
+
if (Exit.isFailure(exit)) console.error("WorkerContext.waitUntil failure handler failed", Cause.pretty(exit.cause));
|
|
1223
|
+
});
|
|
1224
|
+
ctx.waitUntil(runPromiseExit(Effect.scoped(Effect.provideContext(effect, context))).then(async (exit) => {
|
|
1225
|
+
if (Exit.isSuccess(exit)) return;
|
|
1226
|
+
await runHandler(exit.cause);
|
|
1227
|
+
if (mode === "propagate") throw causeError(exit.cause);
|
|
1228
|
+
}));
|
|
1229
|
+
})));
|
|
1230
|
+
return {
|
|
1231
|
+
raw: ctx,
|
|
1232
|
+
waitUntil: (effect, options) => schedule(effect, options, options?.mode ?? "observe"),
|
|
1233
|
+
waitUntilPropagating: (effect, options) => schedule(effect, options, "propagate"),
|
|
1234
|
+
passThroughOnException: Effect.sync(() => ctx.passThroughOnException())
|
|
1235
|
+
};
|
|
1236
|
+
};
|
|
1237
|
+
//#endregion
|
|
1238
|
+
//#region src/Worker.ts
|
|
1239
|
+
var Worker_exports = /* @__PURE__ */ __exportAll({
|
|
1240
|
+
ExecutionContext: () => ExecutionContext,
|
|
1241
|
+
NativeRequest: () => NativeRequest,
|
|
1242
|
+
Tag: () => Tag$7,
|
|
1243
|
+
WorkerContext: () => WorkerContext,
|
|
1244
|
+
implement: () => implement$4,
|
|
1245
|
+
isWebSocketUpgrade: () => isWebSocketUpgrade,
|
|
1246
|
+
make: () => make$6,
|
|
1247
|
+
makeFetchHandler: () => makeFetchHandler,
|
|
1248
|
+
method: () => method$2,
|
|
1249
|
+
renderHttpResponse: () => renderHttpResponse
|
|
1430
1250
|
});
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1251
|
+
var ExecutionContext = class extends Context.Service()("effect-cf/ExecutionContext") {};
|
|
1252
|
+
var WorkerContext = class extends Context.Service()("effect-cf/WorkerContext") {};
|
|
1253
|
+
var NativeRequest = class extends Context.Service()("effect-cf/NativeRequest") {};
|
|
1254
|
+
const isWebSocketUpgrade = (request) => request.headers.get("Upgrade")?.toLowerCase() === "websocket";
|
|
1255
|
+
const reservedMethodNames$2 = new Set([
|
|
1256
|
+
"constructor",
|
|
1257
|
+
"dup",
|
|
1258
|
+
"fetch",
|
|
1259
|
+
"connect",
|
|
1260
|
+
"queue",
|
|
1261
|
+
"scheduled",
|
|
1262
|
+
"tail",
|
|
1263
|
+
"tailStream",
|
|
1264
|
+
"test",
|
|
1265
|
+
"trace",
|
|
1266
|
+
"alarm",
|
|
1267
|
+
"webSocketMessage",
|
|
1268
|
+
"webSocketClose",
|
|
1269
|
+
"webSocketError"
|
|
1270
|
+
]);
|
|
1271
|
+
const RunSymbol$1 = Symbol.for("effect-cf/Worker/run");
|
|
1272
|
+
const renderHttpResponse = (effect) => Effect.flatMap(effect, (response) => Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
|
|
1273
|
+
const renderFetchSuccess = (effect) => Effect.flatMap(effect, (response) => response instanceof Response ? Effect.succeed(response) : Effect.map(Effect.context(), (context) => HttpServerResponse.toWeb(response, { context })));
|
|
1274
|
+
const isWorkerOptions = (options) => typeof options === "object" && options !== null && ("eventLayer" in options || "fetch" in options || "queue" in options || "rpc" in options);
|
|
1275
|
+
function make$6(layer, optionsOrFetch) {
|
|
1276
|
+
const options = isWorkerOptions(optionsOrFetch) ? optionsOrFetch : { fetch: optionsOrFetch };
|
|
1277
|
+
class EffectWorker extends WorkerEntrypoint {
|
|
1278
|
+
runtime;
|
|
1279
|
+
constructor(ctx, env) {
|
|
1280
|
+
super(ctx, env);
|
|
1281
|
+
let runWaitUntilEffect = () => Promise.reject(/* @__PURE__ */ new Error("WorkerContext runtime is not initialized"));
|
|
1282
|
+
const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(layer$7, Layer.succeed(ExecutionContext, ctx), ConfigProvider.layer(Effect.succeed(WorkerConfig.providerFromEnv(env))), Layer.succeed(WorkerContext, fromExecutionContext(ctx, (effect) => runWaitUntilEffect(effect))), Layer.succeed(WorkerEnvironment, env)));
|
|
1283
|
+
this.runtime = ManagedRuntime.make(runtimeLayer);
|
|
1284
|
+
runWaitUntilEffect = (effect) => this.runtime.runPromiseExit(effect);
|
|
1285
|
+
}
|
|
1286
|
+
[RunSymbol$1](effect, runOptions = {}) {
|
|
1287
|
+
const effectWithEventLayer = runOptions.eventLayer === false || options.eventLayer === void 0 ? effect : effect.pipe(Effect.provide(options.eventLayer, { local: true }));
|
|
1288
|
+
return this.runtime.runPromise(Effect.scoped(effectWithEventLayer));
|
|
1289
|
+
}
|
|
1290
|
+
fetch(request) {
|
|
1291
|
+
const fetchHandler = options.fetch;
|
|
1292
|
+
if (fetchHandler === void 0) return Promise.resolve(new Response("Not Found", { status: 404 }));
|
|
1293
|
+
const requestServices = Layer.mergeAll(Layer.succeed(NativeRequest, request), Layer.succeed(HttpServerRequest.HttpServerRequest, HttpServerRequest.fromWeb(request)));
|
|
1294
|
+
return this[RunSymbol$1](renderFetchSuccess(fetchHandler).pipe(Effect.provide(requestServices)));
|
|
1295
|
+
}
|
|
1296
|
+
queue(batch) {
|
|
1297
|
+
const queueHandler = options.queue;
|
|
1298
|
+
if (queueHandler === void 0) return Promise.resolve();
|
|
1299
|
+
const messages = batch.messages.map((message) => fromMessage(message, message.body));
|
|
1300
|
+
return this[RunSymbol$1](queueHandler(fromMessageBatch(batch, messages)));
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
defineEntrypointRpcMethods("Worker", EffectWorker.prototype, options.rpc, reservedMethodNames$2, (self, effect) => self[RunSymbol$1](effect));
|
|
1304
|
+
return assumeEntrypointClass(EffectWorker);
|
|
1305
|
+
}
|
|
1306
|
+
const makeFetchHandler = (layer, options) => {
|
|
1307
|
+
const WorkerClass = make$6(layer, options);
|
|
1308
|
+
return { fetch: (request, env, ctx) => Promise.resolve(new WorkerClass(ctx, env).fetch(request)) };
|
|
1309
|
+
};
|
|
1310
|
+
const Tag$7 = Tag$8;
|
|
1311
|
+
const method$2 = method$3;
|
|
1312
|
+
const implement$4 = implement$5;
|
|
1313
|
+
//#endregion
|
|
1314
|
+
//#region src/DurableObjectNamespace.ts
|
|
1315
|
+
var DurableObjectNamespace_exports = /* @__PURE__ */ __exportAll({
|
|
1316
|
+
DurableObjectFetchError: () => DurableObjectFetchError,
|
|
1317
|
+
DurableObjectRpcError: () => DurableObjectRpcError,
|
|
1318
|
+
isDurableObjectNamespaceClient: () => isDurableObjectNamespaceClient,
|
|
1319
|
+
layer: () => layer$6,
|
|
1320
|
+
makeClient: () => makeClient$4,
|
|
1321
|
+
makeDirectMethods: () => makeDirectMethods
|
|
1438
1322
|
});
|
|
1439
|
-
const
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1323
|
+
const expectedDurableObjectNamespace = "Durable Object namespace binding with getByName(), get(), idFromName(), idFromString(), newUniqueId(), and jurisdiction()";
|
|
1324
|
+
/**
|
|
1325
|
+
* Failure raised when invoking an RPC method on a Durable Object stub.
|
|
1326
|
+
*/
|
|
1327
|
+
var DurableObjectRpcError = class extends Data.TaggedError("DurableObjectRpcError") {};
|
|
1328
|
+
/**
|
|
1329
|
+
* Failure raised when forwarding a request to a Durable Object stub.
|
|
1330
|
+
*/
|
|
1331
|
+
var DurableObjectFetchError = class extends Data.TaggedError("DurableObjectFetchError") {};
|
|
1332
|
+
const hasFunction$1 = (value, key) => typeof Reflect.get(value, key) === "function";
|
|
1333
|
+
const isDurableObjectNamespaceClient = (value) => typeof value === "object" && value !== null && hasFunction$1(value, "getByName") && hasFunction$1(value, "get") && hasFunction$1(value, "idFromName") && hasFunction$1(value, "idFromString") && hasFunction$1(value, "newUniqueId") && hasFunction$1(value, "jurisdiction");
|
|
1334
|
+
const makeClient$4 = (definition) => {
|
|
1335
|
+
return (namespace) => {
|
|
1336
|
+
const newUniqueId = (options) => Effect.sync(() => namespace.newUniqueId(options));
|
|
1337
|
+
const idFromName = (name) => Effect.sync(() => namespace.idFromName(name));
|
|
1338
|
+
const idFromString = (id) => Effect.sync(() => namespace.idFromString(id));
|
|
1339
|
+
const get = (id, options) => Effect.sync(() => namespace.get(id, options));
|
|
1340
|
+
const getByName = (name, options) => Effect.sync(() => namespace.getByName(name, options));
|
|
1341
|
+
const jurisdiction = (value) => Effect.sync(() => namespace.jurisdiction(value));
|
|
1342
|
+
const fetch = (stub, input, init) => Effect.tryPromise({
|
|
1343
|
+
try: () => stub.fetch(input, init),
|
|
1344
|
+
catch: (cause) => new DurableObjectFetchError({
|
|
1345
|
+
binding: definition.binding,
|
|
1346
|
+
cause
|
|
1347
|
+
})
|
|
1348
|
+
});
|
|
1349
|
+
const rpc = (stub, method, ...args) => Effect.gen(function* () {
|
|
1350
|
+
const methodName = String(method);
|
|
1351
|
+
return yield* invokeRpcMethod(stub, method, definition.definition === void 0 ? args : yield* encodeArgs(definition.definition, methodName, args).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1352
|
+
binding: definition.binding,
|
|
1353
|
+
method: methodName,
|
|
1354
|
+
cause
|
|
1355
|
+
}))), (cause) => new DurableObjectRpcError({
|
|
1356
|
+
binding: definition.binding,
|
|
1357
|
+
method: methodName,
|
|
1358
|
+
cause
|
|
1359
|
+
}));
|
|
1360
|
+
});
|
|
1361
|
+
const decodeSuccess$1 = (methodName, value) => Effect.gen(function* () {
|
|
1362
|
+
if (definition.definition === void 0) return value;
|
|
1363
|
+
return yield* decodeSuccess(definition.definition, methodName, value).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1364
|
+
binding: definition.binding,
|
|
1365
|
+
method: methodName,
|
|
1366
|
+
cause
|
|
1367
|
+
})));
|
|
1368
|
+
});
|
|
1369
|
+
const call = (stub, method, ...args) => Effect.gen(function* () {
|
|
1370
|
+
const methodName = String(method);
|
|
1371
|
+
return yield* decodeSuccess$1(methodName, yield* resolve(yield* rpc(stub, method, ...args)).pipe(Effect.mapError((cause) => new DurableObjectRpcError({
|
|
1372
|
+
binding: definition.binding,
|
|
1373
|
+
method: methodName,
|
|
1374
|
+
cause
|
|
1375
|
+
}))));
|
|
1376
|
+
});
|
|
1377
|
+
const scopedCall = (stub, method, ...args) => Effect.gen(function* () {
|
|
1378
|
+
return yield* decodeSuccess$1(String(method), yield* scoped(yield* rpc(stub, method, ...args)));
|
|
1379
|
+
});
|
|
1380
|
+
const directMethods = makeDirectMethods(definition.definition, {
|
|
1381
|
+
call,
|
|
1382
|
+
fetch,
|
|
1383
|
+
get,
|
|
1384
|
+
getByName
|
|
1385
|
+
});
|
|
1386
|
+
return Object.assign(directMethods, {
|
|
1387
|
+
newUniqueId,
|
|
1388
|
+
idFromName,
|
|
1389
|
+
idFromString,
|
|
1390
|
+
get,
|
|
1391
|
+
getByName,
|
|
1392
|
+
jurisdiction,
|
|
1393
|
+
fetch,
|
|
1394
|
+
rpc,
|
|
1395
|
+
call,
|
|
1396
|
+
scopedCall,
|
|
1397
|
+
unsafeRaw: Effect.succeed(namespace)
|
|
1398
|
+
});
|
|
1399
|
+
};
|
|
1444
1400
|
};
|
|
1445
|
-
const
|
|
1446
|
-
const
|
|
1447
|
-
const
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
if (url !== void 0) layers.push(OtlpLogger.layer({
|
|
1464
|
-
url,
|
|
1465
|
-
resource: common.resource,
|
|
1466
|
-
headers: mergeHeaders(settings.headers, settings.logsHeaders),
|
|
1467
|
-
exportInterval: common.loggerExportInterval,
|
|
1468
|
-
maxBatchSize: common.maxBatchSize,
|
|
1469
|
-
shutdownTimeout: common.shutdownTimeout,
|
|
1470
|
-
excludeLogSpans: common.loggerExcludeLogSpans,
|
|
1471
|
-
mergeWithExisting: common.loggerMergeWithExisting
|
|
1472
|
-
}).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
|
|
1473
|
-
}
|
|
1474
|
-
if (signals.has("traces")) {
|
|
1475
|
-
const url = tracesEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/traces"));
|
|
1476
|
-
if (url !== void 0) layers.push(OtlpTracer.layer({
|
|
1477
|
-
url,
|
|
1478
|
-
resource: common.resource,
|
|
1479
|
-
headers: mergeHeaders(settings.headers, settings.tracesHeaders),
|
|
1480
|
-
exportInterval: common.tracerExportInterval,
|
|
1481
|
-
maxBatchSize: common.maxBatchSize,
|
|
1482
|
-
context: common.tracerContext,
|
|
1483
|
-
shutdownTimeout: common.shutdownTimeout
|
|
1484
|
-
}).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
|
|
1485
|
-
}
|
|
1486
|
-
if (signals.has("metrics")) {
|
|
1487
|
-
const url = metricsEndpoint ?? (endpoint === void 0 ? void 0 : appendOtlpPath(endpoint, "/v1/metrics"));
|
|
1488
|
-
if (url !== void 0) layers.push(OtlpMetrics.layer({
|
|
1489
|
-
url,
|
|
1490
|
-
resource: common.resource,
|
|
1491
|
-
headers: mergeHeaders(settings.headers, settings.metricsHeaders),
|
|
1492
|
-
exportInterval: common.metricsExportInterval,
|
|
1493
|
-
shutdownTimeout: common.shutdownTimeout,
|
|
1494
|
-
temporality: common.metricsTemporality
|
|
1495
|
-
}).pipe(Layer.provide(serializationLayer(options.serialization)), Layer.provide(FetchHttpClient.layer)));
|
|
1401
|
+
const layer$6 = (tag, definition) => layer$11(tag, definition.binding, (value) => isDurableObjectNamespaceClient(value), makeClient$4(definition), { expected: expectedDurableObjectNamespace });
|
|
1402
|
+
const makeDirectMethods = (rpcDefinition, helpers) => {
|
|
1403
|
+
const methods = {};
|
|
1404
|
+
if (rpcDefinition !== void 0) {
|
|
1405
|
+
for (const methodName of Object.keys(rpcDefinition.methods)) methods[methodName] = (stub, ...args) => helpers.call(stub, methodName, ...args);
|
|
1406
|
+
const makeClient = (getStub) => {
|
|
1407
|
+
const client = { fetch: (input, init) => Effect.gen(function* () {
|
|
1408
|
+
const stub = yield* getStub();
|
|
1409
|
+
return yield* helpers.fetch(stub, input, init);
|
|
1410
|
+
}) };
|
|
1411
|
+
for (const methodName of Object.keys(rpcDefinition.methods)) client[methodName] = (...args) => Effect.gen(function* () {
|
|
1412
|
+
const stub = yield* getStub();
|
|
1413
|
+
return yield* helpers.call(stub, methodName, ...args);
|
|
1414
|
+
});
|
|
1415
|
+
return client;
|
|
1416
|
+
};
|
|
1417
|
+
methods.byName = (name, options) => makeClient(() => helpers.getByName(name, options));
|
|
1418
|
+
methods.byId = (id, options) => makeClient(() => helpers.get(id, options));
|
|
1496
1419
|
}
|
|
1497
|
-
return
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
* When only `OTEL_EXPORTER_OTLP_ENDPOINT` is configured, per-signal paths are
|
|
1508
|
-
* derived by appending `/v1/logs`, `/v1/traces`, and `/v1/metrics`. Signal
|
|
1509
|
-
* specific endpoints are used as-is, matching the OpenTelemetry OTLP exporter
|
|
1510
|
-
* convention.
|
|
1511
|
-
*/
|
|
1512
|
-
const layer$6 = (options = {}) => makeLayer(options);
|
|
1513
|
-
/** Base OTLP telemetry layer forced to JSON serialization. */
|
|
1514
|
-
const layerJson = (options = {}) => layer$6({
|
|
1515
|
-
...options,
|
|
1516
|
-
serialization: "json"
|
|
1517
|
-
});
|
|
1518
|
-
/** Base OTLP telemetry layer forced to protobuf serialization. */
|
|
1519
|
-
const layerProtobuf = (options = {}) => layer$6({
|
|
1520
|
-
...options,
|
|
1521
|
-
serialization: "protobuf"
|
|
1420
|
+
return methods;
|
|
1421
|
+
};
|
|
1422
|
+
//#endregion
|
|
1423
|
+
//#region src/DurableObjectDefinition.ts
|
|
1424
|
+
var DurableObjectDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
1425
|
+
DurableObject: () => DurableObject$1,
|
|
1426
|
+
Tag: () => Tag$6,
|
|
1427
|
+
implement: () => implement$3,
|
|
1428
|
+
make: () => make$5,
|
|
1429
|
+
method: () => method$1
|
|
1522
1430
|
});
|
|
1431
|
+
const reservedMethodNames$1 = new Set([
|
|
1432
|
+
"constructor",
|
|
1433
|
+
"dup",
|
|
1434
|
+
"fetch",
|
|
1435
|
+
"alarm",
|
|
1436
|
+
"webSocketMessage",
|
|
1437
|
+
"webSocketClose",
|
|
1438
|
+
"webSocketError"
|
|
1439
|
+
]);
|
|
1523
1440
|
/**
|
|
1524
|
-
*
|
|
1525
|
-
*
|
|
1526
|
-
* Provide this layer at runtime scope for long-lived metrics aggregation, or at
|
|
1527
|
-
* handler scope when traces/logs should flush as the Cloudflare event finishes.
|
|
1441
|
+
* Defines a single RPC method schema in a Durable Object definition.
|
|
1528
1442
|
*/
|
|
1529
|
-
const
|
|
1530
|
-
"cloudflare.resource_type": "worker",
|
|
1531
|
-
"cloudflare.worker.name": options.workerName
|
|
1532
|
-
});
|
|
1443
|
+
const method$1 = method$4;
|
|
1533
1444
|
/**
|
|
1534
|
-
*
|
|
1445
|
+
* Creates a Durable Object RPC definition plus implementation/binding helpers.
|
|
1535
1446
|
*
|
|
1536
|
-
*
|
|
1537
|
-
*
|
|
1538
|
-
*
|
|
1447
|
+
* @example
|
|
1448
|
+
* ```ts
|
|
1449
|
+
* const ChatRoom = DurableObjectDefinition.make("ChatRoom", {
|
|
1450
|
+
* postMessage: DurableObjectDefinition.method({
|
|
1451
|
+
* args: [Schema.String],
|
|
1452
|
+
* success: Schema.Void,
|
|
1453
|
+
* }),
|
|
1454
|
+
* });
|
|
1455
|
+
* ```
|
|
1539
1456
|
*/
|
|
1540
|
-
const
|
|
1541
|
-
"
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
return new Proxy(rpc, { get(target, property, receiver) {
|
|
1548
|
-
const handler = Reflect.get(target, property, receiver);
|
|
1549
|
-
if (typeof handler !== "function") return handler;
|
|
1550
|
-
return (...args) => Effect.suspend(() => Reflect.apply(handler, receiver, args)).pipe(Effect.provide(layer));
|
|
1551
|
-
} });
|
|
1457
|
+
const makeDefinition$2 = (id, methods) => {
|
|
1458
|
+
assertNoReservedMethods("Durable Object", methods, reservedMethodNames$1);
|
|
1459
|
+
const definition = make$8(id, methods);
|
|
1460
|
+
return Object.assign(definition, { make: (layer, options) => make$4(layer, {
|
|
1461
|
+
...options,
|
|
1462
|
+
rpc: wrapHandlers(definition, options.rpc)
|
|
1463
|
+
}) });
|
|
1552
1464
|
};
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
const
|
|
1562
|
-
const
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1465
|
+
const make$5 = (id, methods) => Tag$6()(id, methods);
|
|
1466
|
+
const Tag$6 = () => (id, methods) => {
|
|
1467
|
+
const definition = makeDefinition$2(id, methods);
|
|
1468
|
+
const tag = Context.Service()(id);
|
|
1469
|
+
const bindingDefinition = (binding) => ({
|
|
1470
|
+
...binding,
|
|
1471
|
+
definition
|
|
1472
|
+
});
|
|
1473
|
+
const layer = (binding) => layer$6(tag, bindingDefinition(binding));
|
|
1474
|
+
const newUniqueId = Effect.fnUntraced(function* (options) {
|
|
1475
|
+
return yield* (yield* tag).newUniqueId(options);
|
|
1476
|
+
});
|
|
1477
|
+
const idFromName = Effect.fnUntraced(function* (name) {
|
|
1478
|
+
return yield* (yield* tag).idFromName(name);
|
|
1479
|
+
});
|
|
1480
|
+
const idFromString = Effect.fnUntraced(function* (value) {
|
|
1481
|
+
return yield* (yield* tag).idFromString(value);
|
|
1482
|
+
});
|
|
1483
|
+
const get = Effect.fnUntraced(function* (objectId, options) {
|
|
1484
|
+
return yield* (yield* tag).get(objectId, options);
|
|
1485
|
+
});
|
|
1486
|
+
const getByName = Effect.fnUntraced(function* (name, options) {
|
|
1487
|
+
return yield* (yield* tag).getByName(name, options);
|
|
1488
|
+
});
|
|
1489
|
+
const jurisdiction = Effect.fnUntraced(function* (value) {
|
|
1490
|
+
return yield* (yield* tag).jurisdiction(value);
|
|
1491
|
+
});
|
|
1492
|
+
const fetch = (stub, input, init) => Effect.gen(function* () {
|
|
1493
|
+
return yield* (yield* tag).fetch(stub, input, init);
|
|
1494
|
+
});
|
|
1495
|
+
const rpc = (stub, method, ...args) => Effect.gen(function* () {
|
|
1496
|
+
return yield* (yield* tag).rpc(stub, method, ...args);
|
|
1497
|
+
});
|
|
1498
|
+
const call = (stub, method, ...args) => Effect.gen(function* () {
|
|
1499
|
+
return yield* (yield* tag).call(stub, method, ...args);
|
|
1500
|
+
});
|
|
1501
|
+
const scopedCall = (stub, method, ...args) => Effect.gen(function* () {
|
|
1502
|
+
return yield* (yield* tag).scopedCall(stub, method, ...args);
|
|
1503
|
+
});
|
|
1504
|
+
const unsafeRaw = Effect.fnUntraced(function* () {
|
|
1505
|
+
return yield* (yield* tag).unsafeRaw;
|
|
1506
|
+
});
|
|
1507
|
+
const directMethods = makeDirectMethods(definition, {
|
|
1508
|
+
call,
|
|
1509
|
+
fetch,
|
|
1510
|
+
get,
|
|
1511
|
+
getByName
|
|
1512
|
+
});
|
|
1513
|
+
return Object.assign(tag, directMethods, {
|
|
1514
|
+
id: definition.id,
|
|
1515
|
+
methods: definition.methods,
|
|
1516
|
+
make: definition.make,
|
|
1517
|
+
layer,
|
|
1518
|
+
newUniqueId,
|
|
1519
|
+
idFromName,
|
|
1520
|
+
idFromString,
|
|
1521
|
+
get,
|
|
1522
|
+
getByName,
|
|
1523
|
+
jurisdiction,
|
|
1524
|
+
fetch,
|
|
1525
|
+
rpc,
|
|
1526
|
+
call,
|
|
1527
|
+
scopedCall,
|
|
1528
|
+
unsafeRaw
|
|
1529
|
+
});
|
|
1530
|
+
};
|
|
1531
|
+
const DurableObject$1 = Tag$6;
|
|
1532
|
+
const wrapHandlers = (definition, handlers) => {
|
|
1533
|
+
const wrapped = {};
|
|
1534
|
+
for (const key of Object.keys(definition.methods)) {
|
|
1535
|
+
const handler = handlers[key];
|
|
1536
|
+
wrapped[key] = (...args) => Effect.gen(function* () {
|
|
1537
|
+
return yield* encodeSuccess(definition, key, yield* handler(...yield* decodeArgs(definition, key, args)));
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
return wrapped;
|
|
1569
1541
|
};
|
|
1570
1542
|
/**
|
|
1571
|
-
*
|
|
1572
|
-
*
|
|
1573
|
-
* Each defined handler is provided with {@link durableObjectLayer}. Because
|
|
1574
|
-
* Durable Object handlers run inside `Effect.scoped`, the exporter scope closes
|
|
1575
|
-
* and flushes at the end of each Cloudflare event.
|
|
1543
|
+
* Helper for implementing handlers with the exact method shape of a definition.
|
|
1576
1544
|
*/
|
|
1577
|
-
const
|
|
1578
|
-
const telemetryLayer = durableObjectLayer(options);
|
|
1579
|
-
const alarm = handlers.alarm;
|
|
1580
|
-
const webSocketMessage = handlers.webSocketMessage;
|
|
1581
|
-
const webSocketClose = handlers.webSocketClose;
|
|
1582
|
-
const webSocketError = handlers.webSocketError;
|
|
1583
|
-
return {
|
|
1584
|
-
...handlers,
|
|
1585
|
-
initialize: handlers.initialize === void 0 ? void 0 : handlers.initialize.pipe(Effect.provide(telemetryLayer)),
|
|
1586
|
-
fetch: handlers.fetch === void 0 ? void 0 : handlers.fetch.pipe(Effect.provide(telemetryLayer)),
|
|
1587
|
-
alarms: handlers.alarms === void 0 ? void 0 : handlers.alarms.pipe(Effect.provide(telemetryLayer)),
|
|
1588
|
-
alarm: alarm === void 0 ? void 0 : (alarmInfo) => alarm(alarmInfo).pipe(Effect.provide(telemetryLayer)),
|
|
1589
|
-
webSocketMessage: webSocketMessage === void 0 ? void 0 : (socket, message) => webSocketMessage(socket, message).pipe(Effect.provide(telemetryLayer)),
|
|
1590
|
-
webSocketClose: webSocketClose === void 0 ? void 0 : (socket, code, reason, wasClean) => webSocketClose(socket, code, reason, wasClean).pipe(Effect.provide(telemetryLayer)),
|
|
1591
|
-
webSocketError: webSocketError === void 0 ? void 0 : (socket, error) => webSocketError(socket, error).pipe(Effect.provide(telemetryLayer)),
|
|
1592
|
-
rpc: provideRpcLayer(handlers.rpc, telemetryLayer)
|
|
1593
|
-
};
|
|
1594
|
-
};
|
|
1545
|
+
const implement$3 = (_definition, handlers) => handlers;
|
|
1595
1546
|
//#endregion
|
|
1596
|
-
//#region src/
|
|
1597
|
-
var
|
|
1598
|
-
|
|
1599
|
-
|
|
1547
|
+
//#region src/DurableObject.ts
|
|
1548
|
+
var DurableObject_exports = /* @__PURE__ */ __exportAll({
|
|
1549
|
+
Tag: () => Tag$5,
|
|
1550
|
+
implement: () => implement$2,
|
|
1551
|
+
make: () => make$4,
|
|
1552
|
+
method: () => method
|
|
1600
1553
|
});
|
|
1601
|
-
const
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
const make$4 = (id, definition) => Service()(id, definition);
|
|
1554
|
+
const reservedMethodNames = new Set([
|
|
1555
|
+
"constructor",
|
|
1556
|
+
"dup",
|
|
1557
|
+
"fetch",
|
|
1558
|
+
"alarm",
|
|
1559
|
+
"webSocketMessage",
|
|
1560
|
+
"webSocketClose",
|
|
1561
|
+
"webSocketError"
|
|
1562
|
+
]);
|
|
1563
|
+
const RunSymbol = Symbol.for("effect-cf/DurableObject/run");
|
|
1612
1564
|
/**
|
|
1613
|
-
*
|
|
1614
|
-
*
|
|
1615
|
-
* The returned service exposes the raw `D1Database` binding and `sqlLayer(...)`
|
|
1616
|
-
* for providing `effect/unstable/sql` via `@effect/sql-d1`.
|
|
1617
|
-
*
|
|
1618
|
-
* @example
|
|
1619
|
-
* ```ts
|
|
1620
|
-
* class TodoDatabase extends D1.Service<TodoDatabase>()("TodoDatabase", {
|
|
1621
|
-
* binding: "TODO_DB",
|
|
1622
|
-
* }) {}
|
|
1623
|
-
*
|
|
1624
|
-
* const SqlLive = TodoDatabase.sqlLayer();
|
|
1625
|
-
* ```
|
|
1565
|
+
* Creates a Durable Object class backed by a single managed Effect runtime.
|
|
1626
1566
|
*/
|
|
1627
|
-
const
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
[
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1567
|
+
const make$4 = (layer, options = {}) => {
|
|
1568
|
+
class EffectDurableObject extends DurableObject {
|
|
1569
|
+
runtime;
|
|
1570
|
+
constructor(state, env) {
|
|
1571
|
+
super(state, env);
|
|
1572
|
+
const runtimeLayer = provideEntrypointServices(layer, Layer.mergeAll(layer$7, Layer.succeed(DurableObjectState, fromDurableObjectState(state)), Layer.succeed(WorkerEnvironment, env)));
|
|
1573
|
+
this.runtime = ManagedRuntime.make(runtimeLayer);
|
|
1574
|
+
const initialize = options.initialize;
|
|
1575
|
+
if (initialize !== void 0) state.waitUntil(this[RunSymbol](initialize, { eventLayer: false }));
|
|
1576
|
+
}
|
|
1577
|
+
[RunSymbol](effect, runOptions = {}) {
|
|
1578
|
+
const effectWithEventLayer = runOptions.eventLayer === false || options.eventLayer === void 0 ? effect : effect.pipe(Effect.provide(options.eventLayer, { local: true }));
|
|
1579
|
+
return this.runtime.runPromise(Effect.scoped(effectWithEventLayer));
|
|
1580
|
+
}
|
|
1581
|
+
fetch(request) {
|
|
1582
|
+
const fetchHandler = options.fetch;
|
|
1583
|
+
if (fetchHandler === void 0) return Promise.resolve(new Response("Not Found", { status: 404 }));
|
|
1584
|
+
return this[RunSymbol](Effect.provideService(fetchHandler, NativeRequest, request));
|
|
1585
|
+
}
|
|
1586
|
+
alarm(alarmInfo) {
|
|
1587
|
+
const logicalAlarms = options.alarms?.pipe(Effect.asVoid);
|
|
1588
|
+
const rawAlarm = options.alarm?.(alarmInfo);
|
|
1589
|
+
if (logicalAlarms !== void 0 && rawAlarm !== void 0) return this[RunSymbol](Effect.gen(function* () {
|
|
1590
|
+
yield* logicalAlarms;
|
|
1591
|
+
yield* rawAlarm;
|
|
1592
|
+
}));
|
|
1593
|
+
if (logicalAlarms !== void 0) return this[RunSymbol](logicalAlarms);
|
|
1594
|
+
if (rawAlarm !== void 0) return this[RunSymbol](rawAlarm);
|
|
1595
|
+
}
|
|
1596
|
+
webSocketMessage(socket, message) {
|
|
1597
|
+
if (options.webSocketMessage !== void 0) return this[RunSymbol](options.webSocketMessage(fromWebSocket(socket), message));
|
|
1598
|
+
}
|
|
1599
|
+
webSocketClose(socket, code, reason, wasClean) {
|
|
1600
|
+
if (options.webSocketClose !== void 0) return this[RunSymbol](options.webSocketClose(fromWebSocket(socket), code, reason, wasClean));
|
|
1601
|
+
}
|
|
1602
|
+
webSocketError(socket, error) {
|
|
1603
|
+
if (options.webSocketError !== void 0) return this[RunSymbol](options.webSocketError(fromWebSocket(socket), error));
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
defineEntrypointRpcMethods("Durable Object", EffectDurableObject.prototype, options.rpc, reservedMethodNames, (self, effect) => self[RunSymbol](effect));
|
|
1607
|
+
return assumeEntrypointClass(EffectDurableObject);
|
|
1641
1608
|
};
|
|
1609
|
+
const Tag$5 = Tag$6;
|
|
1610
|
+
const method = method$1;
|
|
1611
|
+
const implement$2 = implement$3;
|
|
1642
1612
|
//#endregion
|
|
1643
1613
|
//#region src/DurableObjectAlarm.ts
|
|
1644
1614
|
var DurableObjectAlarm_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -2205,7 +2175,7 @@ const makeClient$3 = (definition) => (images) => {
|
|
|
2205
2175
|
unsafeRaw: Effect.succeed(images)
|
|
2206
2176
|
};
|
|
2207
2177
|
};
|
|
2208
|
-
const layer$3 = (tag, definition) => layer$
|
|
2178
|
+
const layer$3 = (tag, definition) => layer$11(tag, definition.binding, isImagesBinding, makeClient$3(definition), { expected: expectedImagesBinding });
|
|
2209
2179
|
const make$3 = (id) => Tag$4()(id);
|
|
2210
2180
|
const Tag$4 = () => (id) => {
|
|
2211
2181
|
const tag = Context.Service()(id);
|
|
@@ -2300,7 +2270,7 @@ const makeClient$2 = (definition) => {
|
|
|
2300
2270
|
unsafeRaw: Effect.succeed(kv)
|
|
2301
2271
|
});
|
|
2302
2272
|
};
|
|
2303
|
-
const layer$2 = (tag, definition) => layer$
|
|
2273
|
+
const layer$2 = (tag, definition) => layer$11(tag, definition.binding, isKvNamespace, makeClient$2(definition), { expected: expectedKvNamespace });
|
|
2304
2274
|
const makeDefinition$1 = (id, definition) => {
|
|
2305
2275
|
const kvDefinition = {
|
|
2306
2276
|
id,
|
|
@@ -2417,7 +2387,7 @@ const makeClient$1 = (definition) => {
|
|
|
2417
2387
|
};
|
|
2418
2388
|
};
|
|
2419
2389
|
};
|
|
2420
|
-
const layer$1 = (tag, definition) => layer$
|
|
2390
|
+
const layer$1 = (tag, definition) => layer$11(tag, definition.binding, isR2Bucket, makeClient$1(definition), { expected: expectedR2Bucket });
|
|
2421
2391
|
const make$2 = (id) => Tag$2()(id);
|
|
2422
2392
|
const Tag$2 = () => (id) => {
|
|
2423
2393
|
const tag = Context.Service()(id);
|
|
@@ -2503,7 +2473,7 @@ const makeClient = (definition) => {
|
|
|
2503
2473
|
unsafeRaw: Effect.succeed(workflow)
|
|
2504
2474
|
});
|
|
2505
2475
|
};
|
|
2506
|
-
const layer = (tag, definition) => layer$
|
|
2476
|
+
const layer = (tag, definition) => layer$11(tag, definition.binding, (value) => isWorkflow(value), makeClient(definition), { expected: expectedWorkflow });
|
|
2507
2477
|
//#endregion
|
|
2508
2478
|
//#region src/WorkflowDefinition.ts
|
|
2509
2479
|
var WorkflowDefinition_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -2524,7 +2494,7 @@ const make$1 = (id, definition) => Tag$1()(id, definition);
|
|
|
2524
2494
|
const Tag$1 = () => (id, definition) => {
|
|
2525
2495
|
const workflowDefinition = makeDefinition(id, definition);
|
|
2526
2496
|
const tag = Context.Service()(id);
|
|
2527
|
-
const layer$
|
|
2497
|
+
const layer$12 = (binding) => layer(tag, {
|
|
2528
2498
|
...binding,
|
|
2529
2499
|
payload: definition.payload,
|
|
2530
2500
|
result: definition.result
|
|
@@ -2546,7 +2516,7 @@ const Tag$1 = () => (id, definition) => {
|
|
|
2546
2516
|
payload: workflowDefinition.payload,
|
|
2547
2517
|
result: workflowDefinition.result,
|
|
2548
2518
|
make: workflowDefinition.make,
|
|
2549
|
-
layer: layer$
|
|
2519
|
+
layer: layer$12,
|
|
2550
2520
|
create,
|
|
2551
2521
|
createBatch,
|
|
2552
2522
|
get,
|