rivetkit 2.3.0-rc.9 → 2.3.0
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 +498 -62
- package/dist/browser/client.js +227 -171
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +50 -20
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/tsup/actor/errors.cjs +2 -2
- package/dist/tsup/actor/errors.d.cts +1 -1
- package/dist/tsup/actor/errors.d.ts +1 -1
- package/dist/tsup/actor/errors.js +1 -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 +496 -69
- package/dist/tsup/agent-os/index.d.ts +496 -69
- package/dist/tsup/agent-os/index.js +2163 -2087
- package/dist/tsup/agent-os/index.js.map +1 -1
- package/dist/tsup/{chunk-W7EYSYVI.js → chunk-2OTRTA3J.js} +134 -20
- package/dist/tsup/chunk-2OTRTA3J.js.map +1 -0
- package/dist/tsup/{chunk-VJFRBJVQ.cjs → chunk-3677IIOV.cjs} +138 -24
- package/dist/tsup/chunk-3677IIOV.cjs.map +1 -0
- package/dist/tsup/{chunk-4CGA6QJO.cjs → chunk-47HHIEXH.cjs} +24 -9
- package/dist/tsup/chunk-47HHIEXH.cjs.map +1 -0
- package/dist/tsup/{chunk-F3Q5BFQ6.js → chunk-4JDSFJS5.js} +66 -79
- package/dist/tsup/chunk-4JDSFJS5.js.map +1 -0
- package/dist/tsup/{chunk-GVTOE34S.cjs → chunk-7QKCIVAY.cjs} +222 -235
- package/dist/tsup/chunk-7QKCIVAY.cjs.map +1 -0
- package/dist/tsup/{chunk-CPA4Y3RG.cjs → chunk-B6VUNZUD.cjs} +10 -10
- package/dist/tsup/chunk-B6VUNZUD.cjs.map +1 -0
- package/dist/tsup/{chunk-H37XQU3I.js → chunk-BEI24WTI.js} +2 -2
- package/dist/tsup/{chunk-KIWH5H3K.js → chunk-BRP62GZC.js} +3 -3
- package/dist/tsup/chunk-BRP62GZC.js.map +1 -0
- package/dist/tsup/{chunk-T6YVRM4K.js → chunk-DPIMKYNB.js} +63 -2
- package/dist/tsup/chunk-DPIMKYNB.js.map +1 -0
- package/dist/tsup/{chunk-Y5NSCZA2.cjs → chunk-DXXJPH55.cjs} +44 -15
- package/dist/tsup/chunk-DXXJPH55.cjs.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-4WPEZBK4.cjs → chunk-I4LN3FNT.cjs} +10 -10
- package/dist/tsup/chunk-I4LN3FNT.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-QAZLM4WT.cjs → chunk-KORQB2IR.cjs} +3 -3
- package/dist/tsup/{chunk-QAZLM4WT.cjs.map → chunk-KORQB2IR.cjs.map} +1 -1
- package/dist/tsup/{chunk-MALSPBAF.cjs → chunk-LVTBW2RE.cjs} +3 -3
- package/dist/tsup/{chunk-MALSPBAF.cjs.map → chunk-LVTBW2RE.cjs.map} +1 -1
- package/dist/tsup/{chunk-H7P7WR2Y.js → chunk-MEHBWPLJ.js} +6 -6
- package/dist/tsup/chunk-MEHBWPLJ.js.map +1 -0
- package/dist/tsup/{chunk-WQ4HNA4W.cjs → chunk-NIY3RSPX.cjs} +64 -3
- package/dist/tsup/chunk-NIY3RSPX.cjs.map +1 -0
- package/dist/tsup/{chunk-MMMEZM5J.js → chunk-P2GNQ4RN.js} +4 -4
- package/dist/tsup/chunk-P2GNQ4RN.js.map +1 -0
- package/dist/tsup/{chunk-KJTA3ATT.js → chunk-UMZVD6DQ.js} +22 -7
- package/dist/tsup/chunk-UMZVD6DQ.js.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-VRCIXJRN.js → chunk-VTTFNQQI.js} +36 -7
- package/dist/tsup/chunk-VTTFNQQI.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/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-0Ta55UV0.d.ts → config-BxWAw3iH.d.ts} +529 -23
- package/dist/tsup/{config-Ca8dN4cS.d.cts → config-CZQQ-mso.d.cts} +529 -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/{context-B_IWbWne.d.ts → context-Bw7xq8w3.d.cts} +8 -8
- package/dist/tsup/{context-CUrQ9MHc.d.cts → context-D8QA76sV.d.ts} +8 -8
- 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 +730 -336
- 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 +633 -239
- 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-DQosb24I.d.cts} +1 -1
- package/dist/tsup/{utils-DVekpm4I.d.ts → utils-DQosb24I.d.ts} +1 -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 +307 -282
- package/dist/tsup/workflow/mod.cjs.map +1 -1
- package/dist/tsup/workflow/mod.d.cts +6 -6
- package/dist/tsup/workflow/mod.d.ts +6 -6
- package/dist/tsup/workflow/mod.js +501 -476
- package/dist/tsup/workflow/mod.js.map +1 -1
- package/package.json +32 -11
- package/src/actor/config.ts +159 -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 +9 -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 +154 -74
- package/src/registry/napi-runtime.ts +13 -2
- package/src/registry/native-validation.ts +10 -12
- package/src/registry/native.ts +367 -181
- package/src/registry/process-metrics.ts +250 -0
- package/src/registry/runtime.ts +41 -1
- package/src/registry/wasm-runtime.ts +18 -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 +6 -0
- package/src/utils/router.ts +1 -1
- package/src/utils/serve.ts +4 -5
- package/src/utils.ts +1 -2
- package/src/workflow/context.ts +61 -33
- package/src/workflow/driver.ts +4 -6
- package/src/workflow/inspector.ts +4 -3
- package/src/workflow/mod.ts +15 -17
- 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-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/{chunk-H37XQU3I.js.map → chunk-BEI24WTI.js.map} +0 -0
package/src/registry/native.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
CONN_STATE_MANAGER_SYMBOL,
|
|
5
5
|
getRunFunction,
|
|
6
6
|
getRunInspectorConfig,
|
|
7
|
+
RAW_STATE_SYMBOL,
|
|
7
8
|
type WorkflowInspectorConfig,
|
|
8
9
|
} from "@/actor/config";
|
|
9
10
|
import type { AnyActorDefinition } from "@/actor/definition";
|
|
@@ -32,6 +33,7 @@ import { convertRegistryConfigToClientConfig } from "@/client/config";
|
|
|
32
33
|
import { HEADER_CONN_PARAMS } from "@/common/actor-router-consts";
|
|
33
34
|
import type { AnyDatabaseProvider } from "@/common/database/config";
|
|
34
35
|
import { wrapJsNativeDatabase } from "@/common/database/native-database";
|
|
36
|
+
import { assertJsonCompatValue, type JsonCompatValue } from "@/common/encoding";
|
|
35
37
|
import { decodeWorkflowHistoryTransport } from "@/common/inspector-transport";
|
|
36
38
|
import { deconstructError, stringifyError } from "@/common/utils";
|
|
37
39
|
import type {
|
|
@@ -47,11 +49,7 @@ import type {
|
|
|
47
49
|
RuntimeKind,
|
|
48
50
|
SqliteBackend,
|
|
49
51
|
} from "@/registry/config";
|
|
50
|
-
import {
|
|
51
|
-
decodeCborCompat,
|
|
52
|
-
decodeCborJsonCompat,
|
|
53
|
-
encodeCborCompat,
|
|
54
|
-
} from "@/serde";
|
|
52
|
+
import { decodeCborCompat, encodeCborCompat } from "@/serde";
|
|
55
53
|
import { getEnvUniversal, VERSION } from "@/utils";
|
|
56
54
|
import { logger } from "./log";
|
|
57
55
|
import { loadNapiRuntime } from "./napi-runtime";
|
|
@@ -73,12 +71,16 @@ import type {
|
|
|
73
71
|
RuntimeActorConfig,
|
|
74
72
|
RuntimeBytes,
|
|
75
73
|
RuntimeHttpResponse,
|
|
74
|
+
RuntimeInspectorTabEntry,
|
|
76
75
|
RuntimeQueueMessage,
|
|
77
76
|
RuntimeServeConfig,
|
|
78
77
|
RuntimeStateDeltaPayload,
|
|
79
78
|
WebSocketHandle,
|
|
80
79
|
} from "./runtime";
|
|
81
80
|
import { loadWasmRuntime } from "./wasm-runtime";
|
|
81
|
+
import nodeFs from "node:fs";
|
|
82
|
+
import nodePath from "node:path";
|
|
83
|
+
import { createWriteThroughProxy } from "./write-through-proxy";
|
|
82
84
|
|
|
83
85
|
const textEncoder = new TextEncoder();
|
|
84
86
|
const textDecoder = new TextDecoder();
|
|
@@ -345,6 +347,15 @@ function databaseNotConfiguredError(): RivetError {
|
|
|
345
347
|
);
|
|
346
348
|
}
|
|
347
349
|
|
|
350
|
+
function databaseClientNotReadyError(): RivetError {
|
|
351
|
+
return new RivetError(
|
|
352
|
+
"actor",
|
|
353
|
+
"database_client_not_ready",
|
|
354
|
+
"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.",
|
|
355
|
+
{ public: true },
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
|
|
348
359
|
function stateNotEnabledError(): RivetError {
|
|
349
360
|
return new RivetError(
|
|
350
361
|
"actor",
|
|
@@ -413,8 +424,33 @@ function clearNativeRuntimeState(
|
|
|
413
424
|
async function cleanupNativeSleepRuntimeState(
|
|
414
425
|
runtime: CoreRuntime,
|
|
415
426
|
ctx: ActorContextHandle,
|
|
427
|
+
afterTrackedWorkDrained?: () => Promise<void>,
|
|
416
428
|
): Promise<void> {
|
|
417
|
-
|
|
429
|
+
// The bounded wait gives shutdown work one grace-period chance to finish.
|
|
430
|
+
// Drained means all tracked shutdown work completed before the deadline, so
|
|
431
|
+
// we can save final state and clear runtime state immediately. If it did not
|
|
432
|
+
// drain, close database handles now, then defer the final save and clear until
|
|
433
|
+
// the tracked work finishes without a deadline.
|
|
434
|
+
const drained = await runtime.actorWaitForTrackedShutdownWork(ctx);
|
|
435
|
+
if (!drained) {
|
|
436
|
+
await closeNativeDatabaseClient(runtime, ctx);
|
|
437
|
+
await closeNativeSqlDatabase(runtime, ctx);
|
|
438
|
+
void runtime
|
|
439
|
+
.actorWaitForTrackedShutdownWorkUnbounded(ctx)
|
|
440
|
+
.then(async () => {
|
|
441
|
+
await afterTrackedWorkDrained?.();
|
|
442
|
+
clearNativeRuntimeState(runtime, ctx);
|
|
443
|
+
})
|
|
444
|
+
.catch((error) => {
|
|
445
|
+
logger().warn({
|
|
446
|
+
msg: "deferred native sleep cleanup failed",
|
|
447
|
+
error: stringifyError(error),
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
await afterTrackedWorkDrained?.();
|
|
418
454
|
await closeNativeDatabaseClient(runtime, ctx);
|
|
419
455
|
await closeNativeSqlDatabase(runtime, ctx);
|
|
420
456
|
clearNativeRuntimeState(runtime, ctx);
|
|
@@ -587,11 +623,19 @@ function decodeValue<T>(value?: RuntimeBytes | null): T {
|
|
|
587
623
|
return undefined as T;
|
|
588
624
|
}
|
|
589
625
|
|
|
590
|
-
return
|
|
626
|
+
return decodeCborCompat(value);
|
|
591
627
|
}
|
|
592
628
|
|
|
593
629
|
function encodeValue(value: unknown): RuntimeBytes {
|
|
594
|
-
return encodeCborCompat(value);
|
|
630
|
+
return encodeCborCompat(value as JsonCompatValue);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function normalizeArgs(value: unknown): unknown[] {
|
|
634
|
+
return Array.isArray(value)
|
|
635
|
+
? value
|
|
636
|
+
: value === undefined || value === null
|
|
637
|
+
? []
|
|
638
|
+
: [value];
|
|
595
639
|
}
|
|
596
640
|
|
|
597
641
|
function unwrapTsfnPayload<T>(error: unknown, payload: T): T {
|
|
@@ -924,6 +968,7 @@ function serializeWorkflowEntryKind(
|
|
|
924
968
|
}
|
|
925
969
|
}
|
|
926
970
|
|
|
971
|
+
// TODO: Switch inspector routes to CBOR encoding
|
|
927
972
|
function serializeWorkflowHistoryForJson(data: ArrayBuffer | null): {
|
|
928
973
|
nameRegistry: string[];
|
|
929
974
|
entries: Array<{
|
|
@@ -957,7 +1002,7 @@ function serializeWorkflowHistoryForJson(data: ArrayBuffer | null): {
|
|
|
957
1002
|
|
|
958
1003
|
const history = decodeWorkflowHistoryTransport(data);
|
|
959
1004
|
|
|
960
|
-
return {
|
|
1005
|
+
return jsonSafe({
|
|
961
1006
|
nameRegistry: [...history.nameRegistry],
|
|
962
1007
|
entries: history.entries.map((entry) => ({
|
|
963
1008
|
id: entry.id,
|
|
@@ -987,7 +1032,7 @@ function serializeWorkflowHistoryForJson(data: ArrayBuffer | null): {
|
|
|
987
1032
|
],
|
|
988
1033
|
),
|
|
989
1034
|
),
|
|
990
|
-
};
|
|
1035
|
+
});
|
|
991
1036
|
}
|
|
992
1037
|
|
|
993
1038
|
function toHttpJsonCompatible<T>(value: T): T {
|
|
@@ -1059,60 +1104,7 @@ function wrapNativeCallback<Args extends Array<unknown>, Result>(
|
|
|
1059
1104
|
|
|
1060
1105
|
function decodeArgs(value?: RuntimeBytes | null): unknown[] {
|
|
1061
1106
|
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;
|
|
1107
|
+
return normalizeArgs(decoded);
|
|
1116
1108
|
}
|
|
1117
1109
|
|
|
1118
1110
|
function buildRequest(init: {
|
|
@@ -1204,14 +1196,25 @@ class NativeConnAdapter {
|
|
|
1204
1196
|
);
|
|
1205
1197
|
}
|
|
1206
1198
|
|
|
1199
|
+
[RAW_STATE_SYMBOL](): unknown {
|
|
1200
|
+
return this.#readState();
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1207
1203
|
get state(): unknown {
|
|
1208
1204
|
const nextState = this.#readState();
|
|
1209
|
-
return createWriteThroughProxy(
|
|
1210
|
-
|
|
1211
|
-
|
|
1205
|
+
return createWriteThroughProxy(
|
|
1206
|
+
nextState,
|
|
1207
|
+
(nextValue) => {
|
|
1208
|
+
this.#writeState(nextValue, { writeNative: true });
|
|
1209
|
+
},
|
|
1210
|
+
(newValue) => {
|
|
1211
|
+
assertJsonCompatValue(newValue);
|
|
1212
|
+
},
|
|
1213
|
+
);
|
|
1212
1214
|
}
|
|
1213
1215
|
|
|
1214
1216
|
set state(value: unknown) {
|
|
1217
|
+
assertJsonCompatValue(value);
|
|
1215
1218
|
this.#writeState(value, { writeNative: true });
|
|
1216
1219
|
}
|
|
1217
1220
|
|
|
@@ -1683,7 +1686,12 @@ class NativeQueueAdapter {
|
|
|
1683
1686
|
signal?: AbortSignal;
|
|
1684
1687
|
},
|
|
1685
1688
|
) {
|
|
1686
|
-
|
|
1689
|
+
const { token, cleanup } = await createCancellationTokenHandle(
|
|
1690
|
+
this.#runtime,
|
|
1691
|
+
options?.signal,
|
|
1692
|
+
);
|
|
1693
|
+
|
|
1694
|
+
try {
|
|
1687
1695
|
await callNative(() =>
|
|
1688
1696
|
this.#runtime.actorQueueWaitForNamesAvailable(
|
|
1689
1697
|
this.#ctx,
|
|
@@ -1691,57 +1699,11 @@ class NativeQueueAdapter {
|
|
|
1691
1699
|
{
|
|
1692
1700
|
timeoutMs: options?.timeout,
|
|
1693
1701
|
},
|
|
1702
|
+
token,
|
|
1694
1703
|
),
|
|
1695
1704
|
);
|
|
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
|
-
}
|
|
1705
|
+
} finally {
|
|
1706
|
+
cleanup?.();
|
|
1745
1707
|
}
|
|
1746
1708
|
}
|
|
1747
1709
|
|
|
@@ -2323,6 +2285,104 @@ class TrackedWebSocketHandleAdapter implements UniversalWebSocket {
|
|
|
2323
2285
|
}
|
|
2324
2286
|
}
|
|
2325
2287
|
|
|
2288
|
+
class NativeConnectionMap implements ReadonlyMap<string, NativeConnAdapter> {
|
|
2289
|
+
#runtime: CoreRuntime;
|
|
2290
|
+
#ctx: ActorContextHandle;
|
|
2291
|
+
#schemas: NativeValidationConfig;
|
|
2292
|
+
|
|
2293
|
+
constructor(
|
|
2294
|
+
runtime: CoreRuntime,
|
|
2295
|
+
ctx: ActorContextHandle,
|
|
2296
|
+
schemas: NativeValidationConfig,
|
|
2297
|
+
) {
|
|
2298
|
+
this.#runtime = runtime;
|
|
2299
|
+
this.#ctx = ctx;
|
|
2300
|
+
this.#schemas = schemas;
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2303
|
+
#connToAdapter(conn: ConnHandle): NativeConnAdapter {
|
|
2304
|
+
return new NativeConnAdapter(
|
|
2305
|
+
this.#runtime,
|
|
2306
|
+
conn,
|
|
2307
|
+
this.#schemas,
|
|
2308
|
+
this.#ctx,
|
|
2309
|
+
(connId) =>
|
|
2310
|
+
callNativeSync(() =>
|
|
2311
|
+
this.#runtime.actorQueueHibernationRemoval(
|
|
2312
|
+
this.#ctx,
|
|
2313
|
+
connId,
|
|
2314
|
+
),
|
|
2315
|
+
),
|
|
2316
|
+
);
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
get size(): number {
|
|
2320
|
+
return callNativeSync(() => this.#runtime.actorConns(this.#ctx)).length;
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
get(key: string): NativeConnAdapter | undefined {
|
|
2324
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2325
|
+
const conn = conns.find((c) => this.#runtime.connId(c) === key);
|
|
2326
|
+
if (!conn) return undefined;
|
|
2327
|
+
return this.#connToAdapter(conn);
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
has(key: string): boolean {
|
|
2331
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2332
|
+
return conns.some((c) => this.#runtime.connId(c) === key);
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
keys(): MapIterator<string> {
|
|
2336
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2337
|
+
return conns
|
|
2338
|
+
.map((c) => this.#runtime.connId(c))
|
|
2339
|
+
[Symbol.iterator]() satisfies MapIterator<string>;
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2342
|
+
values(): MapIterator<NativeConnAdapter> {
|
|
2343
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2344
|
+
return conns
|
|
2345
|
+
.map((c) => this.#connToAdapter(c))
|
|
2346
|
+
[Symbol.iterator]() satisfies MapIterator<NativeConnAdapter>;
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
entries(): MapIterator<[string, NativeConnAdapter]> {
|
|
2350
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2351
|
+
return conns
|
|
2352
|
+
.map(
|
|
2353
|
+
(c) =>
|
|
2354
|
+
[this.#runtime.connId(c), this.#connToAdapter(c)] as [
|
|
2355
|
+
string,
|
|
2356
|
+
NativeConnAdapter,
|
|
2357
|
+
],
|
|
2358
|
+
)
|
|
2359
|
+
[Symbol.iterator]() satisfies MapIterator<
|
|
2360
|
+
[string, NativeConnAdapter]
|
|
2361
|
+
>;
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
forEach(
|
|
2365
|
+
callback: (
|
|
2366
|
+
value: NativeConnAdapter,
|
|
2367
|
+
key: string,
|
|
2368
|
+
map: ReadonlyMap<string, NativeConnAdapter>,
|
|
2369
|
+
) => void,
|
|
2370
|
+
thisArg?: unknown,
|
|
2371
|
+
): void {
|
|
2372
|
+
const conns = callNativeSync(() => this.#runtime.actorConns(this.#ctx));
|
|
2373
|
+
for (const conn of conns) {
|
|
2374
|
+
const id = this.#runtime.connId(conn);
|
|
2375
|
+
callback.call(thisArg, this.#connToAdapter(conn), id, this);
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
[Symbol.iterator](): MapIterator<[string, NativeConnAdapter]> {
|
|
2380
|
+
return this.entries();
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
readonly [Symbol.toStringTag] = "NativeConnectionMap";
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2326
2386
|
export class ActorContextHandleAdapter {
|
|
2327
2387
|
#runtime: CoreRuntime;
|
|
2328
2388
|
#ctx: ActorContextHandle;
|
|
@@ -2331,9 +2391,9 @@ export class ActorContextHandleAdapter {
|
|
|
2331
2391
|
#abortSignalCleanup?: () => void;
|
|
2332
2392
|
#client?: AnyClient;
|
|
2333
2393
|
#clientFactory?: () => AnyClient;
|
|
2394
|
+
#connMap?: NativeConnectionMap;
|
|
2334
2395
|
#databaseProvider?: Exclude<AnyDatabaseProvider, undefined>;
|
|
2335
2396
|
#db?: unknown;
|
|
2336
|
-
#dbProxy?: unknown;
|
|
2337
2397
|
#dispatchCancelToken?: CancellationTokenHandle;
|
|
2338
2398
|
#kv?: NativeKvAdapter;
|
|
2339
2399
|
#queue?: NativeQueueAdapter;
|
|
@@ -2396,32 +2456,25 @@ export class ActorContextHandleAdapter {
|
|
|
2396
2456
|
throw databaseNotConfiguredError();
|
|
2397
2457
|
}
|
|
2398
2458
|
|
|
2399
|
-
if (
|
|
2400
|
-
this.#
|
|
2401
|
-
|
|
2402
|
-
{
|
|
2403
|
-
get: (_target, property) => {
|
|
2404
|
-
if (property === "then") {
|
|
2405
|
-
return undefined;
|
|
2406
|
-
}
|
|
2459
|
+
if (this.#db) {
|
|
2460
|
+
return this.#db;
|
|
2461
|
+
}
|
|
2407
2462
|
|
|
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
|
-
);
|
|
2463
|
+
const runtimeState = getNativeRuntimeState(this.#runtime, this.#ctx);
|
|
2464
|
+
const cachedClient = runtimeState.databaseClient;
|
|
2465
|
+
if (cachedClient) {
|
|
2466
|
+
this.#db = cachedClient.client;
|
|
2467
|
+
return this.#db;
|
|
2422
2468
|
}
|
|
2423
2469
|
|
|
2424
|
-
|
|
2470
|
+
throw databaseClientNotReadyError();
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
[RAW_STATE_SYMBOL](): unknown {
|
|
2474
|
+
if (!this.#stateEnabled) {
|
|
2475
|
+
throw stateNotEnabledError();
|
|
2476
|
+
}
|
|
2477
|
+
return this.#readState();
|
|
2425
2478
|
}
|
|
2426
2479
|
|
|
2427
2480
|
get state(): unknown {
|
|
@@ -2444,8 +2497,9 @@ export class ActorContextHandleAdapter {
|
|
|
2444
2497
|
(nextValue) => {
|
|
2445
2498
|
this.#writeState(nextValue, { scheduleSave: true });
|
|
2446
2499
|
},
|
|
2447
|
-
() => {
|
|
2500
|
+
(newValue) => {
|
|
2448
2501
|
this.#assertCanMutateState();
|
|
2502
|
+
assertJsonCompatValue(newValue);
|
|
2449
2503
|
},
|
|
2450
2504
|
);
|
|
2451
2505
|
}
|
|
@@ -2457,6 +2511,7 @@ export class ActorContextHandleAdapter {
|
|
|
2457
2511
|
throw stateNotEnabledError();
|
|
2458
2512
|
}
|
|
2459
2513
|
this.#assertCanMutateState();
|
|
2514
|
+
assertJsonCompatValue(value);
|
|
2460
2515
|
this.#writeState(value, { scheduleSave: true });
|
|
2461
2516
|
}
|
|
2462
2517
|
|
|
@@ -2523,27 +2578,15 @@ export class ActorContextHandleAdapter {
|
|
|
2523
2578
|
return callNativeSync(() => this.#runtime.actorRegion(this.#ctx));
|
|
2524
2579
|
}
|
|
2525
2580
|
|
|
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
|
-
);
|
|
2581
|
+
get conns(): ReadonlyMap<string, NativeConnAdapter> {
|
|
2582
|
+
if (!this.#connMap) {
|
|
2583
|
+
this.#connMap = new NativeConnectionMap(
|
|
2584
|
+
this.#runtime,
|
|
2585
|
+
this.#ctx,
|
|
2586
|
+
this.#schemas,
|
|
2587
|
+
);
|
|
2588
|
+
}
|
|
2589
|
+
return this.#connMap;
|
|
2547
2590
|
}
|
|
2548
2591
|
|
|
2549
2592
|
get log() {
|
|
@@ -2862,6 +2905,7 @@ export class ActorContextHandleAdapter {
|
|
|
2862
2905
|
}
|
|
2863
2906
|
|
|
2864
2907
|
sleep(): void {
|
|
2908
|
+
this.#flushStateChange();
|
|
2865
2909
|
callNativeSync(() => this.#runtime.actorSleep(this.#ctx));
|
|
2866
2910
|
}
|
|
2867
2911
|
|
|
@@ -3286,9 +3330,87 @@ function buildActorConfig(
|
|
|
3286
3330
|
actions: Object.keys((config.actions ?? {}) as Record<string, unknown>)
|
|
3287
3331
|
.sort()
|
|
3288
3332
|
.map((name) => ({ name })),
|
|
3333
|
+
inspectorTabs: buildInspectorTabs(config.inspector),
|
|
3289
3334
|
};
|
|
3290
3335
|
}
|
|
3291
3336
|
|
|
3337
|
+
function buildInspectorTabs(
|
|
3338
|
+
inspector: unknown,
|
|
3339
|
+
): Array<RuntimeInspectorTabEntry> | undefined {
|
|
3340
|
+
if (!inspector || typeof inspector !== "object") return undefined;
|
|
3341
|
+
const tabs = (inspector as { tabs?: unknown }).tabs;
|
|
3342
|
+
if (!Array.isArray(tabs) || tabs.length === 0) return undefined;
|
|
3343
|
+
return tabs.map((raw) => {
|
|
3344
|
+
const entry = raw as {
|
|
3345
|
+
id: string;
|
|
3346
|
+
label?: string;
|
|
3347
|
+
source?: string;
|
|
3348
|
+
icon?: string;
|
|
3349
|
+
hidden?: boolean;
|
|
3350
|
+
};
|
|
3351
|
+
if (entry.hidden === true) {
|
|
3352
|
+
return { id: entry.id, hidden: true };
|
|
3353
|
+
}
|
|
3354
|
+
// Resolve the author's source path against the current working
|
|
3355
|
+
// directory so the Rust runtime gets an absolute path. The author
|
|
3356
|
+
// runs the actor process from their project root by convention.
|
|
3357
|
+
const resolved =
|
|
3358
|
+
entry.source !== undefined
|
|
3359
|
+
? nodePath.resolve(entry.source)
|
|
3360
|
+
: undefined;
|
|
3361
|
+
if (resolved !== undefined) {
|
|
3362
|
+
validateInspectorTabSource(entry.id, resolved);
|
|
3363
|
+
}
|
|
3364
|
+
return {
|
|
3365
|
+
id: entry.id,
|
|
3366
|
+
label: entry.label,
|
|
3367
|
+
icon: entry.icon,
|
|
3368
|
+
source: resolved,
|
|
3369
|
+
};
|
|
3370
|
+
});
|
|
3371
|
+
}
|
|
3372
|
+
|
|
3373
|
+
function validateInspectorTabSource(tabId: string, resolved: string): void {
|
|
3374
|
+
// Catch obviously dangerous misconfigurations at registry construction
|
|
3375
|
+
// rather than silently exposing the wrong subtree over the unauthenticated
|
|
3376
|
+
// `/inspector/custom-tabs/<id>/*` route. Fail loudly so misconfigured
|
|
3377
|
+
// actors never start.
|
|
3378
|
+
if (resolved === nodePath.parse(resolved).root) {
|
|
3379
|
+
throw new Error(
|
|
3380
|
+
`inspector.tabs[id="${tabId}"].source resolves to the filesystem root (${resolved}). ` +
|
|
3381
|
+
"Point it at the tab's own static-asset directory instead.",
|
|
3382
|
+
);
|
|
3383
|
+
}
|
|
3384
|
+
let stat: import("node:fs").Stats;
|
|
3385
|
+
try {
|
|
3386
|
+
stat = nodeFs.statSync(resolved);
|
|
3387
|
+
} catch (err) {
|
|
3388
|
+
const code = (err as NodeJS.ErrnoException)?.code;
|
|
3389
|
+
if (code === "ENOENT") {
|
|
3390
|
+
throw new Error(
|
|
3391
|
+
`inspector.tabs[id="${tabId}"].source (${resolved}) does not exist.`,
|
|
3392
|
+
);
|
|
3393
|
+
}
|
|
3394
|
+
if (code === "EACCES") {
|
|
3395
|
+
throw new Error(
|
|
3396
|
+
`inspector.tabs[id="${tabId}"].source (${resolved}) is not readable (EACCES).`,
|
|
3397
|
+
);
|
|
3398
|
+
}
|
|
3399
|
+
throw new Error(
|
|
3400
|
+
`inspector.tabs[id="${tabId}"].source (${resolved}) could not be stat'd: ${
|
|
3401
|
+
(err as Error)?.message ?? err
|
|
3402
|
+
}`,
|
|
3403
|
+
);
|
|
3404
|
+
}
|
|
3405
|
+
if (!stat.isDirectory()) {
|
|
3406
|
+
throw new Error(
|
|
3407
|
+
`inspector.tabs[id="${tabId}"].source (${resolved}) must be a directory, got ${
|
|
3408
|
+
stat.isFile() ? "file" : "non-directory"
|
|
3409
|
+
}.`,
|
|
3410
|
+
);
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3292
3414
|
export function buildNativeFactory(
|
|
3293
3415
|
runtime: CoreRuntime,
|
|
3294
3416
|
registryConfig: RegistryConfig,
|
|
@@ -3548,6 +3670,10 @@ export function buildNativeFactory(
|
|
|
3548
3670
|
getNativeWorkflowInspector(ctx) !== undefined,
|
|
3549
3671
|
});
|
|
3550
3672
|
} catch (error) {
|
|
3673
|
+
logger().error({
|
|
3674
|
+
msg: "error replaying workflow history",
|
|
3675
|
+
error,
|
|
3676
|
+
});
|
|
3551
3677
|
return errorResponse(error);
|
|
3552
3678
|
}
|
|
3553
3679
|
}
|
|
@@ -3715,18 +3841,46 @@ export function buildNativeFactory(
|
|
|
3715
3841
|
404,
|
|
3716
3842
|
);
|
|
3717
3843
|
}
|
|
3718
|
-
const body = (await jsRequest.json()) as {
|
|
3844
|
+
const body = (await jsRequest.json()) as {
|
|
3845
|
+
args?: unknown;
|
|
3846
|
+
properties?: unknown;
|
|
3847
|
+
};
|
|
3848
|
+
if (body.args !== undefined && body.properties !== undefined) {
|
|
3849
|
+
return jsonResponse(
|
|
3850
|
+
{ error: "use either args or properties, not both" },
|
|
3851
|
+
{ status: 400 },
|
|
3852
|
+
);
|
|
3853
|
+
}
|
|
3854
|
+
if (
|
|
3855
|
+
body.properties !== undefined &&
|
|
3856
|
+
(body.properties === null ||
|
|
3857
|
+
typeof body.properties !== "object" ||
|
|
3858
|
+
Array.isArray(body.properties))
|
|
3859
|
+
) {
|
|
3860
|
+
return jsonResponse(
|
|
3861
|
+
{ error: "properties must be an object" },
|
|
3862
|
+
{ status: 400 },
|
|
3863
|
+
);
|
|
3864
|
+
}
|
|
3865
|
+
const args =
|
|
3866
|
+
body.properties !== undefined
|
|
3867
|
+
? [body.properties]
|
|
3868
|
+
: normalizeArgs(body.args);
|
|
3719
3869
|
try {
|
|
3720
3870
|
const output = await action(
|
|
3721
3871
|
actorCtx,
|
|
3722
3872
|
...validateActionArgs(
|
|
3723
3873
|
schemaConfig.actionInputSchemas,
|
|
3724
3874
|
actionName,
|
|
3725
|
-
|
|
3875
|
+
args,
|
|
3726
3876
|
),
|
|
3727
3877
|
);
|
|
3728
3878
|
return jsonResponse({ output });
|
|
3729
3879
|
} catch (error) {
|
|
3880
|
+
logger().error({
|
|
3881
|
+
msg: "Error handling inspector action request",
|
|
3882
|
+
error,
|
|
3883
|
+
});
|
|
3730
3884
|
return errorResponse(error);
|
|
3731
3885
|
}
|
|
3732
3886
|
}
|
|
@@ -3741,6 +3895,10 @@ export function buildNativeFactory(
|
|
|
3741
3895
|
{ status: 404 },
|
|
3742
3896
|
);
|
|
3743
3897
|
} catch (error) {
|
|
3898
|
+
logger().error({
|
|
3899
|
+
msg: "Error handling inspector request",
|
|
3900
|
+
error,
|
|
3901
|
+
});
|
|
3744
3902
|
return errorResponse(error);
|
|
3745
3903
|
} finally {
|
|
3746
3904
|
await actorCtx.dispose();
|
|
@@ -3913,26 +4071,35 @@ export function buildNativeFactory(
|
|
|
3913
4071
|
async (error: unknown, payload: { ctx: ActorContextHandle }) => {
|
|
3914
4072
|
const { ctx } = unwrapTsfnPayload(error, payload);
|
|
3915
4073
|
const actorCtx = makeActorCtx(ctx);
|
|
4074
|
+
// TODO: Move this save hook into cleanupNativeSleepRuntimeState
|
|
4075
|
+
// so immediate and deferred sleep cleanup share one save-state
|
|
4076
|
+
// path instead of passing a callback through cleanup.
|
|
4077
|
+
const saveActorState = async () => {
|
|
4078
|
+
if (runtime.kind === "wasm") {
|
|
4079
|
+
// Wasm cannot use the native context save helper here because
|
|
4080
|
+
// the runtime owns the serialized state handoff.
|
|
4081
|
+
await runtime.actorSaveState(
|
|
4082
|
+
ctx,
|
|
4083
|
+
actorCtx.serializeForTick("save"),
|
|
4084
|
+
);
|
|
4085
|
+
} else {
|
|
4086
|
+
await actorCtx.saveState({
|
|
4087
|
+
immediate: true,
|
|
4088
|
+
});
|
|
4089
|
+
}
|
|
4090
|
+
};
|
|
3916
4091
|
try {
|
|
3917
4092
|
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
|
-
}
|
|
4093
|
+
await onSleep(actorCtx);
|
|
3932
4094
|
}
|
|
4095
|
+
await saveActorState();
|
|
3933
4096
|
} finally {
|
|
3934
4097
|
try {
|
|
3935
|
-
await cleanupNativeSleepRuntimeState(
|
|
4098
|
+
await cleanupNativeSleepRuntimeState(
|
|
4099
|
+
runtime,
|
|
4100
|
+
ctx,
|
|
4101
|
+
saveActorState,
|
|
4102
|
+
);
|
|
3936
4103
|
} finally {
|
|
3937
4104
|
await actorCtx.dispose();
|
|
3938
4105
|
}
|
|
@@ -4589,10 +4756,29 @@ export async function buildServeConfig(
|
|
|
4589
4756
|
serverlessMaxStartPayloadBytes: config.serverless.maxStartPayloadBytes,
|
|
4590
4757
|
};
|
|
4591
4758
|
|
|
4592
|
-
|
|
4759
|
+
// Always best-effort resolve the npm-installed engine binary and hand its
|
|
4760
|
+
// path to the core. The core alone decides whether to actually spawn a local
|
|
4761
|
+
// engine (its `should_manage_engine`, based on the endpoint + spawn mode), so
|
|
4762
|
+
// JS must not duplicate that decision here. Only JS knows the npm
|
|
4763
|
+
// `node_modules` layout, so it resolves the path; if no binary is available
|
|
4764
|
+
// (remote-only install, unsupported platform, optional deps skipped), leave
|
|
4765
|
+
// it unset and let the core report `engine.binary_unavailable` if it actually
|
|
4766
|
+
// needs one.
|
|
4767
|
+
try {
|
|
4593
4768
|
const { getEnginePath } = await loadEngineCli();
|
|
4594
4769
|
serveConfig.engineBinaryPath = getEnginePath();
|
|
4770
|
+
} catch (error) {
|
|
4771
|
+
// The npm-installed engine binary could not be resolved. The core still
|
|
4772
|
+
// decides whether it needs to spawn a local engine; if it does, it will
|
|
4773
|
+
// fail with engine.binary_unavailable (auto-download is off in the napi
|
|
4774
|
+
// runtime). Warn so the cause is actionable.
|
|
4775
|
+
logger().warn({
|
|
4776
|
+
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",
|
|
4777
|
+
error: stringifyError(error),
|
|
4778
|
+
});
|
|
4595
4779
|
}
|
|
4780
|
+
serveConfig.engineHost = config.engineHost;
|
|
4781
|
+
serveConfig.enginePort = config.enginePort;
|
|
4596
4782
|
if (config.test?.enabled) {
|
|
4597
4783
|
serveConfig.inspectorTestToken =
|
|
4598
4784
|
getEnvUniversal("_RIVET_TEST_INSPECTOR_TOKEN") ?? "token";
|