@dudousxd/nestjs-durable-core 0.49.4 → 0.50.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
@@ -1100,6 +1100,11 @@ function normalizeChildOptions(options) {
1100
1100
  } : options ?? {};
1101
1101
  }
1102
1102
  __name(normalizeChildOptions, "normalizeChildOptions");
1103
+ function formatIssuePath(path) {
1104
+ if (!path || path.length === 0) return "(root)";
1105
+ return path.map((segment) => String(typeof segment === "object" ? segment.key : segment)).join(".");
1106
+ }
1107
+ __name(formatIssuePath, "formatIssuePath");
1103
1108
  function resolveStepPolicy(config, opts) {
1104
1109
  const policy = {};
1105
1110
  const retries = opts?.retries ?? config?.retries;
@@ -1130,7 +1135,7 @@ var Position = class Position2 {
1130
1135
  this.seq -= 1;
1131
1136
  }
1132
1137
  };
1133
- function createWorkflowCtx(host, runId, compensations, workflow = "") {
1138
+ function createWorkflowCtx(host, runId, compensations, workflow = "", searchAttributesSchema) {
1134
1139
  const { store, replay } = host;
1135
1140
  const pos = new Position();
1136
1141
  const readCheckpoint = /* @__PURE__ */ __name((seq) => {
@@ -1599,6 +1604,24 @@ function createWorkflowCtx(host, runId, compensations, workflow = "") {
1599
1604
  }
1600
1605
  return;
1601
1606
  }
1607
+ if (searchAttributesSchema) {
1608
+ const run = await store.getRun(runId);
1609
+ const merged = {
1610
+ ...run?.searchAttributes ?? {},
1611
+ ...attrs
1612
+ };
1613
+ const result = searchAttributesSchema["~standard"].validate(merged);
1614
+ if (result instanceof Promise) {
1615
+ throw new Error(`workflow "${workflow}": ctx.upsertSearchAttributes schema validation must be synchronous (the searchAttributes schema's \`~standard.validate\` returned a Promise) \u2014 replay-determinism requires a sync validator; drop any async refinement from the schema passed to @Workflow({ searchAttributes }).`);
1616
+ }
1617
+ if (result.issues) {
1618
+ const offendingKeys = [
1619
+ ...new Set(result.issues.map((issue) => formatIssuePath(issue.path)))
1620
+ ];
1621
+ const details = result.issues.map((issue) => `${formatIssuePath(issue.path)}: ${issue.message}`).join("; ");
1622
+ throw new Error(`workflow "${workflow}": ctx.upsertSearchAttributes rejected by its searchAttributes schema \u2014 offending key(s) ${offendingKeys.join(", ")} \u2014 ${details}`);
1623
+ }
1624
+ }
1602
1625
  await host.upsertSearchAttributes(runId, attrs);
1603
1626
  await writeCheckpoint(instantCheckpoint({
1604
1627
  runId,
@@ -1954,6 +1977,7 @@ var WorkflowEngine = class {
1954
1977
  singleton: opts?.singleton,
1955
1978
  executionTimeoutMs: opts?.executionTimeout != null ? parseDuration(opts.executionTimeout) : void 0,
1956
1979
  validateInput: opts?.validateInput,
1980
+ searchAttributesSchema: opts?.searchAttributesSchema,
1957
1981
  onEvent: opts?.onEvent,
1958
1982
  eventBatch: opts?.eventBatch,
1959
1983
  // A real, retained in-process body — so `workflowBody` can hand it to an in-app worker, and so
@@ -3653,7 +3677,7 @@ var WorkflowEngine = class {
3653
3677
  const snapshot = await this.store.listCheckpoints(run.id);
3654
3678
  const replay = /* @__PURE__ */ new Map();
3655
3679
  for (const cp of snapshot) replay.set(cp.seq, cp);
3656
- const ctx = createWorkflowCtx(this.ctxHostFor(replay, run.namespace), run.id, compensations, run.workflow);
3680
+ const ctx = createWorkflowCtx(this.ctxHostFor(replay, run.namespace), run.id, compensations, run.workflow, registered?.searchAttributesSchema);
3657
3681
  try {
3658
3682
  const output = await runInWorkflowCtx(ctx, () => fn(ctx, run.input));
3659
3683
  if (this.cancelRequested.has(run.id)) {
@@ -4409,12 +4433,17 @@ var TERMINAL_RUN_STATUSES = [
4409
4433
  // src/run-waiting.ts
4410
4434
  var WEBHOOK_PREFIX = "wh:";
4411
4435
  var CHILD_PREFIX = "child:";
4436
+ var BREAKPOINT_PREFIX = "bp:";
4412
4437
  var EVENT_PREFIX = "event:";
4413
4438
  function classifyWaiterToken(token) {
4414
4439
  if (token.startsWith(WEBHOOK_PREFIX)) return {
4415
4440
  on: "webhook",
4416
4441
  name: token
4417
4442
  };
4443
+ if (token.startsWith(BREAKPOINT_PREFIX)) return {
4444
+ on: "breakpoint",
4445
+ name: "breakpoint"
4446
+ };
4418
4447
  if (token.startsWith(CHILD_PREFIX)) return {
4419
4448
  on: "child",
4420
4449
  name: token.slice(CHILD_PREFIX.length)
@@ -4835,6 +4864,19 @@ function attributeOperand(filter) {
4835
4864
  }
4836
4865
  __name(attributeOperand, "attributeOperand");
4837
4866
 
4867
+ // src/search-attributes-schema.ts
4868
+ function readSearchAttributes(schema, run) {
4869
+ const result = schema["~standard"].validate(run.searchAttributes ?? {});
4870
+ if (result instanceof Promise) {
4871
+ throw new Error("readSearchAttributes: schema validation must be synchronous (the searchAttributes schema's `~standard.validate` returned a Promise) \u2014 async Standard Schema validators are not supported.");
4872
+ }
4873
+ if (result.issues) {
4874
+ return {};
4875
+ }
4876
+ return result.value;
4877
+ }
4878
+ __name(readSearchAttributes, "readSearchAttributes");
4879
+
4838
4880
  // src/tokens.ts
4839
4881
  var STATE_STORE = Symbol.for("nestjs-durable:STATE_STORE");
4840
4882
  var TRANSPORT = Symbol.for("nestjs-durable:TRANSPORT");
@@ -5210,6 +5252,7 @@ export {
5210
5252
  normalizeAttributeRows,
5211
5253
  parseDuration,
5212
5254
  prevCronFireMs,
5255
+ readSearchAttributes,
5213
5256
  resolveRunWaiting,
5214
5257
  runInWorkflowCtx,
5215
5258
  runSchedules,