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