@dudousxd/nestjs-durable-core 0.67.0 → 0.68.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
@@ -1752,12 +1752,10 @@ var SingletonGate = class {
1752
1752
  ]
1753
1753
  })).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime() || a.id.localeCompare(b.id));
1754
1754
  for (const next of gated.slice(0, cfg.limit ?? 1)) {
1755
- if (next.wakeAt != null) {
1756
- await this.deps.store.updateRun(next.id, {
1757
- wakeAt: void 0,
1758
- updatedAt: /* @__PURE__ */ new Date()
1759
- }).catch(() => void 0);
1760
- }
1755
+ await this.deps.store.updateRun(next.id, {
1756
+ wakeAt: this.deps.clock(),
1757
+ updatedAt: /* @__PURE__ */ new Date()
1758
+ }).catch(() => void 0);
1761
1759
  this.deps.dispatch(next.id);
1762
1760
  }
1763
1761
  }
@@ -6002,6 +6000,76 @@ function mergeRunFacetRows(rows) {
6002
6000
  }
6003
6001
  __name(mergeRunFacetRows, "mergeRunFacetRows");
6004
6002
 
6003
+ // src/run-value-facets.ts
6004
+ var RUN_VALUE_FACET_LIMIT = 100;
6005
+ var RUN_VALUE_FACET_SCAN = 5e3;
6006
+ function axisIsRunColumn(axis) {
6007
+ return axis.field === "workflow" || axis.field === "status" || axis.field === "origin" || axis.field === "namespace";
6008
+ }
6009
+ __name(axisIsRunColumn, "axisIsRunColumn");
6010
+ function valuesOf(run, axis) {
6011
+ switch (axis.field) {
6012
+ case "workflow":
6013
+ return [
6014
+ run.workflow
6015
+ ];
6016
+ case "status":
6017
+ return [
6018
+ run.status
6019
+ ];
6020
+ case "origin":
6021
+ return [
6022
+ facetOrigin(run.origin)
6023
+ ];
6024
+ case "namespace":
6025
+ return run.namespace === void 0 ? [] : [
6026
+ run.namespace
6027
+ ];
6028
+ case "tag":
6029
+ return run.tags ?? [];
6030
+ case "attributeKey":
6031
+ return Object.keys(run.searchAttributes ?? {});
6032
+ case "attributeValue": {
6033
+ const value = run.searchAttributes?.[axis.key];
6034
+ return value === void 0 ? [] : [
6035
+ String(value)
6036
+ ];
6037
+ }
6038
+ }
6039
+ }
6040
+ __name(valuesOf, "valuesOf");
6041
+ function mergeRunValueFacetRows(rows, opts) {
6042
+ const counts = /* @__PURE__ */ new Map();
6043
+ for (const row of rows) {
6044
+ const value = row.value ?? null;
6045
+ counts.set(value, (counts.get(value) ?? 0) + Number(row.count));
6046
+ }
6047
+ const merged = [
6048
+ ...counts
6049
+ ].map(([value, count]) => ({
6050
+ value,
6051
+ count
6052
+ })).filter((row) => row.count > 0).sort((a, b) => {
6053
+ if (b.count !== a.count) return b.count - a.count;
6054
+ if (a.value === null) return 1;
6055
+ if (b.value === null) return -1;
6056
+ return a.value.localeCompare(b.value);
6057
+ });
6058
+ return merged.slice(0, opts?.limit ?? RUN_VALUE_FACET_LIMIT);
6059
+ }
6060
+ __name(mergeRunValueFacetRows, "mergeRunValueFacetRows");
6061
+ function runValueFacetsFromRuns(runs, axis, opts) {
6062
+ const rows = [];
6063
+ for (const run of runs) {
6064
+ for (const value of valuesOf(run, axis)) rows.push({
6065
+ value,
6066
+ count: 1
6067
+ });
6068
+ }
6069
+ return mergeRunValueFacetRows(rows, opts);
6070
+ }
6071
+ __name(runValueFacetsFromRuns, "runValueFacetsFromRuns");
6072
+
6005
6073
  // src/run-gateway.ts
