@cadenza.io/core 3.26.0 → 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 +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +87 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +87 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3853,6 +3853,7 @@ var Actor = class {
|
|
|
3853
3853
|
this.stateByKey = /* @__PURE__ */ new Map();
|
|
3854
3854
|
this.sessionByKey = /* @__PURE__ */ new Map();
|
|
3855
3855
|
this.idempotencyByKey = /* @__PURE__ */ new Map();
|
|
3856
|
+
this.pendingHydrationByKey = /* @__PURE__ */ new Map();
|
|
3856
3857
|
this.writeQueueByKey = /* @__PURE__ */ new Map();
|
|
3857
3858
|
this.nextTaskBindingIndex = 0;
|
|
3858
3859
|
if (!spec.name || typeof spec.name !== "string") {
|
|
@@ -3864,6 +3865,7 @@ var Actor = class {
|
|
|
3864
3865
|
}
|
|
3865
3866
|
this.kind = options.isMeta || spec.kind === "meta" ? "meta" : "standard";
|
|
3866
3867
|
this.sourceDefinition = options.definitionSource;
|
|
3868
|
+
this.hydrateDurableState = options.hydrateDurableState;
|
|
3867
3869
|
this.spec = {
|
|
3868
3870
|
...spec,
|
|
3869
3871
|
defaultKey: normalizedDefaultKey,
|
|
@@ -3887,9 +3889,11 @@ var Actor = class {
|
|
|
3887
3889
|
bindingOptions.touchSession
|
|
3888
3890
|
);
|
|
3889
3891
|
const actorKey = this.resolveActorKey(normalizedInput, invocationOptions);
|
|
3890
|
-
|
|
3892
|
+
const now2 = Date.now();
|
|
3893
|
+
this.pruneExpiredActorKeys(now2);
|
|
3894
|
+
this.touchSession(actorKey, invocationOptions.touchSession, now2);
|
|
3891
3895
|
const runTask = async () => {
|
|
3892
|
-
const stateRecord = this.
|
|
3896
|
+
const stateRecord = await this.maybeHydrateStateRecord(actorKey);
|
|
3893
3897
|
stateRecord.lastReadAt = Date.now();
|
|
3894
3898
|
let durableStateChanged = false;
|
|
3895
3899
|
let runtimeStateChanged = false;
|
|
@@ -4058,6 +4062,7 @@ var Actor = class {
|
|
|
4058
4062
|
*/
|
|
4059
4063
|
getDurableState(actorKey) {
|
|
4060
4064
|
const key = normalizeActorKey(actorKey) ?? this.spec.defaultKey;
|
|
4065
|
+
this.pruneExpiredActorKeys(Date.now());
|
|
4061
4066
|
return cloneForDurableState(this.ensureStateRecord(key).durableState);
|
|
4062
4067
|
}
|
|
4063
4068
|
/**
|
|
@@ -4065,6 +4070,7 @@ var Actor = class {
|
|
|
4065
4070
|
*/
|
|
4066
4071
|
getRuntimeState(actorKey) {
|
|
4067
4072
|
const key = normalizeActorKey(actorKey) ?? this.spec.defaultKey;
|
|
4073
|
+
this.pruneExpiredActorKeys(Date.now());
|
|
4068
4074
|
return this.ensureStateRecord(key).runtimeState;
|
|
4069
4075
|
}
|
|
4070
4076
|
/**
|
|
@@ -4078,6 +4084,7 @@ var Actor = class {
|
|
|
4078
4084
|
*/
|
|
4079
4085
|
getDurableVersion(actorKey) {
|
|
4080
4086
|
const key = normalizeActorKey(actorKey) ?? this.spec.defaultKey;
|
|
4087
|
+
this.pruneExpiredActorKeys(Date.now());
|
|
4081
4088
|
return this.ensureStateRecord(key).version;
|
|
4082
4089
|
}
|
|
4083
4090
|
/**
|
|
@@ -4085,6 +4092,7 @@ var Actor = class {
|
|
|
4085
4092
|
*/
|
|
4086
4093
|
getRuntimeVersion(actorKey) {
|
|
4087
4094
|
const key = normalizeActorKey(actorKey) ?? this.spec.defaultKey;
|
|
4095
|
+
this.pruneExpiredActorKeys(Date.now());
|
|
4088
4096
|
return this.ensureStateRecord(key).runtimeVersion;
|
|
4089
4097
|
}
|
|
4090
4098
|
/**
|
|
@@ -4127,6 +4135,7 @@ var Actor = class {
|
|
|
4127
4135
|
this.stateByKey.clear();
|
|
4128
4136
|
this.sessionByKey.clear();
|
|
4129
4137
|
this.idempotencyByKey.clear();
|
|
4138
|
+
this.pendingHydrationByKey.clear();
|
|
4130
4139
|
if ((this.spec.loadPolicy ?? "eager") === "eager") {
|
|
4131
4140
|
this.ensureStateRecord(this.spec.defaultKey);
|
|
4132
4141
|
}
|
|
@@ -4138,6 +4147,7 @@ var Actor = class {
|
|
|
4138
4147
|
}
|
|
4139
4148
|
this.stateByKey.delete(normalizedKey);
|
|
4140
4149
|
this.sessionByKey.delete(normalizedKey);
|
|
4150
|
+
this.pendingHydrationByKey.delete(normalizedKey);
|
|
4141
4151
|
for (const key of this.idempotencyByKey.keys()) {
|
|
4142
4152
|
if (key.startsWith(`${normalizedKey}:`)) {
|
|
4143
4153
|
this.idempotencyByKey.delete(key);
|
|
@@ -4223,6 +4233,7 @@ var Actor = class {
|
|
|
4223
4233
|
runtimeState: this.resolveInitialRuntimeState(),
|
|
4224
4234
|
version: 0,
|
|
4225
4235
|
runtimeVersion: 0,
|
|
4236
|
+
hydrationResolved: this.hydrateDurableState === void 0,
|
|
4226
4237
|
createdAt: now2,
|
|
4227
4238
|
lastReadAt: now2,
|
|
4228
4239
|
lastDurableWriteAt: now2,
|
|
@@ -4232,6 +4243,54 @@ var Actor = class {
|
|
|
4232
4243
|
this.touchSession(actorKey, true, now2);
|
|
4233
4244
|
return record;
|
|
4234
4245
|
}
|
|
4246
|
+
async maybeHydrateStateRecord(actorKey) {
|
|
4247
|
+
const record = this.ensureStateRecord(actorKey);
|
|
4248
|
+
if (record.hydrationResolved || !this.hydrateDurableState) {
|
|
4249
|
+
return record;
|
|
4250
|
+
}
|
|
4251
|
+
const pending = this.pendingHydrationByKey.get(actorKey);
|
|
4252
|
+
if (pending) {
|
|
4253
|
+
return pending;
|
|
4254
|
+
}
|
|
4255
|
+
let hydrationPromise;
|
|
4256
|
+
hydrationPromise = (async () => {
|
|
4257
|
+
const current = this.ensureStateRecord(actorKey);
|
|
4258
|
+
if (current.hydrationResolved || !this.hydrateDurableState) {
|
|
4259
|
+
return current;
|
|
4260
|
+
}
|
|
4261
|
+
const snapshot = await this.hydrateDurableState(actorKey);
|
|
4262
|
+
const latest = this.ensureStateRecord(actorKey);
|
|
4263
|
+
if (latest.hydrationResolved) {
|
|
4264
|
+
return latest;
|
|
4265
|
+
}
|
|
4266
|
+
if (snapshot) {
|
|
4267
|
+
const durableVersion = Number(snapshot.durableVersion);
|
|
4268
|
+
if (!Number.isInteger(durableVersion) || durableVersion < 0) {
|
|
4269
|
+
throw new Error(
|
|
4270
|
+
`Actor "${this.spec.name}" received invalid hydrated durable version for key "${actorKey}"`
|
|
4271
|
+
);
|
|
4272
|
+
}
|
|
4273
|
+
if (!isObject2(snapshot.durableState) || Array.isArray(snapshot.durableState)) {
|
|
4274
|
+
throw new Error(
|
|
4275
|
+
`Actor "${this.spec.name}" received invalid hydrated durable state for key "${actorKey}"`
|
|
4276
|
+
);
|
|
4277
|
+
}
|
|
4278
|
+
const hydratedAt = Date.now();
|
|
4279
|
+
latest.durableState = cloneForDurableState(snapshot.durableState);
|
|
4280
|
+
latest.version = durableVersion;
|
|
4281
|
+
latest.lastReadAt = hydratedAt;
|
|
4282
|
+
latest.lastDurableWriteAt = hydratedAt;
|
|
4283
|
+
}
|
|
4284
|
+
latest.hydrationResolved = true;
|
|
4285
|
+
return latest;
|
|
4286
|
+
})().finally(() => {
|
|
4287
|
+
if (this.pendingHydrationByKey.get(actorKey) === hydrationPromise) {
|
|
4288
|
+
this.pendingHydrationByKey.delete(actorKey);
|
|
4289
|
+
}
|
|
4290
|
+
});
|
|
4291
|
+
this.pendingHydrationByKey.set(actorKey, hydrationPromise);
|
|
4292
|
+
return hydrationPromise;
|
|
4293
|
+
}
|
|
4235
4294
|
touchSession(actorKey, shouldTouch, touchedAt) {
|
|
4236
4295
|
if (!this.spec.session?.enabled || !shouldTouch) {
|
|
4237
4296
|
return;
|
|
@@ -4255,6 +4314,30 @@ var Actor = class {
|
|
|
4255
4314
|
existing.absoluteExpiresAt = touchedAt + absoluteTtlMs;
|
|
4256
4315
|
}
|
|
4257
4316
|
}
|
|
4317
|
+
pruneExpiredActorKeys(now2) {
|
|
4318
|
+
if (!this.spec.session?.enabled || this.sessionByKey.size === 0) {
|
|
4319
|
+
return;
|
|
4320
|
+
}
|
|
4321
|
+
for (const [actorKey, session] of this.sessionByKey.entries()) {
|
|
4322
|
+
if (!this.isSessionExpired(session, now2)) {
|
|
4323
|
+
continue;
|
|
4324
|
+
}
|
|
4325
|
+
if (this.writeQueueByKey.has(actorKey)) {
|
|
4326
|
+
continue;
|
|
4327
|
+
}
|
|
4328
|
+
this.stateByKey.delete(actorKey);
|
|
4329
|
+
this.sessionByKey.delete(actorKey);
|
|
4330
|
+
}
|
|
4331
|
+
}
|
|
4332
|
+
isSessionExpired(session, now2) {
|
|
4333
|
+
if (session.absoluteExpiresAt !== null && now2 >= session.absoluteExpiresAt) {
|
|
4334
|
+
return true;
|
|
4335
|
+
}
|
|
4336
|
+
if (session.idleExpiresAt !== null && now2 >= session.idleExpiresAt) {
|
|
4337
|
+
return true;
|
|
4338
|
+
}
|
|
4339
|
+
return false;
|
|
4340
|
+
}
|
|
4258
4341
|
runWithOptionalIdempotency(taskBindingId, actorKey, options, runTask) {
|
|
4259
4342
|
const idempotencyPolicy = this.spec.idempotency;
|
|
4260
4343
|
const enabled = idempotencyPolicy?.enabled ?? false;
|
|
@@ -7305,7 +7388,8 @@ var Cadenza = class {
|
|
|
7305
7388
|
};
|
|
7306
7389
|
const actorOptions = {
|
|
7307
7390
|
isMeta: options.isMeta,
|
|
7308
|
-
definitionSource: definition
|
|
7391
|
+
definitionSource: definition,
|
|
7392
|
+
hydrateDurableState: options.hydrateDurableState
|
|
7309
7393
|
};
|
|
7310
7394
|
return this.createActor(spec, actorOptions);
|
|
7311
7395
|
}
|