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,7 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
export const ServerlessStartHeadersSchema = z.object({
|
|
4
|
-
endpoint: z.string({
|
|
4
|
+
endpoint: z.string({
|
|
5
|
+
required_error: "x-rivet-endpoint header is required",
|
|
6
|
+
}),
|
|
5
7
|
token: z
|
|
6
8
|
.string({ invalid_type_error: "x-rivet-token header must be a string" })
|
|
7
9
|
.optional(),
|
|
@@ -15,6 +17,6 @@ export const ServerlessStartHeadersSchema = z.object({
|
|
|
15
17
|
required_error: "x-rivet-runner-name header is required",
|
|
16
18
|
}),
|
|
17
19
|
namespace: z.string({
|
|
18
|
-
required_error: "x-rivet-namespace-
|
|
20
|
+
required_error: "x-rivet-namespace-name header is required",
|
|
19
21
|
}),
|
|
20
22
|
});
|
package/src/manager/router.ts
CHANGED
|
@@ -166,7 +166,7 @@ function addServerlessRoutes(
|
|
|
166
166
|
token: c.req.header("x-rivet-token") ?? undefined,
|
|
167
167
|
totalSlots: c.req.header("x-rivet-total-slots"),
|
|
168
168
|
runnerName: c.req.header("x-rivet-runner-name"),
|
|
169
|
-
namespace: c.req.header("x-rivet-namespace-
|
|
169
|
+
namespace: c.req.header("x-rivet-namespace-name"),
|
|
170
170
|
});
|
|
171
171
|
if (!parseResult.success) {
|
|
172
172
|
throw new InvalidRequest(
|
|
@@ -262,7 +262,7 @@ function addManagerRoutes(
|
|
|
262
262
|
path: "/actors",
|
|
263
263
|
request: {
|
|
264
264
|
query: z.object({
|
|
265
|
-
name: z.string(),
|
|
265
|
+
name: z.string().optional(),
|
|
266
266
|
actor_ids: z.string().optional(),
|
|
267
267
|
key: z.string().optional(),
|
|
268
268
|
}),
|
|
@@ -282,6 +282,36 @@ function addManagerRoutes(
|
|
|
282
282
|
|
|
283
283
|
const actors: ActorOutput[] = [];
|
|
284
284
|
|
|
285
|
+
// Validate: cannot provide both actor_ids and (name or key)
|
|
286
|
+
if (actorIdsParsed && (name || key)) {
|
|
287
|
+
return c.json(
|
|
288
|
+
{
|
|
289
|
+
error: "Cannot provide both actor_ids and (name + key). Use either actor_ids or (name + key).",
|
|
290
|
+
},
|
|
291
|
+
400,
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Validate: when key is provided, name must also be provided
|
|
296
|
+
if (key && !name) {
|
|
297
|
+
return c.json(
|
|
298
|
+
{
|
|
299
|
+
error: "When providing 'key', 'name' must also be provided.",
|
|
300
|
+
},
|
|
301
|
+
400,
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Validate: must provide either actor_ids or (name + key)
|
|
306
|
+
if (!actorIdsParsed && !key) {
|
|
307
|
+
return c.json(
|
|
308
|
+
{
|
|
309
|
+
error: "Must provide either 'actor_ids' or both 'name' and 'key'.",
|
|
310
|
+
},
|
|
311
|
+
400,
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
285
315
|
if (actorIdsParsed) {
|
|
286
316
|
if (actorIdsParsed.length > 32) {
|
|
287
317
|
return c.json(
|
|
@@ -298,8 +328,10 @@ function addManagerRoutes(
|
|
|
298
328
|
});
|
|
299
329
|
}
|
|
300
330
|
|
|
331
|
+
// Fetch actors by ID
|
|
301
332
|
for (const actorId of actorIdsParsed) {
|
|
302
333
|
if (name) {
|
|
334
|
+
// If name is provided, use it directly
|
|
303
335
|
const actorOutput = await managerDriver.getForId({
|
|
304
336
|
c,
|
|
305
337
|
name,
|
|
@@ -308,12 +340,29 @@ function addManagerRoutes(
|
|
|
308
340
|
if (actorOutput) {
|
|
309
341
|
actors.push(actorOutput);
|
|
310
342
|
}
|
|
343
|
+
} else {
|
|
344
|
+
// If no name is provided, try all registered actor types
|
|
345
|
+
// Actor IDs are globally unique, so we'll find it in one of them
|
|
346
|
+
for (const actorName of Object.keys(
|
|
347
|
+
registryConfig.use,
|
|
348
|
+
)) {
|
|
349
|
+
const actorOutput = await managerDriver.getForId({
|
|
350
|
+
c,
|
|
351
|
+
name: actorName,
|
|
352
|
+
actorId,
|
|
353
|
+
});
|
|
354
|
+
if (actorOutput) {
|
|
355
|
+
actors.push(actorOutput);
|
|
356
|
+
break; // Found the actor, no need to check other names
|
|
357
|
+
}
|
|
358
|
+
}
|
|
311
359
|
}
|
|
312
360
|
}
|
|
313
361
|
} else if (key) {
|
|
362
|
+
// At this point, name is guaranteed to be defined due to validation above
|
|
314
363
|
const actorOutput = await managerDriver.getWithKey({
|
|
315
364
|
c,
|
|
316
|
-
name
|
|
365
|
+
name: name!,
|
|
317
366
|
key: [key], // Convert string to ActorKey array
|
|
318
367
|
});
|
|
319
368
|
if (actorOutput) {
|
|
@@ -449,8 +498,14 @@ function addManagerRoutes(
|
|
|
449
498
|
router.post(".test/inline-driver/call", async (c) => {
|
|
450
499
|
// TODO: use openapi instead
|
|
451
500
|
const buffer = await c.req.arrayBuffer();
|
|
452
|
-
const {
|
|
453
|
-
|
|
501
|
+
const {
|
|
502
|
+
encoding,
|
|
503
|
+
transport,
|
|
504
|
+
method,
|
|
505
|
+
args,
|
|
506
|
+
}: TestInlineDriverCallRequest = cbor.decode(
|
|
507
|
+
new Uint8Array(buffer),
|
|
508
|
+
);
|
|
454
509
|
|
|
455
510
|
logger().debug({
|
|
456
511
|
msg: "received inline request",
|
|
@@ -463,7 +518,9 @@ function addManagerRoutes(
|
|
|
463
518
|
// Forward inline driver request
|
|
464
519
|
let response: TestInlineDriverCallResponse<unknown>;
|
|
465
520
|
try {
|
|
466
|
-
const output = await ((managerDriver as any)[method] as any)(
|
|
521
|
+
const output = await ((managerDriver as any)[method] as any)(
|
|
522
|
+
...args,
|
|
523
|
+
);
|
|
467
524
|
response = { ok: output };
|
|
468
525
|
} catch (rawErr) {
|
|
469
526
|
const err = deconstructError(rawErr, logger(), {}, true);
|
|
@@ -476,11 +533,15 @@ function addManagerRoutes(
|
|
|
476
533
|
|
|
477
534
|
router.get(".test/inline-driver/connect-websocket/*", async (c) => {
|
|
478
535
|
const upgradeWebSocket = runConfig.getUpgradeWebSocket?.();
|
|
479
|
-
invariant(
|
|
536
|
+
invariant(
|
|
537
|
+
upgradeWebSocket,
|
|
538
|
+
"websockets not supported on this platform",
|
|
539
|
+
);
|
|
480
540
|
|
|
481
541
|
return upgradeWebSocket(async (c: any) => {
|
|
482
542
|
// Extract information from sec-websocket-protocol header
|
|
483
|
-
const protocolHeader =
|
|
543
|
+
const protocolHeader =
|
|
544
|
+
c.req.header("sec-websocket-protocol") || "";
|
|
484
545
|
const protocols = protocolHeader.split(/,\s*/);
|
|
485
546
|
|
|
486
547
|
// Parse protocols to extract connection info
|
|
@@ -515,7 +576,9 @@ function addManagerRoutes(
|
|
|
515
576
|
} else if (protocol.startsWith(WS_PROTOCOL_CONN_ID)) {
|
|
516
577
|
connId = protocol.substring(WS_PROTOCOL_CONN_ID.length);
|
|
517
578
|
} else if (protocol.startsWith(WS_PROTOCOL_CONN_TOKEN)) {
|
|
518
|
-
connToken = protocol.substring(
|
|
579
|
+
connToken = protocol.substring(
|
|
580
|
+
WS_PROTOCOL_CONN_TOKEN.length,
|
|
581
|
+
);
|
|
519
582
|
}
|
|
520
583
|
}
|
|
521
584
|
|
|
@@ -619,9 +682,12 @@ function addManagerRoutes(
|
|
|
619
682
|
// Send a special request to the actor to force disconnect the connection
|
|
620
683
|
const response = await managerDriver.sendRequest(
|
|
621
684
|
actorId,
|
|
622
|
-
new Request(
|
|
623
|
-
|
|
624
|
-
|
|
685
|
+
new Request(
|
|
686
|
+
`http://actor/.test/force-disconnect?conn=${connId}`,
|
|
687
|
+
{
|
|
688
|
+
method: "POST",
|
|
689
|
+
},
|
|
690
|
+
),
|
|
625
691
|
);
|
|
626
692
|
|
|
627
693
|
if (!response.ok) {
|
|
@@ -23,6 +23,7 @@ export type ActorsListResponse = z.infer<typeof ActorsListResponseSchema>;
|
|
|
23
23
|
|
|
24
24
|
// MARK: POST /actors
|
|
25
25
|
export const ActorsCreateRequestSchema = z.object({
|
|
26
|
+
datacenter: z.string().optional(),
|
|
26
27
|
name: z.string(),
|
|
27
28
|
runner_name_selector: z.string(),
|
|
28
29
|
crash_policy: z.string(),
|
|
@@ -38,6 +39,7 @@ export type ActorsCreateResponse = z.infer<typeof ActorsCreateResponseSchema>;
|
|
|
38
39
|
|
|
39
40
|
// MARK: PUT /actors
|
|
40
41
|
export const ActorsGetOrCreateRequestSchema = z.object({
|
|
42
|
+
datacenter: z.string().optional(),
|
|
41
43
|
name: z.string(),
|
|
42
44
|
key: z.string(),
|
|
43
45
|
runner_name_selector: z.string(),
|
package/src/registry/mod.ts
CHANGED
|
@@ -62,7 +62,10 @@ export class Registry<A extends RegistryActors> {
|
|
|
62
62
|
const config = RunnerConfigSchema.parse(inputConfig);
|
|
63
63
|
|
|
64
64
|
// Validate autoConfigureServerless is only used with serverless runner
|
|
65
|
-
if (
|
|
65
|
+
if (
|
|
66
|
+
config.autoConfigureServerless &&
|
|
67
|
+
config.runnerKind !== "serverless"
|
|
68
|
+
) {
|
|
66
69
|
throw new Error(
|
|
67
70
|
"autoConfigureServerless can only be configured when runnerKind is 'serverless'",
|
|
68
71
|
);
|
|
@@ -171,7 +174,10 @@ export class Registry<A extends RegistryActors> {
|
|
|
171
174
|
...driverLog,
|
|
172
175
|
});
|
|
173
176
|
if (isInspectorEnabled(config, "manager") && managerDriver.inspector) {
|
|
174
|
-
logger().info({
|
|
177
|
+
logger().info({
|
|
178
|
+
msg: "inspector ready",
|
|
179
|
+
url: getInspectorUrl(config),
|
|
180
|
+
});
|
|
175
181
|
}
|
|
176
182
|
|
|
177
183
|
// Print welcome information
|
|
@@ -182,7 +188,9 @@ export class Registry<A extends RegistryActors> {
|
|
|
182
188
|
if (!config.disableDefaultServer) {
|
|
183
189
|
console.log(` - Endpoint: ${getEndpoint(config)}`);
|
|
184
190
|
} else if (config.overrideServerAddress) {
|
|
185
|
-
console.log(
|
|
191
|
+
console.log(
|
|
192
|
+
` - Endpoint: ${config.overrideServerAddress}`,
|
|
193
|
+
);
|
|
186
194
|
}
|
|
187
195
|
if (config.runEngine) {
|
|
188
196
|
const padding = " ".repeat(Math.max(0, 13 - "Engine".length));
|
|
@@ -192,7 +200,10 @@ export class Registry<A extends RegistryActors> {
|
|
|
192
200
|
const padding = " ".repeat(Math.max(0, 13 - k.length));
|
|
193
201
|
console.log(` - ${k}:${padding}${v}`);
|
|
194
202
|
}
|
|
195
|
-
if (
|
|
203
|
+
if (
|
|
204
|
+
isInspectorEnabled(config, "manager") &&
|
|
205
|
+
managerDriver.inspector
|
|
206
|
+
) {
|
|
196
207
|
console.log(` - Inspector: ${getInspectorUrl(config)}`);
|
|
197
208
|
}
|
|
198
209
|
console.log();
|
|
@@ -210,7 +221,10 @@ export class Registry<A extends RegistryActors> {
|
|
|
210
221
|
}
|
|
211
222
|
|
|
212
223
|
// Configure serverless runner if enabled when actor driver is disabled
|
|
213
|
-
if (
|
|
224
|
+
if (
|
|
225
|
+
config.runnerKind === "serverless" &&
|
|
226
|
+
config.autoConfigureServerless
|
|
227
|
+
) {
|
|
214
228
|
Promise.all(readyPromises).then(async () => {
|
|
215
229
|
await configureServerlessRunner(config);
|
|
216
230
|
});
|
|
@@ -245,13 +259,19 @@ async function configureServerlessRunner(config: RunnerConfig): Promise<void> {
|
|
|
245
259
|
try {
|
|
246
260
|
// Ensure we have required config values
|
|
247
261
|
if (!config.runnerName) {
|
|
248
|
-
throw new Error(
|
|
262
|
+
throw new Error(
|
|
263
|
+
"runnerName is required for serverless configuration",
|
|
264
|
+
);
|
|
249
265
|
}
|
|
250
266
|
if (!config.namespace) {
|
|
251
|
-
throw new Error(
|
|
267
|
+
throw new Error(
|
|
268
|
+
"namespace is required for serverless configuration",
|
|
269
|
+
);
|
|
252
270
|
}
|
|
253
271
|
if (!config.endpoint) {
|
|
254
|
-
throw new Error(
|
|
272
|
+
throw new Error(
|
|
273
|
+
"endpoint is required for serverless configuration",
|
|
274
|
+
);
|
|
255
275
|
}
|
|
256
276
|
|
|
257
277
|
// Prepare the configuration
|
|
@@ -288,7 +308,9 @@ async function configureServerlessRunner(config: RunnerConfig): Promise<void> {
|
|
|
288
308
|
});
|
|
289
309
|
const serverlessConfig = {
|
|
290
310
|
serverless: {
|
|
291
|
-
url:
|
|
311
|
+
url:
|
|
312
|
+
customConfig.url ||
|
|
313
|
+
`http://localhost:${config.defaultServerPort}`,
|
|
292
314
|
headers: customConfig.headers || {},
|
|
293
315
|
max_runners: customConfig.maxRunners ?? 100,
|
|
294
316
|
min_runners: customConfig.minRunners ?? 0,
|
|
@@ -50,7 +50,9 @@ export const RunnerConfigSchema = z
|
|
|
50
50
|
runEngineVersion: z
|
|
51
51
|
.string()
|
|
52
52
|
.optional()
|
|
53
|
-
.default(
|
|
53
|
+
.default(
|
|
54
|
+
() => getEnvUniversal("RIVET_RUN_ENGINE_VERSION") ?? "25.8.2",
|
|
55
|
+
),
|
|
54
56
|
|
|
55
57
|
/** @experimental */
|
|
56
58
|
overrideServerAddress: z.string().optional(),
|
|
@@ -15,13 +15,13 @@ import { apiCall } from "./api-utils";
|
|
|
15
15
|
// MARK: Get actor
|
|
16
16
|
export async function getActor(
|
|
17
17
|
config: ClientConfig,
|
|
18
|
-
|
|
18
|
+
_: string,
|
|
19
19
|
actorId: RivetId,
|
|
20
20
|
): Promise<ActorsListResponse> {
|
|
21
21
|
return apiCall<never, ActorsListResponse>(
|
|
22
22
|
config,
|
|
23
23
|
"GET",
|
|
24
|
-
`/actors?
|
|
24
|
+
`/actors?actor_ids=${encodeURIComponent(actorId)}`,
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -60,7 +60,9 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
60
60
|
//
|
|
61
61
|
// See https://github.com/vercel/next.js/blob/5e6b008b561caf2710ab7be63320a3d549474a5b/packages/next/shared/lib/constants.ts#L19-L23
|
|
62
62
|
if (getEnvUniversal("NEXT_PHASE") === "phase-production-build") {
|
|
63
|
-
logger().info(
|
|
63
|
+
logger().info(
|
|
64
|
+
"detected next.js build phase, disabling health check",
|
|
65
|
+
);
|
|
64
66
|
runConfig.disableHealthCheck = true;
|
|
65
67
|
}
|
|
66
68
|
|
|
@@ -70,10 +72,10 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
70
72
|
if (!runConfig.disableHealthCheck) {
|
|
71
73
|
this.#metadataPromise = this.#performMetadataCheck(runConfig);
|
|
72
74
|
this.#metadataPromise.catch((error) => {
|
|
73
|
-
|
|
74
|
-
logger().info({
|
|
75
|
+
logger().error({
|
|
75
76
|
msg: "metadata check failed",
|
|
76
|
-
error:
|
|
77
|
+
error:
|
|
78
|
+
error instanceof Error ? error.message : String(error),
|
|
77
79
|
});
|
|
78
80
|
});
|
|
79
81
|
}
|
|
@@ -219,6 +221,7 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
219
221
|
});
|
|
220
222
|
|
|
221
223
|
const { actor, created } = await getOrCreateActor(this.#config, {
|
|
224
|
+
datacenter: region,
|
|
222
225
|
name,
|
|
223
226
|
key: serializeActorKey(key),
|
|
224
227
|
runner_name_selector: this.#config.runnerName,
|
|
@@ -250,6 +253,7 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
250
253
|
name,
|
|
251
254
|
key,
|
|
252
255
|
input,
|
|
256
|
+
region,
|
|
253
257
|
}: CreateInput): Promise<ActorOutput> {
|
|
254
258
|
// Wait for metadata check to complete if in progress
|
|
255
259
|
if (this.#metadataPromise) {
|
|
@@ -260,6 +264,7 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
260
264
|
|
|
261
265
|
// Create actor via engine API
|
|
262
266
|
const result = await createActor(this.#config, {
|
|
267
|
+
datacenter: region,
|
|
263
268
|
name,
|
|
264
269
|
runner_name_selector: this.#config.runnerName,
|
|
265
270
|
key: serializeActorKey(key),
|
|
@@ -290,13 +295,20 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
290
295
|
logger().info({ msg: "actor destroyed", actorId });
|
|
291
296
|
}
|
|
292
297
|
|
|
293
|
-
async sendRequest(
|
|
298
|
+
async sendRequest(
|
|
299
|
+
actorId: string,
|
|
300
|
+
actorRequest: Request,
|
|
301
|
+
): Promise<Response> {
|
|
294
302
|
// Wait for metadata check to complete if in progress
|
|
295
303
|
if (this.#metadataPromise) {
|
|
296
304
|
await this.#metadataPromise;
|
|
297
305
|
}
|
|
298
306
|
|
|
299
|
-
return await sendHttpRequestToActor(
|
|
307
|
+
return await sendHttpRequestToActor(
|
|
308
|
+
this.#config,
|
|
309
|
+
actorId,
|
|
310
|
+
actorRequest,
|
|
311
|
+
);
|
|
300
312
|
}
|
|
301
313
|
|
|
302
314
|
async openWebSocket(
|
|
@@ -333,7 +345,11 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
333
345
|
await this.#metadataPromise;
|
|
334
346
|
}
|
|
335
347
|
|
|
336
|
-
return await sendHttpRequestToActor(
|
|
348
|
+
return await sendHttpRequestToActor(
|
|
349
|
+
this.#config,
|
|
350
|
+
actorId,
|
|
351
|
+
actorRequest,
|
|
352
|
+
);
|
|
337
353
|
}
|
|
338
354
|
|
|
339
355
|
async proxyWebSocket(
|
|
@@ -42,7 +42,10 @@ export async function createWebSocketProxy(
|
|
|
42
42
|
// Setup connection promise
|
|
43
43
|
state.connectPromise = new Promise<void>((resolve, reject) => {
|
|
44
44
|
targetWs.addEventListener("open", () => {
|
|
45
|
-
logger().debug({
|
|
45
|
+
logger().debug({
|
|
46
|
+
msg: "target websocket connected",
|
|
47
|
+
targetUrl,
|
|
48
|
+
});
|
|
46
49
|
|
|
47
50
|
if (clientWs.readyState !== 1) {
|
|
48
51
|
logger().warn({
|
|
@@ -102,7 +105,10 @@ export async function createWebSocketProxy(
|
|
|
102
105
|
|
|
103
106
|
onMessage: async (event: any, clientWs: WSContext) => {
|
|
104
107
|
if (!state.targetWs || !state.connectPromise) {
|
|
105
|
-
logger().error({
|
|
108
|
+
logger().error({
|
|
109
|
+
msg: "websocket state not initialized",
|
|
110
|
+
targetUrl,
|
|
111
|
+
});
|
|
106
112
|
return;
|
|
107
113
|
}
|
|
108
114
|
|
|
@@ -123,7 +129,11 @@ export async function createWebSocketProxy(
|
|
|
123
129
|
targetUrl,
|
|
124
130
|
error,
|
|
125
131
|
});
|
|
126
|
-
closeWebSocketIfOpen(
|
|
132
|
+
closeWebSocketIfOpen(
|
|
133
|
+
clientWs,
|
|
134
|
+
1011,
|
|
135
|
+
"Failed to connect to target",
|
|
136
|
+
);
|
|
127
137
|
}
|
|
128
138
|
},
|
|
129
139
|
|
|
@@ -141,7 +151,10 @@ export async function createWebSocketProxy(
|
|
|
141
151
|
state.targetWs.readyState === WebSocket.OPEN ||
|
|
142
152
|
state.targetWs.readyState === WebSocket.CONNECTING
|
|
143
153
|
) {
|
|
144
|
-
state.targetWs.close(
|
|
154
|
+
state.targetWs.close(
|
|
155
|
+
1000,
|
|
156
|
+
event.reason || "Client disconnected",
|
|
157
|
+
);
|
|
145
158
|
}
|
|
146
159
|
}
|
|
147
160
|
},
|
|
@@ -167,7 +180,10 @@ function closeWebSocketIfOpen(
|
|
|
167
180
|
): void {
|
|
168
181
|
if (ws.readyState === 1) {
|
|
169
182
|
ws.close(code, reason);
|
|
170
|
-
} else if (
|
|
183
|
+
} else if (
|
|
184
|
+
"close" in ws &&
|
|
185
|
+
(ws as WebSocket).readyState === WebSocket.OPEN
|
|
186
|
+
) {
|
|
171
187
|
ws.close(code, reason);
|
|
172
188
|
}
|
|
173
189
|
}
|
package/src/serde.ts
CHANGED
|
@@ -63,7 +63,9 @@ export function serializeWithEncoding<T>(
|
|
|
63
63
|
return cbor.encode(value);
|
|
64
64
|
} else if (encoding === "bare") {
|
|
65
65
|
if (!versionedDataHandler) {
|
|
66
|
-
throw new Error(
|
|
66
|
+
throw new Error(
|
|
67
|
+
"VersionedDataHandler is required for 'bare' encoding",
|
|
68
|
+
);
|
|
67
69
|
}
|
|
68
70
|
return versionedDataHandler.serializeWithEmbeddedVersion(value);
|
|
69
71
|
} else {
|
|
@@ -96,7 +98,9 @@ export function deserializeWithEncoding<T>(
|
|
|
96
98
|
"buffer cannot be string for bare encoding",
|
|
97
99
|
);
|
|
98
100
|
if (!versionedDataHandler) {
|
|
99
|
-
throw new Error(
|
|
101
|
+
throw new Error(
|
|
102
|
+
"VersionedDataHandler is required for 'bare' encoding",
|
|
103
|
+
);
|
|
100
104
|
}
|
|
101
105
|
return versionedDataHandler.deserializeWithEmbeddedVersion(buffer);
|
|
102
106
|
} else {
|
package/src/test/mod.ts
CHANGED
|
@@ -94,7 +94,8 @@ export async function setupTest<A extends Registry<any>>(
|
|
|
94
94
|
const port = await getPort();
|
|
95
95
|
const server = serve(registry, { port });
|
|
96
96
|
c.onTestFinished(
|
|
97
|
-
async () =>
|
|
97
|
+
async () =>
|
|
98
|
+
await new Promise((resolve) => server.close(() => resolve())),
|
|
98
99
|
);
|
|
99
100
|
|
|
100
101
|
throw "TODO: Fix engine port";
|
package/src/utils.ts
CHANGED
|
@@ -19,7 +19,8 @@ export function httpUserAgent(): string {
|
|
|
19
19
|
let userAgent = `RivetKit/${VERSION}`;
|
|
20
20
|
|
|
21
21
|
// Navigator
|
|
22
|
-
const navigatorObj =
|
|
22
|
+
const navigatorObj =
|
|
23
|
+
typeof navigator !== "undefined" ? navigator : undefined;
|
|
23
24
|
if (navigatorObj?.userAgent) userAgent += ` ${navigatorObj.userAgent}`;
|
|
24
25
|
|
|
25
26
|
_userAgent = userAgent;
|
|
@@ -62,7 +63,10 @@ export function toUint8Array(data: ArrayBuffer | ArrayBufferView): Uint8Array {
|
|
|
62
63
|
} else if (ArrayBuffer.isView(data)) {
|
|
63
64
|
// Handle other ArrayBufferView types (Int8Array, Uint16Array, DataView, etc.)
|
|
64
65
|
return new Uint8Array(
|
|
65
|
-
data.buffer.slice(
|
|
66
|
+
data.buffer.slice(
|
|
67
|
+
data.byteOffset,
|
|
68
|
+
data.byteOffset + data.byteLength,
|
|
69
|
+
),
|
|
66
70
|
);
|
|
67
71
|
} else {
|
|
68
72
|
throw new TypeError("Input must be ArrayBuffer or ArrayBufferView");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/nathan/rivetkit/packages/rivetkit/dist/tsup/chunk-2I6L3VRO.cjs","../../src/test/mod.ts","../../src/test/config.ts","../../src/test/log.ts"],"names":["server"],"mappings":"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","file":"/Users/nathan/rivetkit/packages/rivetkit/dist/tsup/chunk-2I6L3VRO.cjs","sourcesContent":[null,"import { createServer } from \"node:net\";\nimport { serve as honoServe, type ServerType } from \"@hono/node-server\";\nimport { createNodeWebSocket } from \"@hono/node-ws\";\nimport { type TestContext, vi } from \"vitest\";\nimport { ClientConfigSchema } from \"@/client/config\";\nimport { type Client, createClient } from \"@/client/mod\";\nimport { chooseDefaultDriver } from \"@/drivers/default\";\nimport { createFileSystemOrMemoryDriver } from \"@/drivers/file-system/mod\";\nimport {\n\tconfigureInspectorAccessToken,\n\tgetInspectorUrl,\n} from \"@/inspector/utils\";\nimport { createManagerRouter } from \"@/manager/router\";\nimport { createClientWithDriver } from \"@/mod\";\nimport type { Registry } from \"@/registry/mod\";\nimport { RunnerConfigSchema } from \"@/registry/run-config\";\nimport { ConfigSchema, type InputConfig } from \"./config\";\nimport { logger } from \"./log\";\n\nfunction serve(registry: Registry<any>, inputConfig?: InputConfig): ServerType {\n\t// Configure default configuration\n\tinputConfig ??= {};\n\n\tconst config = ConfigSchema.parse(inputConfig);\n\n\tlet upgradeWebSocket: any;\n\tif (!config.getUpgradeWebSocket) {\n\t\tconfig.getUpgradeWebSocket = () => upgradeWebSocket!;\n\t}\n\n\t// Create router\n\tconst runConfig = RunnerConfigSchema.parse(inputConfig);\n\tconst driver = inputConfig.driver ?? createFileSystemOrMemoryDriver(false);\n\tconst managerDriver = driver.manager(registry.config, config);\n\tconst client = createClientWithDriver(\n\t\tmanagerDriver,\n\t\tClientConfigSchema.parse({}),\n\t);\n\tconfigureInspectorAccessToken(config, managerDriver);\n\tconst { router } = createManagerRouter(\n\t\tregistry.config,\n\t\trunConfig,\n\t\tmanagerDriver,\n\t\tdriver,\n\t\tclient,\n\t);\n\n\t// Inject WebSocket\n\tconst nodeWebSocket = createNodeWebSocket({ app: router });\n\tupgradeWebSocket = nodeWebSocket.upgradeWebSocket;\n\n\tconst server = honoServe({\n\t\tfetch: router.fetch,\n\t\thostname: config.hostname,\n\t\tport: config.port,\n\t});\n\tnodeWebSocket.injectWebSocket(server);\n\n\tlogger().info({\n\t\tmsg: \"rivetkit started\",\n\t\thostname: config.hostname,\n\t\tport: config.port,\n\t\tdefinitions: Object.keys(registry.config.use).length,\n\t});\n\n\treturn server;\n}\n\nexport interface SetupTestResult<A extends Registry<any>> {\n\tclient: Client<A>;\n\tmockDriver: {\n\t\tactorDriver: {\n\t\t\tsetCreateVarsContext: (ctx: any) => void;\n\t\t};\n\t};\n}\n\n// Must use `TestContext` since global hooks do not work when running concurrently\nexport async function setupTest<A extends Registry<any>>(\n\tc: TestContext,\n\tregistry: A,\n): Promise<SetupTestResult<A>> {\n\tvi.useFakeTimers();\n\n\t// Set up mock driver for testing createVars context\n\tconst mockDriverContext: any = {};\n\tconst setDriverContextFn = (ctx: any) => {\n\t\tmockDriverContext.current = ctx;\n\t};\n\n\t// We don't need to modify the driver context anymore since we're testing with the actual context\n\n\t// Start server with a random port\n\tconst port = await getPort();\n\tconst server = serve(registry, { port });\n\tc.onTestFinished(\n\t\tasync () => await new Promise((resolve) => server.close(() => resolve())),\n\t);\n\n\tthrow \"TODO: Fix engine port\";\n\n\t// // TODO: Figure out how to make this the correct endpoint\n\t// // Create client\n\t// const client = createClient<A>(`http://127.0.0.1:${port}`);\n\t// c.onTestFinished(async () => await client.dispose());\n\t//\n\t// return {\n\t// \tclient,\n\t// \tmockDriver: {\n\t// \t\tactorDriver: {\n\t// \t\t\tsetCreateVarsContext: setDriverContextFn,\n\t// \t\t},\n\t// \t},\n\t// };\n}\n\nexport async function getPort(): Promise<number> {\n\t// Pick random port between 10000 and 65535 (avoiding well-known and registered ports)\n\tconst MIN_PORT = 10000;\n\tconst MAX_PORT = 65535;\n\tconst getRandomPort = () =>\n\t\tMath.floor(Math.random() * (MAX_PORT - MIN_PORT + 1)) + MIN_PORT;\n\n\tlet port = getRandomPort();\n\tlet maxAttempts = 10;\n\n\twhile (maxAttempts > 0) {\n\t\ttry {\n\t\t\t// Try to create a server on the port to check if it's available\n\t\t\tconst server = await new Promise<any>((resolve, reject) => {\n\t\t\t\tconst server = createServer();\n\n\t\t\t\tserver.once(\"error\", (err: Error & { code?: string }) => {\n\t\t\t\t\tif (err.code === \"EADDRINUSE\") {\n\t\t\t\t\t\treject(new Error(`Port ${port} is in use`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tserver.once(\"listening\", () => {\n\t\t\t\t\tresolve(server);\n\t\t\t\t});\n\n\t\t\t\tserver.listen(port);\n\t\t\t});\n\n\t\t\t// Close the server since we're just checking availability\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tserver.close(() => resolve());\n\t\t\t});\n\n\t\t\treturn port;\n\t\t} catch (err) {\n\t\t\t// If port is in use, try a different one\n\t\t\tmaxAttempts--;\n\t\t\tif (maxAttempts <= 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tport = getRandomPort();\n\t\t}\n\t}\n\n\tthrow new Error(\"Could not find an available port after multiple attempts\");\n}\n","import { z } from \"zod\";\nimport { RunnerConfigSchema } from \"@/registry/run-config\";\n\nexport const ConfigSchema = RunnerConfigSchema.removeDefault()\n\t.extend({\n\t\thostname: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.default(process.env.HOSTNAME ?? \"127.0.0.1\"),\n\t\tport: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.default(Number.parseInt(process.env.PORT ?? \"8080\")),\n\t})\n\t.default({});\nexport type InputConfig = z.input<typeof ConfigSchema>;\n","import { getLogger } from \"@/common/log\";\n\nexport function logger() {\n\treturn getLogger(\"test\");\n}\n"]}
|