6006
6074
  var RunGateway = class {
6007
6075
  static {
@@ -6023,11 +6091,21 @@ var CodecStateStore = class {
6023
6091
  * of resolving to a silently wrong empty result.
6024
6092
  */
6025
6093
  runFacets;
6094
+ /**
6095
+ * Forwarded verbatim, and safe to: the axes a value facet enumerates are searchable metadata
6096
+ * (workflow, status, origin, namespace, tags, search attributes), none of which the codec encodes.
6097
+ * Bound the same conditional way as {@link runFacets} so absence is reported, not faked.
6098
+ */
6099
+ runValueFacets;
6026
6100
  constructor(inner, codec) {
6027
6101
  this.inner = inner;
6028
6102
  this.codec = codec;
6029
6103
  const facets = inner.runFacets;
6030
6104
  if (facets) this.runFacets = (query) => facets.call(inner, query);
6105
+ const valueFacets = inner.runValueFacets;
6106
+ if (valueFacets) {
6107
+ this.runValueFacets = (axis, query, opts) => valueFacets.call(inner, axis, query, opts);
6108
+ }
6031
6109
  }
6032
6110
  enc(v) {
6033
6111
  return v === void 0 ? void 0 : this.codec.encode(v);
@@ -6382,8 +6460,10 @@ async function runSchedules(engine, schedules, nowMs, opts) {
6382
6460
  __name(runSchedules, "runSchedules");
6383
6461
 
6384
6462
  // src/search-attributes.ts
6385
- function compare(actual, op, expected) {
6386
- switch (op) {
6463
+ function compare(actual, filter) {
6464
+ if (filter.op === "in") return filter.values.some((v) => actual === v);
6465
+ const expected = filter.value;
6466
+ switch (filter.op) {
6387
6467
  case "eq":
6388
6468
  return actual === expected;
6389
6469
  case "ne":
@@ -6402,7 +6482,7 @@ __name(compare, "compare");
6402
6482
  function matchesAttributes(attributes, filters) {
6403
6483
  if (!filters?.length) return true;
6404
6484
  if (!attributes) return false;
6405
- return filters.every((f) => f.key in attributes && compare(attributes[f.key], f.op, f.value));
6485
+ return filters.every((f) => f.key in attributes && compare(attributes[f.key], f));
6406
6486
  }
6407
6487
  __name(matchesAttributes, "matchesAttributes");
6408
6488
  function applyAttributeQuery(rows, query) {
@@ -6468,6 +6548,30 @@ function attributeOperand(filter) {
6468
6548
  return filter.value;
6469
6549
  }
6470
6550
  __name(attributeOperand, "attributeOperand");
6551
+ function attributePredicateOperands(filter) {
6552
+ if (filter.op === "in") {
6553
+ return filter.values.map((value) => {
6554
+ const scalar = {
6555
+ key: filter.key,
6556
+ op: "eq",
6557
+ value
6558
+ };
6559
+ return {
6560
+ column: attributeColumnFor(scalar),
6561
+ comparator: "=",
6562
+ operand: attributeOperand(scalar)
6563
+ };
6564
+ });
6565
+ }
6566
+ return [
6567
+ {
6568
+ column: attributeColumnFor(filter),
6569
+ comparator: sqlComparator(filter.op),
6570
+ operand: attributeOperand(filter)
6571
+ }
6572
+ ];
6573
+ }
6574
+ __name(attributePredicateOperands, "attributePredicateOperands");
6471
6575
 
6472
6576
  // src/search-attributes-schema.ts
6473
6577
  function readSearchAttributes(schema, run) {
@@ -6695,33 +6799,27 @@ var InMemoryStateStore = class {
6695
6799
  const byRun = this.attributeIndex.get(f.key);
6696
6800
  const out = /* @__PURE__ */ new Set();
6697
6801
  if (!byRun) return out;
6698
- const numeric = typeof f.value === "number";
6699
- const operand = typeof f.value === "boolean" ? f.value ? "true" : "false" : f.value;
6802
+ const comparisons = attributePredicateOperands(f);
6700
6803
  for (const row of byRun.values()) {
6701
- const actual = numeric ? row.numValue : row.strValue;
6702
- if (actual == null) continue;
6703
- let ok = false;
6704
- switch (f.op) {
6705
- case "eq":
6706
- ok = actual === operand;
6707
- break;
6708
- case "ne":
6709
- ok = actual !== operand;
6710
- break;
6711
- case "gt":
6712
- ok = actual > operand;
6713
- break;
6714
- case "gte":
6715
- ok = actual >= operand;
6716
- break;
6717
- case "lt":
6718
- ok = actual < operand;
6719
- break;
6720
- case "lte":
6721
- ok = actual <= operand;
6722
- break;
6723
- }
6724
- if (ok) out.add(row.runId);
6804
+ const matched = comparisons.some(({ column, comparator, operand }) => {
6805
+ const actual = column === "numValue" ? row.numValue : row.strValue;
6806
+ if (actual == null) return false;
6807
+ switch (comparator) {
6808
+ case "=":
6809
+ return actual === operand;
6810
+ case "<>":
6811
+ return actual !== operand;
6812
+ case ">":
6813
+ return actual > operand;
6814
+ case ">=":
6815
+ return actual >= operand;
6816
+ case "<":
6817
+ return actual < operand;
6818
+ default:
6819
+ return actual <= operand;
6820
+ }
6821
+ });
6822
+ if (matched) out.add(row.runId);
6725
6823
  }
6726
6824
  return out;
6727
6825
  }
@@ -6732,12 +6830,20 @@ var InMemoryStateStore = class {
6732
6830
  ...this.runs.values()
6733
6831
  ];
6734
6832
  if (query.workflow) runs = runs.filter((r) => r.workflow === query.workflow);
6833
+ if (query.workflows) runs = runs.filter((r) => query.workflows?.includes(r.workflow));
6735
6834
  if (query.status) runs = runs.filter((r) => r.status === query.status);
6736
6835
  if (query.statuses) runs = runs.filter((r) => query.statuses?.includes(r.status));
6737
6836
  if (query.tag) runs = runs.filter((r) => r.tags?.includes(query.tag));
6837
+ if (query.tags) runs = runs.filter((r) => r.tags?.some((t) => query.tags?.includes(t)));
6738
6838
  if (query.namespace !== void 0) runs = runs.filter((r) => r.namespace === query.namespace);
6839
+ if (query.namespaces) {
6840
+ runs = runs.filter((r) => r.namespace !== void 0 && query.namespaces?.includes(r.namespace));
6841
+ }
6739
6842
  if (query.origin === null) runs = runs.filter((r) => r.origin == null);
6740
6843
  else if (query.origin !== void 0) runs = runs.filter((r) => r.origin === query.origin);
6844
+ if (query.origins) {
6845
+ runs = runs.filter((r) => query.origins?.includes(r.origin ?? null));
6846
+ }
6741
6847
  if (query.attributes?.length) {
6742
6848
  let candidates = null;
6743
6849
  for (const f of query.attributes) {
@@ -6774,6 +6880,16 @@ var InMemoryStateStore = class {
6774
6880
  count: 1
6775
6881
  })));
6776
6882
  }
6883
+ /** Counted over the newest `scan` matching runs for EVERY axis, not just `tag`: this store holds
6884
+ * its runs in a Map with no index to group by, so the bound that the SQL stores need only for tags
6885
+ * is the honest one to apply here throughout. */
6886
+ async runValueFacets(axis, query, opts) {
6887
+ const runs = await this.listRuns({
6888
+ ...query,
6889
+ limit: opts?.scan ?? RUN_VALUE_FACET_SCAN
6890
+ });
6891
+ return runValueFacetsFromRuns(runs, axis, opts);
6892
+ }
6777
6893
  async listCheckpoints(runId) {
6778
6894
  const rows = [
6779
6895
  ...this.checkpoints.values()
@@ -6874,6 +6990,8 @@ export {
6874
6990
  LEGACY_V1_PROTOCOL,
6875
6991
  NonDeterminismError,
6876
6992
  QueueController,
6993
+ RUN_VALUE_FACET_LIMIT,
6994
+ RUN_VALUE_FACET_SCAN,
6877
6995
  RemoteStepError,
6878
6996
  RemoteStepTimeout,
6879
6997
  RemoteWorkflowExecutor,
@@ -6896,6 +7014,8 @@ export {
6896
7014
  applyAttributeQuery,
6897
7015
  attributeColumnFor,
6898
7016
  attributeOperand,
7017
+ attributePredicateOperands,
7018
+ axisIsRunColumn,
6899
7019
  bindWorkflowClass,
6900
7020
  breakpointToken,
6901
7021
  buildWorkflowDirectory,
@@ -6929,6 +7049,7 @@ export {
6929
7049
  log,
6930
7050
  matchesAttributes,
6931
7051
  mergeRunFacetRows,
7052
+ mergeRunValueFacetRows,
6932
7053
  missingCapabilities,
6933
7054
  negotiate,
6934
7055
  normalizeAttributeRows,
@@ -6947,6 +7068,7 @@ export {
6947
7068
  runInWorkflowCtx,
6948
7069
  runSchedules,
6949
7070
  runStepHandler,
7071
+ runValueFacetsFromRuns,
6950
7072
  sanitizeQueueToken,
6951
7073
  scheduledRunId,
6952
7074
  sqlComparator,