rivetkit 2.3.0-rc.12 → 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/dist/browser/client.d.ts +50 -0
- package/dist/browser/client.js +98 -84
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +12 -2
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/tsup/actor/errors.d.cts +1 -1
- package/dist/tsup/actor/errors.d.ts +1 -1
- package/dist/tsup/agent-os/index.cjs +66 -3
- package/dist/tsup/agent-os/index.cjs.map +1 -1
- package/dist/tsup/agent-os/index.d.cts +50 -0
- package/dist/tsup/agent-os/index.d.ts +50 -0
- package/dist/tsup/agent-os/index.js +66 -3
- package/dist/tsup/agent-os/index.js.map +1 -1
- package/dist/tsup/{chunk-EWVOWEMD.js → chunk-33YE6XCI.js} +4 -4
- package/dist/tsup/{chunk-2ZTBRZRS.cjs → chunk-7OR3CHD5.cjs} +10 -10
- package/dist/tsup/{chunk-2ZTBRZRS.cjs.map → chunk-7OR3CHD5.cjs.map} +1 -1
- package/dist/tsup/{chunk-UETC5RF7.cjs → chunk-7XQCARVY.cjs} +3 -3
- package/dist/tsup/{chunk-UETC5RF7.cjs.map → chunk-7XQCARVY.cjs.map} +1 -1
- package/dist/tsup/{chunk-SS56HFM2.cjs → chunk-BSPS6NSN.cjs} +5 -5
- package/dist/tsup/{chunk-SS56HFM2.cjs.map → chunk-BSPS6NSN.cjs.map} +1 -1
- package/dist/tsup/{chunk-WIMUFZVJ.js → chunk-DPIMKYNB.js} +61 -2
- package/dist/tsup/chunk-DPIMKYNB.js.map +1 -0
- package/dist/tsup/{chunk-2U6RLFKX.cjs → chunk-E5CLYAUZ.cjs} +144 -142
- package/dist/tsup/chunk-E5CLYAUZ.cjs.map +1 -0
- package/dist/tsup/{chunk-VNMIAPPF.cjs → chunk-EBWOJRCC.cjs} +21 -4
- package/dist/tsup/chunk-EBWOJRCC.cjs.map +1 -0
- package/dist/tsup/{chunk-OLIJHKLL.js → chunk-HHNYEQD3.js} +6 -6
- package/dist/tsup/chunk-HHNYEQD3.js.map +1 -0
- package/dist/tsup/{chunk-3EVVOYFD.js → chunk-IOUSQVXI.js} +20 -3
- package/dist/tsup/chunk-IOUSQVXI.js.map +1 -0
- package/dist/tsup/{chunk-C7AAIILH.cjs → chunk-ISDKSSYR.cjs} +4 -4
- package/dist/tsup/{chunk-C7AAIILH.cjs.map → chunk-ISDKSSYR.cjs.map} +1 -1
- package/dist/tsup/{chunk-7UZF56RS.js → chunk-J72WHUBC.js} +10 -8
- package/dist/tsup/{chunk-7UZF56RS.js.map → chunk-J72WHUBC.js.map} +1 -1
- package/dist/tsup/{chunk-6KTMKPNU.cjs → chunk-KWABEUUA.cjs} +10 -10
- package/dist/tsup/chunk-KWABEUUA.cjs.map +1 -0
- package/dist/tsup/{chunk-WHYBAEWG.cjs → chunk-NIY3RSPX.cjs} +62 -3
- package/dist/tsup/chunk-NIY3RSPX.cjs.map +1 -0
- package/dist/tsup/{chunk-VLXRFJ7P.js → chunk-T44AVAGW.js} +2 -2
- package/dist/tsup/{chunk-QKSGGKGQ.js → chunk-TCXEM6PA.js} +2 -2
- package/dist/tsup/{chunk-OOB32JVG.js → chunk-ZI5CNA2Z.js} +2 -2
- package/dist/tsup/client/mod.cjs +7 -7
- package/dist/tsup/client/mod.cjs.map +1 -1
- package/dist/tsup/client/mod.d.cts +3 -3
- package/dist/tsup/client/mod.d.ts +3 -3
- package/dist/tsup/client/mod.js +6 -6
- package/dist/tsup/common/log.cjs +2 -2
- package/dist/tsup/common/log.js +1 -1
- package/dist/tsup/common/websocket.cjs +3 -3
- package/dist/tsup/common/websocket.js +2 -2
- package/dist/tsup/{config-DKgPGC0f.d.ts → config-BxWAw3iH.d.ts} +121 -2
- package/dist/tsup/{config-BtAh7oBu.d.cts → config-CZQQ-mso.d.cts} +121 -2
- package/dist/tsup/{context-Cfjl5pgz.d.cts → context-Bw7xq8w3.d.cts} +1 -1
- package/dist/tsup/{context-C-6dGebY.d.ts → context-D8QA76sV.d.ts} +1 -1
- package/dist/tsup/dynamic/mod.cjs +2 -2
- package/dist/tsup/dynamic/mod.d.cts +2 -2
- package/dist/tsup/dynamic/mod.d.ts +2 -2
- package/dist/tsup/dynamic/mod.js +1 -1
- package/dist/tsup/inspector/mod.cjs +5 -5
- package/dist/tsup/inspector/mod.js +4 -4
- package/dist/tsup/inspector-tab/mod.cjs +173 -0
- package/dist/tsup/inspector-tab/mod.cjs.map +1 -0
- package/dist/tsup/inspector-tab/mod.d.cts +250 -0
- package/dist/tsup/inspector-tab/mod.d.ts +250 -0
- package/dist/tsup/inspector-tab/mod.js +173 -0
- package/dist/tsup/inspector-tab/mod.js.map +1 -0
- package/dist/tsup/mod.cjs +189 -81
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +4 -4
- package/dist/tsup/mod.d.ts +4 -4
- package/dist/tsup/mod.js +124 -16
- package/dist/tsup/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +10 -10
- package/dist/tsup/test/mod.d.cts +2 -2
- package/dist/tsup/test/mod.d.ts +2 -2
- package/dist/tsup/test/mod.js +6 -6
- package/dist/tsup/{utils-DVekpm4I.d.cts → utils-DQosb24I.d.cts} +1 -1
- package/dist/tsup/{utils-DVekpm4I.d.ts → utils-DQosb24I.d.ts} +1 -1
- package/dist/tsup/utils.cjs +2 -2
- package/dist/tsup/utils.d.cts +1 -1
- package/dist/tsup/utils.d.ts +1 -1
- package/dist/tsup/utils.js +1 -1
- package/dist/tsup/workflow/mod.cjs +11 -11
- package/dist/tsup/workflow/mod.cjs.map +1 -1
- package/dist/tsup/workflow/mod.d.cts +4 -4
- package/dist/tsup/workflow/mod.d.ts +4 -4
- package/dist/tsup/workflow/mod.js +5 -5
- package/package.json +19 -9
- package/src/actor/config.ts +91 -0
- package/src/actor/instance/mod.ts +4 -4
- package/src/actor/mod.ts +2 -0
- package/src/common/engine.ts +28 -1
- package/src/devtools-loader/index.ts +4 -7
- package/src/devtools-loader/serve-devtools.ts +26 -0
- package/src/engine-client/actor-http-client.ts +2 -2
- package/src/engine-client/ws-proxy.ts +5 -0
- package/src/inspector-tab/mod.ts +315 -0
- package/src/registry/config/index.ts +37 -7
- package/src/registry/index.ts +4 -2
- package/src/registry/native.ts +118 -7
- package/src/registry/runtime.ts +20 -0
- package/src/utils/env-vars.ts +6 -0
- package/dist/tsup/chunk-2U6RLFKX.cjs.map +0 -1
- package/dist/tsup/chunk-3EVVOYFD.js.map +0 -1
- package/dist/tsup/chunk-6KTMKPNU.cjs.map +0 -1
- package/dist/tsup/chunk-OLIJHKLL.js.map +0 -1
- package/dist/tsup/chunk-VNMIAPPF.cjs.map +0 -1
- package/dist/tsup/chunk-WHYBAEWG.cjs.map +0 -1
- package/dist/tsup/chunk-WIMUFZVJ.js.map +0 -1
- /package/dist/tsup/{chunk-EWVOWEMD.js.map → chunk-33YE6XCI.js.map} +0 -0
- /package/dist/tsup/{chunk-VLXRFJ7P.js.map → chunk-T44AVAGW.js.map} +0 -0
- /package/dist/tsup/{chunk-QKSGGKGQ.js.map → chunk-TCXEM6PA.js.map} +0 -0
- /package/dist/tsup/{chunk-OOB32JVG.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.
|
|
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.
|
|
187
|
-
"@rivetkit/engine-envoy-protocol": "2.3.0-rc.
|
|
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.
|
|
190
|
-
"@rivetkit/rivetkit-wasm": "2.3.0-rc.
|
|
191
|
-
"@rivetkit/traces": "2.3.0-rc.
|
|
192
|
-
"@rivetkit/virtual-websocket": "2.3.0-rc.
|
|
193
|
-
"@rivetkit/workflow-engine": "2.3.0-rc.
|
|
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",
|
package/src/actor/config.ts
CHANGED
|
@@ -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(
|
|
@@ -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
package/src/common/engine.ts
CHANGED
|
@@ -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 =
|
|
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
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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.
|
|
39
|
+
guardHeaders.delete("content-length");
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -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) => {
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type and schema declarations for custom Rivet inspector tabs.
|
|
3
|
+
*
|
|
4
|
+
* Everything here is **derived from runtime Zod schemas** that the
|
|
5
|
+
* dashboard and rivetkit itself use, so the published types cannot
|
|
6
|
+
* drift from the wire format. There are three sources of truth:
|
|
7
|
+
*
|
|
8
|
+
* 1. The `inspector.tabs[]` actor-config Zod schemas in
|
|
9
|
+
* `../actor/config.ts` — re-exported below. These validate the
|
|
10
|
+
* authoring surface (`defineActor({ inspector: { tabs: [...] } })`).
|
|
11
|
+
* 2. The dashboard ↔ tab postMessage envelopes defined in this file.
|
|
12
|
+
* The inspector-ui SPA (`frontend/apps/inspector-ui/src/bridge.ts`)
|
|
13
|
+
* imports the same schemas to validate messages at runtime, so any
|
|
14
|
+
* change here lands on both ends in lockstep.
|
|
15
|
+
* 3. The inspector HTTP endpoint response schemas defined in this
|
|
16
|
+
* file. The dashboard parses every response through them; if the
|
|
17
|
+
* Rust handler ever emits a different shape, the dashboard fails
|
|
18
|
+
* loudly at the parse step instead of silently casting `unknown`.
|
|
19
|
+
*
|
|
20
|
+
* Tab bundles import these types for autocomplete and compile-time
|
|
21
|
+
* safety:
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import type {
|
|
25
|
+
* ShellToTabMessage,
|
|
26
|
+
* TabToShellMessage,
|
|
27
|
+
* V1Init,
|
|
28
|
+
* InspectorStateResponse,
|
|
29
|
+
* } from "rivetkit/inspector-tab";
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { z } from "zod";
|
|
34
|
+
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Re-exported from `../actor/config.ts` — the authoring schema for
|
|
37
|
+
// `defineActor({ inspector: { tabs: [...] } })`.
|
|
38
|
+
// ============================================================================
|
|
39
|
+
|
|
40
|
+
export {
|
|
41
|
+
ActorInspectorConfigSchema,
|
|
42
|
+
BUILTIN_INSPECTOR_TAB_IDS,
|
|
43
|
+
BuiltinInspectorTabIdSchema,
|
|
44
|
+
CustomInspectorTabEntrySchema,
|
|
45
|
+
HideInspectorTabEntrySchema,
|
|
46
|
+
InspectorTabEntrySchema,
|
|
47
|
+
} from "../actor/config";
|
|
48
|
+
export type { ActorInspectorConfig } from "../actor/config";
|
|
49
|
+
|
|
50
|
+
import type {
|
|
51
|
+
CustomInspectorTabEntrySchema,
|
|
52
|
+
HideInspectorTabEntrySchema,
|
|
53
|
+
InspectorTabEntrySchema,
|
|
54
|
+
} from "../actor/config";
|
|
55
|
+
|
|
56
|
+
/** One entry in the actor's `inspector.tabs[]` declaration. */
|
|
57
|
+
export type ActorInspectorTabEntry = z.input<typeof InspectorTabEntrySchema>;
|
|
58
|
+
/** A custom-tab entry — adds a new tab to the dashboard strip. */
|
|
59
|
+
export type ActorCustomInspectorTabEntry = z.input<
|
|
60
|
+
typeof CustomInspectorTabEntrySchema
|
|
61
|
+
>;
|
|
62
|
+
/** A hide modifier — removes a built-in tab from the strip. */
|
|
63
|
+
export type ActorHideInspectorTabEntry = z.input<
|
|
64
|
+
typeof HideInspectorTabEntrySchema
|
|
65
|
+
>;
|
|
66
|
+
/** Union of the six built-in inspector tab ids. */
|
|
67
|
+
export type BuiltinInspectorTabId =
|
|
68
|
+
| "workflow"
|
|
69
|
+
| "database"
|
|
70
|
+
| "state"
|
|
71
|
+
| "queue"
|
|
72
|
+
| "connections"
|
|
73
|
+
| "console";
|
|
74
|
+
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// Dashboard ↔ tab postMessage envelope (source of truth).
|
|
77
|
+
//
|
|
78
|
+
// These Zod schemas are imported by `frontend/apps/inspector-ui/src/bridge.ts`
|
|
79
|
+
// and used to validate inbound messages at runtime. Changes here flow to
|
|
80
|
+
// both sides in a single commit.
|
|
81
|
+
// ============================================================================
|
|
82
|
+
|
|
83
|
+
/** Public tab descriptor that crosses the dashboard ↔ inspector-ui bridge. */
|
|
84
|
+
export const InspectorTabDescriptorSchema = z.object({
|
|
85
|
+
id: z.string(),
|
|
86
|
+
label: z.string(),
|
|
87
|
+
icon: z.string(),
|
|
88
|
+
/**
|
|
89
|
+
* `true` for author-shipped custom tabs; absent or `false` for
|
|
90
|
+
* built-in tabs the SPA renders. Lets the dashboard route the
|
|
91
|
+
* iframe `src` to `/inspector/custom-tabs/<id>/` for custom tabs and
|
|
92
|
+
* `/inspector/ui/` for built-ins without the dashboard needing to
|
|
93
|
+
* know which ids are built-in.
|
|
94
|
+
*/
|
|
95
|
+
isCustom: z.boolean().optional(),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Initial handshake from the dashboard. Sent on first mount and again on
|
|
100
|
+
* every token refresh. Tabs MUST accept late `init` messages and replace
|
|
101
|
+
* the cached token.
|
|
102
|
+
*/
|
|
103
|
+
export const V1InitSchema = z.object({
|
|
104
|
+
type: z.literal("init"),
|
|
105
|
+
v: z.literal(1),
|
|
106
|
+
/** The actor this tab is mounted for. */
|
|
107
|
+
actorId: z.string(),
|
|
108
|
+
/**
|
|
109
|
+
* Per-actor inspector bearer token. Tabs include it as
|
|
110
|
+
* `Authorization: Bearer ${authToken}` on every authenticated fetch.
|
|
111
|
+
*/
|
|
112
|
+
authToken: z.string(),
|
|
113
|
+
/**
|
|
114
|
+
* Outer Rivet API token. Optional; not required for inspector HTTP
|
|
115
|
+
* routes but available to tabs that want to call the engine REST API.
|
|
116
|
+
*/
|
|
117
|
+
rivetToken: z.string().optional(),
|
|
118
|
+
/**
|
|
119
|
+
* The tab id the dashboard wants active at mount time. Multi-view
|
|
120
|
+
* tabs may read this to seed their initial route; most tabs ignore it.
|
|
121
|
+
*/
|
|
122
|
+
activeTab: z.string().optional(),
|
|
123
|
+
/**
|
|
124
|
+
* Dashboard's currently active theme. Tabs that use the shared
|
|
125
|
+
* stylesheet (`/inspector/tab.css`) mirror it by toggling the `dark`
|
|
126
|
+
* class on `<html>`. Optional for backwards compatibility — tabs
|
|
127
|
+
* should default to `"dark"` if absent (the dashboard pinned dark
|
|
128
|
+
* mode before this field was added).
|
|
129
|
+
*/
|
|
130
|
+
theme: z.enum(["light", "dark"]).optional(),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Dashboard tells the inspector-ui SPA which built-in tab to render. Not
|
|
135
|
+
* sent to custom tabs — when the user activates a custom tab the
|
|
136
|
+
* dashboard navigates the outer iframe to a different `src`.
|
|
137
|
+
*/
|
|
138
|
+
export const V1SetActiveTabSchema = z.object({
|
|
139
|
+
type: z.literal("set-active-tab"),
|
|
140
|
+
v: z.literal(1),
|
|
141
|
+
tab: z.string(),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Tab → dashboard. Sent once after the message listener is registered.
|
|
146
|
+
* The dashboard hides the "Connecting to inspector…" overlay on receipt;
|
|
147
|
+
* if it never arrives the overlay times out after 8 s.
|
|
148
|
+
*/
|
|
149
|
+
export const V1ReadySchema = z.object({
|
|
150
|
+
type: z.literal("ready"),
|
|
151
|
+
v: z.literal(1),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Tab → dashboard. Sent when the tab gets a 401 on an inspector data
|
|
156
|
+
* call. The dashboard refreshes the token and re-issues `v1Init`.
|
|
157
|
+
*/
|
|
158
|
+
export const V1TokenRefreshNeededSchema = z.object({
|
|
159
|
+
type: z.literal("token-refresh-needed"),
|
|
160
|
+
v: z.literal(1),
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Emitted by the inspector-ui SPA to tell the dashboard which tabs to
|
|
165
|
+
* render in the strip. Custom tab bundles do NOT emit this — only the
|
|
166
|
+
* SPA does.
|
|
167
|
+
*/
|
|
168
|
+
export const V1TabsAvailableSchema = z.object({
|
|
169
|
+
type: z.literal("tabs-available"),
|
|
170
|
+
v: z.literal(1),
|
|
171
|
+
tabs: z.array(InspectorTabDescriptorSchema),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
/** Discriminated union of messages a tab can RECEIVE from the dashboard. */
|
|
175
|
+
export const ShellToTabMessageSchema = z.discriminatedUnion("type", [
|
|
176
|
+
V1InitSchema,
|
|
177
|
+
V1SetActiveTabSchema,
|
|
178
|
+
]);
|
|
179
|
+
|
|
180
|
+
/** Discriminated union of messages a tab can SEND to the dashboard. */
|
|
181
|
+
export const TabToShellMessageSchema = z.discriminatedUnion("type", [
|
|
182
|
+
V1ReadySchema,
|
|
183
|
+
V1TabsAvailableSchema,
|
|
184
|
+
V1TokenRefreshNeededSchema,
|
|
185
|
+
]);
|
|
186
|
+
|
|
187
|
+
export type InspectorTabDescriptor = z.infer<
|
|
188
|
+
typeof InspectorTabDescriptorSchema
|
|
189
|
+
>;
|
|
190
|
+
export type V1Init = z.infer<typeof V1InitSchema>;
|
|
191
|
+
export type V1SetActiveTab = z.infer<typeof V1SetActiveTabSchema>;
|
|
192
|
+
export type V1Ready = z.infer<typeof V1ReadySchema>;
|
|
193
|
+
export type V1TokenRefreshNeeded = z.infer<typeof V1TokenRefreshNeededSchema>;
|
|
194
|
+
export type V1TabsAvailable = z.infer<typeof V1TabsAvailableSchema>;
|
|
195
|
+
export type ShellToTabMessage = z.infer<typeof ShellToTabMessageSchema>;
|
|
196
|
+
export type TabToShellMessage = z.infer<typeof TabToShellMessageSchema>;
|
|
197
|
+
|
|
198
|
+
/** Stable envelope protocol version. Bump only when introducing a v2 shape. */
|
|
199
|
+
export const POSTMESSAGE_PROTOCOL_VERSION = 1;
|
|
200
|
+
|
|
201
|
+
/** URL query parameters the dashboard sets on the tab iframe `src`. */
|
|
202
|
+
export const SHELL_ORIGIN_PARAM = "shellOrigin";
|
|
203
|
+
export const ACTOR_ID_PARAM = "actorId";
|
|
204
|
+
|
|
205
|
+
// ============================================================================
|
|
206
|
+
// Inspector HTTP endpoint response schemas (source of truth).
|
|
207
|
+
//
|
|
208
|
+
// The dashboard parses every authenticated inspector response through
|
|
209
|
+
// these schemas (`frontend/src/components/actors/actor-inspector-context.tsx`).
|
|
210
|
+
// If the Rust handler emits a different shape the parse fails and the
|
|
211
|
+
// dashboard surfaces an error — drift is loud.
|
|
212
|
+
// ============================================================================
|
|
213
|
+
|
|
214
|
+
/** `GET /inspector/state` response shape. */
|
|
215
|
+
export const InspectorStateResponseSchema = z.object({
|
|
216
|
+
/** Current actor state (whatever shape the actor declared). */
|
|
217
|
+
state: z.unknown(),
|
|
218
|
+
/**
|
|
219
|
+
* `false` when the actor did not declare any state — `state` is then
|
|
220
|
+
* `null` and `PATCH /inspector/state` returns an error.
|
|
221
|
+
*/
|
|
222
|
+
isStateEnabled: z.boolean(),
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
/** `POST /inspector/action/<name>` request body. */
|
|
226
|
+
export const InspectorActionRequestSchema = z
|
|
227
|
+
.object({
|
|
228
|
+
/** Positional arguments. Mutually exclusive with `properties`. */
|
|
229
|
+
args: z.array(z.unknown()).optional(),
|
|
230
|
+
/** Keyed arguments. Mutually exclusive with `args`. */
|
|
231
|
+
properties: z.record(z.string(), z.unknown()).optional(),
|
|
232
|
+
})
|
|
233
|
+
.refine(
|
|
234
|
+
(body) => !(body.args !== undefined && body.properties !== undefined),
|
|
235
|
+
"Use either `args` or `properties`, not both",
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
/** `POST /inspector/action/<name>` response shape. */
|
|
239
|
+
export const InspectorActionResponseSchema = z.object({
|
|
240
|
+
output: z.unknown(),
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
/** `GET /inspector/rpcs` response shape — the list of action names. */
|
|
244
|
+
export const InspectorRpcsResponseSchema = z.object({
|
|
245
|
+
rpcs: z.array(z.string()),
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
/** One connection record in `GET /inspector/connections`. */
|
|
249
|
+
export const InspectorConnectionSchema = z.object({
|
|
250
|
+
connectionType: z.string().nullable(),
|
|
251
|
+
id: z.string(),
|
|
252
|
+
details: z.object({
|
|
253
|
+
connectionType: z.string().nullable(),
|
|
254
|
+
params: z.unknown(),
|
|
255
|
+
stateEnabled: z.boolean(),
|
|
256
|
+
state: z.unknown(),
|
|
257
|
+
subscriptions: z.number(),
|
|
258
|
+
isHibernatable: z.boolean(),
|
|
259
|
+
}),
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
/** `GET /inspector/connections` response shape. */
|
|
263
|
+
export const InspectorConnectionsResponseSchema = z.object({
|
|
264
|
+
connections: z.array(InspectorConnectionSchema),
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
/** One queued message in `GET /inspector/queue`. */
|
|
268
|
+
export const InspectorQueueMessageSchema = z.object({
|
|
269
|
+
id: z.string(),
|
|
270
|
+
name: z.string(),
|
|
271
|
+
createdAtMs: z.number(),
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
/** `GET /inspector/queue` response shape. */
|
|
275
|
+
export const InspectorQueueResponseSchema = z.object({
|
|
276
|
+
size: z.number(),
|
|
277
|
+
maxSize: z.number(),
|
|
278
|
+
/** `true` if `?limit=N` truncated the message list below `size`. */
|
|
279
|
+
truncated: z.boolean(),
|
|
280
|
+
messages: z.array(InspectorQueueMessageSchema),
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
/** `GET /inspector/tab-config` response shape. */
|
|
284
|
+
export const InspectorTabConfigResponseSchema = z.object({
|
|
285
|
+
tabs: z.array(
|
|
286
|
+
z.object({
|
|
287
|
+
id: z.string(),
|
|
288
|
+
label: z.string().optional(),
|
|
289
|
+
icon: z.string().nullable().optional(),
|
|
290
|
+
hidden: z.boolean().optional(),
|
|
291
|
+
}),
|
|
292
|
+
),
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
export type InspectorStateResponse = z.infer<
|
|
296
|
+
typeof InspectorStateResponseSchema
|
|
297
|
+
>;
|
|
298
|
+
export type InspectorActionRequest = z.infer<
|
|
299
|
+
typeof InspectorActionRequestSchema
|
|
300
|
+
>;
|
|
301
|
+
export type InspectorActionResponse = z.infer<
|
|
302
|
+
typeof InspectorActionResponseSchema
|
|
303
|
+
>;
|
|
304
|
+
export type InspectorRpcsResponse = z.infer<typeof InspectorRpcsResponseSchema>;
|
|
305
|
+
export type InspectorConnection = z.infer<typeof InspectorConnectionSchema>;
|
|
306
|
+
export type InspectorConnectionsResponse = z.infer<
|
|
307
|
+
typeof InspectorConnectionsResponseSchema
|
|
308
|
+
>;
|
|
309
|
+
export type InspectorQueueMessage = z.infer<typeof InspectorQueueMessageSchema>;
|
|
310
|
+
export type InspectorQueueResponse = z.infer<
|
|
311
|
+
typeof InspectorQueueResponseSchema
|
|
312
|
+
>;
|
|
313
|
+
export type InspectorTabConfigResponse = z.infer<
|
|
314
|
+
typeof InspectorTabConfigResponseSchema
|
|
315
|
+
>;
|