rivetkit 2.3.0-rc.11 → 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.
Files changed (123) hide show
  1. package/dist/browser/client.d.ts +407 -20
  2. package/dist/browser/client.js +101 -86
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +12 -2
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/tsup/actor/errors.d.cts +1 -1
  7. package/dist/tsup/actor/errors.d.ts +1 -1
  8. package/dist/tsup/agent-os/index.cjs +66 -3
  9. package/dist/tsup/agent-os/index.cjs.map +1 -1
  10. package/dist/tsup/agent-os/index.d.cts +404 -17
  11. package/dist/tsup/agent-os/index.d.ts +404 -17
  12. package/dist/tsup/agent-os/index.js +66 -3
  13. package/dist/tsup/agent-os/index.js.map +1 -1
  14. package/dist/tsup/{chunk-WXYWDLJY.js → chunk-33YE6XCI.js} +4 -4
  15. package/dist/tsup/{chunk-2NXFKPRB.cjs → chunk-7OR3CHD5.cjs} +10 -10
  16. package/dist/tsup/{chunk-2NXFKPRB.cjs.map → chunk-7OR3CHD5.cjs.map} +1 -1
  17. package/dist/tsup/{chunk-LW5HNCWD.cjs → chunk-7XQCARVY.cjs} +3 -3
  18. package/dist/tsup/{chunk-LW5HNCWD.cjs.map → chunk-7XQCARVY.cjs.map} +1 -1
  19. package/dist/tsup/{chunk-GX6W4MW3.cjs → chunk-BSPS6NSN.cjs} +5 -5
  20. package/dist/tsup/{chunk-GX6W4MW3.cjs.map → chunk-BSPS6NSN.cjs.map} +1 -1
  21. package/dist/tsup/{chunk-T3VCJ4PV.js → chunk-DPIMKYNB.js} +61 -2
  22. package/dist/tsup/chunk-DPIMKYNB.js.map +1 -0
  23. package/dist/tsup/{chunk-XG25CGSW.cjs → chunk-E5CLYAUZ.cjs} +146 -143
  24. package/dist/tsup/chunk-E5CLYAUZ.cjs.map +1 -0
  25. package/dist/tsup/{chunk-RDBGKI66.cjs → chunk-EBWOJRCC.cjs} +22 -5
  26. package/dist/tsup/chunk-EBWOJRCC.cjs.map +1 -0
  27. package/dist/tsup/{chunk-YRQ4F5CD.js → chunk-HHNYEQD3.js} +6 -6
  28. package/dist/tsup/chunk-HHNYEQD3.js.map +1 -0
  29. package/dist/tsup/{chunk-4FP4FFB5.js → chunk-IOUSQVXI.js} +21 -4
  30. package/dist/tsup/chunk-IOUSQVXI.js.map +1 -0
  31. package/dist/tsup/{chunk-LNP7Q6I6.cjs → chunk-ISDKSSYR.cjs} +4 -4
  32. package/dist/tsup/{chunk-LNP7Q6I6.cjs.map → chunk-ISDKSSYR.cjs.map} +1 -1
  33. package/dist/tsup/{chunk-TTLUIDVH.js → chunk-J72WHUBC.js} +12 -9
  34. package/dist/tsup/chunk-J72WHUBC.js.map +1 -0
  35. package/dist/tsup/{chunk-Y3JBOFBG.cjs → chunk-KWABEUUA.cjs} +10 -10
  36. package/dist/tsup/chunk-KWABEUUA.cjs.map +1 -0
  37. package/dist/tsup/{chunk-XCDCURZ4.cjs → chunk-NIY3RSPX.cjs} +62 -3
  38. package/dist/tsup/chunk-NIY3RSPX.cjs.map +1 -0
  39. package/dist/tsup/{chunk-3P2JUHWJ.js → chunk-T44AVAGW.js} +2 -2
  40. package/dist/tsup/{chunk-GRFBV2U7.js → chunk-TCXEM6PA.js} +2 -2
  41. package/dist/tsup/{chunk-KRC4L3YB.js → chunk-ZI5CNA2Z.js} +2 -2
  42. package/dist/tsup/client/mod.cjs +7 -7
  43. package/dist/tsup/client/mod.cjs.map +1 -1
  44. package/dist/tsup/client/mod.d.cts +3 -3
  45. package/dist/tsup/client/mod.d.ts +3 -3
  46. package/dist/tsup/client/mod.js +6 -6
  47. package/dist/tsup/common/log.cjs +2 -2
  48. package/dist/tsup/common/log.js +1 -1
  49. package/dist/tsup/common/websocket.cjs +3 -3
  50. package/dist/tsup/common/websocket.js +2 -2
  51. package/dist/tsup/{config-De5UVu0V.d.ts → config-BxWAw3iH.d.ts} +476 -20
  52. package/dist/tsup/{config-CTwe3WwC.d.cts → config-CZQQ-mso.d.cts} +476 -20
  53. package/dist/tsup/{context-Dmj477Uh.d.cts → context-Bw7xq8w3.d.cts} +1 -1
  54. package/dist/tsup/{context-DPHISlUi.d.ts → context-D8QA76sV.d.ts} +1 -1
  55. package/dist/tsup/dynamic/mod.cjs +2 -2
  56. package/dist/tsup/dynamic/mod.d.cts +2 -2
  57. package/dist/tsup/dynamic/mod.d.ts +2 -2
  58. package/dist/tsup/dynamic/mod.js +1 -1
  59. package/dist/tsup/inspector/mod.cjs +5 -5
  60. package/dist/tsup/inspector/mod.js +4 -4
  61. package/dist/tsup/inspector-tab/mod.cjs +173 -0
  62. package/dist/tsup/inspector-tab/mod.cjs.map +1 -0
  63. package/dist/tsup/inspector-tab/mod.d.cts +250 -0
  64. package/dist/tsup/inspector-tab/mod.d.ts +250 -0
  65. package/dist/tsup/inspector-tab/mod.js +173 -0
  66. package/dist/tsup/inspector-tab/mod.js.map +1 -0
  67. package/dist/tsup/mod.cjs +341 -138
  68. package/dist/tsup/mod.cjs.map +1 -1
  69. package/dist/tsup/mod.d.cts +4 -4
  70. package/dist/tsup/mod.d.ts +4 -4
  71. package/dist/tsup/mod.js +277 -74
  72. package/dist/tsup/mod.js.map +1 -1
  73. package/dist/tsup/test/mod.cjs +10 -10
  74. package/dist/tsup/test/mod.d.cts +2 -2
  75. package/dist/tsup/test/mod.d.ts +2 -2
  76. package/dist/tsup/test/mod.js +6 -6
  77. package/dist/tsup/{utils-DVekpm4I.d.ts → utils-DQosb24I.d.cts} +1 -1
  78. package/dist/tsup/{utils-DVekpm4I.d.cts → utils-DQosb24I.d.ts} +1 -1
  79. package/dist/tsup/utils.cjs +2 -2
  80. package/dist/tsup/utils.d.cts +1 -1
  81. package/dist/tsup/utils.d.ts +1 -1
  82. package/dist/tsup/utils.js +1 -1
  83. package/dist/tsup/workflow/mod.cjs +11 -11
  84. package/dist/tsup/workflow/mod.cjs.map +1 -1
  85. package/dist/tsup/workflow/mod.d.cts +4 -4
  86. package/dist/tsup/workflow/mod.d.ts +4 -4
  87. package/dist/tsup/workflow/mod.js +5 -5
  88. package/package.json +19 -9
  89. package/src/actor/config.ts +111 -10
  90. package/src/actor/definition.ts +6 -5
  91. package/src/actor/instance/mod.ts +4 -4
  92. package/src/actor/mod.ts +2 -0
  93. package/src/client/actor-common.ts +24 -27
  94. package/src/client/actor-handle.ts +2 -1
  95. package/src/common/engine.ts +28 -1
  96. package/src/common/utils.ts +1 -1
  97. package/src/devtools-loader/index.ts +4 -7
  98. package/src/devtools-loader/serve-devtools.ts +26 -0
  99. package/src/drivers/engine/actor-driver.ts +16 -5
  100. package/src/engine-client/actor-http-client.ts +2 -2
  101. package/src/engine-client/api-endpoints.ts +5 -1
  102. package/src/engine-client/ws-proxy.ts +5 -0
  103. package/src/inspector-tab/mod.ts +315 -0
  104. package/src/registry/config/index.ts +40 -16
  105. package/src/registry/index.ts +143 -62
  106. package/src/registry/napi-runtime.ts +6 -0
  107. package/src/registry/native.ts +170 -27
  108. package/src/registry/process-metrics.ts +16 -4
  109. package/src/registry/runtime.ts +26 -0
  110. package/src/registry/wasm-runtime.ts +16 -1
  111. package/src/utils/env-vars.ts +6 -0
  112. package/dist/tsup/chunk-4FP4FFB5.js.map +0 -1
  113. package/dist/tsup/chunk-RDBGKI66.cjs.map +0 -1
  114. package/dist/tsup/chunk-T3VCJ4PV.js.map +0 -1
  115. package/dist/tsup/chunk-TTLUIDVH.js.map +0 -1
  116. package/dist/tsup/chunk-XCDCURZ4.cjs.map +0 -1
  117. package/dist/tsup/chunk-XG25CGSW.cjs.map +0 -1
  118. package/dist/tsup/chunk-Y3JBOFBG.cjs.map +0 -1
  119. package/dist/tsup/chunk-YRQ4F5CD.js.map +0 -1
  120. /package/dist/tsup/{chunk-WXYWDLJY.js.map → chunk-33YE6XCI.js.map} +0 -0
  121. /package/dist/tsup/{chunk-3P2JUHWJ.js.map → chunk-T44AVAGW.js.map} +0 -0
  122. /package/dist/tsup/{chunk-GRFBV2U7.js.map → chunk-TCXEM6PA.js.map} +0 -0
  123. /package/dist/tsup/{chunk-KRC4L3YB.js.map → chunk-ZI5CNA2Z.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rivetkit",
3
- "version": "2.3.0-rc.11",
3
+ "version": "2.3.0-rc.13",
4
4
  "description": "Lightweight libraries for building stateful actors on edge platforms",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -126,6 +126,16 @@
126
126
  "default": "./dist/tsup/inspector/mod.cjs"
127
127
  }
