@rivetkit/cloudflare-workers 2.2.2-rc.1 → 2.3.0-rc.14

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.cjs DELETED
@@ -1,1093 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); 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/actor-handler-do.ts
2
- var _cloudflareworkers = require('cloudflare:workers');
3
- var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant);
4
- var _rivetkit = require('rivetkit');
5
- var _driverhelpers = require('rivetkit/driver-helpers');
6
-
7
- // src/actor-driver.ts
8
-
9
-
10
- var _utils = require('rivetkit/utils');
11
-
12
- // src/log.ts
13
- var _log = require('rivetkit/log');
14
- function logger() {
15
- return _log.getLogger.call(void 0, "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 = _nullishCoalesce((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 = _nullishCoalesce((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
-
112
-
113
-
114
-
115
- // src/config.ts
116
- var _v4 = require('zod/v4');
117
- var ConfigSchemaBase = _v4.z.object({
118
- /** Path that the Rivet manager API will be mounted. */
119
- managerPath: _v4.z.string().optional().default("/api/rivet"),
120
- /** Deprecated. Runner key for authentication. */
121
- runnerKey: _v4.z.string().optional(),
122
- /** Disable the welcome message. */
123
- noWelcome: _v4.z.boolean().optional().default(false),
124
- fetch: _v4.z.custom().optional()
125
- });
126
- var ConfigSchema = ConfigSchemaBase.default(
127
- () => ConfigSchemaBase.parse({})
128
- );
129
-
130
- // src/manager-driver.ts
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
- var _errors = require('rivetkit/errors');
143
-
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(_driverhelpers.WS_PROTOCOL_STANDARD);
225
- protocols.push(`${_driverhelpers.WS_PROTOCOL_TARGET}actor`);
226
- protocols.push(`${_driverhelpers.WS_PROTOCOL_ACTOR}${encodeURIComponent(actorId)}`);
227
- protocols.push(`${_driverhelpers.WS_PROTOCOL_ENCODING}${encoding}`);
228
- if (params) {
229
- protocols.push(
230
- `${_driverhelpers.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 (0, _errors.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(_driverhelpers.WS_PROTOCOL_STANDARD);
313
- protocols.push(`${_driverhelpers.WS_PROTOCOL_TARGET}actor`);
314
- protocols.push(`${_driverhelpers.WS_PROTOCOL_ACTOR}${encodeURIComponent(actorId)}`);
315
- protocols.push(`${_driverhelpers.WS_PROTOCOL_ENCODING}${encoding}`);
316
- if (params) {
317
- protocols.push(
318
- `${_driverhelpers.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 (0, _errors.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
- _utils.assertUnreachable.call(void 0, 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 (0, _errors.ActorDuplicateKey)(name, key);
461
- }
462
- throw new (0, _errors.InternalError)(
463
- `Unknown error creating actor: ${JSON.stringify(result.error)}`
464
- );
465
- } else {
466
- _utils.assertUnreachable.call(void 0, 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"
480
- }
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
- var _ws = require('hono/ws');
497
-
498
- var upgradeWebSocket = _ws.defineWebSocketHelper.call(void 0, 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 (0, _ws.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) => {
523
- 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) => {
532
- 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) => {
541
- 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(_driverhelpers.WS_PROTOCOL_STANDARD)) {
551
- headers["Sec-WebSocket-Protocol"] = _driverhelpers.WS_PROTOCOL_STANDARD;
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 _cloudflareworkers.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 } = _driverhelpers.buildManagerRouter.call(void 0,
580
- parsedConfig,
581
- managerDriver,
582
- () => upgradeWebSocket
583
- );
584
- const client = _rivetkit.createClientWithDriver.call(void 0, 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
- );
612
- }
613
- }
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
- _invariant2.default.call(void 0,
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
- }
641
- };
642
- var ActorGlobalState = (_class = class {constructor() { _class.prototype.__init.call(this); }
643
- // Initialization state
644
-
645
- // Loaded actor state
646
-
647
-
648
-
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
- __init() {this.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
- }, _class);
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) {
681
- 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 = _utils.promiseWithResolvers.call(void 0,
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 = _rivetkit.lookupInRegistry.call(void 0, 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)) {
793
- return;
794
- }
795
- if (actorState.destroying) {
796
- return;
797
- }
798
- actorState.destroying = true;
799
- this.#callOnStopAsync(actorId, doId, actorState.actorInstance);
800
- }
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();
814
- }
815
- };
816
- function createCloudflareActorsActorDriverBuilder(globalState) {
817
- return (config, managerDriver, inlineClient) => {
818
- return new CloudflareActorsActorDriver(
819
- config,
820
- managerDriver,
821
- inlineClient,
822
- globalState
823
- );
824
- };
825
- }
826
-
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 _cloudflareworkers.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.default.call(void 0, 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.default.call(void 0,
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.`
899
- );
900
- return this.#state.actor;
901
- }
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: _cloudflareworkers.env });
905
- const managerDriver = new CloudflareActorsManagerDriver();
906
- const inlineClient = _rivetkit.createClientWithDriver.call(void 0,
907
- managerDriver
908
- );
909
- const actorDriverBuilder = createCloudflareActorsActorDriverBuilder(globalState);
910
- const actorDriver = actorDriverBuilder(
911
- parsedConfig,
912
- managerDriver,
913
- inlineClient
914
- );
915
- const actorRouter = _rivetkit.createActorRouter.call(void 0,
916
- parsedConfig,
917
- actorDriver,
918
- getUpgradeWebSocket,
919
- _nullishCoalesce(((_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 = _nullishCoalesce(((_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 };
966
- }
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
- });
1025
- }
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
1037
- );
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
- }
1080
- };
1081
- }
1082
- function initializeActorKvStorage(sql, input) {
1083
- const initialKvState = _driverhelpers.getInitialActorKvState.call(void 0, input);
1084
- for (const [key, value] of initialKvState) {
1085
- kvPut(sql, key, value);
1086
- }
1087
- }
1088
-
1089
-
1090
-
1091
-
1092
- exports.createActorDurableObject = createActorDurableObject; exports.createHandler = createHandler; exports.createInlineClient = createInlineClient;
1093
- //# sourceMappingURL=mod.cjs.map