rivetkit 2.3.24-rc.1 → 2.3.24
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 +3 -2
- package/dist/browser/client.js +36 -17
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +1 -1
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/tsup/agent-os/index.cjs +1 -1
- package/dist/tsup/agent-os/index.cjs.map +1 -1
- package/dist/tsup/agent-os/index.d.cts +0 -2
- package/dist/tsup/agent-os/index.d.ts +0 -2
- package/dist/tsup/agent-os/index.js +1 -1
- package/dist/tsup/agent-os/index.js.map +1 -1
- package/dist/tsup/{chunk-6HW3TU7Q.js → chunk-45WBFRBN.js} +2 -2
- package/dist/tsup/{chunk-64CRWLOX.js → chunk-7OEOLF5T.js} +3 -3
- package/dist/tsup/{chunk-LTGBHN5Z.js → chunk-CSOHAAZK.js} +1 -1
- package/dist/tsup/chunk-CSOHAAZK.js.map +1 -0
- package/dist/tsup/{chunk-CE6NBGOL.cjs → chunk-JOJ42ZLR.cjs} +3 -3
- package/dist/tsup/{chunk-CE6NBGOL.cjs.map → chunk-JOJ42ZLR.cjs.map} +1 -1
- package/dist/tsup/{chunk-ERBNWARB.cjs → chunk-L4AZXL2Q.cjs} +4 -4
- package/dist/tsup/{chunk-ERBNWARB.cjs.map → chunk-L4AZXL2Q.cjs.map} +1 -1
- package/dist/tsup/{chunk-YVVFOKEP.cjs → chunk-NNM2X3ER.cjs} +2 -2
- package/dist/tsup/chunk-NNM2X3ER.cjs.map +1 -0
- package/dist/tsup/{chunk-OB5JLDBM.js → chunk-NSNBWLCG.js} +2 -2
- package/dist/tsup/{chunk-NGJWQMUU.cjs → chunk-NWCAIWHL.cjs} +1 -1
- package/dist/tsup/chunk-NWCAIWHL.cjs.map +1 -0
- package/dist/tsup/{chunk-M5J3PXNU.js → chunk-QMR2J7PT.js} +2 -2
- package/dist/tsup/{chunk-QQ454DVR.js → chunk-QZQE75U2.js} +2 -2
- package/dist/tsup/{chunk-B6WTPGOR.js → chunk-SW22GCYF.js} +30 -11
- package/dist/tsup/chunk-SW22GCYF.js.map +1 -0
- package/dist/tsup/{chunk-PFHGTLF2.cjs → chunk-TMMZAGZL.cjs} +10 -10
- package/dist/tsup/{chunk-PFHGTLF2.cjs.map → chunk-TMMZAGZL.cjs.map} +1 -1
- package/dist/tsup/{chunk-R3UI7MO3.cjs → chunk-TQNVNKDB.cjs} +165 -146
- package/dist/tsup/chunk-TQNVNKDB.cjs.map +1 -0
- package/dist/tsup/{chunk-JKDAOE4T.js → chunk-UIPQ7RI4.js} +4 -4
- package/dist/tsup/{chunk-SWQCSORE.cjs → chunk-WCSFWDKH.cjs} +3 -3
- package/dist/tsup/{chunk-SWQCSORE.cjs.map → chunk-WCSFWDKH.cjs.map} +1 -1
- package/dist/tsup/{chunk-DAC73W53.cjs → chunk-WTZGJFD4.cjs} +7 -7
- package/dist/tsup/{chunk-DAC73W53.cjs.map → chunk-WTZGJFD4.cjs.map} +1 -1
- package/dist/tsup/{chunk-JJCUSUWO.js → chunk-YH2CAWLD.js} +2 -2
- package/dist/tsup/chunk-YH2CAWLD.js.map +1 -0
- package/dist/tsup/{chunk-JMO6AVUC.cjs → chunk-ZCHJJ2FZ.cjs} +3 -3
- package/dist/tsup/{chunk-JMO6AVUC.cjs.map → chunk-ZCHJJ2FZ.cjs.map} +1 -1
- package/dist/tsup/client/mod.cjs +5 -5
- package/dist/tsup/client/mod.d.cts +5 -2
- package/dist/tsup/client/mod.d.ts +5 -2
- package/dist/tsup/client/mod.js +4 -4
- package/dist/tsup/common/log.cjs +2 -2
- package/dist/tsup/common/log.js +1 -1
- package/dist/tsup/common/websocket.cjs +3 -3
- package/dist/tsup/common/websocket.js +2 -2
- package/dist/tsup/{config-RV6gIa2L.d.ts → config-Cv6pjCt-.d.ts} +0 -4
- package/dist/tsup/{config-CuKzfH58.d.cts → config-osdJqQwX.d.cts} +0 -4
- package/dist/tsup/{context-DoMKZBQA.d.ts → context-CoVbKBuk.d.ts} +1 -1
- package/dist/tsup/{context-DPCxyjax.d.cts → context-DpjrM7n7.d.cts} +1 -1
- package/dist/tsup/db/drizzle.cjs +2 -2
- package/dist/tsup/db/drizzle.js +1 -1
- package/dist/tsup/db/mod.cjs +3 -3
- package/dist/tsup/db/mod.js +2 -2
- package/dist/tsup/dynamic/mod.cjs +2 -2
- package/dist/tsup/dynamic/mod.d.cts +1 -1
- package/dist/tsup/dynamic/mod.d.ts +1 -1
- package/dist/tsup/dynamic/mod.js +1 -1
- package/dist/tsup/inspector/mod.cjs +5 -5
- package/dist/tsup/inspector/mod.js +4 -4
- package/dist/tsup/inspector/workflow.cjs +4 -4
- package/dist/tsup/inspector/workflow.js +3 -3
- package/dist/tsup/inspector-tab/mod.cjs +2 -2
- package/dist/tsup/inspector-tab/mod.d.cts +2 -2
- package/dist/tsup/inspector-tab/mod.d.ts +2 -2
- package/dist/tsup/inspector-tab/mod.js +1 -1
- package/dist/tsup/mod.cjs +188 -416
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +3 -3
- package/dist/tsup/mod.d.ts +3 -3
- package/dist/tsup/mod.js +90 -318
- package/dist/tsup/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +6 -6
- package/dist/tsup/test/mod.d.cts +1 -1
- package/dist/tsup/test/mod.d.ts +1 -1
- package/dist/tsup/test/mod.js +4 -4
- package/dist/tsup/utils.cjs +2 -2
- package/dist/tsup/utils.js +1 -1
- package/dist/tsup/workflow/mod.cjs +21 -69
- package/dist/tsup/workflow/mod.cjs.map +1 -1
- package/dist/tsup/workflow/mod.d.cts +3 -3
- package/dist/tsup/workflow/mod.d.ts +3 -3
- package/dist/tsup/workflow/mod.js +16 -64
- package/dist/tsup/workflow/mod.js.map +1 -1
- package/package.json +9 -9
- package/src/actor/config.ts +0 -2
- package/src/client/config.ts +3 -0
- package/src/client/raw-utils.ts +7 -2
- package/src/common/fetch-like.ts +14 -0
- package/src/engine-client/actor-http-client.ts +16 -6
- package/src/registry/napi-runtime.ts +0 -8
- package/src/registry/native.ts +65 -332
- package/src/registry/run-handler-coordinator.test.ts +0 -102
- package/src/registry/run-handler-coordinator.ts +17 -84
- package/src/registry/runtime.ts +0 -2
- package/src/registry/wasm-runtime.ts +0 -8
- package/src/workflow/context.ts +0 -20
- package/src/workflow/driver.ts +1 -25
- package/src/workflow/mod.ts +12 -46
- package/dist/tsup/chunk-B6WTPGOR.js.map +0 -1
- package/dist/tsup/chunk-JJCUSUWO.js.map +0 -1
- package/dist/tsup/chunk-LTGBHN5Z.js.map +0 -1
- package/dist/tsup/chunk-NGJWQMUU.cjs.map +0 -1
- package/dist/tsup/chunk-R3UI7MO3.cjs.map +0 -1
- package/dist/tsup/chunk-YVVFOKEP.cjs.map +0 -1
- package/src/registry/lost-callbacks.test.ts +0 -64
- /package/dist/tsup/{chunk-6HW3TU7Q.js.map → chunk-45WBFRBN.js.map} +0 -0
- /package/dist/tsup/{chunk-64CRWLOX.js.map → chunk-7OEOLF5T.js.map} +0 -0
- /package/dist/tsup/{chunk-OB5JLDBM.js.map → chunk-NSNBWLCG.js.map} +0 -0
- /package/dist/tsup/{chunk-M5J3PXNU.js.map → chunk-QMR2J7PT.js.map} +0 -0
- /package/dist/tsup/{chunk-QQ454DVR.js.map → chunk-QZQE75U2.js.map} +0 -0
- /package/dist/tsup/{chunk-JKDAOE4T.js.map → chunk-UIPQ7RI4.js.map} +0 -0
package/src/registry/native.ts
CHANGED
|
@@ -541,11 +541,8 @@ async function cleanupNativeSleepRuntimeState(
|
|
|
541
541
|
void runtime
|
|
542
542
|
.actorWaitForTrackedShutdownWorkUnbounded(ctx)
|
|
543
543
|
.then(async () => {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
} finally {
|
|
547
|
-
clearNativeRuntimeState(runtime, ctx);
|
|
548
|
-
}
|
|
544
|
+
await afterTrackedWorkDrained?.();
|
|
545
|
+
clearNativeRuntimeState(runtime, ctx);
|
|
549
546
|
})
|
|
550
547
|
.catch((error) => {
|
|
551
548
|
logger().warn({
|
|
@@ -556,31 +553,10 @@ async function cleanupNativeSleepRuntimeState(
|
|
|
556
553
|
return;
|
|
557
554
|
}
|
|
558
555
|
|
|
559
|
-
|
|
560
|
-
await afterTrackedWorkDrained?.();
|
|
561
|
-
} finally {
|
|
562
|
-
try {
|
|
563
|
-
await closeNativeDatabaseClient(runtime, ctx);
|
|
564
|
-
await closeNativeSqlDatabase(runtime, ctx);
|
|
565
|
-
} finally {
|
|
566
|
-
clearNativeRuntimeState(runtime, ctx);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
async function cleanupNativeLostRuntimeState(
|
|
572
|
-
runtime: CoreRuntime,
|
|
573
|
-
ctx: ActorContextHandle,
|
|
574
|
-
): Promise<void> {
|
|
575
|
-
// Core has already abandoned a lost generation's user work, so this does not wait for it.
|
|
576
|
-
// A custom database client's `close` is user code, so a lost generation drops the client
|
|
577
|
-
// without calling it. The native database underneath is closed by the runtime.
|
|
556
|
+
await afterTrackedWorkDrained?.();
|
|
578
557
|
await closeNativeDatabaseClient(runtime, ctx);
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
} finally {
|
|
582
|
-
clearNativeRuntimeState(runtime, ctx);
|
|
583
|
-
}
|
|
558
|
+
await closeNativeSqlDatabase(runtime, ctx);
|
|
559
|
+
clearNativeRuntimeState(runtime, ctx);
|
|
584
560
|
}
|
|
585
561
|
|
|
586
562
|
function closeNativeSqlDatabase(
|
|
@@ -609,11 +585,6 @@ async function closeNativeDatabaseClient(
|
|
|
609
585
|
|
|
610
586
|
runtimeState.databaseClient = undefined;
|
|
611
587
|
|
|
612
|
-
// `close` is user code from a database provider. Cleanup paths await before reaching this,
|
|
613
|
-
// so check here: a lost generation drops the client without calling it.
|
|
614
|
-
if (callNativeSync(() => runtime.actorIsLost(ctx))) {
|
|
615
|
-
return;
|
|
616
|
-
}
|
|
617
588
|
if (
|
|
618
589
|
entry.client &&
|
|
619
590
|
typeof entry.client === "object" &&
|
|
@@ -1330,76 +1301,6 @@ function wrapNativeCallback<Args extends Array<unknown>, Result>(
|
|
|
1330
1301
|
};
|
|
1331
1302
|
}
|
|
1332
1303
|
|
|
1333
|
-
/**
|
|
1334
|
-
* Callbacks that still run for a lost generation. They release the generation's runtime
|
|
1335
|
-
* resources and skip the user hook themselves.
|
|
1336
|
-
*/
|
|
1337
|
-
const LOST_GENERATION_CLEANUP_CALLBACKS = new Set(["onSleep", "onDestroy"]);
|
|
1338
|
-
|
|
1339
|
-
/**
|
|
1340
|
-
* Refuses to start a user callback for a generation that was declared lost. Call it right
|
|
1341
|
-
* before the callback, after any other user code such as schema validation.
|
|
1342
|
-
*/
|
|
1343
|
-
function throwIfActorLost(runtime: CoreRuntime, ctx: ActorContextHandle): void {
|
|
1344
|
-
if (callNativeSync(() => runtime.actorIsLost(ctx))) {
|
|
1345
|
-
throw actorGenerationLostError();
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
function actorGenerationLostError(): RivetError {
|
|
1350
|
-
return new RivetError(
|
|
1351
|
-
"actor",
|
|
1352
|
-
"stopping",
|
|
1353
|
-
"Actor generation was declared lost; it starts no new user callbacks.",
|
|
1354
|
-
);
|
|
1355
|
-
}
|
|
1356
|
-
|
|
1357
|
-
/**
|
|
1358
|
-
* Refuses every runtime callback for a generation that has been declared lost. Runtime
|
|
1359
|
-
* callbacks can be queued or spawned before the loss and only start afterward, so the check
|
|
1360
|
-
* runs when JS actually enters the callback.
|
|
1361
|
-
*/
|
|
1362
|
-
export function refuseCallbacksAfterLost<T extends Record<string, unknown>>(
|
|
1363
|
-
runtime: CoreRuntime,
|
|
1364
|
-
callbacks: T,
|
|
1365
|
-
): T {
|
|
1366
|
-
const guard = (callback: (...args: unknown[]) => unknown) => {
|
|
1367
|
-
return async (...args: unknown[]) => {
|
|
1368
|
-
const ctx = (args[1] as { ctx?: ActorContextHandle } | undefined)
|
|
1369
|
-
?.ctx;
|
|
1370
|
-
if (
|
|
1371
|
-
ctx !== undefined &&
|
|
1372
|
-
callNativeSync(() => runtime.actorIsLost(ctx))
|
|
1373
|
-
) {
|
|
1374
|
-
throw encodeNativeCallbackError(actorGenerationLostError());
|
|
1375
|
-
}
|
|
1376
|
-
return await callback(...args);
|
|
1377
|
-
};
|
|
1378
|
-
};
|
|
1379
|
-
const guarded: Record<string, unknown> = {};
|
|
1380
|
-
for (const [name, value] of Object.entries(callbacks)) {
|
|
1381
|
-
if (LOST_GENERATION_CLEANUP_CALLBACKS.has(name)) {
|
|
1382
|
-
guarded[name] = value;
|
|
1383
|
-
} else if (typeof value === "function") {
|
|
1384
|
-
guarded[name] = guard(value as (...args: unknown[]) => unknown);
|
|
1385
|
-
} else if (
|
|
1386
|
-
name === "actions" &&
|
|
1387
|
-
value !== null &&
|
|
1388
|
-
typeof value === "object"
|
|
1389
|
-
) {
|
|
1390
|
-
guarded[name] = Object.fromEntries(
|
|
1391
|
-
Object.entries(value).map(([actionName, handler]) => [
|
|
1392
|
-
actionName,
|
|
1393
|
-
guard(handler as (...args: unknown[]) => unknown),
|
|
1394
|
-
]),
|
|
1395
|
-
);
|
|
1396
|
-
} else {
|
|
1397
|
-
guarded[name] = value;
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
return guarded as T;
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
1304
|
function decodeArgs(value?: RuntimeBytes | null): unknown[] {
|
|
1404
1305
|
const decoded = decodeValue<unknown>(value);
|
|
1405
1306
|
return normalizeArgs(decoded);
|
|
@@ -1979,26 +1880,9 @@ class NativeQueueAdapter {
|
|
|
1979
1880
|
this.#schemas = schemas;
|
|
1980
1881
|
}
|
|
1981
1882
|
|
|
1982
|
-
// Queue results arrive after awaits, and their schema validation is user code, so each
|
|
1983
|
-
// validation checks that the generation was not lost first.
|
|
1984
|
-
#validateBody(name: string, body: unknown): unknown {
|
|
1985
|
-
throwIfActorLost(this.#runtime, this.#ctx);
|
|
1986
|
-
return validateQueueBody(this.#schemas, name, body);
|
|
1987
|
-
}
|
|
1988
|
-
|
|
1989
|
-
#validateComplete(name: string, response: unknown): unknown {
|
|
1990
|
-
throwIfActorLost(this.#runtime, this.#ctx);
|
|
1991
|
-
return validateQueueComplete(this.#schemas, name, response);
|
|
1992
|
-
}
|
|
1993
|
-
|
|
1994
|
-
#wrap(message: Parameters<typeof wrapQueueMessage>[0]) {
|
|
1995
|
-
throwIfActorLost(this.#runtime, this.#ctx);
|
|
1996
|
-
return wrapQueueMessage(message, this.#schemas);
|
|
1997
|
-
}
|
|
1998
|
-
|
|
1999
1883
|
async send(name: string, body: unknown) {
|
|
2000
|
-
const validatedBody = this.#
|
|
2001
|
-
return
|
|
1884
|
+
const validatedBody = validateQueueBody(this.#schemas, name, body);
|
|
1885
|
+
return wrapQueueMessage(
|
|
2002
1886
|
await callNative(() =>
|
|
2003
1887
|
this.#runtime.actorQueueSend(
|
|
2004
1888
|
this.#ctx,
|
|
@@ -2006,6 +1890,7 @@ class NativeQueueAdapter {
|
|
|
2006
1890
|
encodeValue(validatedBody),
|
|
2007
1891
|
),
|
|
2008
1892
|
),
|
|
1893
|
+
this.#schemas,
|
|
2009
1894
|
);
|
|
2010
1895
|
}
|
|
2011
1896
|
|
|
@@ -2063,7 +1948,9 @@ class NativeQueueAdapter {
|
|
|
2063
1948
|
token,
|
|
2064
1949
|
),
|
|
2065
1950
|
);
|
|
2066
|
-
const wrapped = messages.map((message) =>
|
|
1951
|
+
const wrapped = messages.map((message) =>
|
|
1952
|
+
wrapQueueMessage(message, this.#schemas),
|
|
1953
|
+
);
|
|
2067
1954
|
return completable
|
|
2068
1955
|
? wrapped.map((message) =>
|
|
2069
1956
|
this.#makeCompletableMessage(message),
|
|
@@ -2088,7 +1975,7 @@ class NativeQueueAdapter {
|
|
|
2088
1975
|
);
|
|
2089
1976
|
|
|
2090
1977
|
try {
|
|
2091
|
-
return
|
|
1978
|
+
return wrapQueueMessage(
|
|
2092
1979
|
await callNative(() =>
|
|
2093
1980
|
this.#runtime.actorQueueWaitForNames(
|
|
2094
1981
|
this.#ctx,
|
|
@@ -2100,6 +1987,7 @@ class NativeQueueAdapter {
|
|
|
2100
1987
|
token,
|
|
2101
1988
|
),
|
|
2102
1989
|
),
|
|
1990
|
+
this.#schemas,
|
|
2103
1991
|
);
|
|
2104
1992
|
} finally {
|
|
2105
1993
|
cleanup?.();
|
|
@@ -2144,7 +2032,8 @@ class NativeQueueAdapter {
|
|
|
2144
2032
|
message: { id: number | bigint; name: string },
|
|
2145
2033
|
response?: unknown,
|
|
2146
2034
|
): Promise<void> {
|
|
2147
|
-
const validatedResponse =
|
|
2035
|
+
const validatedResponse = validateQueueComplete(
|
|
2036
|
+
this.#schemas,
|
|
2148
2037
|
message.name,
|
|
2149
2038
|
response,
|
|
2150
2039
|
);
|
|
@@ -2167,7 +2056,7 @@ class NativeQueueAdapter {
|
|
|
2167
2056
|
signal?: AbortSignal;
|
|
2168
2057
|
},
|
|
2169
2058
|
) {
|
|
2170
|
-
const validatedBody = this.#
|
|
2059
|
+
const validatedBody = validateQueueBody(this.#schemas, name, body);
|
|
2171
2060
|
const { token, cleanup } = await createCancellationTokenHandle(
|
|
2172
2061
|
this.#runtime,
|
|
2173
2062
|
options?.signal,
|
|
@@ -2187,7 +2076,11 @@ class NativeQueueAdapter {
|
|
|
2187
2076
|
);
|
|
2188
2077
|
return response === undefined || response === null
|
|
2189
2078
|
? undefined
|
|
2190
|
-
:
|
|
2079
|
+
: validateQueueComplete(
|
|
2080
|
+
this.#schemas,
|
|
2081
|
+
name,
|
|
2082
|
+
decodeValue(response),
|
|
2083
|
+
);
|
|
2191
2084
|
} finally {
|
|
2192
2085
|
cleanup?.();
|
|
2193
2086
|
}
|
|
@@ -2690,12 +2583,6 @@ class TrackedWebSocketHandleAdapter implements UniversalWebSocket {
|
|
|
2690
2583
|
handler: TrackedWebSocketListener,
|
|
2691
2584
|
event: any,
|
|
2692
2585
|
): void {
|
|
2693
|
-
// Messages and opens start new user work, so a lost generation drops them. Each listener
|
|
2694
|
-
// is checked because an earlier one can run while the generation is lost. Close and
|
|
2695
|
-
// error still reach listeners, like the abort signal, so user code can wind down.
|
|
2696
|
-
if ((type === "message" || type === "open") && this.#ctx.isLost) {
|
|
2697
|
-
return;
|
|
2698
|
-
}
|
|
2699
2586
|
try {
|
|
2700
2587
|
const result = handler(event);
|
|
2701
2588
|
if (!this.#isPromiseLike(result)) {
|
|
@@ -3076,15 +2963,6 @@ export class ActorContextHandleAdapter {
|
|
|
3076
2963
|
return callNativeSync(() => this.#runtime.actorId(this.#ctx));
|
|
3077
2964
|
}
|
|
3078
2965
|
|
|
3079
|
-
get actorGeneration(): number | undefined {
|
|
3080
|
-
return callNativeSync(() => this.#runtime.actorGeneration(this.#ctx));
|
|
3081
|
-
}
|
|
3082
|
-
|
|
3083
|
-
/** Whether this generation was declared lost. A lost generation starts no new user code. */
|
|
3084
|
-
get isLost(): boolean {
|
|
3085
|
-
return callNativeSync(() => this.#runtime.actorIsLost(this.#ctx));
|
|
3086
|
-
}
|
|
3087
|
-
|
|
3088
2966
|
get name(): string {
|
|
3089
2967
|
return callNativeSync(() => this.#runtime.actorName(this.#ctx));
|
|
3090
2968
|
}
|
|
@@ -3218,10 +3096,6 @@ export class ActorContextHandleAdapter {
|
|
|
3218
3096
|
}
|
|
3219
3097
|
|
|
3220
3098
|
const actorId = this.actorId;
|
|
3221
|
-
// `createClient` is user code from a database provider.
|
|
3222
|
-
if (this.isLost) {
|
|
3223
|
-
throw actorGenerationLostError();
|
|
3224
|
-
}
|
|
3225
3099
|
const createdClient = await this.#databaseProvider.createClient({
|
|
3226
3100
|
actorId,
|
|
3227
3101
|
kv: {
|
|
@@ -3399,12 +3273,9 @@ export class ActorContextHandleAdapter {
|
|
|
3399
3273
|
return;
|
|
3400
3274
|
}
|
|
3401
3275
|
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
throw actorGenerationLostError();
|
|
3406
|
-
}
|
|
3407
|
-
await this.#databaseProvider.onMigrate(client as never);
|
|
3276
|
+
await this.#databaseProvider.onMigrate(
|
|
3277
|
+
(await this.ensureDatabaseClient()) as never,
|
|
3278
|
+
);
|
|
3408
3279
|
}
|
|
3409
3280
|
|
|
3410
3281
|
async closeDatabase(): Promise<void> {
|
|
@@ -3739,8 +3610,7 @@ export class ActorContextHandleAdapter {
|
|
|
3739
3610
|
this.#runtime.actorRequestSave(this.#ctx, { immediate: false }),
|
|
3740
3611
|
);
|
|
3741
3612
|
|
|
3742
|
-
|
|
3743
|
-
if (!this.#onStateChange || this.isLost) {
|
|
3613
|
+
if (!this.#onStateChange) {
|
|
3744
3614
|
return;
|
|
3745
3615
|
}
|
|
3746
3616
|
|
|
@@ -3789,13 +3659,6 @@ class NativeWorkflowRuntimeAdapter {
|
|
|
3789
3659
|
#completions = new Map<string, (response?: unknown) => Promise<void>>();
|
|
3790
3660
|
|
|
3791
3661
|
readonly id: string;
|
|
3792
|
-
/** Actor generation, used to keep workflow registrations of different generations apart. */
|
|
3793
|
-
readonly generation: number | undefined;
|
|
3794
|
-
|
|
3795
|
-
/** Whether this generation was declared lost. Workflow code checks it before each user callback. */
|
|
3796
|
-
get isLost(): boolean {
|
|
3797
|
-
return this.#ctx.isLost;
|
|
3798
|
-
}
|
|
3799
3662
|
readonly driver: {
|
|
3800
3663
|
kvBatchGet: (
|
|
3801
3664
|
actorId: string,
|
|
@@ -3867,7 +3730,6 @@ class NativeWorkflowRuntimeAdapter {
|
|
|
3867
3730
|
this.#ctx = ctx;
|
|
3868
3731
|
this.#onMessagesReceived = onMessagesReceived;
|
|
3869
3732
|
this.id = ctx.actorId;
|
|
3870
|
-
this.generation = ctx.actorGeneration;
|
|
3871
3733
|
this.driver = {
|
|
3872
3734
|
kvBatchGet: async (actorId, keys) => {
|
|
3873
3735
|
this.#assertActorId(actorId);
|
|
@@ -4239,29 +4101,14 @@ export function buildNativeFactory(
|
|
|
4239
4101
|
? new RunHandlerCoordinator(config.run)
|
|
4240
4102
|
: undefined;
|
|
4241
4103
|
const getNativeWorkflowInspector = (ctx: ActorContextHandle) => {
|
|
4242
|
-
// Inspector workflow calls run user code (history, state, replay). A lost generation
|
|
4243
|
-
// exposes no workflow inspector.
|
|
4244
|
-
if (callNativeSync(() => runtime.actorIsLost(ctx))) {
|
|
4245
|
-
return undefined;
|
|
4246
|
-
}
|
|
4247
4104
|
const actorId = callNativeSync(() => runtime.actorId(ctx));
|
|
4248
4105
|
const restart = () =>
|
|
4249
4106
|
callNativeSync(() => runtime.actorRestartRunHandler(ctx));
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
const inspector = (runHandlerCoordinator?.getInspector(
|
|
4254
|
-
actorId,
|
|
4255
|
-
restart,
|
|
4256
|
-
actorGeneration,
|
|
4257
|
-
)?.workflow ?? getRunInspectorConfig(config.run, actorId)?.workflow) as
|
|
4107
|
+
return (runHandlerCoordinator?.getInspector(actorId, restart)
|
|
4108
|
+
?.workflow ??
|
|
4109
|
+
getRunInspectorConfig(config.run, actorId)?.workflow) as
|
|
4258
4110
|
| NativeWorkflowInspectorConfig
|
|
4259
4111
|
| undefined;
|
|
4260
|
-
// Building the inspector can run a user factory, and the generation can be lost meanwhile.
|
|
4261
|
-
if (callNativeSync(() => runtime.actorIsLost(ctx))) {
|
|
4262
|
-
return undefined;
|
|
4263
|
-
}
|
|
4264
|
-
return inspector;
|
|
4265
4112
|
};
|
|
4266
4113
|
const onStateChange =
|
|
4267
4114
|
typeof config.onStateChange === "function"
|
|
@@ -4381,11 +4228,6 @@ export function buildNativeFactory(
|
|
|
4381
4228
|
}
|
|
4382
4229
|
}
|
|
4383
4230
|
|
|
4384
|
-
// Reading connection params runs the user schema, and authentication awaited before this.
|
|
4385
|
-
const inspectorConnParams = (conn: { params: unknown }) => {
|
|
4386
|
-
throwIfActorLost(runtime, ctx);
|
|
4387
|
-
return conn.params;
|
|
4388
|
-
};
|
|
4389
4231
|
const workflowHistory = () =>
|
|
4390
4232
|
serializeWorkflowHistoryForJson(
|
|
4391
4233
|
getNativeWorkflowInspector(ctx)?.getHistory() ?? null,
|
|
@@ -4424,7 +4266,7 @@ export function buildNativeFactory(
|
|
|
4424
4266
|
id: conn.id,
|
|
4425
4267
|
details: {
|
|
4426
4268
|
type: null,
|
|
4427
|
-
params:
|
|
4269
|
+
params: conn.params,
|
|
4428
4270
|
stateEnabled: true,
|
|
4429
4271
|
state: conn.state,
|
|
4430
4272
|
subscriptions: 0,
|
|
@@ -4684,7 +4526,7 @@ export function buildNativeFactory(
|
|
|
4684
4526
|
id: conn.id,
|
|
4685
4527
|
details: {
|
|
4686
4528
|
type: null,
|
|
4687
|
-
params:
|
|
4529
|
+
params: conn.params,
|
|
4688
4530
|
stateEnabled: true,
|
|
4689
4531
|
state: conn.state,
|
|
4690
4532
|
subscriptions: 0,
|
|
@@ -4746,22 +4588,15 @@ export function buildNativeFactory(
|
|
|
4746
4588
|
body.properties !== undefined
|
|
4747
4589
|
? [body.properties]
|
|
4748
4590
|
: normalizeArgs(body.args);
|
|
4749
|
-
// Authentication and body parsing may finish after the generation was lost.
|
|
4750
|
-
if (callNativeSync(() => runtime.actorIsLost(ctx))) {
|
|
4751
|
-
return jsonResponse(
|
|
4752
|
-
{ error: "actor generation was declared lost" },
|
|
4753
|
-
{ status: 503 },
|
|
4754
|
-
);
|
|
4755
|
-
}
|
|
4756
4591
|
try {
|
|
4757
|
-
const
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4592
|
+
const output = await action(
|
|
4593
|
+
actorCtx,
|
|
4594
|
+
...validateActionArgs(
|
|
4595
|
+
schemaConfig.actionInputSchemas,
|
|
4596
|
+
actionName,
|
|
4597
|
+
args,
|
|
4598
|
+
),
|
|
4761
4599
|
);
|
|
4762
|
-
// Schema validation is user code and can run while the generation is lost.
|
|
4763
|
-
throwIfActorLost(runtime, ctx);
|
|
4764
|
-
const output = await action(actorCtx, ...validatedArgs);
|
|
4765
4600
|
return jsonResponse({ output });
|
|
4766
4601
|
} catch (error) {
|
|
4767
4602
|
logger().error({
|
|
@@ -4903,14 +4738,7 @@ export function buildNativeFactory(
|
|
|
4903
4738
|
await actorCtx.closeDatabase();
|
|
4904
4739
|
}
|
|
4905
4740
|
await actorCtx.runDatabaseMigrations();
|
|
4906
|
-
|
|
4907
|
-
// generation starts no new user hooks.
|
|
4908
|
-
if (
|
|
4909
|
-
typeof config.onMigrate === "function" &&
|
|
4910
|
-
!callNativeSync(() =>
|
|
4911
|
-
runtime.actorIsLost(ctx),
|
|
4912
|
-
)
|
|
4913
|
-
) {
|
|
4741
|
+
if (typeof config.onMigrate === "function") {
|
|
4914
4742
|
await config.onMigrate(actorCtx, isNew);
|
|
4915
4743
|
}
|
|
4916
4744
|
} catch (error) {
|
|
@@ -4966,38 +4794,10 @@ export function buildNativeFactory(
|
|
|
4966
4794
|
const { ctx } = unwrapTsfnPayload(error, payload);
|
|
4967
4795
|
const actorCtx = makeActorCtx(ctx);
|
|
4968
4796
|
const actorId = callNativeSync(() => runtime.actorId(ctx));
|
|
4969
|
-
const actorGeneration = callNativeSync(() =>
|
|
4970
|
-
runtime.actorGeneration(ctx),
|
|
4971
|
-
);
|
|
4972
|
-
// The engine can declare this generation lost before or during `onSleep`.
|
|
4973
|
-
// A lost generation releases its own runtime resources only: no user hook,
|
|
4974
|
-
// no state save, and nothing keyed by actor id alone.
|
|
4975
|
-
const isLost = () =>
|
|
4976
|
-
callNativeSync(() => runtime.actorIsLost(ctx));
|
|
4977
|
-
if (isLost()) {
|
|
4978
|
-
try {
|
|
4979
|
-
await cleanupNativeLostRuntimeState(runtime, ctx);
|
|
4980
|
-
} finally {
|
|
4981
|
-
runHandlerCoordinator?.destroy(
|
|
4982
|
-
actorId,
|
|
4983
|
-
actorGeneration,
|
|
4984
|
-
{
|
|
4985
|
-
disposeInspector: false,
|
|
4986
|
-
},
|
|
4987
|
-
);
|
|
4988
|
-
await actorCtx.dispose();
|
|
4989
|
-
}
|
|
4990
|
-
return;
|
|
4991
|
-
}
|
|
4992
4797
|
// TODO: Move this save hook into cleanupNativeSleepRuntimeState
|
|
4993
4798
|
// so immediate and deferred sleep cleanup share one save-state
|
|
4994
4799
|
// path instead of passing a callback through cleanup.
|
|
4995
4800
|
const saveActorState = async () => {
|
|
4996
|
-
// Cleanup waits on tracked work first, and the generation can be lost
|
|
4997
|
-
// during that wait.
|
|
4998
|
-
if (isLost()) {
|
|
4999
|
-
return;
|
|
5000
|
-
}
|
|
5001
4801
|
if (runtime.kind === "wasm") {
|
|
5002
4802
|
// Wasm cannot use the native context save helper here because
|
|
5003
4803
|
// the runtime owns the serialized state handoff.
|
|
@@ -5018,26 +4818,14 @@ export function buildNativeFactory(
|
|
|
5018
4818
|
await saveActorState();
|
|
5019
4819
|
} finally {
|
|
5020
4820
|
try {
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
runtime,
|
|
5026
|
-
ctx,
|
|
5027
|
-
saveActorState,
|
|
5028
|
-
);
|
|
5029
|
-
}
|
|
5030
|
-
} finally {
|
|
5031
|
-
runHandlerCoordinator?.destroy(
|
|
5032
|
-
actorId,
|
|
5033
|
-
actorGeneration,
|
|
5034
|
-
{
|
|
5035
|
-
disposeInspector: !isLost(),
|
|
5036
|
-
},
|
|
4821
|
+
await cleanupNativeSleepRuntimeState(
|
|
4822
|
+
runtime,
|
|
4823
|
+
ctx,
|
|
4824
|
+
saveActorState,
|
|
5037
4825
|
);
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
4826
|
+
} finally {
|
|
4827
|
+
runHandlerCoordinator?.destroy(actorId);
|
|
4828
|
+
disposeRunInspector(config.run, actorId);
|
|
5041
4829
|
await actorCtx.dispose();
|
|
5042
4830
|
}
|
|
5043
4831
|
}
|
|
@@ -5048,22 +4836,12 @@ export function buildNativeFactory(
|
|
|
5048
4836
|
const { ctx } = unwrapTsfnPayload(error, payload);
|
|
5049
4837
|
const actorCtx = makeActorCtx(ctx);
|
|
5050
4838
|
const actorId = callNativeSync(() => runtime.actorId(ctx));
|
|
5051
|
-
// A lost generation still releases its runtime state but starts no user hook. Loss
|
|
5052
|
-
// is rechecked before each user callback because it can happen while one runs.
|
|
5053
|
-
const isLost = () =>
|
|
5054
|
-
callNativeSync(() => runtime.actorIsLost(ctx));
|
|
5055
4839
|
// Close run control before user cleanup so replay cannot race actor
|
|
5056
4840
|
// destruction. Recreating this actor id receives a fresh controller.
|
|
5057
|
-
runHandlerCoordinator?.destroy(
|
|
5058
|
-
|
|
5059
|
-
callNativeSync(() => runtime.actorGeneration(ctx)),
|
|
5060
|
-
{ disposeInspector: !isLost() },
|
|
5061
|
-
);
|
|
5062
|
-
if (!isLost()) {
|
|
5063
|
-
disposeRunInspector(config.run, actorId);
|
|
5064
|
-
}
|
|
4841
|
+
runHandlerCoordinator?.destroy(actorId);
|
|
4842
|
+
disposeRunInspector(config.run, actorId);
|
|
5065
4843
|
try {
|
|
5066
|
-
if (typeof config.onDestroy === "function"
|
|
4844
|
+
if (typeof config.onDestroy === "function") {
|
|
5067
4845
|
await config.onDestroy(actorCtx);
|
|
5068
4846
|
}
|
|
5069
4847
|
} finally {
|
|
@@ -5101,16 +4879,12 @@ export function buildNativeFactory(
|
|
|
5101
4879
|
: undefined,
|
|
5102
4880
|
);
|
|
5103
4881
|
try {
|
|
5104
|
-
const validatedParams = validateConnParams(
|
|
5105
|
-
schemaConfig.connParamsSchema,
|
|
5106
|
-
decodeValue(params),
|
|
5107
|
-
);
|
|
5108
|
-
// Schema validation is user code and can run while the
|
|
5109
|
-
// generation is lost.
|
|
5110
|
-
throwIfActorLost(runtime, ctx);
|
|
5111
4882
|
await config.onBeforeConnect(
|
|
5112
4883
|
actorCtx,
|
|
5113
|
-
|
|
4884
|
+
validateConnParams(
|
|
4885
|
+
schemaConfig.connParamsSchema,
|
|
4886
|
+
decodeValue(params),
|
|
4887
|
+
),
|
|
5114
4888
|
);
|
|
5115
4889
|
} finally {
|
|
5116
4890
|
await actorCtx.dispose();
|
|
@@ -5158,25 +4932,15 @@ export function buildNativeFactory(
|
|
|
5158
4932
|
() => actorCtx.assertCanMutateState(),
|
|
5159
4933
|
);
|
|
5160
4934
|
try {
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
config.connState,
|
|
5165
|
-
);
|
|
5166
|
-
} else {
|
|
5167
|
-
const validatedParams = validateConnParams(
|
|
5168
|
-
schemaConfig.connParamsSchema,
|
|
5169
|
-
decodeValue(params),
|
|
5170
|
-
);
|
|
5171
|
-
// Schema validation is user code and can run while the
|
|
5172
|
-
// generation is lost.
|
|
5173
|
-
throwIfActorLost(runtime, ctx);
|
|
5174
|
-
nextConnState =
|
|
5175
|
-
await config.createConnState(
|
|
4935
|
+
const nextConnState = hasStaticConnState
|
|
4936
|
+
? structuredClone(config.connState)
|
|
4937
|
+
: await config.createConnState(
|
|
5176
4938
|
actorCtx,
|
|
5177
|
-
|
|
4939
|
+
validateConnParams(
|
|
4940
|
+
schemaConfig.connParamsSchema,
|
|
4941
|
+
decodeValue(params),
|
|
4942
|
+
),
|
|
5178
4943
|
);
|
|
5179
|
-
}
|
|
5180
4944
|
connAdapter.initializeState(nextConnState);
|
|
5181
4945
|
return encodeValue(nextConnState);
|
|
5182
4946
|
} finally {
|
|
@@ -5335,13 +5099,6 @@ export function buildNativeFactory(
|
|
|
5335
5099
|
) => {
|
|
5336
5100
|
const { ctx, name, args, output } =
|
|
5337
5101
|
unwrapTsfnPayload(error, payload);
|
|
5338
|
-
// The action may finish after its generation was lost, and a lost
|
|
5339
|
-
// generation starts no new user callbacks.
|
|
5340
|
-
if (
|
|
5341
|
-
callNativeSync(() => runtime.actorIsLost(ctx))
|
|
5342
|
-
) {
|
|
5343
|
-
return output;
|
|
5344
|
-
}
|
|
5345
5102
|
const actorCtx = makeActorCtx(ctx);
|
|
5346
5103
|
try {
|
|
5347
5104
|
return encodeValue(
|
|
@@ -5439,9 +5196,6 @@ export function buildNativeFactory(
|
|
|
5439
5196
|
}
|
|
5440
5197
|
};
|
|
5441
5198
|
try {
|
|
5442
|
-
// Inspector routing awaits, and the generation can be lost
|
|
5443
|
-
// meanwhile. Schema validation is user code.
|
|
5444
|
-
throwIfActorLost(runtime, ctx);
|
|
5445
5199
|
const connParams = validateConnParams(
|
|
5446
5200
|
schemaConfig.connParamsSchema,
|
|
5447
5201
|
rawConnParams
|
|
@@ -5480,14 +5234,6 @@ export function buildNativeFactory(
|
|
|
5480
5234
|
abortRequest,
|
|
5481
5235
|
);
|
|
5482
5236
|
}
|
|
5483
|
-
// Connection setup awaits, and the generation can be lost meanwhile.
|
|
5484
|
-
if (
|
|
5485
|
-
callNativeSync(() =>
|
|
5486
|
-
runtime.actorIsLost(ctx),
|
|
5487
|
-
)
|
|
5488
|
-
) {
|
|
5489
|
-
throw actorGenerationLostError();
|
|
5490
|
-
}
|
|
5491
5237
|
const response = await config.onRequest(
|
|
5492
5238
|
requestCtx,
|
|
5493
5239
|
handlerRequest,
|
|
@@ -5588,11 +5334,6 @@ export function buildNativeFactory(
|
|
|
5588
5334
|
const { ctx } = unwrapTsfnPayload(error, payload);
|
|
5589
5335
|
const actorId = callNativeSync(() => runtime.actorId(ctx));
|
|
5590
5336
|
const executeRun = async () => {
|
|
5591
|
-
// The coordinator can hold `run` behind other run work until after the
|
|
5592
|
-
// generation was lost.
|
|
5593
|
-
if (callNativeSync(() => runtime.actorIsLost(ctx))) {
|
|
5594
|
-
return;
|
|
5595
|
-
}
|
|
5596
5337
|
const actorCtx = makeActorCtx(ctx);
|
|
5597
5338
|
try {
|
|
5598
5339
|
await run(actorCtx);
|
|
@@ -5608,7 +5349,6 @@ export function buildNativeFactory(
|
|
|
5608
5349
|
runtime.actorRestartRunHandler(ctx),
|
|
5609
5350
|
),
|
|
5610
5351
|
executeRun,
|
|
5611
|
-
callNativeSync(() => runtime.actorGeneration(ctx)),
|
|
5612
5352
|
);
|
|
5613
5353
|
// Only a start suppressed behind a failed replay must preserve a
|
|
5614
5354
|
// consumed durable wake. Closed actors must remain closed.
|
|
@@ -5685,18 +5425,14 @@ export function buildNativeFactory(
|
|
|
5685
5425
|
: makeActorCtx(ctx, undefined, cancelToken);
|
|
5686
5426
|
const runAction = async () => {
|
|
5687
5427
|
try {
|
|
5688
|
-
const validatedArgs = validateActionArgs(
|
|
5689
|
-
schemaConfig.actionInputSchemas,
|
|
5690
|
-
name,
|
|
5691
|
-
decodeArgs(args),
|
|
5692
|
-
);
|
|
5693
|
-
// Schema validation is user code and can run while the
|
|
5694
|
-
// generation is lost.
|
|
5695
|
-
throwIfActorLost(runtime, ctx);
|
|
5696
5428
|
return encodeValue(
|
|
5697
5429
|
await handler(
|
|
5698
5430
|
actorCtx,
|
|
5699
|
-
...
|
|
5431
|
+
...validateActionArgs(
|
|
5432
|
+
schemaConfig.actionInputSchemas,
|
|
5433
|
+
name,
|
|
5434
|
+
decodeArgs(args),
|
|
5435
|
+
),
|
|
5700
5436
|
...(scheduledFire
|
|
5701
5437
|
? [scheduledFire]
|
|
5702
5438
|
: []),
|
|
@@ -5775,9 +5511,6 @@ export function buildNativeFactory(
|
|
|
5775
5511
|
if (canPublish && !(await canPublish(actorCtx))) {
|
|
5776
5512
|
throw forbiddenError();
|
|
5777
5513
|
}
|
|
5778
|
-
// `canPublish` can finish after the generation was lost, and
|
|
5779
|
-
// sending validates the body with user schema code.
|
|
5780
|
-
throwIfActorLost(runtime, ctx);
|
|
5781
5514
|
|
|
5782
5515
|
const decodedBody = decodeValue(body);
|
|
5783
5516
|
if (wait) {
|
|
@@ -5851,7 +5584,7 @@ export function buildNativeFactory(
|
|
|
5851
5584
|
};
|
|
5852
5585
|
|
|
5853
5586
|
return runtime.createActorFactory(
|
|
5854
|
-
|
|
5587
|
+
callbacks,
|
|
5855
5588
|
buildActorConfig(definition, registryConfig, runtime.kind),
|
|
5856
5589
|
);
|
|
5857
5590
|
}
|