rivetkit 0.0.0-skip-ready-wait-flatten-client-options.1cae221 → 0.0.0-sqlite-uds.4e59a38
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 +561 -89
- package/dist/browser/client.js +1063 -430
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.d.ts +22 -2
- package/dist/browser/inspector/client.js +1036 -232
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/tsup/actor/errors.cjs +6 -2
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +1 -74
- package/dist/tsup/actor/errors.d.ts +1 -74
- package/dist/tsup/actor/errors.js +5 -1
- package/dist/tsup/agent-os/index.cjs +2218 -2082
- package/dist/tsup/agent-os/index.cjs.map +1 -1
- package/dist/tsup/agent-os/index.d.cts +556 -85
- package/dist/tsup/agent-os/index.d.ts +556 -85
- package/dist/tsup/agent-os/index.js +2220 -2084
- package/dist/tsup/agent-os/index.js.map +1 -1
- package/dist/tsup/{chunk-NFC5VU36.cjs → chunk-3GC3EP6D.cjs} +18 -10
- package/dist/tsup/chunk-3GC3EP6D.cjs.map +1 -0
- package/dist/tsup/{chunk-7MRGNVSR.js → chunk-3GLNEWGY.js} +78 -6
- package/dist/tsup/chunk-3GLNEWGY.js.map +1 -0
- package/dist/tsup/{chunk-V3QNBJ7N.cjs → chunk-4FC7TVS6.cjs} +35 -10
- package/dist/tsup/chunk-4FC7TVS6.cjs.map +1 -0
- package/dist/tsup/{chunk-POTPHU3P.cjs → chunk-62LSMTP2.cjs} +3 -3
- package/dist/tsup/{chunk-POTPHU3P.cjs.map → chunk-62LSMTP2.cjs.map} +1 -1
- package/dist/tsup/{chunk-OIKOPSXQ.js → chunk-7IVUT2JT.js} +12 -4
- package/dist/tsup/chunk-7IVUT2JT.js.map +1 -0
- package/dist/tsup/{chunk-22XU3BVY.cjs → chunk-GEYQLGXC.cjs} +925 -328
- package/dist/tsup/chunk-GEYQLGXC.cjs.map +1 -0
- package/dist/tsup/{chunk-D2TLG75Y.cjs → chunk-GMN45CQ6.cjs} +10 -10
- package/dist/tsup/chunk-GMN45CQ6.cjs.map +1 -0
- package/dist/tsup/{chunk-3BFYSYRU.js → chunk-HXUEHHJF.js} +3 -2
- package/dist/tsup/chunk-HXUEHHJF.js.map +1 -0
- package/dist/tsup/{chunk-IOYKCB6Y.cjs → chunk-I336PMWT.cjs} +44 -9
- package/dist/tsup/chunk-I336PMWT.cjs.map +1 -0
- package/dist/tsup/{chunk-RZEJJJKU.js → chunk-IB73AMGJ.js} +42 -7
- package/dist/tsup/chunk-IB73AMGJ.js.map +1 -0
- package/dist/tsup/{chunk-4ZIWB4CQ.js → chunk-ITWJ6Y7G.js} +2 -2
- package/dist/tsup/{chunk-PCBNKI2J.js → chunk-JZ7TWV65.js} +1 -1
- package/dist/tsup/chunk-JZ7TWV65.js.map +1 -0
- package/dist/tsup/{chunk-W54QCENI.js → chunk-KTNBYGRU.js} +134 -20
- package/dist/tsup/chunk-KTNBYGRU.js.map +1 -0
- package/dist/tsup/{chunk-AK57AL7S.cjs → chunk-OAPVVVTX.cjs} +79 -7
- package/dist/tsup/chunk-OAPVVVTX.cjs.map +1 -0
- package/dist/tsup/{chunk-TPBHXFB2.cjs → chunk-OUDV3ITX.cjs} +138 -24
- package/dist/tsup/chunk-OUDV3ITX.cjs.map +1 -0
- package/dist/tsup/{chunk-XNZR7UD2.cjs → chunk-PRXTIERO.cjs} +90 -65
- package/dist/tsup/chunk-PRXTIERO.cjs.map +1 -0
- package/dist/tsup/{chunk-LLD2D5LO.cjs → chunk-VE2X4KMG.cjs} +3 -2
- package/dist/tsup/chunk-VE2X4KMG.cjs.map +1 -0
- package/dist/tsup/{chunk-KSG2COSQ.js → chunk-WRZEVVLL.js} +6 -6
- package/dist/tsup/chunk-WRZEVVLL.js.map +1 -0
- package/dist/tsup/{chunk-LNMB25HW.js → chunk-XAIMHUPG.js} +780 -183
- package/dist/tsup/chunk-XAIMHUPG.js.map +1 -0
- package/dist/tsup/{chunk-D4TSTM6C.js → chunk-XZ62SWSC.js} +83 -58
- package/dist/tsup/chunk-XZ62SWSC.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-K34B3OVG.js → chunk-ZZ3WBRPD.js} +34 -9
- package/dist/tsup/chunk-ZZ3WBRPD.js.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.cjs.map +1 -1
- package/dist/tsup/client/mod.d.cts +8 -9
- package/dist/tsup/client/mod.d.ts +8 -9
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +5 -3
- package/dist/tsup/common/log.cjs.map +1 -1
- package/dist/tsup/common/log.d.cts +5 -1
- package/dist/tsup/common/log.d.ts +5 -1
- package/dist/tsup/common/log.js +6 -4
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{config-CRdGwwbr.d.cts → config-CxG53eQo.d.cts} +577 -36
- package/dist/tsup/{config-kxXbtrJU.d.ts → config-DLOxy81E.d.cts} +5 -5
- package/dist/tsup/{config-kxXbtrJU.d.cts → config-DLOxy81E.d.ts} +5 -5
- package/dist/tsup/{config-DIpBWm5C.d.ts → config-Ds6DCRhV.d.ts} +577 -36
- package/dist/tsup/context-8KlcOYIs.d.cts +129 -0
- package/dist/tsup/context-Cfbm4QLr.d.ts +129 -0
- package/dist/tsup/db/drizzle.cjs +151 -79
- package/dist/tsup/db/drizzle.cjs.map +1 -1
- package/dist/tsup/db/drizzle.d.cts +2 -2
- package/dist/tsup/db/drizzle.d.ts +2 -2
- package/dist/tsup/db/drizzle.js +151 -79
- package/dist/tsup/db/drizzle.js.map +1 -1
- package/dist/tsup/db/mod.cjs +79 -24
- package/dist/tsup/db/mod.cjs.map +1 -1
- package/dist/tsup/db/mod.d.cts +2 -2
- package/dist/tsup/db/mod.d.ts +2 -2
- package/dist/tsup/db/mod.js +78 -23
- package/dist/tsup/db/mod.js.map +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 +47 -12
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +37 -15
- package/dist/tsup/inspector/mod.d.ts +37 -15
- package/dist/tsup/inspector/mod.js +46 -11
- package/dist/tsup/inspector/mod.js.map +1 -1
- package/dist/tsup/inspector-tab/mod.cjs +162 -0
- package/dist/tsup/inspector-tab/mod.cjs.map +1 -0
- package/dist/tsup/inspector-tab/mod.d.cts +240 -0
- package/dist/tsup/inspector-tab/mod.d.ts +240 -0
- package/dist/tsup/inspector-tab/mod.js +162 -0
- package/dist/tsup/inspector-tab/mod.js.map +1 -0
- package/dist/tsup/mod.cjs +1078 -479
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +5 -6
- package/dist/tsup/mod.d.ts +5 -6
- package/dist/tsup/mod.js +996 -397
- 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 -5
- package/dist/tsup/test/mod.d.ts +4 -5
- package/dist/tsup/test/mod.js +18 -15
- package/dist/tsup/test/mod.js.map +1 -1
- package/dist/tsup/utils-CqDnC_PS.d.cts +104 -0
- package/dist/tsup/utils-CqDnC_PS.d.ts +104 -0
- 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 +386 -322
- package/dist/tsup/workflow/mod.cjs.map +1 -1
- package/dist/tsup/workflow/mod.d.cts +8 -9
- package/dist/tsup/workflow/mod.d.ts +8 -9
- package/dist/tsup/workflow/mod.js +363 -299
- package/dist/tsup/workflow/mod.js.map +1 -1
- package/package.json +35 -14
- package/src/actor/config.ts +188 -59
- 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 +70 -7
- package/src/actor/instance/mod.ts +39 -56
- package/src/actor/keys.ts +2 -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 +88 -62
- package/src/client/actor-conn.ts +58 -63
- package/src/client/actor-handle.ts +125 -71
- package/src/client/actor-query.ts +5 -5
- package/src/client/config.ts +3 -3
- package/src/client/errors.ts +2 -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 +10 -10
- package/src/client/resolve-gateway-target.ts +1 -1
- package/src/client/utils.ts +34 -10
- package/src/common/actor-router-consts.ts +7 -4
- 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/generated/client-protocol/v4.ts +599 -0
- package/src/common/bare/generated/inspector/v5.ts +1016 -0
- package/src/common/bare/transport/v1.ts +694 -542
- package/src/common/client-protocol-versioned.ts +176 -67
- package/src/common/client-protocol-zod.ts +7 -0
- package/src/common/client-protocol.ts +1 -1
- package/src/common/database/config.ts +16 -5
- package/src/common/database/mod.test.ts +83 -16
- package/src/common/database/mod.ts +86 -30
- package/src/common/database/native-database.test.ts +35 -22
- package/src/common/database/native-database.ts +26 -10
- 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 +15 -8
- package/src/common/router.ts +49 -23
- package/src/common/utils.ts +10 -202
- package/src/common/websocket-interface.ts +1 -1
- package/src/db/drizzle.ts +173 -96
- 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 +76 -73
- 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 +6 -9
- package/src/engine-client/actor-websocket-client.ts +14 -13
- package/src/engine-client/api-endpoints.ts +51 -2
- package/src/engine-client/api-utils.ts +2 -2
- package/src/engine-client/driver.ts +3 -4
- package/src/engine-client/mod.ts +17 -10
- package/src/engine-client/ws-proxy.ts +9 -4
- package/src/inspector/client.browser.ts +66 -15
- package/src/inspector/mod.ts +2 -4
- package/src/inspector-tab/mod.ts +300 -0
- package/src/registry/config/envoy.ts +1 -2
- package/src/registry/config/index.ts +46 -20
- package/src/registry/index.ts +364 -87
- package/src/registry/napi-runtime.ts +97 -8
- package/src/registry/native-validation.ts +10 -12
- package/src/registry/native.ts +592 -343
- package/src/registry/process-metrics.ts +250 -0
- package/src/registry/runtime.ts +85 -6
- package/src/registry/wasm-runtime.ts +72 -3
- package/src/registry/write-through-proxy.ts +40 -0
- package/src/serde.ts +2 -2
- package/src/serverless/configure.ts +19 -8
- package/src/test/mod.ts +11 -8
- package/src/utils/crypto.ts +14 -0
- 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 +703 -240
- package/src/workflow/driver.ts +23 -12
- package/src/workflow/inspector.ts +12 -3
- package/src/workflow/mod.ts +37 -23
- package/dist/tsup/chunk-22XU3BVY.cjs.map +0 -1
- package/dist/tsup/chunk-2NDZ7JCR.cjs.map +0 -1
- package/dist/tsup/chunk-3BFYSYRU.js.map +0 -1
- package/dist/tsup/chunk-7MRGNVSR.js.map +0 -1
- package/dist/tsup/chunk-AK57AL7S.cjs.map +0 -1
- package/dist/tsup/chunk-D2TLG75Y.cjs.map +0 -1
- package/dist/tsup/chunk-D4TSTM6C.js.map +0 -1
- package/dist/tsup/chunk-IOYKCB6Y.cjs.map +0 -1
- package/dist/tsup/chunk-K34B3OVG.js.map +0 -1
- package/dist/tsup/chunk-KSG2COSQ.js.map +0 -1
- package/dist/tsup/chunk-LLD2D5LO.cjs.map +0 -1
- package/dist/tsup/chunk-LNMB25HW.js.map +0 -1
- package/dist/tsup/chunk-NFC5VU36.cjs.map +0 -1
- package/dist/tsup/chunk-OIKOPSXQ.js.map +0 -1
- package/dist/tsup/chunk-PCBNKI2J.js.map +0 -1
- package/dist/tsup/chunk-RZEJJJKU.js.map +0 -1
- package/dist/tsup/chunk-TPBHXFB2.cjs.map +0 -1
- package/dist/tsup/chunk-V3QNBJ7N.cjs.map +0 -1
- package/dist/tsup/chunk-W54QCENI.js.map +0 -1
- package/dist/tsup/chunk-XNZR7UD2.cjs.map +0 -1
- package/dist/tsup/context-B7G6sk7x.d.ts +0 -92
- package/dist/tsup/context-DzMRHkjC.d.cts +0 -92
- package/dist/tsup/utils-fwx3o3K9.d.cts +0 -18
- package/dist/tsup/utils-fwx3o3K9.d.ts +0 -18
- package/src/utils/serve.ts +0 -217
- /package/dist/tsup/{chunk-4ZIWB4CQ.js.map → chunk-ITWJ6Y7G.js.map} +0 -0
package/src/registry/index.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isLocalEngineEndpoint } from "@/common/engine";
|
|
2
|
+
import { configureBaseLogger } from "@/common/log";
|
|
2
3
|
import { configureServerlessPool } from "@/serverless/configure";
|
|
3
4
|
import { VERSION } from "@/utils";
|
|
5
|
+
import {
|
|
6
|
+
getRivetkitPublicDir,
|
|
7
|
+
getRivetkitRuntimeMode,
|
|
8
|
+
parsePortEnv,
|
|
9
|
+
} from "@/utils/env-vars";
|
|
4
10
|
import {
|
|
5
11
|
type RegistryActors,
|
|
6
12
|
type RegistryConfig,
|
|
@@ -13,6 +19,22 @@ import type { RuntimeServerlessResponseHead } from "./runtime";
|
|
|
13
19
|
|
|
14
20
|
type ShutdownSignal = "SIGINT" | "SIGTERM";
|
|
15
21
|
|
|
22
|
+
function signalExitCode(signal: ShutdownSignal): number {
|
|
23
|
+
switch (signal) {
|
|
24
|
+
case "SIGINT":
|
|
25
|
+
return 130;
|
|
26
|
+
case "SIGTERM":
|
|
27
|
+
return 143;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function finishShutdownSignal(signal: ShutdownSignal): void {
|
|
32
|
+
if (process.pid === 1) {
|
|
33
|
+
process.exit(signalExitCode(signal));
|
|
34
|
+
}
|
|
35
|
+
process.kill(process.pid, signal);
|
|
36
|
+
}
|
|
37
|
+
|
|
16
38
|
export type FetchHandler = (
|
|
17
39
|
request: Request,
|
|
18
40
|
...args: any
|
|
@@ -22,13 +44,25 @@ export interface ServerlessHandler {
|
|
|
22
44
|
fetch: FetchHandler;
|
|
23
45
|
}
|
|
24
46
|
|
|
25
|
-
export interface
|
|
26
|
-
|
|
27
|
-
|
|
47
|
+
export interface RegistryRoutes {
|
|
48
|
+
health(): Promise<Response>;
|
|
49
|
+
metadata(): Promise<Response>;
|
|
50
|
+
prometheusMetrics(request?: Request): Promise<Response>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Injectable dependencies for {@link Registry}. Production code uses the
|
|
55
|
+
* defaults. Tests override `buildConfiguredRegistry` to drive lifecycle
|
|
56
|
+
* orchestration against a fake `CoreRuntime` without an engine.
|
|
57
|
+
*/
|
|
58
|
+
export interface RegistryDeps {
|
|
59
|
+
buildConfiguredRegistry: typeof buildConfiguredRegistry;
|
|
28
60
|
}
|
|
29
61
|
|
|
30
62
|
export class Registry<A extends RegistryActors> {
|
|
31
63
|
#config: RegistryConfigInput<A>;
|
|
64
|
+
#buildConfiguredRegistry: typeof buildConfiguredRegistry;
|
|
65
|
+
public readonly routes: RegistryRoutes;
|
|
32
66
|
|
|
33
67
|
get config(): RegistryConfigInput<A> {
|
|
34
68
|
return this.#config;
|
|
@@ -47,20 +81,39 @@ export class Registry<A extends RegistryActors> {
|
|
|
47
81
|
#shutdownInFlight: Promise<void> | null = null;
|
|
48
82
|
#signalHandlers: Partial<Record<ShutdownSignal, () => void>> = {};
|
|
49
83
|
|
|
50
|
-
constructor(config: RegistryConfigInput<A>) {
|
|
84
|
+
constructor(config: RegistryConfigInput<A>, deps?: Partial<RegistryDeps>) {
|
|
51
85
|
this.#config = config;
|
|
86
|
+
if (config.logging?.baseLogger) {
|
|
87
|
+
configureBaseLogger(config.logging.baseLogger);
|
|
88
|
+
}
|
|
89
|
+
this.#buildConfiguredRegistry =
|
|
90
|
+
deps?.buildConfiguredRegistry ?? buildConfiguredRegistry;
|
|
91
|
+
this.routes = {
|
|
92
|
+
health: () => this.#healthRoute(),
|
|
93
|
+
metadata: () => this.#metadataRoute(),
|
|
94
|
+
prometheusMetrics: (request?: Request) =>
|
|
95
|
+
this.#prometheusMetricsRoute(request),
|
|
96
|
+
};
|
|
52
97
|
}
|
|
53
98
|
|
|
54
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Fires `configureServerlessPool` once per process when the registry
|
|
101
|
+
* config opts into it. Cached on the instance so repeated calls (from
|
|
102
|
+
* `handler()` and `listen()`) only run the upsert once. The retry loop
|
|
103
|
+
* inside `configureServerlessPool` tolerates the engine still warming up.
|
|
104
|
+
*/
|
|
105
|
+
#ensureServerlessPoolConfigured(
|
|
106
|
+
config: RegistryConfig,
|
|
107
|
+
): Promise<void> | undefined {
|
|
55
108
|
if (!config.configurePool) return undefined;
|
|
56
109
|
|
|
57
110
|
if (!this.#configureServerlessPoolPromise) {
|
|
58
|
-
this.#configureServerlessPoolPromise = configureServerlessPool(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
);
|
|
111
|
+
this.#configureServerlessPoolPromise = configureServerlessPool(
|
|
112
|
+
config,
|
|
113
|
+
).catch((error) => {
|
|
114
|
+
this.#configureServerlessPoolPromise = undefined;
|
|
115
|
+
throw error;
|
|
116
|
+
});
|
|
64
117
|
this.#configureServerlessPoolPromise.catch(() => {});
|
|
65
118
|
}
|
|
66
119
|
|
|
@@ -82,7 +135,8 @@ export class Registry<A extends RegistryActors> {
|
|
|
82
135
|
this.#printWelcome(config, "serverless");
|
|
83
136
|
|
|
84
137
|
if (!this.#runtimeServerlessPromise) {
|
|
85
|
-
this.#runtimeServerlessPromise =
|
|
138
|
+
this.#runtimeServerlessPromise =
|
|
139
|
+
this.#buildConfiguredRegistry(config);
|
|
86
140
|
}
|
|
87
141
|
|
|
88
142
|
const { runtime, registry, serveConfig } =
|
|
@@ -96,12 +150,13 @@ export class Registry<A extends RegistryActors> {
|
|
|
96
150
|
serveConfig.serverlessBasePath ?? "/api/rivet",
|
|
97
151
|
);
|
|
98
152
|
const isEngineMetadataRequest =
|
|
99
|
-
request.headers.get("user-agent")?.startsWith("RivetEngine/") ??
|
|
153
|
+
request.headers.get("user-agent")?.startsWith("RivetEngine/") ??
|
|
154
|
+
false;
|
|
100
155
|
|
|
101
156
|
if (isStartRequest) {
|
|
102
157
|
try {
|
|
103
158
|
await this.#ensureServerlessPoolConfigured(config);
|
|
104
|
-
} catch (
|
|
159
|
+
} catch (_error) {
|
|
105
160
|
return new Response(
|
|
106
161
|
JSON.stringify({
|
|
107
162
|
group: "guard",
|
|
@@ -243,7 +298,7 @@ export class Registry<A extends RegistryActors> {
|
|
|
243
298
|
if (isMetadataRequest && !isEngineMetadataRequest) {
|
|
244
299
|
try {
|
|
245
300
|
await this.#ensureServerlessPoolConfigured(config);
|
|
246
|
-
} catch (
|
|
301
|
+
} catch (_error) {
|
|
247
302
|
return new Response(
|
|
248
303
|
JSON.stringify({
|
|
249
304
|
group: "guard",
|
|
@@ -279,21 +334,152 @@ export class Registry<A extends RegistryActors> {
|
|
|
279
334
|
};
|
|
280
335
|
}
|
|
281
336
|
|
|
282
|
-
|
|
337
|
+
/**
|
|
338
|
+
* Bind an HTTP listener provided by the native (Rust) runtime and serve
|
|
339
|
+
* the registry's serverless endpoints over it. Resolves only after the
|
|
340
|
+
* registry is shut down (SIGINT/SIGTERM or `nativeRegistry.shutdown()`).
|
|
341
|
+
*
|
|
342
|
+
* @param opts.port Port to listen on. Defaults to `process.env.RIVET_PORT`
|
|
343
|
+
* if set, otherwise 3000.
|
|
344
|
+
* @param opts.host Address to bind. Defaults to `0.0.0.0`.
|
|
345
|
+
* @param opts.publicDir If set, serves static files from this directory
|
|
346
|
+
* as a fallback below the framework routes.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```ts
|
|
350
|
+
* await registry.listen();
|
|
351
|
+
* await registry.listen({ port: 8080, publicDir: "./public" });
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
public async listen(
|
|
355
|
+
opts: { port?: number; host?: string; publicDir?: string } = {},
|
|
356
|
+
): Promise<void> {
|
|
357
|
+
const port = opts.port ?? parsePortEnv(process.env.RIVET_PORT) ?? 3000;
|
|
358
|
+
const publicDir = opts.publicDir ?? getRivetkitPublicDir();
|
|
359
|
+
const config = this.parseConfig();
|
|
360
|
+
|
|
361
|
+
// Cache on both promise fields so the shutdown drain sees Mode A and B.
|
|
362
|
+
const configuredRegistryPromise = buildConfiguredRegistry(config);
|
|
363
|
+
this.#runtimeServeConfiguredPromise = configuredRegistryPromise;
|
|
364
|
+
this.#runtimeServerlessPromise = configuredRegistryPromise;
|
|
365
|
+
this.#installSignalHandlers(config);
|
|
366
|
+
|
|
367
|
+
this.#printWelcome(config, "serverless", {
|
|
368
|
+
port,
|
|
369
|
+
host: opts.host,
|
|
370
|
+
publicDir,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
// Background fire; the retry loop tolerates engine warm-up.
|
|
374
|
+
this.#ensureServerlessPoolConfigured(config);
|
|
375
|
+
|
|
376
|
+
const { runtime, registry, serveConfig } =
|
|
377
|
+
await configuredRegistryPromise;
|
|
378
|
+
await runtime.serveListener(
|
|
379
|
+
registry,
|
|
380
|
+
{ port, host: opts.host, publicDir },
|
|
381
|
+
serveConfig,
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Returns a health response suitable for mounting in a user-owned router.
|
|
387
|
+
*/
|
|
388
|
+
async #healthRoute(): Promise<Response> {
|
|
389
|
+
const configured = await this.#activeConfiguredRegistry();
|
|
390
|
+
if (!configured) {
|
|
391
|
+
return jsonRouteResponse(503, {
|
|
392
|
+
status: "not_started",
|
|
393
|
+
runtime: "rivetkit",
|
|
394
|
+
version: VERSION,
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const { runtime, registry } = configured;
|
|
399
|
+
if (!runtime.registryHealth) {
|
|
400
|
+
return jsonRouteResponse(501, {
|
|
401
|
+
status: "unsupported",
|
|
402
|
+
runtime: "rivetkit",
|
|
403
|
+
version: VERSION,
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const response = await runtime.registryHealth(registry);
|
|
408
|
+
return new Response(new Uint8Array(response.body), {
|
|
409
|
+
status: response.status,
|
|
410
|
+
headers: response.headers,
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Returns serverless metadata suitable for mounting in a user-owned router.
|
|
416
|
+
*/
|
|
417
|
+
async #metadataRoute(): Promise<Response> {
|
|
418
|
+
const configured = await this.#activeConfiguredRegistry();
|
|
419
|
+
if (!configured) {
|
|
420
|
+
return new Response("registry not started\n", {
|
|
421
|
+
status: 503,
|
|
422
|
+
headers: { "content-type": "text/plain; charset=utf-8" },
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const { runtime, registry } = configured;
|
|
427
|
+
if (!runtime.registryMetadata) {
|
|
428
|
+
return new Response("metadata is not supported by this runtime\n", {
|
|
429
|
+
status: 501,
|
|
430
|
+
headers: { "content-type": "text/plain; charset=utf-8" },
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const response = await runtime.registryMetadata(registry);
|
|
435
|
+
return new Response(new Uint8Array(response.body), {
|
|
436
|
+
status: response.status,
|
|
437
|
+
headers: response.headers,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Returns a Prometheus metrics response suitable for mounting in a user-owned router.
|
|
443
|
+
*/
|
|
444
|
+
async #prometheusMetricsRoute(_request?: Request): Promise<Response> {
|
|
445
|
+
const configured = await this.#activeConfiguredRegistry();
|
|
446
|
+
if (!configured) {
|
|
447
|
+
return new Response("registry not started\n", {
|
|
448
|
+
status: 503,
|
|
449
|
+
headers: { "content-type": "text/plain; charset=utf-8" },
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
const { runtime, registry } = configured;
|
|
454
|
+
if (!runtime.registryMetrics) {
|
|
455
|
+
return new Response("metrics are not supported by this runtime\n", {
|
|
456
|
+
status: 501,
|
|
457
|
+
headers: { "content-type": "text/plain; charset=utf-8" },
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const response = await runtime.registryMetrics(registry);
|
|
462
|
+
return new Response(new Uint8Array(response.body), {
|
|
463
|
+
status: response.status,
|
|
464
|
+
headers: response.headers,
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
async #activeConfiguredRegistry(): Promise<
|
|
469
|
+
Awaited<ReturnType<typeof buildConfiguredRegistry>> | undefined
|
|
470
|
+
> {
|
|
283
471
|
const candidates = [
|
|
284
472
|
this.#runtimeServerlessPromise,
|
|
285
473
|
this.#runtimeServeConfiguredPromise,
|
|
286
|
-
].filter(
|
|
287
|
-
|
|
474
|
+
].filter(
|
|
475
|
+
(
|
|
476
|
+
candidate,
|
|
477
|
+
): candidate is ReturnType<typeof buildConfiguredRegistry> =>
|
|
478
|
+
candidate !== undefined,
|
|
288
479
|
);
|
|
289
480
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
const diagnostics = await runtime.registryDiagnostics?.(registry);
|
|
293
|
-
if (diagnostics) return diagnostics;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return { mode: "not_started", envoyActiveActorCount: null };
|
|
481
|
+
if (candidates.length === 0) return undefined;
|
|
482
|
+
return await candidates[0]!;
|
|
297
483
|
}
|
|
298
484
|
|
|
299
485
|
/**
|
|
@@ -301,35 +487,33 @@ export class Registry<A extends RegistryActors> {
|
|
|
301
487
|
*/
|
|
302
488
|
#startEnvoy(config: RegistryConfig, printWelcome: boolean) {
|
|
303
489
|
if (!this.#runtimeServePromise) {
|
|
304
|
-
const configuredRegistryPromise =
|
|
490
|
+
const configuredRegistryPromise =
|
|
491
|
+
this.#buildConfiguredRegistry(config);
|
|
305
492
|
this.#runtimeServeConfiguredPromise = configuredRegistryPromise;
|
|
306
493
|
this.#runtimeServePromise = configuredRegistryPromise
|
|
307
494
|
.then(async ({ runtime, registry, serveConfig }) => {
|
|
308
495
|
await runtime.serveRegistry(registry, serveConfig);
|
|
309
496
|
})
|
|
310
|
-
.catch((
|
|
497
|
+
.catch((error) => {
|
|
311
498
|
// Always-attached catch so the stored promise never leaves a
|
|
312
499
|
// rejection unhandled. Downstream awaits (e.g. #runShutdown's
|
|
313
500
|
// Promise.race) attach their own catches and still observe
|
|
314
501
|
// resolution via the race.
|
|
315
|
-
logger().warn({
|
|
502
|
+
logger().warn({ error }, "runtime registry serve errored");
|
|
316
503
|
});
|
|
317
504
|
// Install signal handlers once an envoy lifecycle has begun. Only
|
|
318
505
|
// Mode A ever reaches here. Mode B (handler(request)) intentionally
|
|
319
506
|
// does not install handlers because it runs on Workers/Vercel/Deno
|
|
320
507
|
// Deploy where `process.on` is absent or forbidden; those platforms
|
|
321
508
|
// own their own signal policy.
|
|
322
|
-
this.#installSignalHandlers(config
|
|
509
|
+
this.#installSignalHandlers(config);
|
|
323
510
|
}
|
|
324
511
|
if (printWelcome) {
|
|
325
512
|
this.#printWelcome(config, "serverful");
|
|
326
513
|
}
|
|
327
514
|
}
|
|
328
515
|
|
|
329
|
-
#installSignalHandlers(
|
|
330
|
-
config: RegistryConfig,
|
|
331
|
-
configuredRegistryPromise: ReturnType<typeof buildConfiguredRegistry>,
|
|
332
|
-
): void {
|
|
516
|
+
#installSignalHandlers(config: RegistryConfig): void {
|
|
333
517
|
if (this.#shutdownInstalled) return;
|
|
334
518
|
if (config.shutdown?.disableSignalHandlers) return;
|
|
335
519
|
// Guard against non-Node runtimes (Workers/Edge) where `process` may
|
|
@@ -344,12 +528,7 @@ export class Registry<A extends RegistryActors> {
|
|
|
344
528
|
this.#shutdownInstalled = true;
|
|
345
529
|
|
|
346
530
|
const install = (signal: ShutdownSignal) => {
|
|
347
|
-
const handler = () =>
|
|
348
|
-
this.#onShutdownSignal(
|
|
349
|
-
signal,
|
|
350
|
-
config,
|
|
351
|
-
configuredRegistryPromise,
|
|
352
|
-
);
|
|
531
|
+
const handler = () => this.#onShutdownSignal(signal, config);
|
|
353
532
|
this.#signalHandlers[signal] = handler;
|
|
354
533
|
process.on(signal, handler);
|
|
355
534
|
};
|
|
@@ -357,68 +536,101 @@ export class Registry<A extends RegistryActors> {
|
|
|
357
536
|
install("SIGTERM");
|
|
358
537
|
}
|
|
359
538
|
|
|
360
|
-
#onShutdownSignal(
|
|
361
|
-
signal: ShutdownSignal,
|
|
362
|
-
config: RegistryConfig,
|
|
363
|
-
configuredRegistryPromise: ReturnType<typeof buildConfiguredRegistry>,
|
|
364
|
-
): void {
|
|
539
|
+
#onShutdownSignal(signal: ShutdownSignal, config: RegistryConfig): void {
|
|
365
540
|
if (this.#shutdownInFlight !== null) {
|
|
366
|
-
// Second delivery of the same (or another) shutdown signal
|
|
367
|
-
//
|
|
368
|
-
//
|
|
541
|
+
// Second delivery of the same (or another) shutdown signal, or a
|
|
542
|
+
// drain already started by an explicit `shutdown()` call. Remove
|
|
543
|
+
// our handler only, preserving any user-installed listeners. PID 1
|
|
544
|
+
// must exit directly because re-raised default signals can be
|
|
545
|
+
// swallowed by the container signal path.
|
|
369
546
|
this.#removeSignalHandlers();
|
|
370
|
-
|
|
547
|
+
finishShutdownSignal(signal);
|
|
371
548
|
return;
|
|
372
549
|
}
|
|
373
|
-
this.#shutdownInFlight = this.#
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
550
|
+
this.#shutdownInFlight = this.#drain(config)
|
|
551
|
+
.catch((err) => {
|
|
552
|
+
logger().warn({ err }, "shutdown error");
|
|
553
|
+
})
|
|
554
|
+
.then(() => {
|
|
555
|
+
this.#removeSignalHandlers();
|
|
556
|
+
finishShutdownSignal(signal);
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Gracefully drains all live registries.
|
|
562
|
+
*
|
|
563
|
+
* Programmatic counterpart to the SIGINT/SIGTERM handlers: tears down
|
|
564
|
+
* every live `CoreRegistry` (both `start()` and `handler()` modes) and
|
|
565
|
+
* waits for the serve promise to resolve, all bounded by the shutdown
|
|
566
|
+
* grace period. Unlike a signal-driven shutdown, this does not re-raise a
|
|
567
|
+
* signal or exit the process. The caller owns process lifetime.
|
|
568
|
+
*
|
|
569
|
+
* Idempotent: concurrent or repeated calls share a single drain. Safe to
|
|
570
|
+
* call even if nothing has been started.
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```ts
|
|
574
|
+
* const registry = setup({ use: { counter } });
|
|
575
|
+
* registry.start();
|
|
576
|
+
* // ...later, on your own shutdown trigger:
|
|
577
|
+
* await registry.shutdown();
|
|
578
|
+
* ```
|
|
579
|
+
*/
|
|
580
|
+
public async shutdown(): Promise<void> {
|
|
581
|
+
if (this.#shutdownInFlight !== null) return this.#shutdownInFlight;
|
|
582
|
+
const config = this.parseConfig();
|
|
583
|
+
// Uninstall our signal handlers so a later SIGINT/SIGTERM does not
|
|
584
|
+
// re-trigger a drain on already-torn-down registries. Subsequent
|
|
585
|
+
// signals fall back to Node's default termination behavior.
|
|
586
|
+
this.#removeSignalHandlers();
|
|
587
|
+
this.#shutdownInFlight = this.#drain(config).catch((err) => {
|
|
378
588
|
logger().warn({ err }, "shutdown error");
|
|
379
589
|
});
|
|
590
|
+
return this.#shutdownInFlight;
|
|
380
591
|
}
|
|
381
592
|
|
|
382
|
-
async #
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
593
|
+
async #drain(config: RegistryConfig): Promise<void> {
|
|
594
|
+
const modeAPromise = this.#runtimeServeConfiguredPromise;
|
|
595
|
+
const modeBPromise = this.#runtimeServerlessPromise;
|
|
596
|
+
|
|
597
|
+
const gracePeriodMs =
|
|
598
|
+
config.shutdown?.gracePeriodMs ??
|
|
599
|
+
(await this.#actorStopThresholdMs(modeAPromise ?? modeBPromise)) ??
|
|
600
|
+
30 * 60 * 1000;
|
|
388
601
|
// Race the entire drain sequence (both modes + serve promise) against
|
|
389
|
-
// a single grace ceiling.
|
|
390
|
-
//
|
|
391
|
-
// we re-raise the signal.
|
|
602
|
+
// a single grace ceiling. By default, this uses the engine-provided
|
|
603
|
+
// actor stop threshold, matching Pegboard's hard cutoff for actors.
|
|
392
604
|
const drain = async () => {
|
|
393
605
|
// Shut down every live `CoreRegistry` we know about. Mode A
|
|
394
606
|
// (`start()`) and Mode B (`handler()`) each build a separate
|
|
395
|
-
// runtime registry, so one
|
|
396
|
-
//
|
|
397
|
-
const registries: Promise<void>[] = [
|
|
398
|
-
|
|
399
|
-
try {
|
|
400
|
-
const { runtime, registry } =
|
|
401
|
-
await configuredRegistryPromise;
|
|
402
|
-
await runtime.shutdownRegistry(registry);
|
|
403
|
-
} catch (err) {
|
|
404
|
-
logger().warn(
|
|
405
|
-
{ err },
|
|
406
|
-
"runtime registry shutdown errored (mode A)",
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
})(),
|
|
410
|
-
];
|
|
411
|
-
const runtimeServerlessPromise = this.#runtimeServerlessPromise;
|
|
412
|
-
if (runtimeServerlessPromise !== undefined) {
|
|
607
|
+
// runtime registry, so one drain fans out to both to honor the
|
|
608
|
+
// spec invariant "single shutdown tears down both modes".
|
|
609
|
+
const registries: Promise<void>[] = [];
|
|
610
|
+
if (modeAPromise !== undefined) {
|
|
413
611
|
registries.push(
|
|
414
612
|
(async () => {
|
|
415
613
|
try {
|
|
416
|
-
const { runtime, registry } =
|
|
417
|
-
await runtimeServerlessPromise;
|
|
614
|
+
const { runtime, registry } = await modeAPromise;
|
|
418
615
|
await runtime.shutdownRegistry(registry);
|
|
419
616
|
} catch (err) {
|
|
420
617
|
logger().warn(
|
|
421
618
|
{ err },
|
|
619
|
+
"runtime registry shutdown errored (mode A)",
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
})(),
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
if (modeBPromise !== undefined) {
|
|
626
|
+
registries.push(
|
|
627
|
+
(async () => {
|
|
628
|
+
try {
|
|
629
|
+
const { runtime, registry } = await modeBPromise;
|
|
630
|
+
await runtime.shutdownRegistry(registry);
|
|
631
|
+
} catch (err) {
|
|
632
|
+
logger().warn(
|
|
633
|
+
{ error: err },
|
|
422
634
|
"runtime registry shutdown errored (mode B)",
|
|
423
635
|
);
|
|
424
636
|
}
|
|
@@ -441,8 +653,32 @@ export class Registry<A extends RegistryActors> {
|
|
|
441
653
|
setTimeout(resolve, gracePeriodMs).unref?.(),
|
|
442
654
|
),
|
|
443
655
|
]);
|
|
444
|
-
|
|
445
|
-
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
async #actorStopThresholdMs(
|
|
659
|
+
configuredRegistryPromise:
|
|
660
|
+
| ReturnType<typeof buildConfiguredRegistry>
|
|
661
|
+
| undefined,
|
|
662
|
+
): Promise<number | undefined> {
|
|
663
|
+
if (configuredRegistryPromise === undefined) return undefined;
|
|
664
|
+
try {
|
|
665
|
+
const { runtime, registry } = await configuredRegistryPromise;
|
|
666
|
+
const thresholdMs =
|
|
667
|
+
await runtime.registryActorStopThresholdMs?.(registry);
|
|
668
|
+
if (
|
|
669
|
+
thresholdMs !== undefined &&
|
|
670
|
+
Number.isFinite(thresholdMs) &&
|
|
671
|
+
thresholdMs > 0
|
|
672
|
+
) {
|
|
673
|
+
return thresholdMs;
|
|
674
|
+
}
|
|
675
|
+
} catch (err) {
|
|
676
|
+
logger().warn(
|
|
677
|
+
{ err },
|
|
678
|
+
"failed to read actor stop threshold for shutdown grace",
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
return undefined;
|
|
446
682
|
}
|
|
447
683
|
|
|
448
684
|
#removeSignalHandlers(): void {
|
|
@@ -461,6 +697,10 @@ export class Registry<A extends RegistryActors> {
|
|
|
461
697
|
/**
|
|
462
698
|
* Starts the actor envoy for standalone server deployments.
|
|
463
699
|
*
|
|
700
|
+
* Set `RIVETKIT_RUNTIME_MODE=serverless` to instead bind an HTTP listener
|
|
701
|
+
* via `listen()` (Mode B). Mode A (envoy) and Mode B (listener) are
|
|
702
|
+
* mutually exclusive per registry instance.
|
|
703
|
+
*
|
|
464
704
|
* @example
|
|
465
705
|
* ```ts
|
|
466
706
|
* const registry = setup({ use: { counter } });
|
|
@@ -468,6 +708,21 @@ export class Registry<A extends RegistryActors> {
|
|
|
468
708
|
* ```
|
|
469
709
|
*/
|
|
470
710
|
public start() {
|
|
711
|
+
if (getRivetkitRuntimeMode() === "serverless") {
|
|
712
|
+
// start() defaults publicDir to "/public" unless overridden by env.
|
|
713
|
+
const publicDir = getRivetkitPublicDir() ?? "/public";
|
|
714
|
+
// Detached listener; bind failures are fatal so exit hard.
|
|
715
|
+
this.listen({ publicDir }).catch((error) => {
|
|
716
|
+
logger().error({ error }, "auto-listen failed; exiting");
|
|
717
|
+
if (
|
|
718
|
+
typeof process !== "undefined" &&
|
|
719
|
+
typeof process.exit === "function"
|
|
720
|
+
) {
|
|
721
|
+
process.exit(1);
|
|
722
|
+
}
|
|
723
|
+
});
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
471
726
|
const config = this.parseConfig();
|
|
472
727
|
this.#startEnvoy(config, true);
|
|
473
728
|
}
|
|
@@ -475,6 +730,7 @@ export class Registry<A extends RegistryActors> {
|
|
|
475
730
|
#printWelcome(
|
|
476
731
|
config: RegistryConfig,
|
|
477
732
|
kind: "serverless" | "serverful",
|
|
733
|
+
listener?: { port: number; host?: string; publicDir?: string },
|
|
478
734
|
): void {
|
|
479
735
|
if (config.noWelcome || this.#welcomePrinted) return;
|
|
480
736
|
this.#welcomePrinted = true;
|
|
@@ -495,7 +751,9 @@ export class Registry<A extends RegistryActors> {
|
|
|
495
751
|
|
|
496
752
|
if (config.endpoint) {
|
|
497
753
|
const endpointType =
|
|
498
|
-
config.
|
|
754
|
+
config.startEngine || isLocalEngineEndpoint(config.endpoint)
|
|
755
|
+
? "local native"
|
|
756
|
+
: "remote";
|
|
499
757
|
logLine("Endpoint", `${config.endpoint} (${endpointType})`);
|
|
500
758
|
}
|
|
501
759
|
|
|
@@ -504,6 +762,15 @@ export class Registry<A extends RegistryActors> {
|
|
|
504
762
|
}
|
|
505
763
|
|
|
506
764
|
logLine("Actors", Object.keys(config.use).length.toString());
|
|
765
|
+
|
|
766
|
+
if (listener) {
|
|
767
|
+
const host = listener.host ?? "0.0.0.0";
|
|
768
|
+
logLine("Listening", `http://${host}:${listener.port}`);
|
|
769
|
+
if (listener.publicDir) {
|
|
770
|
+
logLine("Public Dir", listener.publicDir);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
507
774
|
console.log();
|
|
508
775
|
}
|
|
509
776
|
}
|
|
@@ -516,7 +783,10 @@ function isServerlessStartRequest(request: Request, basePath: string): boolean {
|
|
|
516
783
|
return parsed.pathname === `${normalizedBase}/start`;
|
|
517
784
|
}
|
|
518
785
|
|
|
519
|
-
function isServerlessMetadataRequest(
|
|
786
|
+
function isServerlessMetadataRequest(
|
|
787
|
+
request: Request,
|
|
788
|
+
basePath: string,
|
|
789
|
+
): boolean {
|
|
520
790
|
if (request.method !== "GET") return false;
|
|
521
791
|
const parsed = new URL(request.url);
|
|
522
792
|
const normalizedBase =
|
|
@@ -524,6 +794,13 @@ function isServerlessMetadataRequest(request: Request, basePath: string): boolea
|
|
|
524
794
|
return parsed.pathname === `${normalizedBase}/metadata`;
|
|
525
795
|
}
|
|
526
796
|
|
|
797
|
+
function jsonRouteResponse(status: number, body: unknown): Response {
|
|
798
|
+
return new Response(JSON.stringify(body), {
|
|
799
|
+
status,
|
|
800
|
+
headers: { "content-type": "application/json" },
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
|
|
527
804
|
export function setup<A extends RegistryActors>(
|
|
528
805
|
input: RegistryConfigInput<A>,
|
|
529
806
|
): Registry<A> {
|