@cadenza.io/core 3.21.0 → 3.22.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.js CHANGED
@@ -6088,18 +6088,6 @@ function deepClone(value) {
6088
6088
  function cloneForDurableState(value) {
6089
6089
  return deepClone(value);
6090
6090
  }
6091
- function cloneForRuntimeState(value) {
6092
- if (Array.isArray(value)) {
6093
- return [...value];
6094
- }
6095
- if (isObject2(value)) {
6096
- const prototype = Object.getPrototypeOf(value);
6097
- if (prototype === Object.prototype || prototype === null) {
6098
- return { ...value };
6099
- }
6100
- }
6101
- return value;
6102
- }
6103
6091
  function cloneForIdempotency(value) {
6104
6092
  try {
6105
6093
  return deepClone(value);
@@ -6160,12 +6148,13 @@ function getActorTaskRuntimeMetadata(taskFunction) {
6160
6148
  return taskFunction[ACTOR_TASK_METADATA];
6161
6149
  }
6162
6150
  var Actor = class {
6151
+ /**
6152
+ * Creates an actor instance and optionally materializes the default key.
6153
+ */
6163
6154
  constructor(spec, options = {}) {
6164
6155
  this.stateByKey = /* @__PURE__ */ new Map();
6165
6156
  this.sessionByKey = /* @__PURE__ */ new Map();
6166
6157
  this.idempotencyByKey = /* @__PURE__ */ new Map();
6167
- this.initializedKeys = /* @__PURE__ */ new Set();
6168
- this.initializationByKey = /* @__PURE__ */ new Map();
6169
6158
  this.nextTaskBindingIndex = 0;
6170
6159
  if (!spec.name || typeof spec.name !== "string") {
6171
6160
  throw new Error("Actor name must be a non-empty string");
@@ -6183,9 +6172,11 @@ var Actor = class {
6183
6172
  };
6184
6173
  if ((this.spec.loadPolicy ?? "eager") === "eager") {
6185
6174
  this.ensureStateRecord(this.spec.defaultKey);
6186
- this.primeInitialization(this.spec.defaultKey);
6187
6175
  }
6188
6176
  }
6177
+ /**
6178
+ * Wraps an actor-aware handler into a standard Cadenza task function.
6179
+ */
6189
6180
  task(handler, bindingOptions = {}) {
6190
6181
  const mode = bindingOptions.mode ?? "read";
6191
6182
  const taskBindingId = `${this.spec.name}:${++this.nextTaskBindingIndex}`;
@@ -6198,11 +6189,6 @@ var Actor = class {
6198
6189
  const actorKey = this.resolveActorKey(normalizedInput, invocationOptions);
6199
6190
  this.touchSession(actorKey, invocationOptions.touchSession, Date.now());
6200
6191
  const runTask = async () => {
6201
- await this.ensureInitialized(
6202
- actorKey,
6203
- normalizedInput,
6204
- invocationOptions
6205
- );
6206
6192
  const stateRecord = this.ensureStateRecord(actorKey);
6207
6193
  stateRecord.lastReadAt = Date.now();
6208
6194
  let durableStateChanged = false;
@@ -6352,32 +6338,54 @@ var Actor = class {
6352
6338
  };
6353
6339
  return wrapped;
6354
6340
  }
6341
+ /**
6342
+ * Returns durable state snapshot for the resolved key.
6343
+ */
6355
6344
  getState(actorKey) {
6356
6345
  return this.getDurableState(actorKey);
6357
6346
  }
6347
+ /**
6348
+ * Returns durable state snapshot for the resolved key.
6349
+ */
6358
6350
  getDurableState(actorKey) {
6359
6351
  const key = normalizeActorKey(actorKey) ?? this.spec.defaultKey;
6360
6352
  return cloneForDurableState(this.ensureStateRecord(key).durableState);
6361
6353
  }
6354
+ /**
6355
+ * Returns runtime state reference for the resolved key.
6356
+ */
6362
6357
  getRuntimeState(actorKey) {
6363
6358
  const key = normalizeActorKey(actorKey) ?? this.spec.defaultKey;
6364
6359
  return this.ensureStateRecord(key).runtimeState;
6365
6360
  }
6361
+ /**
6362
+ * Alias of `getDurableVersion`.
6363
+ */
6366
6364
  getVersion(actorKey) {
6367
6365
  return this.getDurableVersion(actorKey);
6368
6366
  }
6367
+ /**
6368
+ * Returns durable state version for the resolved key.
6369
+ */
6369
6370
  getDurableVersion(actorKey) {
6370
6371
  const key = normalizeActorKey(actorKey) ?? this.spec.defaultKey;
6371
6372
  return this.ensureStateRecord(key).version;
6372
6373
  }
6374
+ /**
6375
+ * Returns runtime state version for the resolved key.
6376
+ */
6373
6377
  getRuntimeVersion(actorKey) {
6374
6378
  const key = normalizeActorKey(actorKey) ?? this.spec.defaultKey;
6375
6379
  return this.ensureStateRecord(key).runtimeVersion;
6376
6380
  }
6381
+ /**
6382
+ * Exports this actor as a serializable definition.
6383
+ */
6377
6384
  toDefinition() {
6378
6385
  if (this.sourceDefinition) {
6379
6386
  return cloneForIdempotency(this.sourceDefinition);
6380
6387
  }
6388
+ const durableInitState = this.spec.state?.durable?.initState ?? this.spec.initState ?? {};
6381
6389
  return {
6382
6390
  name: this.spec.name,
6383
6391
  description: this.spec.description ?? "",
@@ -6391,26 +6399,27 @@ var Actor = class {
6391
6399
  session: this.spec.session,
6392
6400
  runtimeReadGuard: this.spec.runtimeReadGuard,
6393
6401
  key: this.spec.key,
6394
- state: this.spec.state ?? {
6402
+ state: {
6403
+ ...this.spec.state ?? {},
6395
6404
  durable: {
6396
- initialState: this.spec.initialDurableState ?? this.spec.initialState ?? {}
6405
+ ...this.spec.state?.durable ?? {},
6406
+ initState: durableInitState
6397
6407
  },
6398
- runtime: this.spec.initialRuntimeState !== void 0 ? { initialState: this.spec.initialRuntimeState } : void 0
6408
+ runtime: this.spec.state?.runtime
6399
6409
  },
6400
- lifecycle: this.spec.lifecycle,
6401
6410
  tasks: this.spec.taskBindings
6402
6411
  };
6403
6412
  }
6413
+ /**
6414
+ * Resets one actor key or all keys.
6415
+ */
6404
6416
  reset(actorKey) {
6405
6417
  if (actorKey === void 0) {
6406
6418
  this.stateByKey.clear();
6407
6419
  this.sessionByKey.clear();
6408
6420
  this.idempotencyByKey.clear();
6409
- this.initializedKeys.clear();
6410
- this.initializationByKey.clear();
6411
6421
  if ((this.spec.loadPolicy ?? "eager") === "eager") {
6412
6422
  this.ensureStateRecord(this.spec.defaultKey);
6413
- this.primeInitialization(this.spec.defaultKey);
6414
6423
  }
6415
6424
  return;
6416
6425
  }
@@ -6420,8 +6429,6 @@ var Actor = class {
6420
6429
  }
6421
6430
  this.stateByKey.delete(normalizedKey);
6422
6431
  this.sessionByKey.delete(normalizedKey);
6423
- this.initializedKeys.delete(normalizedKey);
6424
- this.initializationByKey.delete(normalizedKey);
6425
6432
  for (const key of this.idempotencyByKey.keys()) {
6426
6433
  if (key.startsWith(`${normalizedKey}:`)) {
6427
6434
  this.idempotencyByKey.delete(key);
@@ -6435,23 +6442,6 @@ var Actor = class {
6435
6442
  }
6436
6443
  return runtimeState;
6437
6444
  }
6438
- buildDefaultInvocationOptions(actorKey) {
6439
- return {
6440
- actorKey,
6441
- loadPolicy: this.spec.loadPolicy ?? "eager",
6442
- writeContract: this.spec.writeContract ?? "overwrite",
6443
- consistencyProfile: this.spec.consistencyProfile,
6444
- idempotencyKey: void 0,
6445
- touchSession: this.spec.session?.extendIdleTtlOnRead ?? true
6446
- };
6447
- }
6448
- primeInitialization(actorKey) {
6449
- this.ensureInitialized(
6450
- actorKey,
6451
- {},
6452
- this.buildDefaultInvocationOptions(actorKey)
6453
- ).catch(() => void 0);
6454
- }
6455
6445
  normalizeInputContext(context) {
6456
6446
  if (!isObject2(context)) {
6457
6447
  return {};
@@ -6500,8 +6490,8 @@ var Actor = class {
6500
6490
  return resolveTemplateKey(input, this.spec.key.template);
6501
6491
  }
6502
6492
  resolveInitialDurableState() {
6503
- const definitionInitialState = this.spec.state?.durable?.initialState;
6504
- const initialDurableState = definitionInitialState ?? this.spec.initialDurableState ?? this.spec.initialState;
6493
+ const legacyDefinitionInitialState = this.spec.state?.durable?.initialState;
6494
+ const initialDurableState = this.spec.state?.durable?.initState ?? legacyDefinitionInitialState ?? this.spec.initState;
6505
6495
  if (initialDurableState === void 0) {
6506
6496
  return {};
6507
6497
  }
@@ -6511,15 +6501,7 @@ var Actor = class {
6511
6501
  return cloneForDurableState(initialDurableState);
6512
6502
  }
6513
6503
  resolveInitialRuntimeState() {
6514
- const definitionInitialRuntimeState = this.spec.state?.runtime?.initialState;
6515
- const initialRuntimeState = definitionInitialRuntimeState ?? this.spec.initialRuntimeState;
6516
- if (initialRuntimeState === void 0) {
6517
- return {};
6518
- }
6519
- if (typeof initialRuntimeState === "function") {
6520
- return cloneForRuntimeState(initialRuntimeState());
6521
- }
6522
- return cloneForRuntimeState(initialRuntimeState);
6504
+ return void 0;
6523
6505
  }
6524
6506
  ensureStateRecord(actorKey) {
6525
6507
  const existing = this.stateByKey.get(actorKey);
@@ -6541,149 +6523,6 @@ var Actor = class {
6541
6523
  this.touchSession(actorKey, true, now2);
6542
6524
  return record;
6543
6525
  }
6544
- async ensureInitialized(actorKey, input, options) {
6545
- this.ensureStateRecord(actorKey);
6546
- if (!this.spec.init) {
6547
- this.initializedKeys.add(actorKey);
6548
- return;
6549
- }
6550
- if (this.initializedKeys.has(actorKey)) {
6551
- return;
6552
- }
6553
- const inFlight = this.initializationByKey.get(actorKey);
6554
- if (inFlight) {
6555
- return inFlight;
6556
- }
6557
- const initializationPromise = Promise.resolve().then(async () => {
6558
- const record = this.ensureStateRecord(actorKey);
6559
- let nextDurableState = cloneForDurableState(record.durableState);
6560
- let nextRuntimeState = record.runtimeState;
6561
- let durableUpdatedViaSetter = false;
6562
- let runtimeUpdatedViaSetter = false;
6563
- const reduceDurableState = (reducer) => {
6564
- nextDurableState = cloneForDurableState(
6565
- reducer(cloneForDurableState(nextDurableState), input)
6566
- );
6567
- durableUpdatedViaSetter = true;
6568
- };
6569
- const setDurableState = (next) => {
6570
- if (typeof next === "function") {
6571
- reduceDurableState(next);
6572
- return;
6573
- }
6574
- nextDurableState = cloneForDurableState(next);
6575
- durableUpdatedViaSetter = true;
6576
- };
6577
- const patchDurableState = (partial) => {
6578
- if (!isObject2(nextDurableState) || !isObject2(partial)) {
6579
- throw new Error(
6580
- `Actor "${this.spec.name}" patchDurableState requires object state and partial patch`
6581
- );
6582
- }
6583
- nextDurableState = {
6584
- ...nextDurableState,
6585
- ...partial
6586
- };
6587
- durableUpdatedViaSetter = true;
6588
- };
6589
- const reduceRuntimeState = (reducer) => {
6590
- nextRuntimeState = reducer(nextRuntimeState, input);
6591
- runtimeUpdatedViaSetter = true;
6592
- };
6593
- const setRuntimeState = (next) => {
6594
- if (typeof next === "function") {
6595
- reduceRuntimeState(next);
6596
- return;
6597
- }
6598
- nextRuntimeState = next;
6599
- runtimeUpdatedViaSetter = true;
6600
- };
6601
- const patchRuntimeState = (partial) => {
6602
- if (!isObject2(nextRuntimeState) || !isObject2(partial)) {
6603
- throw new Error(
6604
- `Actor "${this.spec.name}" patchRuntimeState requires object state and partial patch`
6605
- );
6606
- }
6607
- nextRuntimeState = {
6608
- ...nextRuntimeState,
6609
- ...partial
6610
- };
6611
- runtimeUpdatedViaSetter = true;
6612
- };
6613
- const store = {
6614
- durable: cloneForDurableState(record.durableState),
6615
- runtime: record.runtimeState,
6616
- setDurable: setDurableState,
6617
- patchDurable: patchDurableState,
6618
- reduceDurable: reduceDurableState,
6619
- setRuntime: setRuntimeState,
6620
- patchRuntime: patchRuntimeState,
6621
- reduceRuntime: reduceRuntimeState
6622
- };
6623
- const initResult = await this.spec.init?.({
6624
- baseState: cloneForDurableState(record.durableState),
6625
- durableBaseState: cloneForDurableState(record.durableState),
6626
- runtimeBaseState: record.runtimeState,
6627
- store,
6628
- input,
6629
- actor: {
6630
- name: this.spec.name,
6631
- description: this.spec.description,
6632
- key: actorKey,
6633
- kind: this.kind
6634
- },
6635
- options,
6636
- setState: setDurableState,
6637
- patchState: patchDurableState,
6638
- reduceState: reduceDurableState,
6639
- setDurableState,
6640
- patchDurableState,
6641
- reduceDurableState,
6642
- setRuntimeState,
6643
- patchRuntimeState,
6644
- reduceRuntimeState
6645
- });
6646
- if (initResult !== void 0) {
6647
- if (isObject2(initResult) && ("durableState" in initResult || "runtimeState" in initResult || "state" in initResult)) {
6648
- const normalizedResult = initResult;
6649
- if (normalizedResult.state !== void 0) {
6650
- nextDurableState = cloneForDurableState(normalizedResult.state);
6651
- durableUpdatedViaSetter = true;
6652
- }
6653
- if (normalizedResult.durableState !== void 0) {
6654
- nextDurableState = cloneForDurableState(
6655
- normalizedResult.durableState
6656
- );
6657
- durableUpdatedViaSetter = true;
6658
- }
6659
- if (normalizedResult.runtimeState !== void 0) {
6660
- nextRuntimeState = normalizedResult.runtimeState;
6661
- runtimeUpdatedViaSetter = true;
6662
- }
6663
- } else {
6664
- nextDurableState = cloneForDurableState(initResult);
6665
- durableUpdatedViaSetter = true;
6666
- }
6667
- }
6668
- const writeTimestamp = Date.now();
6669
- if (durableUpdatedViaSetter) {
6670
- record.durableState = nextDurableState;
6671
- record.lastDurableWriteAt = writeTimestamp;
6672
- }
6673
- if (runtimeUpdatedViaSetter) {
6674
- record.runtimeState = nextRuntimeState;
6675
- record.lastRuntimeWriteAt = writeTimestamp;
6676
- }
6677
- this.initializedKeys.add(actorKey);
6678
- }).catch((error) => {
6679
- this.initializedKeys.delete(actorKey);
6680
- throw error;
6681
- }).finally(() => {
6682
- this.initializationByKey.delete(actorKey);
6683
- });
6684
- this.initializationByKey.set(actorKey, initializationPromise);
6685
- return initializationPromise;
6686
- }
6687
6526
  touchSession(actorKey, shouldTouch, touchedAt) {
6688
6527
  if (!this.spec.session?.enabled || !shouldTouch) {
6689
6528
  return;
@@ -6873,105 +6712,6 @@ var Cadenza = class {
6873
6712
  isMeta: true
6874
6713
  };
6875
6714
  }
6876
- static applyActorInitResult(context, result) {
6877
- if (result === void 0) {
6878
- return;
6879
- }
6880
- if (typeof result === "object" && result !== null && ("durableState" in result || "runtimeState" in result || "state" in result)) {
6881
- const normalizedResult = result;
6882
- if (normalizedResult.state !== void 0) {
6883
- context.setState(normalizedResult.state);
6884
- }
6885
- if (normalizedResult.durableState !== void 0) {
6886
- context.setDurableState(normalizedResult.durableState);
6887
- }
6888
- if (normalizedResult.runtimeState !== void 0) {
6889
- context.setRuntimeState(normalizedResult.runtimeState);
6890
- }
6891
- return;
6892
- }
6893
- context.setState(result);
6894
- }
6895
- static createActorInitHandlerFromDefinition(definition, options) {
6896
- const runtimeFactoryToken = definition.state?.runtime?.factoryToken;
6897
- const initHandlerToken = definition.lifecycle?.initHandlerToken;
6898
- const initTaskName = definition.lifecycle?.initTaskName;
6899
- const initRoutineName = definition.lifecycle?.initRoutineName;
6900
- if (!runtimeFactoryToken && !initHandlerToken && !initTaskName && !initRoutineName) {
6901
- return void 0;
6902
- }
6903
- return async (context) => {
6904
- if (runtimeFactoryToken) {
6905
- const runtimeFactory = options.runtimeFactories?.[runtimeFactoryToken];
6906
- if (!runtimeFactory) {
6907
- throw new Error(
6908
- `Actor "${definition.name}" requires runtimeFactory token "${runtimeFactoryToken}"`
6909
- );
6910
- }
6911
- const runtimeState = await runtimeFactory({
6912
- definition,
6913
- actor: {
6914
- name: context.actor.name,
6915
- key: context.actor.key,
6916
- kind: context.actor.kind
6917
- },
6918
- input: context.input,
6919
- config: definition.state?.runtime?.factoryConfig
6920
- });
6921
- context.setRuntimeState(runtimeState);
6922
- }
6923
- if (initHandlerToken) {
6924
- const initHandler = options.initHandlers?.[initHandlerToken];
6925
- if (!initHandler) {
6926
- throw new Error(
6927
- `Actor "${definition.name}" requires initHandler token "${initHandlerToken}"`
6928
- );
6929
- }
6930
- const initHandlerResult = await initHandler(context);
6931
- this.applyActorInitResult(context, initHandlerResult);
6932
- }
6933
- if (initTaskName) {
6934
- const initTask = this.get(initTaskName);
6935
- if (!initTask) {
6936
- throw new Error(
6937
- `Actor "${definition.name}" initTask "${initTaskName}" is not registered`
6938
- );
6939
- }
6940
- const initTaskResult = await initTask.taskFunction(
6941
- {
6942
- ...context.input,
6943
- __actorInit: {
6944
- actor: context.actor,
6945
- options: context.options,
6946
- durableBaseState: context.durableBaseState,
6947
- runtimeBaseState: context.runtimeBaseState
6948
- }
6949
- },
6950
- () => void 0,
6951
- async () => ({}),
6952
- () => void 0
6953
- );
6954
- this.applyActorInitResult(context, initTaskResult);
6955
- }
6956
- if (initRoutineName) {
6957
- const initRoutine = this.getRoutine(initRoutineName);
6958
- if (!initRoutine) {
6959
- throw new Error(
6960
- `Actor "${definition.name}" initRoutine "${initRoutineName}" is not registered`
6961
- );
6962
- }
6963
- this.run(initRoutine, {
6964
- ...context.input,
6965
- __actorInit: {
6966
- actor: context.actor,
6967
- options: context.options,
6968
- durableBaseState: context.durableBaseState,
6969
- runtimeBaseState: context.runtimeBaseState
6970
- }
6971
- });
6972
- }
6973
- };
6974
- }
6975
6715
  /**
6976
6716
  * Executes the specified task or GraphRoutine with the given context using an internal runner.
6977
6717
  *
@@ -7044,10 +6784,22 @@ var Cadenza = class {
7044
6784
  static async inquire(inquiry, context, options) {
7045
6785
  return this.inquiryBroker?.inquire(inquiry, context, options);
7046
6786
  }
6787
+ /**
6788
+ * Creates an in-memory actor runtime instance.
6789
+ *
6790
+ * Actors are not graph nodes. Use `actor.task(...)` to produce standard tasks that
6791
+ * participate in the graph like any other task.
6792
+ */
7047
6793
  static createActor(spec, options = {}) {
7048
6794
  this.bootstrap();
7049
6795
  return new Actor(spec, options);
7050
6796
  }
6797
+ /**
6798
+ * Creates an actor from a serializable actor definition.
6799
+ *
6800
+ * Durable bootstrap state is resolved from `state.durable.initState`.
6801
+ * For backwards compatibility, legacy `state.durable.initialState` is also accepted.
6802
+ */
7051
6803
  static createActorFromDefinition(definition, options = {}) {
7052
6804
  this.bootstrap();
7053
6805
  if (!definition.description || !definition.description.trim()) {
@@ -7069,11 +6821,8 @@ var Cadenza = class {
7069
6821
  runtimeReadGuard: definition.runtimeReadGuard,
7070
6822
  key: definition.key,
7071
6823
  state: definition.state,
7072
- lifecycle: definition.lifecycle,
7073
6824
  taskBindings: definition.tasks,
7074
- initialDurableState: definition.state?.durable?.initialState,
7075
- initialRuntimeState: definition.state?.runtime?.initialState,
7076
- init: this.createActorInitHandlerFromDefinition(definition, options)
6825
+ initState: definition.state?.durable?.initState ?? definition.state?.durable?.initialState
7077
6826
  };
7078
6827
  const actorOptions = {
7079
6828
  isMeta: options.isMeta,