@dudousxd/nestjs-durable-core 0.67.1 → 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
@@ -6000,6 +6000,76 @@ function mergeRunFacetRows(rows) {
6000
6000
  }
6001
6001
  __name(mergeRunFacetRows, "mergeRunFacetRows");
6002
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
+
6003
6073
  // src/run-gateway.ts
6004
6074
  var RunGateway = class {
6005
6075
  static {
@@ -6021,11 +6091,21 @@ var CodecStateStore = class {
6021
6091
  * of resolving to a silently wrong empty result.
6022
6092
  */
6023
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;
6024
6100
  constructor(inner, codec) {
6025
6101
  this.inner = inner;
6026
6102
  this.codec = codec;
6027
6103
  const facets = inner.runFacets;
6028
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
+ }
6029
6109
  }
6030
6110
  enc(v) {
6031
6111
  return v === void 0 ? void 0 : this.codec.encode(v);
@@ -6380,8 +6460,10 @@ async function runSchedules(engine, schedules, nowMs, opts) {
6380
6460
  __name(runSchedules, "runSchedules");
6381
6461
 
6382
6462
  // src/search-attributes.ts
6383
- function compare(actual, op, expected) {
6384
- 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) {
6385
6467
  case "eq":
6386
6468
  return actual === expected;
6387
6469
  case "ne":
@@ -6400,7 +6482,7 @@ __name(compare, "compare");
6400
6482
  function matchesAttributes(attributes, filters) {
6401
6483
  if (!filters?.length) return true;
6402
6484
  if (!attributes) return false;
6403
- 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));
6404
6486
  }
6405
6487
  __name(matchesAttributes, "matchesAttributes");
6406
6488
  function applyAttributeQuery(rows, query) {
@@ -6466,6 +6548,30 @@ function attributeOperand(filter) {
6466
6548
  return filter.value;
6467
6549
  }
6468
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");
6469
6575
 
6470
6576
  // src/search-attributes-schema.ts
6471
6577
  function readSearchAttributes(schema, run) {
@@ -6693,33 +6799,27 @@ var InMemoryStateStore = class {
6693
6799
  const byRun = this.attributeIndex.get(f.key);
6694
6800
  const out = /* @__PURE__ */ new Set();
6695
6801
  if (!byRun) return out;
6696
- const numeric = typeof f.value === "number";
6697
- const operand = typeof f.value === "boolean" ? f.value ? "true" : "false" : f.value;
6802
+ const comparisons = attributePredicateOperands(f);
6698
6803
  for (const row of byRun.values()) {
6699
- const actual = numeric ? row.numValue : row.strValue;
6700
- if (actual == null) continue;
6701
- let ok = false;
6702
- switch (f.op) {
6703
- case "eq":
6704
- ok = actual === operand;
6705
- break;
6706
- case "ne":
6707
- ok = actual !== operand;
6708
- break;
6709
- case "gt":
6710
- ok = actual > operand;
6711
- break;
6712
- case "gte":
6713
- ok = actual >= operand;
6714
- break;
6715
- case "lt":
6716
- ok = actual < operand;
6717
- break;
6718
- case "lte":
6719
- ok = actual <= operand;
6720
- break;
6721
- }
6722
- 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);
6723
6823
  }
6724
6824
  return out;
6725
6825
  }
@@ -6730,12 +6830,20 @@ var InMemoryStateStore = class {
6730
6830
  ...this.runs.values()
6731
6831
  ];
6732
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));
6733
6834
  if (query.status) runs = runs.filter((r) => r.status === query.status);
6734
6835
  if (query.statuses) runs = runs.filter((r) => query.statuses?.includes(r.status));
6735
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)));
6736
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
+ }
6737
6842
  if (query.origin === null) runs = runs.filter((r) => r.origin == null);
6738
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
+ }
6739
6847
  if (query.attributes?.length) {
6740
6848
  let candidates = null;
6741
6849
  for (const f of query.attributes) {
@@ -6772,6 +6880,16 @@ var InMemoryStateStore = class {
6772
6880
  count: 1
6773
6881
  })));
6774
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
+ }
6775
6893
  async listCheckpoints(runId) {
6776
6894
  const rows = [
6777
6895
  ...this.checkpoints.values()
@@ -6872,6 +6990,8 @@ export {
6872
6990
  LEGACY_V1_PROTOCOL,
6873
6991
  NonDeterminismError,
6874
6992
  QueueController,
6993
+ RUN_VALUE_FACET_LIMIT,
6994
+ RUN_VALUE_FACET_SCAN,
6875
6995
  RemoteStepError,
6876
6996
  RemoteStepTimeout,
6877
6997
  RemoteWorkflowExecutor,
@@ -6894,6 +7014,8 @@ export {
6894
7014
  applyAttributeQuery,
6895
7015
  attributeColumnFor,
6896
7016
  attributeOperand,
7017
+ attributePredicateOperands,
7018
+ axisIsRunColumn,
6897
7019
  bindWorkflowClass,
6898
7020
  breakpointToken,
6899
7021
  buildWorkflowDirectory,
@@ -6927,6 +7049,7 @@ export {
6927
7049
  log,
6928
7050
  matchesAttributes,
6929
7051
  mergeRunFacetRows,
7052
+ mergeRunValueFacetRows,
6930
7053
  missingCapabilities,
6931
7054
  negotiate,
6932
7055
  normalizeAttributeRows,
@@ -6945,6 +7068,7 @@ export {
6945
7068
  runInWorkflowCtx,
6946
7069
  runSchedules,
6947
7070
  runStepHandler,
7071
+ runValueFacetsFromRuns,
6948
7072
  sanitizeQueueToken,
6949
7073
  scheduledRunId,
6950
7074
  sqlComparator,