@rivetkit/cloudflare-workers 2.2.1 → 2.3.0-rc.13

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/dist/mod.js CHANGED
@@ -1,1093 +1,152 @@
1
- // src/actor-handler-do.ts
2
- import { DurableObject, env as env2 } from "cloudflare:workers";
3
- import invariant2 from "invariant";
4
- import { createActorRouter, createClientWithDriver as createClientWithDriver2 } from "rivetkit";
5
- import { getInitialActorKvState } from "rivetkit/driver-helpers";
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class;// src/mod.ts
2
+ var _rivetkitwasm = require('@rivetkit/rivetkit-wasm'); var wasmBindings = _interopRequireWildcard(_rivetkitwasm);
3
+ var _rivetkit_wasm_bgwasm = require('@rivetkit/rivetkit-wasm/rivetkit_wasm_bg.wasm'); var _rivetkit_wasm_bgwasm2 = _interopRequireDefault(_rivetkit_wasm_bgwasm);
6
4
 
7
- // src/actor-driver.ts
8
- import invariant from "invariant";
9
- import { lookupInRegistry } from "rivetkit";
10
- import { promiseWithResolvers } from "rivetkit/utils";
11
5
 
12
- // src/log.ts
13
- import { getLogger } from "rivetkit/log";
14
- function logger() {
15
- return getLogger("driver-cloudflare-workers");
16
- }
17
-
18
- // src/actor-kv.ts
19
- var DEFAULT_LIST_LIMIT = 16384;
20
- function kvGet(sql, key) {
21
- const cursor = sql.exec(
22
- "SELECT value FROM _rivetkit_kv_storage WHERE key = ?",
23
- key
24
- );
25
- const result = cursor.raw().next();
26
- if (!result.done && result.value) {
27
- return toUint8Array(result.value[0]);
28
- }
29
- return null;
30
- }
31
- function kvPut(sql, key, value) {
32
- sql.exec(
33
- "INSERT OR REPLACE INTO _rivetkit_kv_storage (key, value) VALUES (?, ?)",
34
- key,
35
- value
36
- );
37
- }
38
- function kvDelete(sql, key) {
39
- sql.exec("DELETE FROM _rivetkit_kv_storage WHERE key = ?", key);
40
- }
41
- function kvDeleteRange(sql, start, end) {
42
- sql.exec(
43
- "DELETE FROM _rivetkit_kv_storage WHERE key >= ? AND key < ?",
44
- start,
45
- end
46
- );
47
- }
48
- function kvListPrefix(sql, prefix, options) {
49
- const upperBound = computePrefixUpperBound(prefix);
50
- if (upperBound) {
51
- return kvListRange(sql, prefix, upperBound, options);
52
- }
53
- const direction = (options == null ? void 0 : options.reverse) ? "DESC" : "ASC";
54
- const limit = (options == null ? void 0 : options.limit) ?? DEFAULT_LIST_LIMIT;
55
- const cursor = sql.exec(
56
- `SELECT key, value FROM _rivetkit_kv_storage WHERE key >= ? ORDER BY key ${direction} LIMIT ?`,
57
- prefix,
58
- limit
59
- );
60
- return readEntries(cursor);
61
- }
62
- function kvListRange(sql, start, end, options) {
63
- const direction = (options == null ? void 0 : options.reverse) ? "DESC" : "ASC";
64
- const limit = (options == null ? void 0 : options.limit) ?? DEFAULT_LIST_LIMIT;
65
- const cursor = sql.exec(
66
- `SELECT key, value FROM _rivetkit_kv_storage WHERE key >= ? AND key < ? ORDER BY key ${direction} LIMIT ?`,
67
- start,
68
- end,
69
- limit
70
- );
71
- return readEntries(cursor);
72
- }
73
- function toUint8Array(value) {
74
- var _a;
75
- if (value instanceof Uint8Array) {
76
- return value;
77
- }
78
- if (value instanceof ArrayBuffer) {
79
- return new Uint8Array(value);
80
- }
81
- throw new Error(
82
- `Unexpected SQL value type: ${typeof value} (${(_a = value == null ? void 0 : value.constructor) == null ? void 0 : _a.name})`
83
- );
84
- }
85
- function readEntries(cursor) {
86
- const entries = [];
87
- for (const row of cursor.raw()) {
88
- entries.push([toUint8Array(row[0]), toUint8Array(row[1])]);
89
- }
90
- return entries;
91
- }
92
- function computePrefixUpperBound(prefix) {
93
- const upperBound = prefix.slice();
94
- for (let i = upperBound.length - 1; i >= 0; i--) {
95
- if (upperBound[i] !== 255) {
96
- upperBound[i]++;
97
- return upperBound.slice(0, i + 1);
98
- }
99
- }
100
- return null;
101
- }
102
-
103
- // src/global-kv.ts
104
- var GLOBAL_KV_KEYS = {
105
- actorMetadata: (actorId) => {
106
- return `actor:${actorId}:metadata`;
107
- }
108
- };
109
-
110
- // src/handler.ts
111
- import { env } from "cloudflare:workers";
112
- import { createClientWithDriver } from "rivetkit";
113
- import { buildManagerRouter } from "rivetkit/driver-helpers";
114
6
 
115
- // src/config.ts
116
- import { z } from "zod/v4";
117
- var ConfigSchemaBase = z.object({
118
- /** Path that the Rivet manager API will be mounted. */
119
- managerPath: z.string().optional().default("/api/rivet"),
120
- /** Deprecated. Runner key for authentication. */
121
- runnerKey: z.string().optional(),
122
- /** Disable the welcome message. */
123
- noWelcome: z.boolean().optional().default(false),
124
- fetch: z.custom().optional()
125
- });
126
- var ConfigSchema = ConfigSchemaBase.default(
127
- () => ConfigSchemaBase.parse({})
128
- );
7
+ var _rivetkit = require('rivetkit');
129
8
 
