rivetkit 2.0.20 → 2.0.21
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/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/{chunk-L3YPHXPE.js → chunk-2POQCWMA.js} +481 -100
- package/dist/tsup/chunk-2POQCWMA.js.map +1 -0
- package/dist/tsup/{chunk-5F6X4AFU.js → chunk-3UIGKLZW.js} +6 -6
- package/dist/tsup/chunk-3UIGKLZW.js.map +1 -0
- package/dist/tsup/{chunk-M6LIJ6BK.js → chunk-4OINFQBR.js} +3 -3
- package/dist/tsup/{chunk-ZODINJWN.cjs → chunk-65SAIRRY.cjs} +12 -12
- package/dist/tsup/chunk-65SAIRRY.cjs.map +1 -0
- package/dist/tsup/{chunk-RI4YHZZW.js → chunk-6G76WIWL.js} +2 -2
- package/dist/tsup/{chunk-RI4YHZZW.js.map → chunk-6G76WIWL.js.map} +1 -1
- package/dist/tsup/{chunk-YFFCPYHY.js → chunk-D2LS4X6E.js} +11 -5
- package/dist/tsup/chunk-D2LS4X6E.js.map +1 -0
- package/dist/tsup/{chunk-QRUGCDA5.js → chunk-DYA34FHW.js} +2 -2
- package/dist/tsup/{chunk-KUZWEM23.cjs → chunk-ELDFBXDV.cjs} +8 -4
- package/dist/tsup/chunk-ELDFBXDV.cjs.map +1 -0
- package/dist/tsup/{chunk-FYP3TZXD.cjs → chunk-FDJ3AVNB.cjs} +32 -26
- package/dist/tsup/chunk-FDJ3AVNB.cjs.map +1 -0
- package/dist/tsup/{chunk-ER5OT3SQ.js → chunk-FUX6U6TL.js} +2 -2
- package/dist/tsup/chunk-FUX6U6TL.js.map +1 -0
- package/dist/tsup/{chunk-RJVSNJO7.cjs → chunk-HN7UXCYQ.cjs} +7 -7
- package/dist/tsup/chunk-HN7UXCYQ.cjs.map +1 -0
- package/dist/tsup/{chunk-QMVCFQ37.js → chunk-HUGSRAGL.js} +8 -4
- package/dist/tsup/chunk-HUGSRAGL.js.map +1 -0
- package/dist/tsup/{chunk-PV22ZBDE.cjs → chunk-JKOUXDK6.cjs} +16 -10
- package/dist/tsup/chunk-JKOUXDK6.cjs.map +1 -0
- package/dist/tsup/{chunk-2I6L3VRO.cjs → chunk-JTIBPF7N.cjs} +14 -14
- package/dist/tsup/chunk-JTIBPF7N.cjs.map +1 -0
- package/dist/tsup/chunk-KSRXX3Z4.cjs.map +1 -1
- package/dist/tsup/{chunk-JZD6FEOE.cjs → chunk-LMJHBF26.cjs} +455 -289
- package/dist/tsup/chunk-LMJHBF26.cjs.map +1 -0
- package/dist/tsup/{chunk-KKRR7DSG.cjs → chunk-LWGCMELP.cjs} +3 -3
- package/dist/tsup/chunk-LWGCMELP.cjs.map +1 -0
- package/dist/tsup/{chunk-2S7HJMMY.cjs → chunk-M5BHNJHB.cjs} +630 -249
- package/dist/tsup/chunk-M5BHNJHB.cjs.map +1 -0
- package/dist/tsup/{chunk-G6JGHCG4.cjs → chunk-O4GUKGK4.cjs} +6 -6
- package/dist/tsup/chunk-O4GUKGK4.cjs.map +1 -0
- package/dist/tsup/{chunk-7ACKZS3T.js → chunk-RZZDFDB6.js} +13 -7
- package/dist/tsup/chunk-RZZDFDB6.js.map +1 -0
- package/dist/tsup/{chunk-MGHPBNWB.js → chunk-VLR3TDHT.js} +2 -2
- package/dist/tsup/{chunk-GQ5WTE64.js → chunk-Y2QONT7B.js} +263 -97
- package/dist/tsup/chunk-Y2QONT7B.js.map +1 -0
- package/dist/tsup/{chunk-DUOTOMP7.cjs → chunk-ZNWE3XBT.cjs} +3 -3
- package/dist/tsup/chunk-ZNWE3XBT.cjs.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.cjs.map +1 -1
- package/dist/tsup/client/mod.d.cts +2 -2
- package/dist/tsup/client/mod.d.ts +2 -2
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.cjs.map +1 -1
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.cjs.map +1 -1
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{conn-CmPcqOCF.d.ts → conn-Clu655RU.d.ts} +72 -71
- package/dist/tsup/{conn-DU5EbfCu.d.cts → conn-lUvFLo_q.d.cts} +72 -71
- package/dist/tsup/driver-helpers/mod.cjs +5 -5
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +1 -1
- package/dist/tsup/driver-helpers/mod.d.ts +1 -1
- package/dist/tsup/driver-helpers/mod.js +4 -4
- package/dist/tsup/driver-test-suite/mod.cjs +603 -294
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +1 -1
- package/dist/tsup/driver-test-suite/mod.d.ts +1 -1
- package/dist/tsup/driver-test-suite/mod.js +574 -265
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +68 -7
- package/dist/tsup/inspector/mod.d.ts +68 -7
- package/dist/tsup/inspector/mod.js +5 -5
- package/dist/tsup/mod.cjs +10 -10
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +2 -2
- package/dist/tsup/mod.d.ts +2 -2
- package/dist/tsup/mod.js +9 -9
- package/dist/tsup/test/mod.cjs +11 -11
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +1 -1
- package/dist/tsup/test/mod.d.ts +1 -1
- package/dist/tsup/test/mod.js +10 -10
- package/dist/tsup/utils.cjs +2 -2
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.js +1 -1
- package/package.json +4 -3
- package/src/actor/config.ts +108 -15
- package/src/actor/conn-drivers.ts +2 -1
- package/src/actor/instance.ts +119 -35
- package/src/actor/keys.test.ts +13 -4
- package/src/actor/protocol/old.ts +10 -3
- package/src/actor/router-endpoints.ts +26 -16
- package/src/actor/router.ts +41 -13
- package/src/actor/unstable-react.ts +1 -1
- package/src/client/actor-common.ts +3 -1
- package/src/client/actor-conn.ts +44 -12
- package/src/client/actor-handle.ts +4 -1
- package/src/client/client.ts +32 -18
- package/src/client/utils.ts +21 -8
- package/src/common/actor-router-consts.ts +2 -0
- package/src/common/inline-websocket-adapter2.ts +24 -6
- package/src/common/log.ts +6 -2
- package/src/common/logfmt.ts +3 -1
- package/src/common/router.ts +3 -1
- package/src/common/utils.ts +6 -2
- package/src/driver-helpers/utils.ts +4 -1
- package/src/driver-test-suite/mod.ts +15 -4
- package/src/driver-test-suite/test-inline-client-driver.ts +35 -13
- package/src/driver-test-suite/tests/action-features.ts +6 -2
- package/src/driver-test-suite/tests/actor-conn-state.ts +18 -8
- package/src/driver-test-suite/tests/actor-conn.ts +35 -13
- package/src/driver-test-suite/tests/actor-handle.ts +35 -15
- package/src/driver-test-suite/tests/actor-inline-client.ts +34 -23
- package/src/driver-test-suite/tests/actor-inspector.ts +241 -131
- package/src/driver-test-suite/tests/actor-reconnect.ts +14 -4
- package/src/driver-test-suite/tests/actor-schedule.ts +12 -3
- package/src/driver-test-suite/tests/actor-sleep.ts +6 -3
- package/src/driver-test-suite/tests/actor-vars.ts +6 -2
- package/src/driver-test-suite/tests/manager-driver.ts +16 -6
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +64 -25
- package/src/driver-test-suite/tests/raw-http.ts +17 -5
- package/src/driver-test-suite/tests/raw-websocket.ts +36 -12
- package/src/driver-test-suite/tests/request-access.ts +18 -8
- package/src/drivers/engine/actor-driver.ts +46 -25
- package/src/drivers/engine/config.ts +2 -1
- package/src/drivers/file-system/global-state.ts +58 -16
- package/src/drivers/file-system/manager.ts +35 -12
- package/src/drivers/file-system/mod.ts +6 -1
- package/src/drivers/file-system/utils.ts +8 -2
- package/src/engine-process/mod.ts +15 -4
- package/src/inspector/actor.ts +63 -23
- package/src/inspector/config.ts +2 -1
- package/src/inspector/manager.ts +10 -3
- package/src/inspector/utils.ts +2 -1
- package/src/manager/driver.ts +4 -1
- package/src/manager/gateway.ts +278 -8
- package/src/manager/hono-websocket-adapter.ts +33 -10
- package/src/manager/router-schema.ts +4 -2
- package/src/manager/router.ts +78 -12
- package/src/manager-api/actors.ts +2 -0
- package/src/registry/mod.ts +31 -9
- package/src/registry/run-config.ts +3 -1
- package/src/remote-manager-driver/api-endpoints.ts +2 -2
- package/src/remote-manager-driver/mod.ts +23 -7
- package/src/remote-manager-driver/ws-proxy.ts +21 -5
- package/src/serde.ts +6 -2
- package/src/test/mod.ts +2 -1
- package/src/utils.ts +6 -2
- package/dist/tsup/chunk-2I6L3VRO.cjs.map +0 -1
- package/dist/tsup/chunk-2S7HJMMY.cjs.map +0 -1
- package/dist/tsup/chunk-5F6X4AFU.js.map +0 -1
- package/dist/tsup/chunk-7ACKZS3T.js.map +0 -1
- package/dist/tsup/chunk-DUOTOMP7.cjs.map +0 -1
- package/dist/tsup/chunk-ER5OT3SQ.js.map +0 -1
- package/dist/tsup/chunk-FYP3TZXD.cjs.map +0 -1
- package/dist/tsup/chunk-G6JGHCG4.cjs.map +0 -1
- package/dist/tsup/chunk-GQ5WTE64.js.map +0 -1
- package/dist/tsup/chunk-JZD6FEOE.cjs.map +0 -1
- package/dist/tsup/chunk-KKRR7DSG.cjs.map +0 -1
- package/dist/tsup/chunk-KUZWEM23.cjs.map +0 -1
- package/dist/tsup/chunk-L3YPHXPE.js.map +0 -1
- package/dist/tsup/chunk-PV22ZBDE.cjs.map +0 -1
- package/dist/tsup/chunk-QMVCFQ37.js.map +0 -1
- package/dist/tsup/chunk-RJVSNJO7.cjs.map +0 -1
- package/dist/tsup/chunk-YFFCPYHY.js.map +0 -1
- package/dist/tsup/chunk-ZODINJWN.cjs.map +0 -1
- /package/dist/tsup/{chunk-M6LIJ6BK.js.map → chunk-4OINFQBR.js.map} +0 -0
- /package/dist/tsup/{chunk-QRUGCDA5.js.map → chunk-DYA34FHW.js.map} +0 -0
- /package/dist/tsup/{chunk-MGHPBNWB.js.map → chunk-VLR3TDHT.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
ActorConfig as EngineActorConfig,
|
|
2
3
|
RunnerConfig as EngineRunnerConfig,
|
|
3
|
-
ActorConfig as RunnerActorConfig,
|
|
4
4
|
} from "@rivetkit/engine-runner";
|
|
5
5
|
import { Runner } from "@rivetkit/engine-runner";
|
|
6
6
|
import * as cbor from "cbor-x";
|
|
@@ -63,8 +63,8 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
63
63
|
#version: number = 1; // Version for the runner protocol
|
|
64
64
|
#alarmTimeout?: LongTimeoutHandle;
|
|
65
65
|
|
|
66
|
-
#runnerStarted: PromiseWithResolvers<undefined> =
|
|
67
|
-
#runnerStopped: PromiseWithResolvers<undefined> =
|
|
66
|
+
#runnerStarted: PromiseWithResolvers<undefined> = promiseWithResolvers();
|
|
67
|
+
#runnerStopped: PromiseWithResolvers<undefined> = promiseWithResolvers();
|
|
68
68
|
|
|
69
69
|
constructor(
|
|
70
70
|
registryConfig: RegistryConfig,
|
|
@@ -153,7 +153,8 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
153
153
|
async #loadActorHandler(actorId: string): Promise<ActorHandler> {
|
|
154
154
|
// Check if actor is already loaded
|
|
155
155
|
const handler = this.#actors.get(actorId);
|
|
156
|
-
if (!handler)
|
|
156
|
+
if (!handler)
|
|
157
|
+
throw new Error(`Actor handler does not exist ${actorId}`);
|
|
157
158
|
if (handler.actorStartPromise) await handler.actorStartPromise.promise;
|
|
158
159
|
if (!handler.actor) throw new Error("Actor should be loaded");
|
|
159
160
|
return handler;
|
|
@@ -220,20 +221,20 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
220
221
|
async #runnerOnActorStart(
|
|
221
222
|
actorId: string,
|
|
222
223
|
generation: number,
|
|
223
|
-
|
|
224
|
+
actorConfig: EngineActorConfig,
|
|
224
225
|
): Promise<void> {
|
|
225
226
|
logger().debug({
|
|
226
227
|
msg: "runner actor starting",
|
|
227
228
|
actorId,
|
|
228
|
-
name:
|
|
229
|
-
key:
|
|
229
|
+
name: actorConfig.name,
|
|
230
|
+
key: actorConfig.key,
|
|
230
231
|
generation,
|
|
231
232
|
});
|
|
232
233
|
|
|
233
234
|
// Deserialize input
|
|
234
235
|
let input: any;
|
|
235
|
-
if (
|
|
236
|
-
input = cbor.decode(
|
|
236
|
+
if (actorConfig.input) {
|
|
237
|
+
input = cbor.decode(actorConfig.input);
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
// Get or create handler
|
|
@@ -259,12 +260,15 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
259
260
|
: serializeEmptyPersistData(input);
|
|
260
261
|
}
|
|
261
262
|
|
|
262
|
-
const name =
|
|
263
|
-
invariant(
|
|
264
|
-
const key = deserializeActorKey(
|
|
263
|
+
const name = actorConfig.name as string;
|
|
264
|
+
invariant(actorConfig.key, "actor should have a key");
|
|
265
|
+
const key = deserializeActorKey(actorConfig.key);
|
|
265
266
|
|
|
266
267
|
// Create actor instance
|
|
267
|
-
const definition = lookupInRegistry(
|
|
268
|
+
const definition = lookupInRegistry(
|
|
269
|
+
this.#registryConfig,
|
|
270
|
+
actorConfig.name,
|
|
271
|
+
);
|
|
268
272
|
handler.actor = definition.instantiate();
|
|
269
273
|
|
|
270
274
|
// Start actor
|
|
@@ -284,7 +288,10 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
284
288
|
logger().debug({ msg: "runner actor started", actorId, name, key });
|
|
285
289
|
}
|
|
286
290
|
|
|
287
|
-
async #runnerOnActorStop(
|
|
291
|
+
async #runnerOnActorStop(
|
|
292
|
+
actorId: string,
|
|
293
|
+
generation: number,
|
|
294
|
+
): Promise<void> {
|
|
288
295
|
logger().debug({ msg: "runner actor stopping", actorId, generation });
|
|
289
296
|
|
|
290
297
|
const handler = this.#actors.get(actorId);
|
|
@@ -296,7 +303,11 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
296
303
|
logger().debug({ msg: "runner actor stopped", actorId });
|
|
297
304
|
}
|
|
298
305
|
|
|
299
|
-
async #runnerFetch(
|
|
306
|
+
async #runnerFetch(
|
|
307
|
+
runner: Runner,
|
|
308
|
+
actorId: string,
|
|
309
|
+
request: Request,
|
|
310
|
+
): Promise<Response> {
|
|
300
311
|
logger().debug({
|
|
301
312
|
msg: "runner fetch",
|
|
302
313
|
actorId,
|
|
@@ -307,6 +318,7 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
307
318
|
}
|
|
308
319
|
|
|
309
320
|
async #runnerWebSocket(
|
|
321
|
+
runner: Runner,
|
|
310
322
|
actorId: string,
|
|
311
323
|
websocketRaw: any,
|
|
312
324
|
request: Request,
|
|
@@ -317,10 +329,8 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
317
329
|
|
|
318
330
|
const url = new URL(request.url);
|
|
319
331
|
|
|
320
|
-
// Parse configuration from Sec-WebSocket-Protocol header
|
|
332
|
+
// Parse configuration from Sec-WebSocket-Protocol header (optional for path-based routing)
|
|
321
333
|
const protocols = request.headers.get("sec-websocket-protocol");
|
|
322
|
-
if (protocols === null)
|
|
323
|
-
throw new Error(`Missing sec-websocket-protocol header`);
|
|
324
334
|
|
|
325
335
|
let encodingRaw: string | undefined;
|
|
326
336
|
let connParamsRaw: string | undefined;
|
|
@@ -329,7 +339,9 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
329
339
|
const protocolList = protocols.split(",").map((p) => p.trim());
|
|
330
340
|
for (const protocol of protocolList) {
|
|
331
341
|
if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
|
|
332
|
-
encodingRaw = protocol.substring(
|
|
342
|
+
encodingRaw = protocol.substring(
|
|
343
|
+
WS_PROTOCOL_ENCODING.length,
|
|
344
|
+
);
|
|
333
345
|
} else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
|
|
334
346
|
connParamsRaw = decodeURIComponent(
|
|
335
347
|
protocol.substring(WS_PROTOCOL_CONN_PARAMS.length),
|
|
@@ -339,7 +351,9 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
339
351
|
}
|
|
340
352
|
|
|
341
353
|
const encoding = EncodingSchema.parse(encodingRaw);
|
|
342
|
-
const connParams = connParamsRaw
|
|
354
|
+
const connParams = connParamsRaw
|
|
355
|
+
? JSON.parse(connParamsRaw)
|
|
356
|
+
: undefined;
|
|
343
357
|
|
|
344
358
|
// Fetch WS handler
|
|
345
359
|
//
|
|
@@ -379,7 +393,9 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
379
393
|
});
|
|
380
394
|
|
|
381
395
|
if (websocket.readyState === 1) {
|
|
382
|
-
wsHandlerPromise.then((x) =>
|
|
396
|
+
wsHandlerPromise.then((x) =>
|
|
397
|
+
x.onOpen?.(new Event("open"), wsContext),
|
|
398
|
+
);
|
|
383
399
|
} else {
|
|
384
400
|
websocket.addEventListener("open", (event) => {
|
|
385
401
|
wsHandlerPromise.then((x) => x.onOpen?.(event, wsContext));
|
|
@@ -409,17 +425,22 @@ export class EngineActorDriver implements ActorDriver {
|
|
|
409
425
|
}
|
|
410
426
|
|
|
411
427
|
async serverlessHandleStart(c: HonoContext): Promise<Response> {
|
|
412
|
-
await this.#runnerStarted.promise;
|
|
413
|
-
|
|
414
428
|
return streamSSE(c, async (stream) => {
|
|
415
|
-
|
|
429
|
+
// NOTE: onAbort does not work reliably
|
|
430
|
+
stream.onAbort(() => {});
|
|
431
|
+
c.req.raw.signal.addEventListener("abort", () => {
|
|
432
|
+
logger().debug("SSE aborted, shutting down runner");
|
|
433
|
+
this.shutdown(true);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
await this.#runnerStarted.promise;
|
|
416
437
|
|
|
417
438
|
// Runner id should be set if the runner started
|
|
418
439
|
const payload = this.#runner.getServerlessInitPacket();
|
|
419
440
|
invariant(payload, "runnerId not set");
|
|
420
441
|
await stream.writeSSE({ data: payload });
|
|
421
442
|
|
|
422
|
-
|
|
443
|
+
await this.#runnerStopped.promise;
|
|
423
444
|
});
|
|
424
445
|
}
|
|
425
446
|
}
|
|
@@ -8,7 +8,8 @@ export const EngingConfigSchema = z
|
|
|
8
8
|
runnerKey: z
|
|
9
9
|
.string()
|
|
10
10
|
.default(
|
|
11
|
-
() =>
|
|
11
|
+
() =>
|
|
12
|
+
getEnvUniversal("RIVET_RUNNER_KEY") ?? crypto.randomUUID(),
|
|
12
13
|
),
|
|
13
14
|
|
|
14
15
|
/** How many actors this runner can run. */
|
|
@@ -120,7 +120,10 @@ export class FileSystemGlobalState {
|
|
|
120
120
|
try {
|
|
121
121
|
this.#cleanupTempFilesSync();
|
|
122
122
|
} catch (err) {
|
|
123
|
-
logger().error({
|
|
123
|
+
logger().error({
|
|
124
|
+
msg: "failed to cleanup temp files",
|
|
125
|
+
error: err,
|
|
126
|
+
});
|
|
124
127
|
}
|
|
125
128
|
} else {
|
|
126
129
|
logger().debug({ msg: "memory driver ready" });
|
|
@@ -152,7 +155,9 @@ export class FileSystemGlobalState {
|
|
|
152
155
|
.sort();
|
|
153
156
|
}
|
|
154
157
|
|
|
155
|
-
const startIndex = params.cursor
|
|
158
|
+
const startIndex = params.cursor
|
|
159
|
+
? actorIds.indexOf(params.cursor) + 1
|
|
160
|
+
: 0;
|
|
156
161
|
|
|
157
162
|
for (let i = startIndex; i < actorIds.length; i++) {
|
|
158
163
|
const actorId = actorIds[i];
|
|
@@ -164,7 +169,11 @@ export class FileSystemGlobalState {
|
|
|
164
169
|
const state = await this.loadActorStateOrError(actorId);
|
|
165
170
|
yield state;
|
|
166
171
|
} catch (error) {
|
|
167
|
-
logger().error({
|
|
172
|
+
logger().error({
|
|
173
|
+
msg: "failed to load actor state",
|
|
174
|
+
actorId,
|
|
175
|
+
error,
|
|
176
|
+
});
|
|
168
177
|
}
|
|
169
178
|
}
|
|
170
179
|
}
|
|
@@ -209,7 +218,9 @@ export class FileSystemGlobalState {
|
|
|
209
218
|
name,
|
|
210
219
|
key,
|
|
211
220
|
createdAt: BigInt(Date.now()),
|
|
212
|
-
persistedData: bufferToArrayBuffer(
|
|
221
|
+
persistedData: bufferToArrayBuffer(
|
|
222
|
+
serializeEmptyPersistData(input),
|
|
223
|
+
),
|
|
213
224
|
};
|
|
214
225
|
await this.writeActor(actorId, entry.state);
|
|
215
226
|
return entry;
|
|
@@ -263,7 +274,9 @@ export class FileSystemGlobalState {
|
|
|
263
274
|
}
|
|
264
275
|
|
|
265
276
|
// For other errors, throw
|
|
266
|
-
const error = new Error(
|
|
277
|
+
const error = new Error(
|
|
278
|
+
`Failed to load actor state: ${innerError}`,
|
|
279
|
+
);
|
|
267
280
|
throw error;
|
|
268
281
|
}
|
|
269
282
|
}
|
|
@@ -284,7 +297,9 @@ export class FileSystemGlobalState {
|
|
|
284
297
|
name,
|
|
285
298
|
key: key as readonly string[],
|
|
286
299
|
createdAt: BigInt(Date.now()),
|
|
287
|
-
persistedData: bufferToArrayBuffer(
|
|
300
|
+
persistedData: bufferToArrayBuffer(
|
|
301
|
+
serializeEmptyPersistData(input),
|
|
302
|
+
),
|
|
288
303
|
};
|
|
289
304
|
await this.writeActor(actorId, entry.state);
|
|
290
305
|
}
|
|
@@ -302,7 +317,8 @@ export class FileSystemGlobalState {
|
|
|
302
317
|
|
|
303
318
|
// Wait for actor to fully start before stopping it to avoid race conditions
|
|
304
319
|
if (actor.loadPromise) await actor.loadPromise.catch();
|
|
305
|
-
if (actor.startPromise?.promise)
|
|
320
|
+
if (actor.startPromise?.promise)
|
|
321
|
+
await actor.startPromise.promise.catch();
|
|
306
322
|
|
|
307
323
|
// Mark as removed
|
|
308
324
|
actor.removed = true;
|
|
@@ -344,14 +360,20 @@ export class FileSystemGlobalState {
|
|
|
344
360
|
timestamp: BigInt(timestamp),
|
|
345
361
|
};
|
|
346
362
|
const data =
|
|
347
|
-
ACTOR_ALARM_VERSIONED.serializeWithEmbeddedVersion(
|
|
363
|
+
ACTOR_ALARM_VERSIONED.serializeWithEmbeddedVersion(
|
|
364
|
+
alarmData,
|
|
365
|
+
);
|
|
348
366
|
await fs.writeFile(tempPath, data);
|
|
349
367
|
await fs.rename(tempPath, alarmPath);
|
|
350
368
|
} catch (error) {
|
|
351
369
|
try {
|
|
352
370
|
await fs.unlink(tempPath);
|
|
353
371
|
} catch {}
|
|
354
|
-
logger().error({
|
|
372
|
+
logger().error({
|
|
373
|
+
msg: "failed to write alarm",
|
|
374
|
+
actorId,
|
|
375
|
+
error,
|
|
376
|
+
});
|
|
355
377
|
throw new Error(`Failed to write alarm: ${error}`);
|
|
356
378
|
}
|
|
357
379
|
}
|
|
@@ -396,7 +418,11 @@ export class FileSystemGlobalState {
|
|
|
396
418
|
} catch {
|
|
397
419
|
// Ignore cleanup errors
|
|
398
420
|
}
|
|
399
|
-
logger().error({
|
|
421
|
+
logger().error({
|
|
422
|
+
msg: "failed to save actor state",
|
|
423
|
+
actorId,
|
|
424
|
+
error,
|
|
425
|
+
});
|
|
400
426
|
throw new Error(`Failed to save actor state: ${error}`);
|
|
401
427
|
}
|
|
402
428
|
}
|
|
@@ -430,7 +456,10 @@ export class FileSystemGlobalState {
|
|
|
430
456
|
try {
|
|
431
457
|
this.#loadAlarmsSync();
|
|
432
458
|
} catch (err) {
|
|
433
|
-
logger().error({
|
|
459
|
+
logger().error({
|
|
460
|
+
msg: "failed to load alarms on startup",
|
|
461
|
+
error: err,
|
|
462
|
+
});
|
|
434
463
|
}
|
|
435
464
|
}
|
|
436
465
|
|
|
@@ -466,7 +495,10 @@ export class FileSystemGlobalState {
|
|
|
466
495
|
|
|
467
496
|
try {
|
|
468
497
|
// Create actor
|
|
469
|
-
const definition = lookupInRegistry(
|
|
498
|
+
const definition = lookupInRegistry(
|
|
499
|
+
registryConfig,
|
|
500
|
+
entry.state.name,
|
|
501
|
+
);
|
|
470
502
|
entry.actor = definition.instantiate();
|
|
471
503
|
|
|
472
504
|
// Start actor
|
|
@@ -531,9 +563,15 @@ export class FileSystemGlobalState {
|
|
|
531
563
|
);
|
|
532
564
|
const timestamp = Number(alarmData.timestamp);
|
|
533
565
|
if (Number.isFinite(timestamp)) {
|
|
534
|
-
this.#scheduleAlarmTimeout(
|
|
566
|
+
this.#scheduleAlarmTimeout(
|
|
567
|
+
alarmData.actorId,
|
|
568
|
+
timestamp,
|
|
569
|
+
);
|
|
535
570
|
} else {
|
|
536
|
-
logger().debug({
|
|
571
|
+
logger().debug({
|
|
572
|
+
msg: "invalid alarm file contents",
|
|
573
|
+
file,
|
|
574
|
+
});
|
|
537
575
|
}
|
|
538
576
|
} catch (err) {
|
|
539
577
|
logger().error({
|
|
@@ -544,7 +582,10 @@ export class FileSystemGlobalState {
|
|
|
544
582
|
}
|
|
545
583
|
}
|
|
546
584
|
} catch (err) {
|
|
547
|
-
logger().error({
|
|
585
|
+
logger().error({
|
|
586
|
+
msg: "failed to list alarms directory",
|
|
587
|
+
error: err,
|
|
588
|
+
});
|
|
548
589
|
}
|
|
549
590
|
}
|
|
550
591
|
|
|
@@ -598,7 +639,8 @@ export class FileSystemGlobalState {
|
|
|
598
639
|
|
|
599
640
|
// Ensure actor state exists and start actor if needed
|
|
600
641
|
const loaded = await this.loadActor(actorId);
|
|
601
|
-
if (!loaded.state)
|
|
642
|
+
if (!loaded.state)
|
|
643
|
+
throw new Error(`Actor does not exist: ${actorId}`);
|
|
602
644
|
|
|
603
645
|
// Start actor if not already running
|
|
604
646
|
const runnerParams = this.#runnerParams;
|
|
@@ -65,7 +65,9 @@ export class FileSystemManagerDriver implements ManagerDriver {
|
|
|
65
65
|
name: actorState.name,
|
|
66
66
|
key: actorState.key as string[],
|
|
67
67
|
startedAt: startedAt,
|
|
68
|
-
createdAt: new Date(
|
|
68
|
+
createdAt: new Date(
|
|
69
|
+
Number(actorState.createdAt),
|
|
70
|
+
).toISOString(),
|
|
69
71
|
features: [
|
|
70
72
|
ActorFeature.State,
|
|
71
73
|
ActorFeature.Connections,
|
|
@@ -92,21 +94,27 @@ export class FileSystemManagerDriver implements ManagerDriver {
|
|
|
92
94
|
},
|
|
93
95
|
getActorById: async (id) => {
|
|
94
96
|
try {
|
|
95
|
-
const result =
|
|
97
|
+
const result =
|
|
98
|
+
await this.#state.loadActorStateOrError(id);
|
|
96
99
|
return transformActor(result);
|
|
97
100
|
} catch {
|
|
98
101
|
return null;
|
|
99
102
|
}
|
|
100
103
|
},
|
|
101
104
|
getBuilds: async () => {
|
|
102
|
-
return Object.keys(this.#registryConfig.use).map(
|
|
103
|
-
name
|
|
104
|
-
|
|
105
|
+
return Object.keys(this.#registryConfig.use).map(
|
|
106
|
+
(name) => ({
|
|
107
|
+
name,
|
|
108
|
+
}),
|
|
109
|
+
);
|
|
105
110
|
},
|
|
106
111
|
createActor: async (input) => {
|
|
107
112
|
const { actorId } = await this.createActor(input);
|
|
108
113
|
try {
|
|
109
|
-
const result =
|
|
114
|
+
const result =
|
|
115
|
+
await this.#state.loadActorStateOrError(
|
|
116
|
+
actorId,
|
|
117
|
+
);
|
|
110
118
|
return transformActor(result);
|
|
111
119
|
} catch {
|
|
112
120
|
return null;
|
|
@@ -134,7 +142,10 @@ export class FileSystemManagerDriver implements ManagerDriver {
|
|
|
134
142
|
);
|
|
135
143
|
}
|
|
136
144
|
|
|
137
|
-
async sendRequest(
|
|
145
|
+
async sendRequest(
|
|
146
|
+
actorId: string,
|
|
147
|
+
actorRequest: Request,
|
|
148
|
+
): Promise<Response> {
|
|
138
149
|
return await this.#actorRouter.fetch(actorRequest, {
|
|
139
150
|
actorId,
|
|
140
151
|
});
|
|
@@ -150,7 +161,9 @@ export class FileSystemManagerDriver implements ManagerDriver {
|
|
|
150
161
|
): Promise<UniversalWebSocket> {
|
|
151
162
|
// Handle raw WebSocket paths
|
|
152
163
|
const pathOnly = path.split("?")[0];
|
|
153
|
-
const normalizedPath = pathOnly.startsWith("/")
|
|
164
|
+
const normalizedPath = pathOnly.startsWith("/")
|
|
165
|
+
? pathOnly
|
|
166
|
+
: `/${pathOnly}`;
|
|
154
167
|
if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
|
|
155
168
|
// Handle standard connect
|
|
156
169
|
const wsHandler = await handleWebSocketConnect(
|
|
@@ -206,7 +219,9 @@ export class FileSystemManagerDriver implements ManagerDriver {
|
|
|
206
219
|
|
|
207
220
|
// Handle raw WebSocket paths
|
|
208
221
|
const pathOnly = path.split("?")[0];
|
|
209
|
-
const normalizedPath = pathOnly.startsWith("/")
|
|
222
|
+
const normalizedPath = pathOnly.startsWith("/")
|
|
223
|
+
? pathOnly
|
|
224
|
+
: `/${pathOnly}`;
|
|
210
225
|
if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
|
|
211
226
|
// Handle standard connect
|
|
212
227
|
const wsHandler = await handleWebSocketConnect(
|
|
@@ -238,7 +253,9 @@ export class FileSystemManagerDriver implements ManagerDriver {
|
|
|
238
253
|
}
|
|
239
254
|
}
|
|
240
255
|
|
|
241
|
-
async getForId({
|
|
256
|
+
async getForId({
|
|
257
|
+
actorId,
|
|
258
|
+
}: GetForIdInput): Promise<ActorOutput | undefined> {
|
|
242
259
|
// Validate the actor exists
|
|
243
260
|
const actor = await this.#state.loadActor(actorId);
|
|
244
261
|
if (!actor.state) {
|
|
@@ -253,7 +270,11 @@ export class FileSystemManagerDriver implements ManagerDriver {
|
|
|
253
270
|
key: actor.state.key as string[],
|
|
254
271
|
};
|
|
255
272
|
} catch (error) {
|
|
256
|
-
logger().error({
|
|
273
|
+
logger().error({
|
|
274
|
+
msg: "failed to read actor state",
|
|
275
|
+
actorId,
|
|
276
|
+
error,
|
|
277
|
+
});
|
|
257
278
|
return undefined;
|
|
258
279
|
}
|
|
259
280
|
}
|
|
@@ -317,7 +338,9 @@ export class FileSystemManagerDriver implements ManagerDriver {
|
|
|
317
338
|
return {
|
|
318
339
|
name: this.#state.persist ? "File System" : "Memory",
|
|
319
340
|
properties: {
|
|
320
|
-
...(this.#state.persist
|
|
341
|
+
...(this.#state.persist
|
|
342
|
+
? { Data: this.#state.storagePath }
|
|
343
|
+
: {}),
|
|
321
344
|
Instances: this.#state.actorCountOnStartup.toString(),
|
|
322
345
|
},
|
|
323
346
|
};
|
|
@@ -31,7 +31,12 @@ export function createFileSystemOrMemoryDriver(
|
|
|
31
31
|
state,
|
|
32
32
|
);
|
|
33
33
|
|
|
34
|
-
state.onRunnerStart(
|
|
34
|
+
state.onRunnerStart(
|
|
35
|
+
registryConfig,
|
|
36
|
+
runConfig,
|
|
37
|
+
inlineClient,
|
|
38
|
+
actorDriver,
|
|
39
|
+
);
|
|
35
40
|
|
|
36
41
|
return actorDriver;
|
|
37
42
|
},
|
|
@@ -99,10 +99,16 @@ function getDataPath(appName: string): string {
|
|
|
99
99
|
appName,
|
|
100
100
|
);
|
|
101
101
|
case "darwin":
|
|
102
|
-
return path.join(
|
|
102
|
+
return path.join(
|
|
103
|
+
homeDir,
|
|
104
|
+
"Library",
|
|
105
|
+
"Application Support",
|
|
106
|
+
appName,
|
|
107
|
+
);
|
|
103
108
|
default: // linux and others
|
|
104
109
|
return path.join(
|
|
105
|
-
process.env.XDG_DATA_HOME ||
|
|
110
|
+
process.env.XDG_DATA_HOME ||
|
|
111
|
+
path.join(homeDir, ".local", "share"),
|
|
106
112
|
appName,
|
|
107
113
|
);
|
|
108
114
|
}
|
|
@@ -23,7 +23,10 @@ interface EnsureEngineProcessOptions {
|
|
|
23
23
|
export async function ensureEngineProcess(
|
|
24
24
|
options: EnsureEngineProcessOptions,
|
|
25
25
|
): Promise<void> {
|
|
26
|
-
logger().debug({
|
|
26
|
+
logger().debug({
|
|
27
|
+
msg: "ensuring engine process",
|
|
28
|
+
version: options.version,
|
|
29
|
+
});
|
|
27
30
|
const storageRoot = getStoragePath();
|
|
28
31
|
const binDir = path.join(storageRoot, "bin");
|
|
29
32
|
const varDir = path.join(storageRoot, "var");
|
|
@@ -256,12 +259,18 @@ export function resolveTargetTripletFor(
|
|
|
256
259
|
break;
|
|
257
260
|
case "linux":
|
|
258
261
|
if (arch === "x64") {
|
|
259
|
-
return {
|
|
262
|
+
return {
|
|
263
|
+
targetTriplet: "x86_64-unknown-linux-musl",
|
|
264
|
+
extension: "",
|
|
265
|
+
};
|
|
260
266
|
}
|
|
261
267
|
break;
|
|
262
268
|
case "win32":
|
|
263
269
|
if (arch === "x64") {
|
|
264
|
-
return {
|
|
270
|
+
return {
|
|
271
|
+
targetTriplet: "x86_64-pc-windows-gnu",
|
|
272
|
+
extension: ".exe",
|
|
273
|
+
};
|
|
265
274
|
}
|
|
266
275
|
break;
|
|
267
276
|
}
|
|
@@ -359,7 +368,9 @@ async function waitForEngineHealth(): Promise<void> {
|
|
|
359
368
|
attempt: i + 1,
|
|
360
369
|
maxRetries,
|
|
361
370
|
});
|
|
362
|
-
await new Promise((resolve) =>
|
|
371
|
+
await new Promise((resolve) =>
|
|
372
|
+
setTimeout(resolve, HEALTH_INTERVAL),
|
|
373
|
+
);
|
|
363
374
|
}
|
|
364
375
|
}
|
|
365
376
|
|