rivetkit 2.3.0-rc.9 → 2.3.1
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 +511 -62
- package/dist/browser/client.js +230 -174
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +53 -23
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/tsup/actor/errors.cjs +4 -2
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +1 -1
- package/dist/tsup/actor/errors.d.ts +1 -1
- package/dist/tsup/actor/errors.js +3 -1
- package/dist/tsup/agent-os/index.cjs +2163 -2087
- package/dist/tsup/agent-os/index.cjs.map +1 -1
- package/dist/tsup/agent-os/index.d.cts +509 -69
- package/dist/tsup/agent-os/index.d.ts +509 -69
- package/dist/tsup/agent-os/index.js +2163 -2087
- package/dist/tsup/agent-os/index.js.map +1 -1
- package/dist/tsup/{chunk-WQ4HNA4W.cjs → chunk-3MHDOUD7.cjs} +73 -3
- package/dist/tsup/chunk-3MHDOUD7.cjs.map +1 -0
- package/dist/tsup/{chunk-QAZLM4WT.cjs → chunk-4FC7TVS6.cjs} +8 -4
- package/dist/tsup/chunk-4FC7TVS6.cjs.map +1 -0
- package/dist/tsup/{chunk-4CGA6QJO.cjs → chunk-4UUEB43Y.cjs} +24 -9
- package/dist/tsup/chunk-4UUEB43Y.cjs.map +1 -0
- package/dist/tsup/{chunk-GVTOE34S.cjs → chunk-5IWLUJ6W.cjs} +222 -235
- package/dist/tsup/chunk-5IWLUJ6W.cjs.map +1 -0
- package/dist/tsup/{chunk-MMMEZM5J.js → chunk-H6VVZMWN.js} +4 -4
- package/dist/tsup/chunk-H6VVZMWN.js.map +1 -0
- package/dist/tsup/{chunk-3YY5S6TV.js → chunk-HXUEHHJF.js} +2 -2
- package/dist/tsup/chunk-HXUEHHJF.js.map +1 -0
- package/dist/tsup/{chunk-H7P7WR2Y.js → chunk-I35VSLEM.js} +6 -6
- package/dist/tsup/chunk-I35VSLEM.js.map +1 -0
- package/dist/tsup/{chunk-H37XQU3I.js → chunk-JBUZRPY5.js} +2 -2
- package/dist/tsup/{chunk-CPA4Y3RG.cjs → chunk-JLJJZYCJ.cjs} +10 -10
- package/dist/tsup/chunk-JLJJZYCJ.cjs.map +1 -0
- package/dist/tsup/{chunk-PCBNKI2J.js → chunk-JZ7TWV65.js} +1 -1
- package/dist/tsup/chunk-JZ7TWV65.js.map +1 -0
- package/dist/tsup/{chunk-VRCIXJRN.js → chunk-L2X3YFER.js} +64 -10
- package/dist/tsup/chunk-L2X3YFER.js.map +1 -0
- package/dist/tsup/{chunk-Y5NSCZA2.cjs → chunk-MNHKOS6L.cjs} +72 -18
- package/dist/tsup/chunk-MNHKOS6L.cjs.map +1 -0
- package/dist/tsup/{chunk-KJTA3ATT.js → chunk-NERUIBOT.js} +22 -7
- package/dist/tsup/chunk-NERUIBOT.js.map +1 -0
- package/dist/tsup/{chunk-4WPEZBK4.cjs → chunk-OST76LRW.cjs} +10 -10
- package/dist/tsup/chunk-OST76LRW.cjs.map +1 -0
- package/dist/tsup/{chunk-MALSPBAF.cjs → chunk-OZBCXBVP.cjs} +3 -3
- package/dist/tsup/{chunk-MALSPBAF.cjs.map → chunk-OZBCXBVP.cjs.map} +1 -1
- package/dist/tsup/{chunk-F3Q5BFQ6.js → chunk-PT6OIW5E.js} +66 -79
- package/dist/tsup/chunk-PT6OIW5E.js.map +1 -0
- package/dist/tsup/{chunk-W7EYSYVI.js → chunk-R6KPN5EW.js} +134 -20
- package/dist/tsup/chunk-R6KPN5EW.js.map +1 -0
- package/dist/tsup/{chunk-VJFRBJVQ.cjs → chunk-V5KMAMX3.cjs} +138 -24
- package/dist/tsup/chunk-V5KMAMX3.cjs.map +1 -0
- package/dist/tsup/{chunk-LD5YASJU.cjs → chunk-VE2X4KMG.cjs} +2 -2
- package/dist/tsup/{chunk-LD5YASJU.cjs.map → chunk-VE2X4KMG.cjs.map} +1 -1
- package/dist/tsup/{chunk-T6YVRM4K.js → chunk-XIX5DOZN.js} +72 -2
- package/dist/tsup/chunk-XIX5DOZN.js.map +1 -0
- package/dist/tsup/{chunk-2NDZ7JCR.cjs → chunk-ZA7FLHKH.cjs} +1 -1
- package/dist/tsup/chunk-ZA7FLHKH.cjs.map +1 -0
- package/dist/tsup/{chunk-KIWH5H3K.js → chunk-ZZ3WBRPD.js} +7 -3
- package/dist/tsup/chunk-ZZ3WBRPD.js.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.d.cts +5 -5
- package/dist/tsup/client/mod.d.ts +5 -5
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{config-Ca8dN4cS.d.cts → config-CzvopP5m.d.cts} +544 -23
- package/dist/tsup/{config-CxjGYf4K.d.cts → config-D49x8NpL.d.cts} +1 -2
- package/dist/tsup/{config-CxjGYf4K.d.ts → config-D49x8NpL.d.ts} +1 -2
- package/dist/tsup/{config-0Ta55UV0.d.ts → config-DZuT7tcp.d.ts} +544 -23
- package/dist/tsup/context-CyAdY-aA.d.ts +128 -0
- package/dist/tsup/context-sNB28g0N.d.cts +128 -0
- package/dist/tsup/db/drizzle.cjs +3 -3
- package/dist/tsup/db/drizzle.d.cts +1 -1
- package/dist/tsup/db/drizzle.d.ts +1 -1
- package/dist/tsup/db/drizzle.js +1 -1
- package/dist/tsup/db/mod.cjs +2 -2
- package/dist/tsup/db/mod.d.cts +2 -2
- package/dist/tsup/db/mod.d.ts +2 -2
- package/dist/tsup/db/mod.js +1 -1
- package/dist/tsup/dynamic/mod.cjs +24 -0
- package/dist/tsup/dynamic/mod.cjs.map +1 -0
- package/dist/tsup/dynamic/mod.d.cts +37 -0
- package/dist/tsup/dynamic/mod.d.ts +37 -0
- package/dist/tsup/dynamic/mod.js +24 -0
- package/dist/tsup/dynamic/mod.js.map +1 -0
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.js +5 -5
- 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 +758 -348
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +5 -5
- package/dist/tsup/mod.d.ts +5 -5
- package/dist/tsup/mod.js +662 -252
- package/dist/tsup/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +21 -18
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +4 -4
- package/dist/tsup/test/mod.d.ts +4 -4
- package/dist/tsup/test/mod.js +18 -15
- package/dist/tsup/test/mod.js.map +1 -1
- package/dist/tsup/{utils-DVekpm4I.d.cts → utils-CqDnC_PS.d.cts} +2 -1
- package/dist/tsup/{utils-DVekpm4I.d.ts → utils-CqDnC_PS.d.ts} +2 -1
- package/dist/tsup/utils.cjs +3 -3
- package/dist/tsup/utils.d.cts +1 -1
- package/dist/tsup/utils.d.ts +1 -1
- package/dist/tsup/utils.js +2 -2
- package/dist/tsup/workflow/mod.cjs +383 -322
- package/dist/tsup/workflow/mod.cjs.map +1 -1
- package/dist/tsup/workflow/mod.d.cts +8 -8
- package/dist/tsup/workflow/mod.d.ts +8 -8
- package/dist/tsup/workflow/mod.js +360 -299
- package/dist/tsup/workflow/mod.js.map +1 -1
- package/package.json +35 -14
- package/src/actor/config.ts +173 -51
- package/src/actor/contexts/index.ts +7 -2
- package/src/actor/definition.ts +17 -19
- package/src/actor/driver.ts +3 -3
- package/src/actor/errors.ts +20 -3
- package/src/actor/instance/mod.ts +26 -34
- package/src/actor/keys.ts +1 -1
- package/src/actor/mod.ts +22 -20
- package/src/actor/schema.ts +2 -2
- package/src/agent-os/actor/index.ts +38 -18
- package/src/agent-os/actor/preview.ts +1 -2
- package/src/agent-os/actor/session.ts +2 -2
- package/src/agent-os/config.ts +1 -1
- package/src/agent-os/fs/database-vfs.ts +1 -1
- package/src/agent-os/index.ts +16 -15
- package/src/client/actor-common.ts +87 -54
- package/src/client/actor-conn.ts +8 -36
- package/src/client/actor-handle.ts +69 -51
- package/src/client/actor-query.ts +5 -5
- package/src/client/errors.ts +1 -1
- package/src/client/lifecycle-errors.ts +2 -4
- package/src/client/query.ts +1 -1
- package/src/client/queue.ts +8 -3
- package/src/client/raw-utils.ts +8 -6
- package/src/client/resolve-gateway-target.ts +1 -1
- package/src/client/utils.ts +2 -7
- package/src/common/actor-websocket.ts +3 -1
- package/src/common/bare/actor-persist/v1.ts +205 -163
- package/src/common/bare/actor-persist/v2.ts +265 -213
- package/src/common/bare/actor-persist/v3.ts +176 -172
- package/src/common/bare/actor-persist/v4.ts +254 -253
- package/src/common/bare/transport/v1.ts +659 -543
- package/src/common/client-protocol-versioned.ts +66 -64
- package/src/common/database/config.ts +2 -8
- package/src/common/database/native-database.ts +1 -1
- package/src/common/database/shared.ts +1 -0
- package/src/common/encoding.ts +250 -16
- package/src/common/engine.ts +28 -1
- package/src/common/eventsource.ts +1 -1
- package/src/common/inline-websocket-adapter.ts +14 -13
- package/src/common/log.ts +1 -0
- package/src/common/router.ts +13 -17
- package/src/common/utils.ts +1 -150
- package/src/common/websocket-interface.ts +1 -1
- package/src/db/mod.ts +1 -1
- package/src/devtools-loader/index.ts +4 -7
- package/src/devtools-loader/serve-devtools.ts +26 -0
- package/src/drivers/engine/actor-driver.ts +58 -56
- package/src/dynamic/instance.ts +32 -0
- package/src/dynamic/internal.ts +50 -0
- package/src/dynamic/isolate-runtime.ts +66 -0
- package/src/dynamic/mod.ts +32 -0
- package/src/engine-client/actor-http-client.ts +3 -3
- package/src/engine-client/actor-websocket-client.ts +6 -5
- package/src/engine-client/api-endpoints.ts +51 -2
- package/src/engine-client/api-utils.ts +2 -2
- package/src/engine-client/driver.ts +1 -1
- package/src/engine-client/mod.ts +6 -3
- package/src/engine-client/ws-proxy.ts +9 -4
- package/src/inspector/client.browser.ts +5 -11
- package/src/inspector/mod.ts +1 -3
- package/src/inspector-tab/mod.ts +315 -0
- package/src/registry/config/envoy.ts +1 -2
- package/src/registry/config/index.ts +40 -16
- package/src/registry/index.ts +209 -73
- package/src/registry/napi-runtime.ts +29 -2
- package/src/registry/native-validation.ts +10 -12
- package/src/registry/native.ts +433 -198
- package/src/registry/process-metrics.ts +250 -0
- package/src/registry/runtime.ts +52 -1
- package/src/registry/wasm-runtime.ts +29 -2
- package/src/registry/write-through-proxy.ts +40 -0
- package/src/serde.ts +2 -2
- package/src/serverless/configure.ts +18 -7
- package/src/test/mod.ts +11 -8
- package/src/utils/endpoint-parser.ts +1 -1
- package/src/utils/env-vars.ts +37 -0
- package/src/utils/router.ts +1 -1
- package/src/utils.ts +1 -2
- package/src/workflow/context.ts +699 -240
- package/src/workflow/driver.ts +23 -12
- package/src/workflow/inspector.ts +4 -3
- package/src/workflow/mod.ts +37 -23
- package/dist/tsup/chunk-2NDZ7JCR.cjs.map +0 -1
- package/dist/tsup/chunk-3YY5S6TV.js.map +0 -1
- package/dist/tsup/chunk-4CGA6QJO.cjs.map +0 -1
- package/dist/tsup/chunk-4WPEZBK4.cjs.map +0 -1
- package/dist/tsup/chunk-CPA4Y3RG.cjs.map +0 -1
- package/dist/tsup/chunk-F3Q5BFQ6.js.map +0 -1
- package/dist/tsup/chunk-GVTOE34S.cjs.map +0 -1
- package/dist/tsup/chunk-H7P7WR2Y.js.map +0 -1
- package/dist/tsup/chunk-KIWH5H3K.js.map +0 -1
- package/dist/tsup/chunk-KJTA3ATT.js.map +0 -1
- package/dist/tsup/chunk-MMMEZM5J.js.map +0 -1
- package/dist/tsup/chunk-PCBNKI2J.js.map +0 -1
- package/dist/tsup/chunk-QAZLM4WT.cjs.map +0 -1
- package/dist/tsup/chunk-T6YVRM4K.js.map +0 -1
- package/dist/tsup/chunk-VJFRBJVQ.cjs.map +0 -1
- package/dist/tsup/chunk-VRCIXJRN.js.map +0 -1
- package/dist/tsup/chunk-W7EYSYVI.js.map +0 -1
- package/dist/tsup/chunk-WQ4HNA4W.cjs.map +0 -1
- package/dist/tsup/chunk-Y5NSCZA2.cjs.map +0 -1
- package/dist/tsup/context-B_IWbWne.d.ts +0 -92
- package/dist/tsup/context-CUrQ9MHc.d.cts +0 -92
- package/src/utils/serve.ts +0 -217
- /package/dist/tsup/{chunk-H37XQU3I.js.map → chunk-JBUZRPY5.js.map} +0 -0
package/src/registry/native.ts
CHANGED
|
@@ -2,8 +2,10 @@ import { VirtualWebSocket } from "@rivetkit/virtual-websocket";
|
|
|
2
2
|
import {
|
|
3
3
|
ACTOR_CONTEXT_INTERNAL_SYMBOL,
|
|
4
4
|
CONN_STATE_MANAGER_SYMBOL,
|
|
5
|
+
disposeRunInspector,
|
|
5
6
|
getRunFunction,
|
|
6
7
|
getRunInspectorConfig,
|
|
8
|
+
RAW_STATE_SYMBOL,
|
|
7
9
|
type WorkflowInspectorConfig,
|
|
8
10
|
} from "@/actor/config";
|
|
9
11
|
import type { AnyActorDefinition } from "@/actor/definition";
|
|
@@ -12,6 +14,7 @@ import {
|
|
|
12
14
|
encodeBridgeRivetError,
|
|
13
15
|
forbiddenError,
|
|
14
16
|
INTERNAL_ERROR_CODE,
|
|
17
|
+
isActorAbortedError,
|
|
15
18
|
isRivetErrorLike,
|
|
16
19
|
RivetError,
|
|
17
20
|
type RivetErrorLike,
|
|
@@ -32,6 +35,7 @@ import { convertRegistryConfigToClientConfig } from "@/client/config";
|
|
|
32
35
|
import { HEADER_CONN_PARAMS } from "@/common/actor-router-consts";
|
|
33
36
|
import type { AnyDatabaseProvider } from "@/common/database/config";
|
|
34
37
|
import { wrapJsNativeDatabase } from "@/common/database/native-database";
|
|
38
|
+
import { assertJsonCompatValue, type JsonCompatValue } from "@/common/encoding";
|
|
35
39
|
import { decodeWorkflowHistoryTransport } from "@/common/inspector-transport";
|
|
36
40
|
import { deconstructError, stringifyError } from "@/common/utils";
|
|
37
41
|
import type {
|
|
@@ -47,12 +51,13 @@ import type {
|
|
|
47
51
|
RuntimeKind,
|
|
48
52
|
SqliteBackend,
|
|
49
53
|
} from "@/registry/config";
|
|
50
|
-
import {
|
|
51
|
-
decodeCborCompat,
|
|
52
|
-
decodeCborJsonCompat,
|
|
53
|
-
encodeCborCompat,
|
|
54
|
-
} from "@/serde";
|
|
54
|
+
import { decodeCborCompat, encodeCborCompat } from "@/serde";
|
|
55
55
|
import { getEnvUniversal, VERSION } from "@/utils";
|
|
56
|
+
import {
|
|
57
|
+
getNodeFsSync,
|
|
58
|
+
getNodePath,
|
|
59
|
+
importNodeDependencies,
|
|
60
|
+
} from "@/utils/node";
|
|
56
61
|
import { logger } from "./log";
|
|
57
62
|
import { loadNapiRuntime } from "./napi-runtime";
|
|
58
63
|
import {
|
|
@@ -73,15 +78,18 @@ import type {
|
|
|
73
78
|
RuntimeActorConfig,
|
|
74
79
|
RuntimeBytes,
|
|
75
80
|
RuntimeHttpResponse,
|
|
81
|
+
RuntimeInspectorTabEntry,
|
|
76
82
|
RuntimeQueueMessage,
|
|
77
83
|
RuntimeServeConfig,
|
|
78
84
|
RuntimeStateDeltaPayload,
|
|
79
85
|
WebSocketHandle,
|
|
80
86
|
} from "./runtime";
|
|
81
87
|
import { loadWasmRuntime } from "./wasm-runtime";
|
|
88
|
+
import { createWriteThroughProxy } from "./write-through-proxy";
|
|
82
89
|
|
|
83
90
|
const textEncoder = new TextEncoder();
|
|
84
91
|
const textDecoder = new TextDecoder();
|
|
92
|
+
|
|
85
93
|
type ResolvedRuntimeKind = Exclude<RuntimeKind, "auto">;
|
|
86
94
|
type RuntimeHostKind = "node-like" | "edge-like";
|
|
87
95
|
export type RuntimeLoaders = {
|
|
@@ -91,6 +99,7 @@ export type RuntimeLoaders = {
|
|
|
91
99
|
) => ReturnType<typeof loadWasmRuntime>;
|
|
92
100
|
detectHost: () => RuntimeHostKind;
|
|
93
101
|
};
|
|
102
|
+
|
|
94
103
|
type SerializeStateReason = "save" | "inspector";
|
|
95
104
|
type NativeOnStateChangeHandler = (
|
|
96
105
|
ctx: ActorContextHandleAdapter,
|
|
@@ -345,6 +354,15 @@ function databaseNotConfiguredError(): RivetError {
|
|
|
345
354
|
);
|
|
346
355
|
}
|
|
347
356
|
|
|
357
|
+
function databaseClientNotReadyError(): RivetError {
|
|
358
|
+
return new RivetError(
|
|
359
|
+
"actor",
|
|
360
|
+
"database_client_not_ready",
|
|
361
|
+
"actor database client was not initialized before user code ran. this is an internal lifecycle error; the migration callback should have pre-warmed the client. file an issue if you can reproduce.",
|
|
362
|
+
{ public: true },
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
348
366
|
function stateNotEnabledError(): RivetError {
|
|
349
367
|
return new RivetError(
|
|
350
368
|
"actor",
|
|
@@ -413,8 +431,33 @@ function clearNativeRuntimeState(
|
|
|
413
431
|
async function cleanupNativeSleepRuntimeState(
|
|
414
432
|
runtime: CoreRuntime,
|
|
415
433
|
ctx: ActorContextHandle,
|
|
434
|
+
afterTrackedWorkDrained?: () => Promise<void>,
|
|
416
435
|
): Promise<void> {
|
|
417
|
-
|
|
436
|
+
// The bounded wait gives shutdown work one grace-period chance to finish.
|
|
437
|
+
// Drained means all tracked shutdown work completed before the deadline, so
|
|
438
|
+
// we can save final state and clear runtime state immediately. If it did not
|
|
439
|
+
// drain, close database handles now, then defer the final save and clear until
|
|
440
|
+
// the tracked work finishes without a deadline.
|
|
441
|
+
const drained = await runtime.actorWaitForTrackedShutdownWork(ctx);
|
|
442
|
+
if (!drained) {
|
|
443
|
+
await closeNativeDatabaseClient(runtime, ctx);
|
|
444
|
+
await closeNativeSqlDatabase(runtime, ctx);
|
|
445
|
+
void runtime
|
|
446
|
+
.actorWaitForTrackedShutdownWorkUnbounded(ctx)
|
|
447
|
+
.then(async () => {
|
|
448
|
+
await afterTrackedWorkDrained?.();
|
|
449
|
+
clearNativeRuntimeState(runtime, ctx);
|
|
450
|
+
})
|
|
451
|
+
.catch((error) => {
|
|
452
|
+
logger().warn({
|
|
453
|
+
msg: "deferred native sleep cleanup failed",
|
|
454
|
+
error: stringifyError(error),
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
await afterTrackedWorkDrained?.();
|
|
418
461
|
await closeNativeDatabaseClient(runtime, ctx);
|
|
419
462
|
await closeNativeSqlDatabase(runtime, ctx);
|
|
420
463
|
clearNativeRuntimeState(runtime, ctx);
|
|
@@ -587,11 +630,19 @@ function decodeValue<T>(value?: RuntimeBytes | null): T {
|
|
|
587
630
|
return undefined as T;
|
|
588
631
|
}
|
|
589
632
|
|
|
590
|
-
return
|
|
633
|
+
return decodeCborCompat(value);
|
|
591
634
|
}
|
|
592
635
|
|
|
593
636
|
function encodeValue(value: unknown): RuntimeBytes {
|
|
594
|
-
return encodeCborCompat(value);
|
|
637
|
+
return encodeCborCompat(value as JsonCompatValue);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
function normalizeArgs(value: unknown): unknown[] {
|
|
641
|
+
return Array.isArray(value)
|
|
642
|
+
? value
|
|
643
|
+
: value === undefined || value === null
|
|
644
|
+
? []
|
|
645
|
+
: [value];
|
|
595
646
|
}
|
|
596
647
|
|
|
597
648
|
function unwrapTsfnPayload<T>(error: unknown, payload: T): T {
|
|
@@ -924,6 +975,7 @@ function serializeWorkflowEntryKind(
|
|
|
924
975
|
}
|
|
925
976
|
}
|
|
926
977
|
|
|
978
|
+
// TODO: Switch inspector routes to CBOR encoding
|
|
927
979
|
function serializeWorkflowHistoryForJson(data: ArrayBuffer | null): {
|
|
928
980
|
nameRegistry: string[];
|
|
929
981
|
entries: Array<{
|
|
@@ -957,7 +1009,7 @@ function serializeWorkflowHistoryForJson(data: ArrayBuffer | null): {
|
|
|
957
1009
|
|
|
958
1010
|
const history = decodeWorkflowHistoryTransport(data);
|
|
959
1011
|
|
|
960
|
-
return {
|
|
1012
|
+
return jsonSafe({
|
|
961
1013
|
nameRegistry: [...history.nameRegistry],
|
|
962
1014
|
entries: history.entries.map((entry) => ({
|
|
963
1015
|
id: entry.id,
|
|
@@ -987,7 +1039,7 @@ function serializeWorkflowHistoryForJson(data: ArrayBuffer | null): {
|
|
|
987
1039
|
],
|
|
988
1040
|
),
|
|
989
1041
|
),
|
|
990
|
-
};
|
|
1042
|
+
});
|
|
991
1043
|
}
|
|
992
1044
|
|
|
993
1045
|
function toHttpJsonCompatible<T>(value: T): T {
|
|
@@ -1059,60 +1111,7 @@ function wrapNativeCallback<Args extends Array<unknown>, Result>(
|
|
|
1059
1111
|
|
|
1060
1112
|
function decodeArgs(value?: RuntimeBytes | null): unknown[] {
|
|
1061
1113
|
const decoded = decodeValue<unknown>(value);
|
|
1062
|
-
return
|
|
1063
|
-
? decoded
|
|
1064
|
-
: decoded === undefined
|
|
1065
|
-
? []
|
|
1066
|
-
: [decoded];
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
function createWriteThroughProxy<T>(
|
|
1070
|
-
value: T,
|
|
1071
|
-
commit: (next: T) => void,
|
|
1072
|
-
beforeChange?: () => void,
|
|
1073
|
-
): T {
|
|
1074
|
-
if (!value || typeof value !== "object") {
|
|
1075
|
-
return value;
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
const proxies = new WeakMap<object, object>();
|
|
1079
|
-
const wrap = (target: object): object => {
|
|
1080
|
-
const cached = proxies.get(target);
|
|
1081
|
-
if (cached) {
|
|
1082
|
-
return cached;
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
const proxy = new Proxy(target, {
|
|
1086
|
-
get(innerTarget, property, receiver) {
|
|
1087
|
-
const result = Reflect.get(innerTarget, property, receiver);
|
|
1088
|
-
return result && typeof result === "object"
|
|
1089
|
-
? wrap(result as object)
|
|
1090
|
-
: result;
|
|
1091
|
-
},
|
|
1092
|
-
set(innerTarget, property, nextValue, receiver) {
|
|
1093
|
-
beforeChange?.();
|
|
1094
|
-
const updated = Reflect.set(
|
|
1095
|
-
innerTarget,
|
|
1096
|
-
property,
|
|
1097
|
-
nextValue,
|
|
1098
|
-
receiver,
|
|
1099
|
-
);
|
|
1100
|
-
commit(value);
|
|
1101
|
-
return updated;
|
|
1102
|
-
},
|
|
1103
|
-
deleteProperty(innerTarget, property) {
|
|
1104
|
-
beforeChange?.();
|
|
1105
|
-
const updated = Reflect.deleteProperty(innerTarget, property);
|
|
1106
|
-
commit(value);
|
|
1107
|
-
return updated;
|
|
1108
|
-
},
|
|
1109
|
-
});
|
|
1110
|
-
|
|
1111
|
-
proxies.set(target, proxy);
|
|
1112
|
-
return proxy;
|
|
1113
|
-
};
|
|
1114
|
-
|
|
1115
|
-
return wrap(value as object) as T;
|
|
1114
|
+
return normalizeArgs(decoded);
|
|
1116
1115
|
}
|
|
1117
1116
|
|
|
1118
1117
|
function buildRequest(init: {
|
|
@@ -1204,14 +1203,25 @@ class NativeConnAdapter {
|
|
|
1204
1203
|
);
|
|
1205
1204
|
}
|
|
1206
1205
|
|
|
1206
|
+
[RAW_STATE_SYMBOL](): unknown {
|
|
1207
|
+
return this.#readState();
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1207
1210
|
get state(): unknown {
|
|
1208
1211
|
const nextState = this.#readState();
|
|
1209
|
-
return createWriteThroughProxy(
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
+
return createWriteThroughProxy(
|
|
1213
|
+
nextState,
|
|
1214
|
+
(nextValue) => {
|
|
1215
|
+
this.#writeState(nextValue, { writeNative: true });
|
|
1216
|
+
},
|
|
1217
|
+
(newValue) => {
|
|
1218
|
+
assertJsonCompatValue(newValue);
|
|
1219
|
+
},
|
|
1220
|
+
);
|
|
1212
1221
|
}
|
|
1213
1222
|
|
|
1214
1223
|
set state(value: unknown) {
|
|
1224
|
+
assertJsonCompatValue(value);
|
|
1215
1225
|
this.#writeState(value, { writeNative: true });
|
|
1216
1226
|
}
|
|
1217
1227
|
|
|
@@ -1683,7 +1693,12 @@ class NativeQueueAdapter {
|
|
|
1683
1693
|
signal?: AbortSignal;
|
|
1684
1694
|
},
|
|
1685
1695
|
) {
|
|
1686
|
-
|
|
1696
|
+
const { token, cleanup } = await createCancellationTokenHandle(
|
|
1697
|
+
this.#runtime,
|
|
1698
|
+
options?.signal,
|
|
1699
|
+
);
|
|
1700
|
+
|
|
1701
|
+
try {
|
|
1687
1702
|
await callNative(() =>
|
|
1688
1703
|
this.#runtime.actorQueueWaitForNamesAvailable(
|
|
1689
1704
|
this.#ctx,
|
|
@@ -1691,57 +1706,11 @@ class NativeQueueAdapter {
|
|
|
1691
1706
|
{
|
|
1692
1707
|
timeoutMs: options?.timeout,
|
|
1693
1708
|
},
|
|
1709
|
+
token,
|
|
1694
1710
|
),
|
|
1695
1711
|
);
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
const deadline =
|
|
1700
|
-
options.timeout === undefined
|
|
1701
|
-
? undefined
|
|
1702
|
-
: Date.now() + options.timeout;
|
|
1703
|
-
|
|
1704
|
-
for (;;) {
|
|
1705
|
-
if (options.signal.aborted) {
|
|
1706
|
-
throw actorAbortedError();
|
|
1707
|
-
}
|
|
1708
|
-
|
|
1709
|
-
const remainingTimeout =
|
|
1710
|
-
deadline === undefined
|
|
1711
|
-
? undefined
|
|
1712
|
-
: Math.max(0, deadline - Date.now());
|
|
1713
|
-
const sliceTimeout =
|
|
1714
|
-
remainingTimeout === undefined
|
|
1715
|
-
? 100
|
|
1716
|
-
: Math.min(remainingTimeout, 100);
|
|
1717
|
-
|
|
1718
|
-
try {
|
|
1719
|
-
await callNative(() =>
|
|
1720
|
-
this.#runtime.actorQueueWaitForNamesAvailable(
|
|
1721
|
-
this.#ctx,
|
|
1722
|
-
[...names],
|
|
1723
|
-
{
|
|
1724
|
-
timeoutMs: sliceTimeout,
|
|
1725
|
-
},
|
|
1726
|
-
),
|
|
1727
|
-
);
|
|
1728
|
-
return;
|
|
1729
|
-
} catch (error) {
|
|
1730
|
-
if (
|
|
1731
|
-
(error as { group?: string; code?: string }).group ===
|
|
1732
|
-
"queue" &&
|
|
1733
|
-
(error as { group?: string; code?: string }).code ===
|
|
1734
|
-
"timed_out"
|
|
1735
|
-
) {
|
|
1736
|
-
if (
|
|
1737
|
-
remainingTimeout === undefined ||
|
|
1738
|
-
remainingTimeout > 100
|
|
1739
|
-
) {
|
|
1740
|
-
continue;
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
throw error;
|
|
1744
|
-
}
|
|
1712
|
+
} finally {
|
|
1713
|
+
cleanup?.();
|
|
1745
1714
|
}
|
|
1746
1715
|
}
|
|
1747
1716
|
|
|
@@ -1844,11 +1813,7 @@ class NativeQueueAdapter {
|
|
|
1844
1813
|
}
|
|
1845
1814
|
yield message;
|
|
1846
1815
|
} catch (error) {
|
|
1847
|
-
if (
|
|
1848
|
-
isRivetErrorLike(error) &&
|
|
1849
|
-
error.group === "actor" &&
|
|
1850
|
-
error.code === "aborted"
|
|
1851
|
-
) {
|
|
1816
|
+
if (isActorAbortedError(error)) {
|
|
1852
1817
|
return;
|
|
1853
1818
|
}
|
|
1854
1819
|
throw error;
|
|
@@ -2323,6 +2288,104 @@ class TrackedWebSocketHandleAdapter implements UniversalWebSocket {
|
|
|
2323
2288
|
}
|
|
2324
2289
|
}
|
|
2325
2290
|
|
|
2291
|
+
class NativeConnectionMap implements ReadonlyMap<string, NativeConnAdapter> {
|
|
2292
|
+
#runtime: CoreRuntime;
|
|
2293
|
+
#ctx: ActorContextHandle;
|
|
2294
|
+
#schemas: NativeValidationConfig;
|
|
2295
|
+
|
|
2296
|
+
constructor(
|
|
2297
|
+
runtime: CoreRuntime,
|
|
2298
|
+
ctx: ActorContextHandle,
|
|
2299
|
+
schemas: NativeValidationConfig,
|
|
2300
|
+
) {
|
|
2301
|
+
this.#runtime = runtime;
|
|
2302
|
+
this.#ctx = ctx;
|
|
2303
|
+
this.#schemas = schemas;
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
#connToAdapter(conn: ConnHandle): NativeConnAdapter {
|
|
2307
|
+
return new NativeConnAdapter(
|
|
2308
|
+
this.#runtime,
|
|
2309
|
+
conn,
|
|
2310
|
+
this.#schemas,
|
|
2311
|
+
this.#ctx,
|
|
2312
|
+
(connId) =>
|
|
2313
|
+
callNativeSync(() =>
|
|
2314
|
+
this.#runtime.actorQueueHibernationRemoval(
|
|
2315
|
+
this.#ctx,
|
|
2316
|
+
connId,
|
|
2317
|
+
),
|
|
2318
|
+
),
|
|
2319
|
+
);
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
get size(): number {
|
|
2323
|
+
return callNativeSync(() => this.#runtime.actorConns(this.#ctx)).length;
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
get(key: string): NativeConnAdapter | undefined {
|
|
2327
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2328
|
+
const conn = conns.find((c) => this.#runtime.connId(c) === key);
|
|
2329
|
+
if (!conn) return undefined;
|
|
2330
|
+
return this.#connToAdapter(conn);
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
has(key: string): boolean {
|
|
2334
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2335
|
+
return conns.some((c) => this.#runtime.connId(c) === key);
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
keys(): MapIterator<string> {
|
|
2339
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2340
|
+
return conns
|
|
2341
|
+
.map((c) => this.#runtime.connId(c))
|
|
2342
|
+
[Symbol.iterator]() satisfies MapIterator<string>;
|
|
2343
|
+
}
|
|
2344
|
+
|
|
2345
|
+
values(): MapIterator<NativeConnAdapter> {
|
|
2346
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2347
|
+
return conns
|
|
2348
|
+
.map((c) => this.#connToAdapter(c))
|
|
2349
|
+
[Symbol.iterator]() satisfies MapIterator<NativeConnAdapter>;
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
entries(): MapIterator<[string, NativeConnAdapter]> {
|
|
2353
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2354
|
+
return conns
|
|
2355
|
+
.map(
|
|
2356
|
+
(c) =>
|
|
2357
|
+
[this.#runtime.connId(c), this.#connToAdapter(c)] as [
|
|
2358
|
+
string,
|
|
2359
|
+
NativeConnAdapter,
|
|
2360
|
+
],
|
|
2361
|
+
)
|
|
2362
|
+
[Symbol.iterator]() satisfies MapIterator<
|
|
2363
|
+
[string, NativeConnAdapter]
|
|
2364
|
+
>;
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
forEach(
|
|
2368
|
+
callback: (
|
|
2369
|
+
value: NativeConnAdapter,
|
|
2370
|
+
key: string,
|
|
2371
|
+
map: ReadonlyMap<string, NativeConnAdapter>,
|
|
2372
|
+
) => void,
|
|
2373
|
+
thisArg?: unknown,
|
|
2374
|
+
): void {
|
|
2375
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2376
|
+
for (const conn of conns) {
|
|
2377
|
+
const id = this.#runtime.connId(conn);
|
|
2378
|
+
callback.call(thisArg, this.#connToAdapter(conn), id, this);
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
[Symbol.iterator](): MapIterator<[string, NativeConnAdapter]> {
|
|
2383
|
+
return this.entries();
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
readonly [Symbol.toStringTag] = "NativeConnectionMap";
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2326
2389
|
export class ActorContextHandleAdapter {
|
|
2327
2390
|
#runtime: CoreRuntime;
|
|
2328
2391
|
#ctx: ActorContextHandle;
|
|
@@ -2331,9 +2394,9 @@ export class ActorContextHandleAdapter {
|
|
|
2331
2394
|
#abortSignalCleanup?: () => void;
|
|
2332
2395
|
#client?: AnyClient;
|
|
2333
2396
|
#clientFactory?: () => AnyClient;
|
|
2397
|
+
#connMap?: NativeConnectionMap;
|
|
2334
2398
|
#databaseProvider?: Exclude<AnyDatabaseProvider, undefined>;
|
|
2335
2399
|
#db?: unknown;
|
|
2336
|
-
#dbProxy?: unknown;
|
|
2337
2400
|
#dispatchCancelToken?: CancellationTokenHandle;
|
|
2338
2401
|
#kv?: NativeKvAdapter;
|
|
2339
2402
|
#queue?: NativeQueueAdapter;
|
|
@@ -2396,32 +2459,25 @@ export class ActorContextHandleAdapter {
|
|
|
2396
2459
|
throw databaseNotConfiguredError();
|
|
2397
2460
|
}
|
|
2398
2461
|
|
|
2399
|
-
if (
|
|
2400
|
-
this.#
|
|
2401
|
-
|
|
2402
|
-
{
|
|
2403
|
-
get: (_target, property) => {
|
|
2404
|
-
if (property === "then") {
|
|
2405
|
-
return undefined;
|
|
2406
|
-
}
|
|
2462
|
+
if (this.#db) {
|
|
2463
|
+
return this.#db;
|
|
2464
|
+
}
|
|
2407
2465
|
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
);
|
|
2414
|
-
if (typeof value !== "function") {
|
|
2415
|
-
return value;
|
|
2416
|
-
}
|
|
2417
|
-
return await value.apply(client, args);
|
|
2418
|
-
};
|
|
2419
|
-
},
|
|
2420
|
-
},
|
|
2421
|
-
);
|
|
2466
|
+
const runtimeState = getNativeRuntimeState(this.#runtime, this.#ctx);
|
|
2467
|
+
const cachedClient = runtimeState.databaseClient;
|
|
2468
|
+
if (cachedClient) {
|
|
2469
|
+
this.#db = cachedClient.client;
|
|
2470
|
+
return this.#db;
|
|
2422
2471
|
}
|
|
2423
2472
|
|
|
2424
|
-
|
|
2473
|
+
throw databaseClientNotReadyError();
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
[RAW_STATE_SYMBOL](): unknown {
|
|
2477
|
+
if (!this.#stateEnabled) {
|
|
2478
|
+
throw stateNotEnabledError();
|
|
2479
|
+
}
|
|
2480
|
+
return this.#readState();
|
|
2425
2481
|
}
|
|
2426
2482
|
|
|
2427
2483
|
get state(): unknown {
|
|
@@ -2444,8 +2500,9 @@ export class ActorContextHandleAdapter {
|
|
|
2444
2500
|
(nextValue) => {
|
|
2445
2501
|
this.#writeState(nextValue, { scheduleSave: true });
|
|
2446
2502
|
},
|
|
2447
|
-
() => {
|
|
2503
|
+
(newValue) => {
|
|
2448
2504
|
this.#assertCanMutateState();
|
|
2505
|
+
assertJsonCompatValue(newValue);
|
|
2449
2506
|
},
|
|
2450
2507
|
);
|
|
2451
2508
|
}
|
|
@@ -2457,6 +2514,7 @@ export class ActorContextHandleAdapter {
|
|
|
2457
2514
|
throw stateNotEnabledError();
|
|
2458
2515
|
}
|
|
2459
2516
|
this.#assertCanMutateState();
|
|
2517
|
+
assertJsonCompatValue(value);
|
|
2460
2518
|
this.#writeState(value, { scheduleSave: true });
|
|
2461
2519
|
}
|
|
2462
2520
|
|
|
@@ -2523,27 +2581,15 @@ export class ActorContextHandleAdapter {
|
|
|
2523
2581
|
return callNativeSync(() => this.#runtime.actorRegion(this.#ctx));
|
|
2524
2582
|
}
|
|
2525
2583
|
|
|
2526
|
-
get conns():
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
this.#ctx,
|
|
2536
|
-
(connId) =>
|
|
2537
|
-
callNativeSync(() =>
|
|
2538
|
-
this.#runtime.actorQueueHibernationRemoval(
|
|
2539
|
-
this.#ctx,
|
|
2540
|
-
connId,
|
|
2541
|
-
),
|
|
2542
|
-
),
|
|
2543
|
-
),
|
|
2544
|
-
],
|
|
2545
|
-
),
|
|
2546
|
-
);
|
|
2584
|
+
get conns(): ReadonlyMap<string, NativeConnAdapter> {
|
|
2585
|
+
if (!this.#connMap) {
|
|
2586
|
+
this.#connMap = new NativeConnectionMap(
|
|
2587
|
+
this.#runtime,
|
|
2588
|
+
this.#ctx,
|
|
2589
|
+
this.#schemas,
|
|
2590
|
+
);
|
|
2591
|
+
}
|
|
2592
|
+
return this.#connMap;
|
|
2547
2593
|
}
|
|
2548
2594
|
|
|
2549
2595
|
get log() {
|
|
@@ -2800,7 +2846,15 @@ export class ActorContextHandleAdapter {
|
|
|
2800
2846
|
|
|
2801
2847
|
internalKeepAwake<T>(run: Promise<T> | (() => Promise<T>)): Promise<T> {
|
|
2802
2848
|
const promise = typeof run === "function" ? run() : run;
|
|
2803
|
-
|
|
2849
|
+
// Track only completion, swallowing the outcome. The real result/error
|
|
2850
|
+
// is delivered through the returned `promise`; without a rejection
|
|
2851
|
+
// handler here every workflow yield (which rejects with SleepError)
|
|
2852
|
+
// would be funneled into the registered task and logged as a spurious
|
|
2853
|
+
// "keep_awake promise rejected" warning.
|
|
2854
|
+
const trackedPromise = promise.then(
|
|
2855
|
+
() => null,
|
|
2856
|
+
() => null,
|
|
2857
|
+
);
|
|
2804
2858
|
try {
|
|
2805
2859
|
callNativeSync(() =>
|
|
2806
2860
|
this.#runtime.actorRegisterTask(this.#ctx, trackedPromise),
|
|
@@ -2862,6 +2916,7 @@ export class ActorContextHandleAdapter {
|
|
|
2862
2916
|
}
|
|
2863
2917
|
|
|
2864
2918
|
sleep(): void {
|
|
2919
|
+
this.#flushStateChange();
|
|
2865
2920
|
callNativeSync(() => this.#runtime.actorSleep(this.#ctx));
|
|
2866
2921
|
}
|
|
2867
2922
|
|
|
@@ -3232,6 +3287,7 @@ function withConnContext(
|
|
|
3232
3287
|
function buildActorConfig(
|
|
3233
3288
|
definition: AnyActorDefinition,
|
|
3234
3289
|
registryConfig: RegistryConfig,
|
|
3290
|
+
runtimeKind: "napi" | "wasm",
|
|
3235
3291
|
): RuntimeActorConfig {
|
|
3236
3292
|
const config = definition.config as unknown as Record<string, unknown>;
|
|
3237
3293
|
const options = (config.options ?? {}) as Record<string, unknown>;
|
|
@@ -3286,9 +3342,100 @@ function buildActorConfig(
|
|
|
3286
3342
|
actions: Object.keys((config.actions ?? {}) as Record<string, unknown>)
|
|
3287
3343
|
.sort()
|
|
3288
3344
|
.map((name) => ({ name })),
|
|
3345
|
+
inspectorTabs: buildInspectorTabs(config.inspector, runtimeKind),
|
|
3289
3346
|
};
|
|
3290
3347
|
}
|
|
3291
3348
|
|
|
3349
|
+
function buildInspectorTabs(
|
|
3350
|
+
inspector: unknown,
|
|
3351
|
+
runtimeKind: "napi" | "wasm",
|
|
3352
|
+
): Array<RuntimeInspectorTabEntry> | undefined {
|
|
3353
|
+
if (!inspector || typeof inspector !== "object") return undefined;
|
|
3354
|
+
const tabs = (inspector as { tabs?: unknown }).tabs;
|
|
3355
|
+
if (!Array.isArray(tabs) || tabs.length === 0) return undefined;
|
|
3356
|
+
return tabs.map((raw) => {
|
|
3357
|
+
const entry = raw as {
|
|
3358
|
+
id: string;
|
|
3359
|
+
label?: string;
|
|
3360
|
+
source?: string;
|
|
3361
|
+
icon?: string;
|
|
3362
|
+
hidden?: boolean;
|
|
3363
|
+
};
|
|
3364
|
+
if (entry.hidden === true) {
|
|
3365
|
+
return { id: entry.id, hidden: true };
|
|
3366
|
+
}
|
|
3367
|
+
|
|
3368
|
+
if (runtimeKind === "wasm") {
|
|
3369
|
+
if (entry.source !== undefined) {
|
|
3370
|
+
logger().warn(
|
|
3371
|
+
{
|
|
3372
|
+
tabId: entry.id,
|
|
3373
|
+
runtimeKind,
|
|
3374
|
+
},
|
|
3375
|
+
"inspector.tabs[].source is not supported on wasm runners (current host: wasm). Tab descriptors will still appear in the dashboard strip but the tab body will render a not-available placeholder.",
|
|
3376
|
+
);
|
|
3377
|
+
}
|
|
3378
|
+
return {
|
|
3379
|
+
id: entry.id,
|
|
3380
|
+
label: entry.label,
|
|
3381
|
+
icon: entry.icon,
|
|
3382
|
+
source: undefined,
|
|
3383
|
+
};
|
|
3384
|
+
}
|
|
3385
|
+
|
|
3386
|
+
const resolved =
|
|
3387
|
+
entry.source !== undefined
|
|
3388
|
+
? getNodePath().resolve(entry.source)
|
|
3389
|
+
: undefined;
|
|
3390
|
+
if (resolved !== undefined) {
|
|
3391
|
+
validateInspectorTabSource(entry.id, resolved);
|
|
3392
|
+
}
|
|
3393
|
+
return {
|
|
3394
|
+
id: entry.id,
|
|
3395
|
+
label: entry.label,
|
|
3396
|
+
icon: entry.icon,
|
|
3397
|
+
source: resolved,
|
|
3398
|
+
};
|
|
3399
|
+
});
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3402
|
+
function validateInspectorTabSource(tabId: string, resolved: string): void {
|
|
3403
|
+
if (resolved === getNodePath().parse(resolved).root) {
|
|
3404
|
+
throw new Error(
|
|
3405
|
+
`inspector.tabs[id="${tabId}"].source resolves to the filesystem root (${resolved}). ` +
|
|
3406
|
+
"Point it at the tab's own static-asset directory instead.",
|
|
3407
|
+
);
|
|
3408
|
+
}
|
|
3409
|
+
let stat: import("node:fs").Stats;
|
|
3410
|
+
try {
|
|
3411
|
+
stat = getNodeFsSync().statSync(resolved);
|
|
3412
|
+
} catch (err) {
|
|
3413
|
+
const code = (err as NodeJS.ErrnoException)?.code;
|
|
3414
|
+
if (code === "ENOENT") {
|
|
3415
|
+
throw new Error(
|
|
3416
|
+
`inspector.tabs[id="${tabId}"].source (${resolved}) does not exist.`,
|
|
3417
|
+
);
|
|
3418
|
+
}
|
|
3419
|
+
if (code === "EACCES") {
|
|
3420
|
+
throw new Error(
|
|
3421
|
+
`inspector.tabs[id="${tabId}"].source (${resolved}) is not readable (EACCES).`,
|
|
3422
|
+
);
|
|
3423
|
+
}
|
|
3424
|
+
throw new Error(
|
|
3425
|
+
`inspector.tabs[id="${tabId}"].source (${resolved}) could not be stat'd: ${
|
|
3426
|
+
(err as Error)?.message ?? err
|
|
3427
|
+
}`,
|
|
3428
|
+
);
|
|
3429
|
+
}
|
|
3430
|
+
if (!stat.isDirectory()) {
|
|
3431
|
+
throw new Error(
|
|
3432
|
+
`inspector.tabs[id="${tabId}"].source (${resolved}) must be a directory, got ${
|
|
3433
|
+
stat.isFile() ? "file" : "non-directory"
|
|
3434
|
+
}.`,
|
|
3435
|
+
);
|
|
3436
|
+
}
|
|
3437
|
+
}
|
|
3438
|
+
|
|
3292
3439
|
export function buildNativeFactory(
|
|
3293
3440
|
runtime: CoreRuntime,
|
|
3294
3441
|
registryConfig: RegistryConfig,
|
|
@@ -3420,15 +3567,23 @@ export function buildNativeFactory(
|
|
|
3420
3567
|
},
|
|
3421
3568
|
);
|
|
3422
3569
|
};
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3570
|
+
|
|
3571
|
+
const isPublicPerActorPath =
|
|
3572
|
+
jsRequest.method === "GET" &&
|
|
3573
|
+
(url.pathname === "/inspector/tab-config" ||
|
|
3574
|
+
url.pathname.startsWith("/inspector/custom-tabs/"));
|
|
3575
|
+
|
|
3576
|
+
if (!isPublicPerActorPath) {
|
|
3577
|
+
try {
|
|
3578
|
+
await runtime.actorVerifyInspectorAuth(
|
|
3579
|
+
ctx,
|
|
3580
|
+
jsRequest.headers
|
|
3581
|
+
.get("authorization")
|
|
3582
|
+
?.replace(/^Bearer\s+/i, "") ?? null,
|
|
3583
|
+
);
|
|
3584
|
+
} catch (error) {
|
|
3585
|
+
return errorResponse(error, 401);
|
|
3586
|
+
}
|
|
3432
3587
|
}
|
|
3433
3588
|
|
|
3434
3589
|
const workflowHistory = () =>
|
|
@@ -3548,6 +3703,10 @@ export function buildNativeFactory(
|
|
|
3548
3703
|
getNativeWorkflowInspector(ctx) !== undefined,
|
|
3549
3704
|
});
|
|
3550
3705
|
} catch (error) {
|
|
3706
|
+
logger().error({
|
|
3707
|
+
msg: "error replaying workflow history",
|
|
3708
|
+
error,
|
|
3709
|
+
});
|
|
3551
3710
|
return errorResponse(error);
|
|
3552
3711
|
}
|
|
3553
3712
|
}
|
|
@@ -3715,18 +3874,46 @@ export function buildNativeFactory(
|
|
|
3715
3874
|
404,
|
|
3716
3875
|
);
|
|
3717
3876
|
}
|
|
3718
|
-
const body = (await jsRequest.json()) as {
|
|
3877
|
+
const body = (await jsRequest.json()) as {
|
|
3878
|
+
args?: unknown;
|
|
3879
|
+
properties?: unknown;
|
|
3880
|
+
};
|
|
3881
|
+
if (body.args !== undefined && body.properties !== undefined) {
|
|
3882
|
+
return jsonResponse(
|
|
3883
|
+
{ error: "use either args or properties, not both" },
|
|
3884
|
+
{ status: 400 },
|
|
3885
|
+
);
|
|
3886
|
+
}
|
|
3887
|
+
if (
|
|
3888
|
+
body.properties !== undefined &&
|
|
3889
|
+
(body.properties === null ||
|
|
3890
|
+
typeof body.properties !== "object" ||
|
|
3891
|
+
Array.isArray(body.properties))
|
|
3892
|
+
) {
|
|
3893
|
+
return jsonResponse(
|
|
3894
|
+
{ error: "properties must be an object" },
|
|
3895
|
+
{ status: 400 },
|
|
3896
|
+
);
|
|
3897
|
+
}
|
|
3898
|
+
const args =
|
|
3899
|
+
body.properties !== undefined
|
|
3900
|
+
? [body.properties]
|
|
3901
|
+
: normalizeArgs(body.args);
|
|
3719
3902
|
try {
|
|
3720
3903
|
const output = await action(
|
|
3721
3904
|
actorCtx,
|
|
3722
3905
|
...validateActionArgs(
|
|
3723
3906
|
schemaConfig.actionInputSchemas,
|
|
3724
3907
|
actionName,
|
|
3725
|
-
|
|
3908
|
+
args,
|
|
3726
3909
|
),
|
|
3727
3910
|
);
|
|
3728
3911
|
return jsonResponse({ output });
|
|
3729
3912
|
} catch (error) {
|
|
3913
|
+
logger().error({
|
|
3914
|
+
msg: "Error handling inspector action request",
|
|
3915
|
+
error,
|
|
3916
|
+
});
|
|
3730
3917
|
return errorResponse(error);
|
|
3731
3918
|
}
|
|
3732
3919
|
}
|
|
@@ -3741,6 +3928,10 @@ export function buildNativeFactory(
|
|
|
3741
3928
|
{ status: 404 },
|
|
3742
3929
|
);
|
|
3743
3930
|
} catch (error) {
|
|
3931
|
+
logger().error({
|
|
3932
|
+
msg: "Error handling inspector request",
|
|
3933
|
+
error,
|
|
3934
|
+
});
|
|
3744
3935
|
return errorResponse(error);
|
|
3745
3936
|
} finally {
|
|
3746
3937
|
await actorCtx.dispose();
|
|
@@ -3913,26 +4104,35 @@ export function buildNativeFactory(
|
|
|
3913
4104
|
async (error: unknown, payload: { ctx: ActorContextHandle }) => {
|
|
3914
4105
|
const { ctx } = unwrapTsfnPayload(error, payload);
|
|
3915
4106
|
const actorCtx = makeActorCtx(ctx);
|
|
4107
|
+
// TODO: Move this save hook into cleanupNativeSleepRuntimeState
|
|
4108
|
+
// so immediate and deferred sleep cleanup share one save-state
|
|
4109
|
+
// path instead of passing a callback through cleanup.
|
|
4110
|
+
const saveActorState = async () => {
|
|
4111
|
+
if (runtime.kind === "wasm") {
|
|
4112
|
+
// Wasm cannot use the native context save helper here because
|
|
4113
|
+
// the runtime owns the serialized state handoff.
|
|
4114
|
+
await runtime.actorSaveState(
|
|
4115
|
+
ctx,
|
|
4116
|
+
actorCtx.serializeForTick("save"),
|
|
4117
|
+
);
|
|
4118
|
+
} else {
|
|
4119
|
+
await actorCtx.saveState({
|
|
4120
|
+
immediate: true,
|
|
4121
|
+
});
|
|
4122
|
+
}
|
|
4123
|
+
};
|
|
3916
4124
|
try {
|
|
3917
4125
|
if (onSleep) {
|
|
3918
|
-
|
|
3919
|
-
await onSleep(actorCtx);
|
|
3920
|
-
} finally {
|
|
3921
|
-
if (runtime.kind === "wasm") {
|
|
3922
|
-
// Wasm cannot use the native context save helper here because
|
|
3923
|
-
// the runtime owns the serialized state handoff.
|
|
3924
|
-
await runtime.actorSaveState(
|
|
3925
|
-
ctx,
|
|
3926
|
-
actorCtx.serializeForTick("save"),
|
|
3927
|
-
);
|
|
3928
|
-
} else {
|
|
3929
|
-
await actorCtx.saveState({ immediate: true });
|
|
3930
|
-
}
|
|
3931
|
-
}
|
|
4126
|
+
await onSleep(actorCtx);
|
|
3932
4127
|
}
|
|
4128
|
+
await saveActorState();
|
|
3933
4129
|
} finally {
|
|
3934
4130
|
try {
|
|
3935
|
-
await cleanupNativeSleepRuntimeState(
|
|
4131
|
+
await cleanupNativeSleepRuntimeState(
|
|
4132
|
+
runtime,
|
|
4133
|
+
ctx,
|
|
4134
|
+
saveActorState,
|
|
4135
|
+
);
|
|
3936
4136
|
} finally {
|
|
3937
4137
|
await actorCtx.dispose();
|
|
3938
4138
|
}
|
|
@@ -3948,6 +4148,11 @@ export function buildNativeFactory(
|
|
|
3948
4148
|
await config.onDestroy(actorCtx);
|
|
3949
4149
|
}
|
|
3950
4150
|
} finally {
|
|
4151
|
+
const actorId = callNativeSync(() => runtime.actorId(ctx));
|
|
4152
|
+
// Release actorId-keyed state so it does not accumulate per
|
|
4153
|
+
// destroyed actor.
|
|
4154
|
+
nativeRunHandlerActiveByActorId.delete(actorId);
|
|
4155
|
+
disposeRunInspector(config.run, actorId);
|
|
3951
4156
|
resolveNativeDestroy(runtime, ctx);
|
|
3952
4157
|
await actorCtx.closeDatabase();
|
|
3953
4158
|
clearNativeRuntimeState(runtime, ctx);
|
|
@@ -4351,7 +4556,11 @@ export function buildNativeFactory(
|
|
|
4351
4556
|
try {
|
|
4352
4557
|
await run(actorCtx);
|
|
4353
4558
|
} finally {
|
|
4354
|
-
|
|
4559
|
+
// Delete rather than set(false): an absent entry already
|
|
4560
|
+
// reads as inactive, and deleting keeps this map bounded
|
|
4561
|
+
// to currently-running handlers instead of accumulating an
|
|
4562
|
+
// entry per actor id forever.
|
|
4563
|
+
nativeRunHandlerActiveByActorId.delete(actorId);
|
|
4355
4564
|
await actorCtx.dispose();
|
|
4356
4565
|
}
|
|
4357
4566
|
},
|
|
@@ -4562,7 +4771,7 @@ export function buildNativeFactory(
|
|
|
4562
4771
|
|
|
4563
4772
|
return runtime.createActorFactory(
|
|
4564
4773
|
callbacks,
|
|
4565
|
-
buildActorConfig(definition, registryConfig),
|
|
4774
|
+
buildActorConfig(definition, registryConfig, runtime.kind),
|
|
4566
4775
|
);
|
|
4567
4776
|
}
|
|
4568
4777
|
|
|
@@ -4589,10 +4798,29 @@ export async function buildServeConfig(
|
|
|
4589
4798
|
serverlessMaxStartPayloadBytes: config.serverless.maxStartPayloadBytes,
|
|
4590
4799
|
};
|
|
4591
4800
|
|
|
4592
|
-
|
|
4801
|
+
// Always best-effort resolve the npm-installed engine binary and hand its
|
|
4802
|
+
// path to the core. The core alone decides whether to actually spawn a local
|
|
4803
|
+
// engine (its `should_manage_engine`, based on the endpoint + spawn mode), so
|
|
4804
|
+
// JS must not duplicate that decision here. Only JS knows the npm
|
|
4805
|
+
// `node_modules` layout, so it resolves the path; if no binary is available
|
|
4806
|
+
// (remote-only install, unsupported platform, optional deps skipped), leave
|
|
4807
|
+
// it unset and let the core report `engine.binary_unavailable` if it actually
|
|
4808
|
+
// needs one.
|
|
4809
|
+
try {
|
|
4593
4810
|
const { getEnginePath } = await loadEngineCli();
|
|
4594
4811
|
serveConfig.engineBinaryPath = getEnginePath();
|
|
4812
|
+
} catch (error) {
|
|
4813
|
+
// The npm-installed engine binary could not be resolved. The core still
|
|
4814
|
+
// decides whether it needs to spawn a local engine; if it does, it will
|
|
4815
|
+
// fail with engine.binary_unavailable (auto-download is off in the napi
|
|
4816
|
+
// runtime). Warn so the cause is actionable.
|
|
4817
|
+
logger().warn({
|
|
4818
|
+
msg: "could not resolve a local engine binary; if a local engine must be spawned it will fail with engine.binary_unavailable — set RIVET_ENGINE_BINARY_PATH or install the @rivetkit/engine-cli platform package",
|
|
4819
|
+
error: stringifyError(error),
|
|
4820
|
+
});
|
|
4595
4821
|
}
|
|
4822
|
+
serveConfig.engineHost = config.engineHost;
|
|
4823
|
+
serveConfig.enginePort = config.enginePort;
|
|
4596
4824
|
if (config.test?.enabled) {
|
|
4597
4825
|
serveConfig.inspectorTestToken =
|
|
4598
4826
|
getEnvUniversal("_RIVET_TEST_INSPECTOR_TOKEN") ?? "token";
|
|
@@ -4616,6 +4844,13 @@ export async function buildRegistryWithRuntime(
|
|
|
4616
4844
|
trySetProcessEnv("_RIVET_TEST_INSPECTOR_TOKEN", "token");
|
|
4617
4845
|
}
|
|
4618
4846
|
|
|
4847
|
+
// Custom inspector tab `source` paths are resolved with node:path while
|
|
4848
|
+
// building actor configs below, so the Node modules must be loaded first.
|
|
4849
|
+
// Native (napi) runtime only; wasm has no filesystem.
|
|
4850
|
+
if (runtime.kind === "napi") {
|
|
4851
|
+
importNodeDependencies();
|
|
4852
|
+
}
|
|
4853
|
+
|
|
4619
4854
|
const registry = runtime.createRegistry();
|
|
4620
4855
|
|
|
4621
4856
|
for (const [name, definition] of Object.entries(config.use)) {
|