128
128
  },
129
+ "./inspector-tab": {
130
+ "import": {
131
+ "types": "./dist/tsup/inspector-tab/mod.d.ts",
132
+ "default": "./dist/tsup/inspector-tab/mod.js"
133
+ },
134
+ "require": {
135
+ "types": "./dist/tsup/inspector-tab/mod.d.cts",
136
+ "default": "./dist/tsup/inspector-tab/mod.cjs"
137
+ }
138
+ },
129
139
  "./inspector/client": {
130
140
  "import": {
131
141
  "types": "./dist/browser/inspector/client.d.ts",
@@ -161,7 +171,7 @@
161
171
  "./dist/tsup/chunk-*.cjs"
162
172
  ],
163
173
  "scripts": {
164
- "build": "tsup src/mod.ts src/client/mod.ts src/common/log.ts src/common/websocket.ts src/actor/errors.ts src/utils.ts src/workflow/mod.ts src/test/mod.ts src/inspector/mod.ts src/db/mod.ts src/db/drizzle.ts src/dynamic/mod.ts && tsup src/agent-os/index.ts --no-clean --out-dir dist/tsup/agent-os",
174
+ "build": "tsup src/mod.ts src/client/mod.ts src/common/log.ts src/common/websocket.ts src/actor/errors.ts src/utils.ts src/workflow/mod.ts src/test/mod.ts src/inspector/mod.ts src/inspector-tab/mod.ts src/db/mod.ts src/db/drizzle.ts src/dynamic/mod.ts && tsup src/agent-os/index.ts --no-clean --out-dir dist/tsup/agent-os",
165
175
  "build:browser": "tsup --config tsup.browser.config.ts",
166
176
  "check-types": "tsc --noEmit",
167
177
  "lint": "biome check . && pnpm run check:test-skips && pnpm run check:wait-for-comments",
@@ -183,14 +193,14 @@
183
193
  "@hono/zod-openapi": "^1.1.5",
184
194
  "@rivet-dev/agent-os-core": "^0.1.1",
185
195
  "@rivetkit/bare-ts": "^0.6.2",
186
- "@rivetkit/engine-cli": "2.3.0-rc.11",
187
- "@rivetkit/engine-envoy-protocol": "2.3.0-rc.11",
196
+ "@rivetkit/engine-cli": "2.3.0-rc.13",
197
+ "@rivetkit/engine-envoy-protocol": "2.3.0-rc.13",
188
198
  "@rivetkit/on-change": "6.0.1",
189
- "@rivetkit/rivetkit-napi": "2.3.0-rc.11",
190
- "@rivetkit/rivetkit-wasm": "2.3.0-rc.11",
191
- "@rivetkit/traces": "2.3.0-rc.11",
192
- "@rivetkit/virtual-websocket": "2.3.0-rc.11",
193
- "@rivetkit/workflow-engine": "2.3.0-rc.11",
199
+ "@rivetkit/rivetkit-napi": "2.3.0-rc.13",
200
+ "@rivetkit/rivetkit-wasm": "2.3.0-rc.13",
201
+ "@rivetkit/traces": "2.3.0-rc.13",
202
+ "@rivetkit/virtual-websocket": "2.3.0-rc.13",
203
+ "@rivetkit/workflow-engine": "2.3.0-rc.13",
194
204
  "cbor-x": "^1.6.0",
195
205
  "drizzle-orm": "^0.44.2",
196
206
  "get-port": "^7.1.0",
@@ -62,6 +62,10 @@ type ActorKvListOptions<
62
62
 
63
63
  type ActorClientFor<T> = T extends Registry<any> ? Client<T> : T;
64
64
 
65
+ /**
66
+ * @deprecated Actor KV is deprecated. Use embedded SQLite (`c.db` / `c.sql`)
67
+ * or actor state instead.
68
+ */
65
69
  export interface ActorKv {
66
70
  get<T extends ActorKvValueType = "text">(
67
71
  key: Uint8Array | string,
@@ -305,6 +309,10 @@ export interface ActorContext<
305
309
  [RAW_STATE_SYMBOL](): TState;
306
310
  state: TState;
307
311
  vars: TVars;
312
+ /**
313
+ * @deprecated Actor KV is deprecated. Use embedded SQLite (`db` / `sql`)
314
+ * or actor state instead.
315
+ */
308
316
  readonly kv: ActorKv;
309
317
  readonly db: InferDatabaseClient<TDatabase>;
310
318
  readonly schedule: ActorSchedule;
@@ -735,6 +743,88 @@ const RunInspectorConfigSchema = z
735
743
  })
736
744
  .optional();
737
745
 
746
+ /**
747
+ * Built-in inspector tabs the dashboard ships. Used to validate
748
+ * `hidden: true` entries and reject custom-tab ids that collide with
749
+ * a built-in.
750
+ */
751
+ export const BUILTIN_INSPECTOR_TAB_IDS = [
752
+ "workflow",
753
+ "database",
754
+ "state",
755
+ "queue",
756
+ "connections",
757
+ "console",
758
+ ] as const;
759
+
760
+ export const BuiltinInspectorTabIdSchema = z.enum(BUILTIN_INSPECTOR_TAB_IDS);
761
+
762
+ // Custom tab id grammar — mirrored in Rust at
763
+ // `rivetkit-rust/packages/rivetkit-core/src/inspector/tabs.rs`. Slashes are
764
+ // forbidden because the runtime splits `/inspector/custom-tabs/<id>/<rest>`
765
+ // on the first `/`.
766
+ const CUSTOM_INSPECTOR_TAB_ID_RE = /^[A-Za-z0-9_-]+$/;
767
+
768
+ export const CustomInspectorTabEntrySchema = z
769
+ .object({
770
+ id: z
771
+ .string()
772
+ .regex(
773
+ CUSTOM_INSPECTOR_TAB_ID_RE,
774
+ "inspector.tabs[].id must contain only letters, digits, underscore, or dash",
775
+ ),
776
+ label: z.string().min(1),
777
+ source: z.string().min(1),
778
+ /**
779
+ * Optional icon id. The dashboard maps strings to glyphs (see its
780
+ * icon registry); unknown ids fall back to a generic icon.
781
+ */
782
+ icon: z.string().min(1).optional(),
783
+ hidden: z.literal(false).optional(),
784
+ })
785
+ .strict();
786
+
787
+ export const HideInspectorTabEntrySchema = z
788
+ .object({
789
+ id: BuiltinInspectorTabIdSchema,
790
+ hidden: z.literal(true),
791
+ })
792
+ .strict();
793
+
794
+ export const InspectorTabEntrySchema = z.union([
795
+ CustomInspectorTabEntrySchema,
796
+ HideInspectorTabEntrySchema,
797
+ ]);
798
+
799
+ export const ActorInspectorConfigSchema = z
800
+ .object({
801
+ tabs: z.array(InspectorTabEntrySchema).default(() => []),
802
+ })
803
+ .strict()
804
+ .refine(
805
+ (data) => {
806
+ const ids = data.tabs.map((t) => t.id);
807
+ return new Set(ids).size === ids.length;
808
+ },
809
+ { message: "Duplicate id in inspector.tabs", path: ["tabs"] },
810
+ )
811
+ .refine(
812
+ (data) => {
813
+ // A custom entry's id must not collide with a built-in id.
814
+ const builtinSet = new Set(BUILTIN_INSPECTOR_TAB_IDS);
815
+ return data.tabs.every(
816
+ (t) => t.hidden === true || !builtinSet.has(t.id as any),
817
+ );
818
+ },
819
+ {
820
+ message:
821
+ "Custom inspector tab id collides with a built-in (use hidden: true to hide a built-in)",
822
+ path: ["tabs"],
823
+ },
824
+ );
825
+
826
+ export type ActorInspectorConfig = z.input<typeof ActorInspectorConfigSchema>;
827
+
738
828
  // Schema for run handler with metadata
739
829
  export const RunConfigSchema = z.object({
740
830
  /** Display name for the actor in the Inspector UI. */
@@ -951,6 +1041,7 @@ export const ActorConfigSchema = z
951
1041
  db: z.any().optional(),
952
1042
  createVars: zFunction().optional(),
953
1043
  options: ActorOptionsSchema,
1044
+ inspector: ActorInspectorConfigSchema.optional(),
954
1045
  })
955
1046
  .strict()
956
1047
  .refine(
@@ -1505,6 +1596,25 @@ export type ActorConfig<
1505
1596
  TDatabase extends AnyDatabaseProvider,
1506
1597
  TEvents extends EventSchemaConfig = Record<never, never>,
1507
1598
  TQueues extends QueueSchemaConfig = Record<never, never>,
1599
+ TActions extends Actions<
1600
+ TState,
1601
+ TConnParams,
1602
+ TConnState,
1603
+ TVars,
1604
+ TInput,
1605
+ TDatabase,
1606
+ TEvents,
1607
+ TQueues
1608
+ > = Actions<
1609
+ TState,
1610
+ TConnParams,
1611
+ TConnState,
1612
+ TVars,
1613
+ TInput,
1614
+ TDatabase,
1615
+ TEvents,
1616
+ TQueues
1617
+ >,
1508
1618
  > = Omit<
1509
1619
  z.infer<typeof ActorConfigSchema>,
1510
1620
  | "actions"
@@ -1540,16 +1650,7 @@ export type ActorConfig<
1540
1650
  TDatabase,
1541
1651
  TEvents,
1542
1652
  TQueues,
1543
- Actions<
1544
- TState,
1545
- TConnParams,
1546
- TConnState,
1547
- TVars,
1548
- TInput,
1549
- TDatabase,
1550
- TEvents,
1551
- TQueues
1552
- >
1653
+ TActions
1553
1654
  > &
1554
1655
  CreateState<
1555
1656
  TState,
@@ -44,7 +44,7 @@ export interface BaseActorDefinition<
44
44
  Q
45
45
  >,
46
46
  > {
47
- readonly config: ActorConfig<S, CP, CS, V, I, DB, E, Q>;
47
+ readonly config: ActorConfig<S, CP, CS, V, I, DB, E, Q, _R>;
48
48
  }
49
49
 
50
50
  export interface AnyActorDefinition {
@@ -84,13 +84,13 @@ export class ActorDefinition<
84
84
  >,
85
85
  > implements BaseActorDefinition<S, CP, CS, V, I, DB, E, Q, R>
86
86
  {
87
- #config: ActorConfig<S, CP, CS, V, I, DB, E, Q>;
87
+ #config: ActorConfig<S, CP, CS, V, I, DB, E, Q, R>;
88
88
 
89
- constructor(config: ActorConfig<S, CP, CS, V, I, DB, E, Q>) {
89
+ constructor(config: ActorConfig<S, CP, CS, V, I, DB, E, Q, R>) {
90
90
  this.#config = config;
91
91
  }
92
92
 
93
- get config(): ActorConfig<S, CP, CS, V, I, DB, E, Q> {
93
+ get config(): ActorConfig<S, CP, CS, V, I, DB, E, Q, R> {
94
94
  return this.#config;
95
95
  }
96
96
  }
@@ -192,7 +192,8 @@ export function actor<
192
192
  TInput,
193
193
  TDatabase,
194
194
  TEvents,
195
- TQueues
195
+ TQueues,
196
+ TActions
196
197
  >;
197
198
  return new ActorDefinition(config);
198
199
  }
@@ -1637,10 +1637,10 @@ export class ActorInstance<
1637
1637
  attributes?: Record<string, unknown>,
1638
1638
  ): Record<string, unknown> {
1639
1639
  return {
1640
- "rivet.actor.id": this.#actorId,
1641
- "rivet.actor.name": this.#name,
1642
- "rivet.actor.key": this.#actorKeyString,
1643
- "rivet.actor.region": this.#region,
1640
+ "rivet.actors.actor.id": this.#actorId,
1641
+ "rivet.actors.actor.name": this.#name,
1642
+ "rivet.actors.actor.key": this.#actorKeyString,
1643
+ "rivet.actors.actor.region": this.#region,
1644
1644
  ...(attributes ?? {}),
1645
1645
  };
1646
1646
  }
package/src/actor/mod.ts CHANGED
@@ -52,6 +52,8 @@ export {
52
52
  export {
53
53
  ActorError,
54
54
  RivetError,
55
+ type RivetErrorLike,
56
+ type RivetErrorOptions,
55
57
  UserError,
56
58
  type UserErrorOptions,
57
59
  } from "./errors";
@@ -38,6 +38,29 @@ type LooseEventSubscribe = (
38
38
  callback: (...args: any[]) => void,
39
39
  ) => () => void;
40
40
 
41
+ type ActorActionMap<R> = {
42
+ [K in keyof NonNullable<R>]: NonNullable<R>[K] extends (
43
+ ...args: infer Args
44
+ ) => infer Return
45
+ ? ActorActionFunction<Args, Awaited<Return>>
46
+ : never;
47
+ };
48
+
49
+ type ActionsOf<AD extends AnyActorDefinition> =
50
+ AD extends BaseActorDefinition<
51
+ any,
52
+ any,
53
+ any,
54
+ any,
55
+ any,
56
+ any,
57
+ any,
58
+ any,
59
+ infer R
60
+ >
61
+ ? R
62
+ : never;
63
+
41
64
  export interface ActorGatewayOptions {
42
65
  skipReadyWait?: boolean;
43
66
  }
@@ -73,33 +96,7 @@ export type ActorDefinitionActions<AD extends AnyActorDefinition> =
73
96
  // biome-ignore lint/suspicious/noExplicitAny: safe to use any here
74
97
  IsAny<AD> extends true
75
98
  ? Record<string, ActorActionFunction<any[], any>>
76
- : AD extends { config: { actions?: infer R } }
77
- ? {
78
- [K in keyof R]: R[K] extends (
79
- ...args: infer Args
80
- ) => infer Return
81
- ? ActorActionFunction<Args, Return>
82
- : never;
83
- }
84
- : AD extends BaseActorDefinition<
85
- any,
86
- any,
87
- any,
88
- any,
89
- any,
90
- any,
91
- any,
92
- any,
93
- infer R
94
- >
95
- ? {
96
- [K in keyof R]: R[K] extends (
97
- ...args: infer Args
98
- ) => infer Return
99
- ? ActorActionFunction<Args, Return>
100
- : never;
101
- }
102
- : {};
99
+ : ActorActionMap<ActionsOf<AD>>;
103
100
 
104
101
  type ActorQueueSend<TQueues extends QueueSchemaConfig> = {
105
102
  <K extends keyof TQueues & string>(
@@ -872,8 +872,9 @@ export class ActorHandleRaw {
872
872
  this.#gatewayOptions,
873
873
  options,
874
874
  );
875
+ const useQueryTarget = isDynamicActorQuery(this.#actorResolutionState);
875
876
  const target = await this.#resolveGatewayRequestTarget(
876
- false,
877
+ useQueryTarget,
877
878
  gatewayOptions,
878
879
  );
879
880
  return await rawWebSocket(
@@ -1,2 +1,29 @@
1
+ export const ENGINE_HOST = "127.0.0.1";
1
2
  export const ENGINE_PORT = 6420;
2
- export const ENGINE_ENDPOINT = `http://127.0.0.1:${ENGINE_PORT}`;
3
+ export const ENGINE_ENDPOINT = buildEngineEndpoint(ENGINE_HOST, ENGINE_PORT);
4
+
5
+ export function buildEngineEndpoint(host: string, port: number): string {
6
+ const urlHost =
7
+ host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
8
+ return `http://${urlHost}:${port}`;
9
+ }
10
+
11
+ export function isLocalEngineEndpoint(endpoint: string): boolean {
12
+ let url: URL;
13
+ try {
14
+ url = new URL(endpoint);
15
+ } catch {
16
+ return false;
17
+ }
18
+
19
+ const hostname = url.hostname.toLowerCase();
20
+ return (
21
+ hostname === "localhost" ||
22
+ hostname === "0.0.0.0" ||
23
+ hostname === "::" ||
24
+ hostname === "[::]" ||
25
+ hostname === "::1" ||
26
+ hostname === "[::1]" ||
27
+ /^127(?:\.\d{1,3}){0,3}$/.test(hostname)
28
+ );
29
+ }
@@ -134,7 +134,7 @@ export function deconstructError(
134
134
  actor = error.actor;
135
135
  }
136
136
  metadata = {
137
- //url: `https://hub.rivet.dev/projects/${actorMetadata.project.slug}/environments/${actorMetadata.environment.slug}/actors?actorId=${actorMetadata.actor.id}`,
137
+ //url: `https://dashboard.rivet.dev/projects/${actorMetadata.project.slug}/environments/${actorMetadata.environment.slug}/actors?actorId=${actorMetadata.actor.id}`,
138
138
  } satisfies errors.InternalErrorMetadata;
139
139
  }
140
140
 
@@ -1,16 +1,11 @@
1
1
  import type { ClientConfigInput } from "@/client/client";
2
- import { VERSION } from "@/utils";
3
2
  import { logger } from "./log";
4
3
 
5
4
  declare global {
6
5
  // Injected via tsup config
7
- // biome-ignore lint/style/noVar: required for global declaration
8
6
  var CUSTOM_RIVETKIT_DEVTOOLS_URL: string | undefined;
9
7
  }
10
8
 
11
- const DEFAULT_DEVTOOLS_URL = (version = VERSION) =>
12
- `https://releases.rivet.dev/rivet/latest/devtools/mod.js?v=${version}`;
13
-
14
9
  const scriptId = "rivetkit-devtools-script";
15
10
 
16
11
  export function injectDevtools(config: ClientConfigInput) {
@@ -20,10 +15,12 @@ export function injectDevtools(config: ClientConfigInput) {
20
15
  }
21
16
 
22
17
  if (!document.getElementById(scriptId)) {
18
+ const src =
19
+ globalThis.CUSTOM_RIVETKIT_DEVTOOLS_URL ||
20
+ `${config.endpoint?.replace(/\/$/, "")}/devtools/mod.js`;
23
21
  const script = document.createElement("script");
24
22
  script.id = scriptId;
25
- script.src =
26
- globalThis.CUSTOM_RIVETKIT_DEVTOOLS_URL || DEFAULT_DEVTOOLS_URL();
23
+ script.src = src;
27
24
  script.async = true;
28
25
  document.head.appendChild(script);
29
26
  }
@@ -0,0 +1,26 @@
1
+ import { getNodeFs, getNodePath, getNodeUrl } from "@/utils/node";
2
+
3
+ export async function getDevtoolsPath(): Promise<string> {
4
+ const url = getNodeUrl();
5
+ const path = getNodePath();
6
+
7
+ const devtoolsPath = path.join(
8
+ path.dirname(url.fileURLToPath(import.meta.url)),
9
+ "../../dist/devtools/mod.js",
10
+ );
11
+
12
+ try {
13
+ await getNodeFs().access(devtoolsPath);
14
+ } catch {
15
+ throw new Error(
16
+ `Devtools bundle not found at ${devtoolsPath}. Run 'pnpm build:pack-devtools' first.`,
17
+ );
18
+ }
19
+
20
+ return devtoolsPath;
21
+ }
22
+
23
+ export async function readDevtoolsBundle(): Promise<Buffer> {
24
+ const devtoolsPath = await getDevtoolsPath();
25
+ return getNodeFs().readFile(devtoolsPath);
26
+ }
@@ -78,7 +78,7 @@ import {
78
78
  import { logger } from "./log";
79
79
 
80
80
  const ENVOY_SSE_PING_INTERVAL = 1000;
81
- const ENVOY_STOP_WAIT_MS = 15_000;
81
+ const FALLBACK_ENVOY_STOP_WAIT_MS = 15_000;
82
82
  const INITIAL_SLEEP_TIMEOUT_MS = 250;
83
83
  const REMOTE_ACK_HOOK_QUERY_PARAM = "__rivetkitAckHook";
84
84
 
@@ -835,6 +835,7 @@ export class EngineActorDriver implements ActorDriver {
835
835
  return;
836
836
  }
837
837
  this.#isShuttingDown = true;
838
+ const envoyStopWaitMs = this.#envoyStopWaitMs();
838
839
 
839
840
  logger().info({ msg: "stopping engine actor driver", immediate });
840
841
  if (!immediate) {
@@ -849,7 +850,7 @@ export class EngineActorDriver implements ActorDriver {
849
850
  this.startSleep(actorId);
850
851
  }
851
852
 
852
- const actorSleepDeadline = Date.now() + ENVOY_STOP_WAIT_MS;
853
+ const actorSleepDeadline = Date.now() + envoyStopWaitMs;
853
854
  while (this.#actors.size > 0 && Date.now() < actorSleepDeadline) {
854
855
  await new Promise((resolve) => setTimeout(resolve, 50));
855
856
  }
@@ -858,7 +859,7 @@ export class EngineActorDriver implements ActorDriver {
858
859
  logger().warn({
859
860
  msg: "timed out waiting for actors to stop before envoy drain",
860
861
  remainingActors: this.#actors.size,
861
- waitMs: ENVOY_STOP_WAIT_MS,
862
+ waitMs: envoyStopWaitMs,
862
863
  });
863
864
  // Snapshot so concurrent removals from `stopActor` do not
864
865
  // invalidate the iterator.
@@ -900,13 +901,13 @@ export class EngineActorDriver implements ActorDriver {
900
901
  const stopped = await Promise.race([
901
902
  this.#envoyStopped.promise.then(() => true),
902
903
  new Promise<false>((resolve) =>
903
- setTimeout(() => resolve(false), ENVOY_STOP_WAIT_MS),
904
+ setTimeout(() => resolve(false), envoyStopWaitMs),
904
905
  ),
905
906
  ]);
906
907
  if (!stopped) {
907
908
  logger().warn({
908
909
  msg: "timed out waiting for envoy shutdown",
909
- waitMs: ENVOY_STOP_WAIT_MS,
910
+ waitMs: envoyStopWaitMs,
910
911
  });
911
912
  }
912
913
 
@@ -917,6 +918,16 @@ export class EngineActorDriver implements ActorDriver {
917
918
  await this.#envoy.started();
918
919
  }
919
920
 
921
+ #envoyStopWaitMs(): number {
922
+ const actorStopThreshold = Number(
923
+ this.#envoy.getProtocolMetadata()?.actorStopThreshold,
924
+ );
925
+ if (Number.isFinite(actorStopThreshold) && actorStopThreshold > 0) {
926
+ return actorStopThreshold;
927
+ }
928
+ return FALLBACK_ENVOY_STOP_WAIT_MS;
929
+ }
930
+
920
931
  async #bindHibernatableConnectSocket(
921
932
  binding: HibernatableConnectBinding,
922
933
  isRestoringHibernatable: boolean,
@@ -34,9 +34,9 @@ export async function sendHttpRequestToGateway(
34
34
  bodyToSend = reqBody;
35
35
 
36
36
  // If this is a streaming request, we need to convert the headers
37
- // for the basic array buffer
37
+ // for the basic array buffer.
38
38
  guardHeaders.delete("transfer-encoding");
39
- guardHeaders.set("content-length", String(bodyToSend.byteLength));
39
+ guardHeaders.delete("content-length");
40
40
  }
41
41
  }
42
42
 
@@ -143,7 +143,11 @@ export async function getRunnerConfig(
143
143
  config: ClientConfig,
144
144
  name: string,
145
145
  ): Promise<RunnerConfigsResponse> {
146
- return apiCall<never, RunnerConfigsResponse>(config, "GET", `/runner-configs?runner_name=${name}`);
146
+ return apiCall<never, RunnerConfigsResponse>(
147
+ config,
148
+ "GET",
149
+ `/runner-configs?runner_name=${name}`,
150
+ );
147
151
  }
148
152
 
149
153
  // MARK: Update runner config
@@ -68,6 +68,11 @@ export async function createWebSocketProxy(
68
68
  reject(error);
69
69
  });
70
70
  });
71
+ // Attach a no-op rejection handler so Node.js does not treat this as
72
+ // an unhandled rejection if onMessage never runs (e.g. the client
73
+ // disconnects before sending a message). The rejection still propagates
74
+ // to any caller that awaits connectPromise directly.
75
+ state.connectPromise.catch(() => {});
71
76
 
72
77
  // Setup bidirectional forwarding
73
78
  state.targetWs.addEventListener("message", (event) => {