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