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