130
- // src/manager-driver.ts
131
- import {
132
- WS_PROTOCOL_ACTOR,
133
- WS_PROTOCOL_CONN_PARAMS,
134
- WS_PROTOCOL_ENCODING,
135
- WS_PROTOCOL_STANDARD,
136
- WS_PROTOCOL_TARGET
137
- } from "rivetkit/driver-helpers";
138
- import {
139
- ActorDuplicateKey,
140
- ActorNotFound,
141
- InternalError
142
- } from "rivetkit/errors";
143
- import { assertUnreachable } from "rivetkit/utils";
144
-
145
- // src/actor-id.ts
146
- function buildActorId(doId, generation) {
147
- return `${doId}:${generation}`;
148
- }
149
- function parseActorId(actorId) {
150
- const parts = actorId.split(":");
151
- if (parts.length !== 2) {
152
- throw new Error(`Invalid actor ID format: ${actorId}`);
153
- }
154
- const [doId, generationStr] = parts;
155
- const generation = parseInt(generationStr, 10);
156
- if (Number.isNaN(generation)) {
157
- throw new Error(`Invalid generation number in actor ID: ${actorId}`);
158
- }
159
- return [doId, generation];
160
- }
161
-
162
- // src/util.ts
163
- var EMPTY_KEY = "(none)";
164
- var KEY_SEPARATOR = ",";
165
- function serializeNameAndKey(name, key) {
166
- const escapedName = name.replace(/:/g, "\\:");
167
- if (key.length === 0) {
168
- return `${escapedName}:${EMPTY_KEY}`;
169
- }
170
- const serializedKey = serializeKey(key);
171
- return `${escapedName}:${serializedKey}`;
172
- }
173
- function serializeKey(key) {
174
- if (key.length === 0) {
175
- return EMPTY_KEY;
176
- }
177
- const escapedParts = key.map((part) => {
178
- if (part === EMPTY_KEY) {
179
- return `\\${EMPTY_KEY}`;
180
- }
181
- let escaped = part.replace(/\\/g, "\\\\");
182
- escaped = escaped.replace(/,/g, "\\,");
183
- return escaped;
184
- });
185
- return escapedParts.join(KEY_SEPARATOR);
186
- }
187
-
188
- // src/manager-driver.ts
189
- var STANDARD_WEBSOCKET_HEADERS = [
190
- "connection",
191
- "upgrade",
192
- "sec-websocket-key",
193
- "sec-websocket-version",
194
- "sec-websocket-protocol",
195
- "sec-websocket-extensions"
196
- ];
197
- var CloudflareActorsManagerDriver = class {
198
- async sendRequest(actorId, actorRequest) {
199
- const env3 = getCloudflareAmbientEnv();
200
- const [doId] = parseActorId(actorId);
201
- logger().debug({
202
- msg: "sending request to durable object",
203
- actorId,
204
- doId,
205
- method: actorRequest.method,
206
- url: actorRequest.url
207
- });
208
- const id = env3.ACTOR_DO.idFromString(doId);
209
- const stub = env3.ACTOR_DO.get(id);
210
- return await stub.fetch(actorRequest);
211
- }
212
- async openWebSocket(path, actorId, encoding, params) {
213
- const env3 = getCloudflareAmbientEnv();
214
- const [doId] = parseActorId(actorId);
215
- logger().debug({
216
- msg: "opening websocket to durable object",
217
- actorId,
218
- doId,
219
- path
220
- });
221
- const id = env3.ACTOR_DO.idFromString(doId);
222
- const stub = env3.ACTOR_DO.get(id);
223
- const protocols = [];
224
- protocols.push(WS_PROTOCOL_STANDARD);
225
- protocols.push(`${WS_PROTOCOL_TARGET}actor`);
226
- protocols.push(`${WS_PROTOCOL_ACTOR}${encodeURIComponent(actorId)}`);
227
- protocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);
228
- if (params) {
229
- protocols.push(
230
- `${WS_PROTOCOL_CONN_PARAMS}${encodeURIComponent(JSON.stringify(params))}`
231
- );
232
- }
233
- const headers = {
234
- Upgrade: "websocket",
235
- Connection: "Upgrade",
236
- "sec-websocket-protocol": protocols.join(", ")
237
- };
238
- const normalizedPath = path.startsWith("/") ? path : `/${path}`;
239
- const url = `http://actor${normalizedPath}`;
240
- logger().debug({ msg: "rewriting websocket url", from: path, to: url });
241
- const response = await stub.fetch(url, {
242
- headers
243
- });
244
- const webSocket = response.webSocket;
245
- if (!webSocket) {
246
- throw new InternalError(
247
- `missing websocket connection in response from DO
248
-
249
- Status: ${response.status}
250
- Response: ${await response.text()}`
251
- );
252
- }
253
- logger().debug({
254
- msg: "durable object websocket connection open",
255
- actorId
256
- });
257
- webSocket.accept();
258
- setTimeout(() => {
259
- var _a;
260
- const event = new Event("open");
261
- (_a = webSocket.onopen) == null ? void 0 : _a.call(webSocket, event);
262
- webSocket.dispatchEvent(event);
263
- }, 0);
264
- return webSocket;
265
- }
266
- async buildGatewayUrl(actorId) {
267
- return `http://actor/gateway/${encodeURIComponent(actorId)}`;
268
- }
269
- async proxyRequest(c, actorRequest, actorId) {
270
- const env3 = getCloudflareAmbientEnv();
271
- const [doId] = parseActorId(actorId);
272
- logger().debug({
273
- msg: "forwarding request to durable object",
274
- actorId,
275
- doId,
276
- method: actorRequest.method,
277
- url: actorRequest.url
278
- });
279
- const id = env3.ACTOR_DO.idFromString(doId);
280
- const stub = env3.ACTOR_DO.get(id);
281
- return await stub.fetch(actorRequest);
282
- }
283
- async proxyWebSocket(c, path, actorId, encoding, params) {
284
- logger().debug({
285
- msg: "forwarding websocket to durable object",
286
- actorId,
287
- path
288
- });
289
- const upgradeHeader = c.req.header("Upgrade");
290
- if (!upgradeHeader || upgradeHeader !== "websocket") {
291
- return new Response("Expected Upgrade: websocket", {
292
- status: 426
293
- });
294
- }
295
- const newUrl = new URL(`http://actor${path}`);
296
- const actorRequest = new Request(newUrl, c.req.raw);
297
- logger().debug({
298
- msg: "rewriting websocket url",
299
- from: c.req.url,
300
- to: actorRequest.url
301
- });
302
- const headerKeys = [];
303
- actorRequest.headers.forEach((v, k) => {
304
- headerKeys.push(k);
305
- });
306
- for (const k of headerKeys) {
307
- if (!STANDARD_WEBSOCKET_HEADERS.includes(k)) {
308
- actorRequest.headers.delete(k);
309
- }
310
- }
311
- const protocols = [];
312
- protocols.push(WS_PROTOCOL_STANDARD);
313
- protocols.push(`${WS_PROTOCOL_TARGET}actor`);
314
- protocols.push(`${WS_PROTOCOL_ACTOR}${encodeURIComponent(actorId)}`);
315
- protocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);
316
- if (params) {
317
- protocols.push(
318
- `${WS_PROTOCOL_CONN_PARAMS}${encodeURIComponent(JSON.stringify(params))}`
319
- );
320
- }
321
- actorRequest.headers.set(
322
- "sec-websocket-protocol",
323
- protocols.join(", ")
324
- );
325
- const env3 = getCloudflareAmbientEnv();
326
- const [doId] = parseActorId(actorId);
327
- const id = env3.ACTOR_DO.idFromString(doId);
328
- const stub = env3.ACTOR_DO.get(id);
329
- return await stub.fetch(actorRequest);
330
- }
331
- async getForId({
332
- c,
333
- name,
334
- actorId
335
- }) {
336
- const env3 = getCloudflareAmbientEnv();
337
- const [doId, expectedGeneration] = parseActorId(actorId);
338
- const id = env3.ACTOR_DO.idFromString(doId);
339
- const stub = env3.ACTOR_DO.get(id);
340
- const result = await stub.getMetadata();
341
- if (!result) {
342
- logger().debug({
343
- msg: "getForId: actor not found",
344
- actorId
345
- });
346
- return void 0;
347
- }
348
- if (result.actorId !== actorId) {
349
- logger().debug({
350
- msg: "getForId: generation mismatch",
351
- requestedActorId: actorId,
352
- actualActorId: result.actorId
353
- });
354
- return void 0;
355
- }
356
- if (result.destroying) {
357
- throw new ActorNotFound(actorId);
358
- }
359
- return {
360
- actorId: result.actorId,
361
- name: result.name,
362
- key: result.key
363
- };
364
- }
365
- async getWithKey({
366
- c,
367
- name,
368
- key
369
- }) {
370
- const env3 = getCloudflareAmbientEnv();
371
- logger().debug({ msg: "getWithKey: searching for actor", name, key });
372
- const nameKeyString = serializeNameAndKey(name, key);
373
- const doId = env3.ACTOR_DO.idFromName(nameKeyString).toString();
374
- const id = env3.ACTOR_DO.idFromString(doId);
375
- const stub = env3.ACTOR_DO.get(id);
376
- const result = await stub.getMetadata();
377
- if (result) {
378
- logger().debug({
379
- msg: "getWithKey: found actor with matching name and key",
380
- actorId: result.actorId,
381
- name: result.name,
382
- key: result.key
383
- });
384
- return {
385
- actorId: result.actorId,
386
- name: result.name,
387
- key: result.key
388
- };
389
- } else {
390
- logger().debug({
391
- msg: "getWithKey: no actor found with matching name and key",
392
- name,
393
- key,
394
- doId
395
- });
396
- return void 0;
397
- }
398
- }
399
- async getOrCreateWithKey({
400
- c,
401
- name,
402
- key,
403
- input
404
- }) {
405
- const env3 = getCloudflareAmbientEnv();
406
- const nameKeyString = serializeNameAndKey(name, key);
407
- const doId = env3.ACTOR_DO.idFromName(nameKeyString);
408
- const actor = env3.ACTOR_DO.get(doId);
409
- const result = await actor.create({
410
- name,
411
- key,
412
- input,
413
- allowExisting: true
414
- });
415
- if ("success" in result) {
416
- const { actorId, created } = result.success;
417
- logger().debug({
418
- msg: "getOrCreateWithKey result",
419
- actorId,
420
- name,
421
- key,
422
- created
423
- });
424
- return {
425
- actorId,
426
- name,
427
- key
428
- };
429
- } else if ("error" in result) {
430
- throw new Error(`Error: ${JSON.stringify(result.error)}`);
431
- } else {
432
- assertUnreachable(result);
433
- }
434
- }
435
- async createActor({
436
- c,
437
- name,
438
- key,
439
- input
440
- }) {
441
- const env3 = getCloudflareAmbientEnv();
442
- const nameKeyString = serializeNameAndKey(name, key);
443
- const doId = env3.ACTOR_DO.idFromName(nameKeyString);
444
- const actor = env3.ACTOR_DO.get(doId);
445
- const result = await actor.create({
446
- name,
447
- key,
448
- input,
449
- allowExisting: false
450
- });
451
- if ("success" in result) {
452
- const { actorId } = result.success;
453
- return {
454
- actorId,
455
- name,
456
- key
457
- };
458
- } else if ("error" in result) {
459
- if (result.error.actorAlreadyExists) {
460
- throw new ActorDuplicateKey(name, key);
9
+ // src/websocket.ts
10
+ var FetchWebSocket = (_class = class _FetchWebSocket {
11
+ static __initStatic() {this.CONNECTING = 0}
12
+ static __initStatic2() {this.OPEN = 1}
13
+ static __initStatic3() {this.CLOSING = 2}
14
+ static __initStatic4() {this.CLOSED = 3}
15
+ __init() {this.binaryType = "arraybuffer"}
16
+ __init2() {this.onopen = null}
17
+ __init3() {this.onmessage = null}
18
+ __init4() {this.onclose = null}
19
+ __init5() {this.onerror = null}
20
+ __init6() {this.readyState = _FetchWebSocket.CONNECTING}
21
+ #socket;
22
+ #pending = [];
23
+ constructor(url, protocols) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);
24
+ void this.#connect(url, protocols);
25
+ }
26
+ async #connect(url, protocols) {
27
+ var _a, _b, _c;
28
+ try {
29
+ const protocolList = Array.isArray(protocols) ? protocols : protocols ? [protocols] : [];
30
+ const headers = new Headers({ Upgrade: "websocket" });
31
+ if (protocolList.length > 0) {
32
+ headers.set("Sec-WebSocket-Protocol", protocolList.join(", "));
461
33
  }
462
- throw new InternalError(
463
- `Unknown error creating actor: ${JSON.stringify(result.error)}`
34
+ const response = await fetch(
35
+ url.replace(/^ws:/, "http:").replace(/^wss:/, "https:"),
36
+ { headers }
464
37
  );
465
- } else {
466
- assertUnreachable(result);
467
- }
468
- }
469
- async listActors({ c, name }) {
470
- logger().warn({
471
- msg: "listActors not fully implemented for Cloudflare Workers",
472
- name
473
- });
474
- return [];
475
- }
476
- displayInformation() {
477
- return {
478
- properties: {
479
- Driver: "Cloudflare Workers"
38
+ const socket = response.webSocket;
39
+ if (!socket) {
40
+ throw new Error(
41
+ `websocket upgrade failed with status ${response.status}`
42
+ );
480
43
  }
481
- };
482
- }
483
- setGetUpgradeWebSocket() {
484
- }
485
- async kvGet(actorId, key) {
486
- const env3 = getCloudflareAmbientEnv();
487
- const [doId] = parseActorId(actorId);
488
- const id = env3.ACTOR_DO.idFromString(doId);
489
- const stub = env3.ACTOR_DO.get(id);
490
- const value = await stub.managerKvGet(key);
491
- return value !== null ? new TextDecoder().decode(value) : null;
492
- }
493
- };
494
-
495
- // src/websocket.ts
496
- import { defineWebSocketHelper, WSContext } from "hono/ws";
497
- import { WS_PROTOCOL_STANDARD as WS_PROTOCOL_STANDARD2 } from "rivetkit/driver-helpers";
498
- var upgradeWebSocket = defineWebSocketHelper(async (c, events) => {
499
- var _a, _b;
500
- const upgradeHeader = c.req.header("Upgrade");
501
- if (upgradeHeader !== "websocket") {
502
- return;
503
- }
504
- const webSocketPair = new WebSocketPair();
505
- const client = webSocketPair[0];
506
- const server = webSocketPair[1];
507
- const wsContext = new WSContext({
508
- close: (code, reason) => server.close(code, reason),
509
- get protocol() {
510
- return server.protocol;
511
- },
512
- raw: server,
513
- get readyState() {
514
- return server.readyState;
515
- },
516
- url: server.url ? new URL(server.url) : null,
517
- send: (source) => server.send(source)
518
- });
519
- if (events.onClose) {
520
- server.addEventListener(
521
- "close",
522
- (evt) => {
44
+ socket.accept();
45
+ socket.binaryType = this.binaryType;
46
+ this.#socket = socket;
47
+ this.readyState = _FetchWebSocket.OPEN;
48
+ socket.addEventListener("message", (event) => {
523
49
  var _a2;
524
- return (_a2 = events.onClose) == null ? void 0 : _a2.call(events, evt, wsContext);
525
- }
526
- );
527
- }
528
- if (events.onMessage) {
529
- server.addEventListener(
530
- "message",
531
- (evt) => {
50
+ (_a2 = this.onmessage) == null ? void 0 : _a2.call(this, event);
51
+ });
52
+ socket.addEventListener("close", (event) => {
532
53
  var _a2;
533
- return (_a2 = events.onMessage) == null ? void 0 : _a2.call(events, evt, wsContext);
534
- }
535
- );
536
- }
537
- if (events.onError) {
538
- server.addEventListener(
539
- "error",
540
- (evt) => {
54
+ this.readyState = _FetchWebSocket.CLOSED;
55
+ (_a2 = this.onclose) == null ? void 0 : _a2.call(this, event);
56
+ });
57
+ socket.addEventListener("error", (event) => {
541
58
  var _a2;
542
- return (_a2 = events.onError) == null ? void 0 : _a2.call(events, evt, wsContext);
543
- }
544
- );
545
- }
546
- (_a = server.accept) == null ? void 0 : _a.call(server);
547
- (_b = events.onOpen) == null ? void 0 : _b.call(events, new Event("open"), wsContext);
548
- const headers = {};
549
- const protocols = c.req.header("Sec-WebSocket-Protocol");
550
- if (typeof protocols === "string" && protocols.split(",").map((x) => x.trim()).includes(WS_PROTOCOL_STANDARD2)) {
551
- headers["Sec-WebSocket-Protocol"] = WS_PROTOCOL_STANDARD2;
552
- }
553
- return new Response(null, {
554
- status: 101,
555
- headers,
556
- webSocket: client
557
- });
558
- });
559
-
560
- // src/handler.ts
561
- function getCloudflareAmbientEnv() {
562
- return env;
563
- }
564
- function createInlineClient(registry, inputConfig) {
565
- inputConfig = { ...inputConfig, runnerKey: "" };
566
- const config = ConfigSchema.parse(inputConfig);
567
- const ActorHandler = createActorDurableObject(
568
- registry,
569
- () => upgradeWebSocket
570
- );
571
- registry.config.noWelcome = true;
572
- registry.config.inspector = {
573
- enabled: false,
574
- token: () => ""
575
- };
576
- registry.config.managerBasePath = "/";
577
- const parsedConfig = registry.parseConfig();
578
- const managerDriver = new CloudflareActorsManagerDriver();
579
- const { router } = buildManagerRouter(
580
- parsedConfig,
581
- managerDriver,
582
- () => upgradeWebSocket
583
- );
584
- const client = createClientWithDriver(managerDriver);
585
- return { client, fetch: router.fetch.bind(router), config, ActorHandler };
586
- }
587
- function createHandler(registry, inputConfig) {
588
- const inline = createInlineClient(registry, inputConfig);
589
- const client = inline.client;
590
- const fetch = inline.fetch;
591
- const config = inline.config;
592
- const ActorHandler = inline.ActorHandler;
593
- const handler = {
594
- fetch: async (request, cfEnv, ctx) => {
595
- const url = new URL(request.url);
596
- const env3 = Object.assign({ RIVET: client }, cfEnv);
597
- if (url.pathname.startsWith(config.managerPath)) {
598
- const strippedPath = url.pathname.substring(
599
- config.managerPath.length
600
- );
601
- url.pathname = strippedPath;
602
- const modifiedRequest = new Request(url.toString(), request);
603
- return fetch(modifiedRequest, env3, ctx);
604
- }
605
- if (config.fetch) {
606
- return config.fetch(request, env3, ctx);
607
- } else {
608
- return new Response(
609
- "This is a RivetKit server.\n\nLearn more at https://rivet.dev\n",
610
- { status: 200 }
611
- );
59
+ (_a2 = this.onerror) == null ? void 0 : _a2.call(this, event);
60
+ });
61
+ (_a = this.onopen) == null ? void 0 : _a.call(this, new Event("open"));
62
+ for (const data of this.#pending.splice(0)) {
63
+ socket.send(data);
612
64
  }
65
+ } catch (error) {
66
+ console.error("rivetkit cloudflare websocket shim failed", error);
67
+ this.readyState = _FetchWebSocket.CLOSED;
68
+ (_b = this.onerror) == null ? void 0 : _b.call(this, error instanceof Event ? error : new Event("error"));
69
+ (_c = this.onclose) == null ? void 0 : _c.call(this, new CloseEvent("close", { code: 1006 }));
613
70
  }
614
- };
615
- return { handler, ActorHandler };
616
- }
617
-
618
- // src/actor-driver.ts
619
- var CloudflareDurableObjectGlobalState = class {
620
- // Map of actor ID -> DO state
621
- #dos = /* @__PURE__ */ new Map();
622
- // WeakMap of DO state -> ActorGlobalState for proper GC
623
- #actors = /* @__PURE__ */ new WeakMap();
624
- getDOState(doId) {
625
- const state = this.#dos.get(doId);
626
- invariant(
627
- state !== void 0,
628
- "durable object state not in global state"
629
- );
630
- return state;
631
- }
632
- setDOState(doId, state) {
633
- this.#dos.set(doId, state);
634
- }
635
- getActorState(ctx) {
636
- return this.#actors.get(ctx);
637
- }
638
- setActorState(ctx, actorState) {
639
- this.#actors.set(ctx, actorState);
640
71
  }
641
- };
642
- var ActorGlobalState = class {
643
- // Initialization state
644
- initialized;
645
- // Loaded actor state
646
- actor;
647
- actorInstance;
648
- actorPromise;
649
- /**
650
- * Indicates if `startDestroy` has been called.
651
- *
652
- * This is stored in memory instead of SQLite since the destroy may be cancelled.
653
- *
654
- * See the corresponding `destroyed` property in SQLite metadata.
655
- */
656
- destroying = false;
657
- reset() {
658
- this.initialized = void 0;
659
- this.actor = void 0;
660
- this.actorInstance = void 0;
661
- this.actorPromise = void 0;
662
- this.destroying = false;
663
- }
664
- };
665
- var CloudflareActorsActorDriver = class {
666
- #registryConfig;
667
- #managerDriver;
668
- #inlineClient;
669
- #globalState;
670
- constructor(registryConfig, managerDriver, inlineClient, globalState) {
671
- this.#registryConfig = registryConfig;
672
- this.#managerDriver = managerDriver;
673
- this.#inlineClient = inlineClient;
674
- this.#globalState = globalState;
675
- }
676
- #getDOCtx(actorId) {
677
- const [doId] = parseActorId(actorId);
678
- return this.#globalState.getDOState(doId).ctx;
679
- }
680
- async loadActor(actorId) {
72
+ send(data) {
681
73
  var _a;
682
- const [doId, expectedGeneration] = parseActorId(actorId);
683
- const doState = this.#globalState.getDOState(doId);
684
- let actorState = this.#globalState.getActorState(doState.ctx);
685
- if (actorState == null ? void 0 : actorState.actorInstance) {
686
- return actorState.actorInstance;
687
- }
688
- if (!actorState) {
689
- actorState = new ActorGlobalState();
690
- actorState.actorPromise = promiseWithResolvers(
691
- (reason) => logger().warn({
692
- msg: "unhandled actor promise rejection",
693
- reason
694
- })
695
- );
696
- this.#globalState.setActorState(doState.ctx, actorState);
697
- } else if (actorState.actorPromise) {
698
- await actorState.actorPromise.promise;
699
- if (!actorState.actorInstance) {
700
- throw new Error(
701
- `Actor ${actorId} failed to load in concurrent request`
702
- );
703
- }
704
- return actorState.actorInstance;
705
- }
706
- const sql = doState.ctx.storage.sql;
707
- const cursor = sql.exec(
708
- "SELECT name, key, destroyed, generation FROM _rivetkit_metadata LIMIT 1"
709
- );
710
- const result = cursor.raw().next();
711
- if (result.done || !result.value) {
712
- throw new Error(
713
- `Actor ${actorId} is not initialized - missing metadata`
714
- );
715
- }
716
- const name = result.value[0];
717
- const key = JSON.parse(result.value[1]);
718
- const destroyed = result.value[2];
719
- const generation = result.value[3];
720
- if (destroyed) {
721
- throw new Error(`Actor ${actorId} is destroyed`);
722
- }
723
- if (generation !== expectedGeneration) {
724
- throw new Error(
725
- `Actor ${actorId} generation mismatch - expected ${expectedGeneration}, got ${generation}`
726
- );
727
- }
728
- const definition = lookupInRegistry(this.#registryConfig, name);
729
- actorState.actorInstance = definition.instantiate();
730
- const actorInstance = actorState.actorInstance;
731
- await actorInstance.start(
732
- this,
733
- this.#inlineClient,
734
- actorId,
735
- name,
736
- key,
737
- "unknown"
738
- // TODO: Support regions in Cloudflare
739
- );
740
- (_a = actorState.actorPromise) == null ? void 0 : _a.resolve();
741
- actorState.actorPromise = void 0;
742
- return actorState.actorInstance;
743
- }
744
- getContext(actorId) {
745
- const [doId] = parseActorId(actorId);
746
- const state = this.#globalState.getDOState(doId);
747
- return { state: state.ctx };
748
- }
749
- async setAlarm(actor, timestamp) {
750
- await this.#getDOCtx(actor.id).storage.setAlarm(timestamp);
751
- }
752
- async getDatabase(actorId) {
753
- return this.#getDOCtx(actorId).storage.sql;
754
- }
755
- // Batch KV operations
756
- async kvBatchPut(actorId, entries) {
757
- const sql = this.#getDOCtx(actorId).storage.sql;
758
- for (const [key, value] of entries) {
759
- kvPut(sql, key, value);
760
- }
761
- }
762
- async kvBatchGet(actorId, keys) {
763
- const sql = this.#getDOCtx(actorId).storage.sql;
764
- const results = [];
765
- for (const key of keys) {
766
- results.push(kvGet(sql, key));
767
- }
768
- return results;
769
- }
770
- async kvBatchDelete(actorId, keys) {
771
- const sql = this.#getDOCtx(actorId).storage.sql;
772
- for (const key of keys) {
773
- kvDelete(sql, key);
774
- }
775
- }
776
- async kvDeleteRange(actorId, start, end) {
777
- const sql = this.#getDOCtx(actorId).storage.sql;
778
- kvDeleteRange(sql, start, end);
779
- }
780
- async kvListPrefix(actorId, prefix, options) {
781
- const sql = this.#getDOCtx(actorId).storage.sql;
782
- return kvListPrefix(sql, prefix, options);
783
- }
784
- async kvListRange(actorId, start, end, options) {
785
- const sql = this.#getDOCtx(actorId).storage.sql;
786
- return kvListRange(sql, start, end, options);
787
- }
788
- startDestroy(actorId) {
789
- const [doId, generation] = parseActorId(actorId);
790
- const doState = this.#globalState.getDOState(doId);
791
- const actorState = this.#globalState.getActorState(doState.ctx);
792
- if (!(actorState == null ? void 0 : actorState.actorInstance)) {
74
+ if (this.readyState === _FetchWebSocket.CONNECTING) {
75
+ this.#pending.push(data);
793
76
  return;
794
77
  }
795
- if (actorState.destroying) {
796
- return;
797
- }
798
- actorState.destroying = true;
799
- this.#callOnStopAsync(actorId, doId, actorState.actorInstance);
78
+ (_a = this.#socket) == null ? void 0 : _a.send(data);
800
79
  }
801
- async #callOnStopAsync(actorId, doId, actor) {
802
- await actor.onStop("destroy");
803
- const doState = this.#globalState.getDOState(doId);
804
- const sql = doState.ctx.storage.sql;
805
- sql.exec("UPDATE _rivetkit_metadata SET destroyed = 1 WHERE 1=1");
806
- sql.exec("DELETE FROM _rivetkit_kv_storage");
807
- await doState.ctx.storage.deleteAlarm();
808
- const env3 = getCloudflareAmbientEnv();
809
- doState.ctx.waitUntil(
810
- env3.ACTOR_KV.delete(GLOBAL_KV_KEYS.actorMetadata(actorId))
811
- );
812
- const actorHandle = this.#globalState.getActorState(doState.ctx);
813
- actorHandle == null ? void 0 : actorHandle.reset();
80
+ close(code, reason) {
81
+ var _a;
82
+ this.readyState = _FetchWebSocket.CLOSING;
83
+ (_a = this.#socket) == null ? void 0 : _a.close(code, reason);
814
84
  }
815
- };
816
- function createCloudflareActorsActorDriverBuilder(globalState) {
817
- return (config, managerDriver, inlineClient) => {
818
- return new CloudflareActorsActorDriver(
819
- config,
820
- managerDriver,
821
- inlineClient,
822
- globalState
823
- );
824
- };
85
+ }, _class.__initStatic(), _class.__initStatic2(), _class.__initStatic3(), _class.__initStatic4(), _class);
86
+ var globalScope = globalThis;
87
+ if (!globalScope.__RIVETKIT_CF_WEBSOCKET_INSTALLED__) {
88
+ globalScope.WebSocket = FetchWebSocket;
89
+ globalScope.__RIVETKIT_CF_WEBSOCKET_INSTALLED__ = true;
825
90
  }
826
91
 
827
- // src/actor-handler-do.ts
828
- function createActorDurableObject(registry, getUpgradeWebSocket) {
829
- const globalState = new CloudflareDurableObjectGlobalState();
830
- const parsedConfig = registry.parseConfig();
831
- return class ActorHandler extends DurableObject {
832
- /**
833
- * This holds a strong reference to ActorGlobalState.
834
- * CloudflareDurableObjectGlobalState holds a weak reference so we can
835
- * access it elsewhere.
836
- **/
837
- #state;
838
- constructor(...args) {
839
- super(...args);
840
- this.ctx.storage.sql.exec(`
841
- CREATE TABLE IF NOT EXISTS _rivetkit_kv_storage(
842
- key BLOB PRIMARY KEY,
843
- value BLOB
844
- );
845
- `);
846
- this.ctx.storage.sql.exec(`
847
- CREATE TABLE IF NOT EXISTS _rivetkit_metadata(
848
- id INTEGER PRIMARY KEY CHECK (id = 1),
849
- name TEXT NOT NULL,
850
- key TEXT NOT NULL,
851
- destroyed INTEGER DEFAULT 0,
852
- generation INTEGER DEFAULT 0
853
- );
854
- `);
855
- const state = globalState.getActorState(this.ctx);
856
- if (state) {
857
- this.#state = state;
858
- } else {
859
- this.#state = new ActorGlobalState();
860
- globalState.setActorState(this.ctx, this.#state);
861
- }
862
- }
863
- async #loadActor() {
864
- var _a, _b;
865
- invariant2(this.#state, "State should be initialized");
866
- if (!this.#state.initialized) {
867
- const cursor = this.ctx.storage.sql.exec(
868
- "SELECT name, key, destroyed, generation FROM _rivetkit_metadata WHERE id = 1"
869
- );
870
- const result = cursor.raw().next();
871
- if (!result.done && result.value) {
872
- const name = result.value[0];
873
- const key = JSON.parse(
874
- result.value[1]
875
- );
876
- const destroyed = result.value[2];
877
- const generation = result.value[3];
878
- if (!destroyed) {
879
- logger().debug({
880
- msg: "already initialized",
881
- name,
882
- key,
883
- generation
884
- });
885
- this.#state.initialized = { name, key, generation };
886
- } else {
887
- logger().debug("actor is destroyed, cannot load");
888
- throw new Error("Actor is destroyed");
889
- }
890
- } else {
891
- logger().debug("not initialized");
892
- throw new Error("Actor is not initialized");
893
- }
894
- }
895
- if (this.#state.actor) {
896
- invariant2(
897
- !this.#state.initialized || this.#state.actor.generation === this.#state.initialized.generation,
898
- `Stale actor cached: actor generation ${this.#state.actor.generation} != initialized generation ${(_a = this.#state.initialized) == null ? void 0 : _a.generation}. This should not happen.`
92
+ // src/mod.ts
93
+ var DEFAULT_MANAGER_PATH = "/api/rivet";
94
+ function setup(config) {
95
+ return _rivetkit.setup.call(void 0, {
96
+ runtime: "wasm",
97
+ wasm: { bindings: wasmBindings, initInput: _rivetkit_wasm_bgwasm2.default },
98
+ noWelcome: true,
99
+ ...config
100
+ });
101
+ }
102
+ function applyEnv(registry, env, managerPath) {
103
+ var _a, _b;
104
+ const config = registry.config;
105
+ if (!config.endpoint && env.RIVET_ENDPOINT) {
106
+ config.endpoint = env.RIVET_ENDPOINT;
107
+ }
108
+ if (!config.namespace && env.RIVET_NAMESPACE) {
109
+ config.namespace = env.RIVET_NAMESPACE;
110
+ }
111
+ if (!config.token && env.RIVET_TOKEN) {
112
+ config.token = env.RIVET_TOKEN;
113
+ }
114
+ if (env.RIVET_POOL && !((_a = config.envoy) == null ? void 0 : _a.poolName)) {
115
+ config.envoy = { ...config.envoy, poolName: env.RIVET_POOL };
116
+ }
117
+ if (!((_b = config.serverless) == null ? void 0 : _b.basePath)) {
118
+ config.serverless = { ...config.serverless, basePath: managerPath };
119
+ }
120
+ }
121
+ function createHandler(registryOrConfig, options = {}) {
122
+ const managerPath = _nullishCoalesce(options.managerPath, () => ( DEFAULT_MANAGER_PATH));
123
+ const registry = registryOrConfig instanceof _rivetkit.Registry ? registryOrConfig : setup(registryOrConfig);
124
+ let envApplied = false;
125
+ return {
126
+ async fetch(request, env, ctx) {
127
+ if (!envApplied) {
128
+ applyEnv(
129
+ registry,
130
+ _nullishCoalesce(env, () => ( {})),
131
+ managerPath
899
132
  );
900
- return this.#state.actor;
133
+ envApplied = true;
901
134
  }
902
- if (!this.#state.initialized) throw new Error("Not initialized");
903
- const actorId = this.ctx.id.toString();
904
- globalState.setDOState(actorId, { ctx: this.ctx, env: env2 });
905
- const managerDriver = new CloudflareActorsManagerDriver();
906
- const inlineClient = createClientWithDriver2(
907
- managerDriver
908
- );
909
- const actorDriverBuilder = createCloudflareActorsActorDriverBuilder(globalState);
910
- const actorDriver = actorDriverBuilder(
911
- parsedConfig,
912
- managerDriver,
913
- inlineClient
914
- );
915
- const actorRouter = createActorRouter(
916
- parsedConfig,
917
- actorDriver,
918
- getUpgradeWebSocket,
919
- ((_b = registry.config.test) == null ? void 0 : _b.enabled) ?? false
920
- );
921
- this.#state.actor = {
922
- actorRouter,
923
- actorDriver,
924
- generation: this.#state.initialized.generation
925
- };
926
- const actorIdWithGen = buildActorId(
927
- actorId,
928
- this.#state.initialized.generation
929
- );
930
- await actorDriver.loadActor(actorIdWithGen);
931
- return this.#state.actor;
932
- }
933
- /** RPC called to get actor metadata without creating it */
934
- async getMetadata() {
935
- var _a;
936
- const cursor = this.ctx.storage.sql.exec(
937
- "SELECT name, key, destroyed, generation FROM _rivetkit_metadata WHERE id = 1"
938
- );
939
- const result = cursor.raw().next();
940
- if (!result.done && result.value) {
941
- const name = result.value[0];
942
- const key = JSON.parse(result.value[1]);
943
- const destroyed = result.value[2];
944
- const generation = result.value[3];
945
- if (destroyed) {
946
- logger().debug({
947
- msg: "getMetadata: actor is destroyed",
948
- name,
949
- key,
950
- generation
951
- });
952
- return void 0;
953
- }
954
- const doId = this.ctx.id.toString();
955
- const actorId = buildActorId(doId, generation);
956
- const destroying = ((_a = globalState.getActorState(this.ctx)) == null ? void 0 : _a.destroying) ?? false;
957
- logger().debug({
958
- msg: "getMetadata: found actor metadata",
959
- actorId,
960
- name,
961
- key,
962
- generation,
963
- destroying
964
- });
965
- return { actorId, name, key, destroying };
135
+ const url = new URL(request.url);
136
+ if (url.pathname === managerPath || url.pathname.startsWith(`${managerPath}/`)) {
137
+ return registry.handler(request);
966
138
  }
967
- logger().debug({
968
- msg: "getMetadata: no metadata found"
969
- });
970
- return void 0;
971
- }
972
- /** RPC called by ManagerDriver.kvGet to read from KV. */
973
- async managerKvGet(key) {
974
- return kvGet(this.ctx.storage.sql, key);
975
- }
976
- /** RPC called by the manager to create a DO. Can optionally allow existing actors. */
977
- async create(req) {
978
- const checkCursor = this.ctx.storage.sql.exec(
979
- "SELECT destroyed, generation FROM _rivetkit_metadata WHERE id = 1"
980
- );
981
- const checkResult = checkCursor.raw().next();
982
- let created = false;
983
- let generation = 0;
984
- if (!checkResult.done && checkResult.value) {
985
- const destroyed = checkResult.value[0];
986
- generation = checkResult.value[1];
987
- if (!destroyed) {
988
- if (!req.allowExisting) {
989
- logger().debug({
990
- msg: "create failed: actor already exists",
991
- name: req.name,
992
- key: req.key,
993
- generation
994
- });
995
- return { error: { actorAlreadyExists: true } };
996
- }
997
- logger().debug({
998
- msg: "actor already exists",
999
- key: req.key,
1000
- generation
1001
- });
1002
- const doId2 = this.ctx.id.toString();
1003
- const actorId2 = buildActorId(doId2, generation);
1004
- return { success: { actorId: actorId2, created: false } };
1005
- }
1006
- generation = generation + 1;
1007
- created = true;
1008
- if (this.#state) {
1009
- this.#state.actor = void 0;
1010
- }
1011
- logger().debug({
1012
- msg: "resurrecting destroyed actor",
1013
- key: req.key,
1014
- oldGeneration: generation - 1,
1015
- newGeneration: generation
1016
- });
1017
- } else {
1018
- generation = 0;
1019
- created = true;
1020
- logger().debug({
1021
- msg: "creating new actor",
1022
- key: req.key,
1023
- generation
1024
- });
139
+ if (options.fetch) {
140
+ return options.fetch(request, env, ctx);
1025
141
  }
1026
- this.ctx.storage.sql.exec(
1027
- `INSERT INTO _rivetkit_metadata (id, name, key, destroyed, generation)
1028
- VALUES (1, ?, ?, 0, ?)
1029
- ON CONFLICT(id) DO UPDATE SET
1030
- name = excluded.name,
1031
- key = excluded.key,
1032
- destroyed = 0,
1033
- generation = excluded.generation`,
1034
- req.name,
1035
- JSON.stringify(req.key),
1036
- generation
142
+ return new Response(
143
+ "This is a RivetKit server.\n\nLearn more at https://rivet.dev\n"
1037
144
  );
1038
- this.#state.initialized = {
1039
- name: req.name,
1040
- key: req.key,
1041
- generation
1042
- };
1043
- const doId = this.ctx.id.toString();
1044
- const actorId = buildActorId(doId, generation);
1045
- if (created) {
1046
- initializeActorKvStorage(this.ctx.storage.sql, req.input);
1047
- const env3 = getCloudflareAmbientEnv();
1048
- const actorData = { name: req.name, key: req.key, generation };
1049
- this.ctx.waitUntil(
1050
- env3.ACTOR_KV.put(
1051
- GLOBAL_KV_KEYS.actorMetadata(actorId),
1052
- JSON.stringify(actorData)
1053
- )
1054
- );
1055
- }
1056
- await this.#loadActor();
1057
- logger().debug({
1058
- msg: created ? "actor created/resurrected" : "returning existing actor",
1059
- actorId,
1060
- created,
1061
- generation
1062
- });
1063
- return { success: { actorId, created } };
1064
- }
1065
- async fetch(request) {
1066
- const { actorRouter, generation } = await this.#loadActor();
1067
- const doId = this.ctx.id.toString();
1068
- const actorId = buildActorId(doId, generation);
1069
- return await actorRouter.fetch(request, {
1070
- actorId
1071
- });
1072
- }
1073
- async alarm() {
1074
- const { actorDriver, generation } = await this.#loadActor();
1075
- const doId = this.ctx.id.toString();
1076
- const actorId = buildActorId(doId, generation);
1077
- const actor = await actorDriver.loadActor(actorId);
1078
- await actor.onAlarm();
1079
145
  }
1080
146
  };
1081
147
  }
1082
- function initializeActorKvStorage(sql, input) {
1083
- const initialKvState = getInitialActorKvState(input);
1084
- for (const [key, value] of initialKvState) {
1085
- kvPut(sql, key, value);
1086
- }
1087
- }
1088
- export {
1089
- createActorDurableObject,
1090
- createHandler,
1091
- createInlineClient
1092
- };
148
+
149
+
150
+
151
+ exports.createHandler = createHandler; exports.setup = setup;
1093
152
  //# sourceMappingURL=mod.js.map