@cadenza.io/core 3.26.1 → 3.27.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/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +56 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +56 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1993,6 +1993,7 @@ interface ActorSpec<D extends Record<string, any>, R = AnyObject> {
|
|
|
1993
1993
|
interface ActorFactoryOptions<D extends Record<string, any> = Record<string, any>, R = AnyObject> {
|
|
1994
1994
|
isMeta?: boolean;
|
|
1995
1995
|
definitionSource?: ActorDefinition<D, R>;
|
|
1996
|
+
hydrateDurableState?: (actorKey: string) => Promise<ActorDurableStateHydration<D> | null>;
|
|
1996
1997
|
}
|
|
1997
1998
|
/**
|
|
1998
1999
|
* Optional per-binding behavior when wrapping actor handlers.
|
|
@@ -2075,6 +2076,10 @@ interface ActorTaskContext<D extends Record<string, any>, R = AnyObject> {
|
|
|
2075
2076
|
* Handler signature used by `actor.task(...)`.
|
|
2076
2077
|
*/
|
|
2077
2078
|
type ActorTaskHandler<D extends Record<string, any>, R = AnyObject> = (context: ActorTaskContext<D, R>) => TaskResult | ActorStateReducer<D> | Promise<TaskResult | ActorStateReducer<D>>;
|
|
2079
|
+
interface ActorDurableStateHydration<D extends Record<string, any>> {
|
|
2080
|
+
durableState: D;
|
|
2081
|
+
durableVersion: number;
|
|
2082
|
+
}
|
|
2078
2083
|
/**
|
|
2079
2084
|
* Metadata attached to wrapped actor task functions.
|
|
2080
2085
|
*/
|
|
@@ -2101,9 +2106,11 @@ declare class Actor<D extends Record<string, any> = AnyObject, R = AnyObject> {
|
|
|
2101
2106
|
readonly spec: ActorSpec<D, R>;
|
|
2102
2107
|
readonly kind: ActorKind;
|
|
2103
2108
|
private readonly sourceDefinition?;
|
|
2109
|
+
private readonly hydrateDurableState?;
|
|
2104
2110
|
private readonly stateByKey;
|
|
2105
2111
|
private readonly sessionByKey;
|
|
2106
2112
|
private readonly idempotencyByKey;
|
|
2113
|
+
private readonly pendingHydrationByKey;
|
|
2107
2114
|
private readonly writeQueueByKey;
|
|
2108
2115
|
private nextTaskBindingIndex;
|
|
2109
2116
|
/**
|
|
@@ -2154,6 +2161,7 @@ declare class Actor<D extends Record<string, any> = AnyObject, R = AnyObject> {
|
|
|
2154
2161
|
private resolveInitialDurableState;
|
|
2155
2162
|
private resolveInitialRuntimeState;
|
|
2156
2163
|
private ensureStateRecord;
|
|
2164
|
+
private maybeHydrateStateRecord;
|
|
2157
2165
|
private touchSession;
|
|
2158
2166
|
private pruneExpiredActorKeys;
|
|
2159
2167
|
private isSessionExpired;
|
package/dist/index.d.ts
CHANGED
|
@@ -1993,6 +1993,7 @@ interface ActorSpec<D extends Record<string, any>, R = AnyObject> {
|
|
|
1993
1993
|
interface ActorFactoryOptions<D extends Record<string, any> = Record<string, any>, R = AnyObject> {
|
|
1994
1994
|
isMeta?: boolean;
|
|
1995
1995
|
definitionSource?: ActorDefinition<D, R>;
|
|
1996
|
+
hydrateDurableState?: (actorKey: string) => Promise<ActorDurableStateHydration<D> | null>;
|
|
1996
1997
|
}
|
|
1997
1998
|
/**
|
|
1998
1999
|
* Optional per-binding behavior when wrapping actor handlers.
|
|
@@ -2075,6 +2076,10 @@ interface ActorTaskContext<D extends Record<string, any>, R = AnyObject> {
|
|
|
2075
2076
|
* Handler signature used by `actor.task(...)`.
|
|
2076
2077
|
*/
|
|
2077
2078
|
type ActorTaskHandler<D extends Record<string, any>, R = AnyObject> = (context: ActorTaskContext<D, R>) => TaskResult | ActorStateReducer<D> | Promise<TaskResult | ActorStateReducer<D>>;
|
|
2079
|
+
interface ActorDurableStateHydration<D extends Record<string, any>> {
|
|
2080
|
+
durableState: D;
|
|
2081
|
+
durableVersion: number;
|
|
2082
|
+
}
|
|
2078
2083
|
/**
|
|
2079
2084
|
* Metadata attached to wrapped actor task functions.
|
|
2080
2085
|
*/
|
|
@@ -2101,9 +2106,11 @@ declare class Actor<D extends Record<string, any> = AnyObject, R = AnyObject> {
|
|
|
2101
2106
|
readonly spec: ActorSpec<D, R>;
|
|
2102
2107
|
readonly kind: ActorKind;
|
|
2103
2108
|
private readonly sourceDefinition?;
|
|
2109
|
+
private readonly hydrateDurableState?;
|
|
2104
2110
|
private readonly stateByKey;
|
|
2105
2111
|
private readonly sessionByKey;
|
|
2106
2112
|
private readonly idempotencyByKey;
|
|
2113
|
+
private readonly pendingHydrationByKey;
|
|
2107
2114
|
private readonly writeQueueByKey;
|
|
2108
2115
|
private nextTaskBindingIndex;
|
|
2109
2116
|
/**
|
|
@@ -2154,6 +2161,7 @@ declare class Actor<D extends Record<string, any> = AnyObject, R = AnyObject> {
|
|
|
2154
2161
|
private resolveInitialDurableState;
|
|
2155
2162
|
private resolveInitialRuntimeState;
|
|
2156
2163
|
private ensureStateRecord;
|
|
2164
|
+
private maybeHydrateStateRecord;
|
|
2157
2165
|
private touchSession;
|
|
2158
2166
|
private pruneExpiredActorKeys;
|
|
2159
2167
|
private isSessionExpired;
|
package/dist/index.js
CHANGED
|
@@ -3893,6 +3893,7 @@ var Actor = class {
|
|
|
3893
3893
|
this.stateByKey = /* @__PURE__ */ new Map();
|
|
3894
3894
|
this.sessionByKey = /* @__PURE__ */ new Map();
|
|
3895
3895
|
this.idempotencyByKey = /* @__PURE__ */ new Map();
|
|
3896
|
+
this.pendingHydrationByKey = /* @__PURE__ */ new Map();
|
|
3896
3897
|
this.writeQueueByKey = /* @__PURE__ */ new Map();
|
|
3897
3898
|
this.nextTaskBindingIndex = 0;
|
|
3898
3899
|
if (!spec.name || typeof spec.name !== "string") {
|
|
@@ -3904,6 +3905,7 @@ var Actor = class {
|
|
|
3904
3905
|
}
|
|
3905
3906
|
this.kind = options.isMeta || spec.kind === "meta" ? "meta" : "standard";
|
|
3906
3907
|
this.sourceDefinition = options.definitionSource;
|
|
3908
|
+
this.hydrateDurableState = options.hydrateDurableState;
|
|
3907
3909
|
this.spec = {
|
|
3908
3910
|
...spec,
|
|
3909
3911
|
defaultKey: normalizedDefaultKey,
|
|
@@ -3931,7 +3933,7 @@ var Actor = class {
|
|
|
3931
3933
|
this.pruneExpiredActorKeys(now2);
|
|
3932
3934
|
this.touchSession(actorKey, invocationOptions.touchSession, now2);
|
|
3933
3935
|
const runTask = async () => {
|
|
3934
|
-
const stateRecord = this.
|
|
3936
|
+
const stateRecord = await this.maybeHydrateStateRecord(actorKey);
|
|
3935
3937
|
stateRecord.lastReadAt = Date.now();
|
|
3936
3938
|
let durableStateChanged = false;
|
|
3937
3939
|
let runtimeStateChanged = false;
|
|
@@ -4173,6 +4175,7 @@ var Actor = class {
|
|
|
4173
4175
|
this.stateByKey.clear();
|
|
4174
4176
|
this.sessionByKey.clear();
|
|
4175
4177
|
this.idempotencyByKey.clear();
|
|
4178
|
+
this.pendingHydrationByKey.clear();
|
|
4176
4179
|
if ((this.spec.loadPolicy ?? "eager") === "eager") {
|
|
4177
4180
|
this.ensureStateRecord(this.spec.defaultKey);
|
|
4178
4181
|
}
|
|
@@ -4184,6 +4187,7 @@ var Actor = class {
|
|
|
4184
4187
|
}
|
|
4185
4188
|
this.stateByKey.delete(normalizedKey);
|
|
4186
4189
|
this.sessionByKey.delete(normalizedKey);
|
|
4190
|
+
this.pendingHydrationByKey.delete(normalizedKey);
|
|
4187
4191
|
for (const key of this.idempotencyByKey.keys()) {
|
|
4188
4192
|
if (key.startsWith(`${normalizedKey}:`)) {
|
|
4189
4193
|
this.idempotencyByKey.delete(key);
|
|
@@ -4269,6 +4273,7 @@ var Actor = class {
|
|
|
4269
4273
|
runtimeState: this.resolveInitialRuntimeState(),
|
|
4270
4274
|
version: 0,
|
|
4271
4275
|
runtimeVersion: 0,
|
|
4276
|
+
hydrationResolved: this.hydrateDurableState === void 0,
|
|
4272
4277
|
createdAt: now2,
|
|
4273
4278
|
lastReadAt: now2,
|
|
4274
4279
|
lastDurableWriteAt: now2,
|
|
@@ -4278,6 +4283,54 @@ var Actor = class {
|
|
|
4278
4283
|
this.touchSession(actorKey, true, now2);
|
|
4279
4284
|
return record;
|
|
4280
4285
|
}
|
|
4286
|
+
async maybeHydrateStateRecord(actorKey) {
|
|
4287
|
+
const record = this.ensureStateRecord(actorKey);
|
|
4288
|
+
if (record.hydrationResolved || !this.hydrateDurableState) {
|
|
4289
|
+
return record;
|
|
4290
|
+
}
|
|
4291
|
+
const pending = this.pendingHydrationByKey.get(actorKey);
|
|
4292
|
+
if (pending) {
|
|
4293
|
+
return pending;
|
|
4294
|
+
}
|
|
4295
|
+
let hydrationPromise;
|
|
4296
|
+
hydrationPromise = (async () => {
|
|
4297
|
+
const current = this.ensureStateRecord(actorKey);
|
|
4298
|
+
if (current.hydrationResolved || !this.hydrateDurableState) {
|
|
4299
|
+
return current;
|
|
4300
|
+
}
|
|
4301
|
+
const snapshot = await this.hydrateDurableState(actorKey);
|
|
4302
|
+
const latest = this.ensureStateRecord(actorKey);
|
|
4303
|
+
if (latest.hydrationResolved) {
|
|
4304
|
+
return latest;
|
|
4305
|
+
}
|
|
4306
|
+
if (snapshot) {
|
|
4307
|
+
const durableVersion = Number(snapshot.durableVersion);
|
|
4308
|
+
if (!Number.isInteger(durableVersion) || durableVersion < 0) {
|
|
4309
|
+
throw new Error(
|
|
4310
|
+
`Actor "${this.spec.name}" received invalid hydrated durable version for key "${actorKey}"`
|
|
4311
|
+
);
|
|
4312
|
+
}
|
|
4313
|
+
if (!isObject2(snapshot.durableState) || Array.isArray(snapshot.durableState)) {
|
|
4314
|
+
throw new Error(
|
|
4315
|
+
`Actor "${this.spec.name}" received invalid hydrated durable state for key "${actorKey}"`
|
|
4316
|
+
);
|
|
4317
|
+
}
|
|
4318
|
+
const hydratedAt = Date.now();
|
|
4319
|
+
latest.durableState = cloneForDurableState(snapshot.durableState);
|
|
4320
|
+
latest.version = durableVersion;
|
|
4321
|
+
latest.lastReadAt = hydratedAt;
|
|
4322
|
+
latest.lastDurableWriteAt = hydratedAt;
|
|
4323
|
+
}
|
|
4324
|
+
latest.hydrationResolved = true;
|
|
4325
|
+
return latest;
|
|
4326
|
+
})().finally(() => {
|
|
4327
|
+
if (this.pendingHydrationByKey.get(actorKey) === hydrationPromise) {
|
|
4328
|
+
this.pendingHydrationByKey.delete(actorKey);
|
|
4329
|
+
}
|
|
4330
|
+
});
|
|
4331
|
+
this.pendingHydrationByKey.set(actorKey, hydrationPromise);
|
|
4332
|
+
return hydrationPromise;
|
|
4333
|
+
}
|
|
4281
4334
|
touchSession(actorKey, shouldTouch, touchedAt) {
|
|
4282
4335
|
if (!this.spec.session?.enabled || !shouldTouch) {
|
|
4283
4336
|
return;
|
|
@@ -7375,7 +7428,8 @@ var Cadenza = class {
|
|
|
7375
7428
|
};
|
|
7376
7429
|
const actorOptions = {
|
|
7377
7430
|
isMeta: options.isMeta,
|
|
7378
|
-
definitionSource: definition
|
|
7431
|
+
definitionSource: definition,
|
|
7432
|
+
hydrateDurableState: options.hydrateDurableState
|
|
7379
7433
|
};
|
|
7380
7434
|
return this.createActor(spec, actorOptions);
|
|
7381
7435
|
}
|