@pgflow/dsl 0.0.0-condition-4354fcb6-20260108134756 → 0.0.0-condition-534994a1-20260113121112

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/CHANGELOG.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # @pgflow/dsl
2
2
 
3
- ## 0.0.0-condition-4354fcb6-20260108134756
3
+ ## 0.0.0-condition-534994a1-20260113121112
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - c25ab9f: Add whenFailed option for error handling after retries exhausted (fail, skip, skip-cascade)
7
+ - 8863a35: Add whenFailed option for error handling after retries exhausted (fail, skip, skip-cascade)
8
8
 
9
9
  ## 0.13.1
10
10
 
@@ -49,12 +49,12 @@ function formatRuntimeOptions(options) {
49
49
  if ('if' in options && options.if !== undefined) {
50
50
  // Serialize JSON pattern and escape for SQL
51
51
  const jsonStr = JSON.stringify(options.if);
52
- parts.push(`condition_pattern => '${jsonStr}'`);
52
+ parts.push(`required_input_pattern => '${jsonStr}'`);
53
53
  }
54
54
  if ('ifNot' in options && options.ifNot !== undefined) {
55
55
  // Serialize JSON pattern and escape for SQL
56
56
  const jsonStr = JSON.stringify(options.ifNot);
57
- parts.push(`condition_not_pattern => '${jsonStr}'`);
57
+ parts.push(`forbidden_input_pattern => '${jsonStr}'`);
58
58
  }
59
59
  if ('whenUnmet' in options && options.whenUnmet !== undefined) {
60
60
  parts.push(`when_unmet => '${options.whenUnmet}'`);
@@ -1,4 +1,15 @@
1
- import { AnyFlow } from './dsl.js';
1
+ import { AnyFlow, WhenUnmetMode, RetriesExhaustedMode, Json } from './dsl.js';
2
+ /**
3
+ * Input pattern wrapper - explicit representation to avoid null vs JSON-null ambiguity.
4
+ * - { defined: false } means no pattern (don't check)
5
+ * - { defined: true, value: Json } means pattern is set (check against value)
6
+ */
7
+ export type InputPattern = {
8
+ defined: false;
9
+ } | {
10
+ defined: true;
11
+ value: Json;
12
+ };
2
13
  /**
3
14
  * Step-level options that can be included in the shape for creation,
4
15
  * but are NOT compared during shape comparison (runtime tunable).
@@ -24,11 +35,18 @@ export interface FlowShapeOptions {
24
35
  * The `options` field is included for flow creation but NOT compared during
25
36
  * shape comparison. Options can be tuned at runtime via SQL without
26
37
  * requiring recompilation. See: /deploy/tune-flow-config/
38
+ *
39
+ * `whenUnmet`, `whenFailed`, and pattern fields ARE structural - they affect
40
+ * DAG execution semantics and must match between worker and database.
27
41
  */
28
42
  export interface StepShape {
29
43
  slug: string;
30
44
  stepType: 'single' | 'map';
31
45
  dependencies: string[];
46
+ whenUnmet: WhenUnmetMode;
47
+ whenFailed: RetriesExhaustedMode;
48
+ requiredInputPattern: InputPattern;
49
+ forbiddenInputPattern: InputPattern;
32
50
  options?: StepShapeOptions;
33
51
  }
34
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"flow-shape.d.ts","sourceRoot":"","sources":["../src/flow-shape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAMnC;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAyBD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAwCzD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,SAAS,EACZ,CAAC,EAAE,SAAS,GACX,qBAAqB,CA6BvB"}
1
+ {"version":3,"file":"flow-shape.d.ts","sourceRoot":"","sources":["../src/flow-shape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAM9E;;;;GAIG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,OAAO,EAAE,KAAK,CAAA;CAAE,GAClB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,CAAC;AAEnC;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,oBAAoB,CAAC;IACjC,oBAAoB,EAAE,YAAY,CAAC;IACnC,qBAAqB,EAAE,YAAY,CAAC;IACpC,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAyBD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAoDzD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,SAAS,EACZ,CAAC,EAAE,SAAS,GACX,qBAAqB,CAiCvB"}
@@ -33,6 +33,16 @@ export function extractFlowShape(flow) {
33
33
  stepType: stepDef.stepType ?? 'single',
34
34
  // Sort dependencies alphabetically for deterministic comparison
35
35
  dependencies: [...stepDef.dependencies].sort(),
36
+ // Condition modes are structural - they affect DAG execution semantics
37
+ whenUnmet: stepDef.options.whenUnmet ?? 'skip',
38
+ whenFailed: stepDef.options.retriesExhausted ?? 'fail',
39
+ // Input patterns use explicit wrapper to avoid null vs JSON-null ambiguity
40
+ requiredInputPattern: stepDef.options.if !== undefined
41
+ ? { defined: true, value: stepDef.options.if }
42
+ : { defined: false },
43
+ forbiddenInputPattern: stepDef.options.ifNot !== undefined
44
+ ? { defined: true, value: stepDef.options.ifNot }
45
+ : { defined: false },
36
46
  };
37
47
  // Only include options if at least one is defined
38
48
  const stepOptions = {
@@ -116,4 +126,23 @@ function compareSteps(a, b, index, differences) {
116
126
  if (aDeps !== bDeps) {
117
127
  differences.push(`Step at index ${index}: dependencies differ [${a.dependencies.join(', ')}] vs [${b.dependencies.join(', ')}]`);
118
128
  }
129
+ // Compare condition modes (structural - affects DAG execution semantics)
130
+ if (a.whenUnmet !== b.whenUnmet) {
131
+ differences.push(`Step at index ${index}: whenUnmet differs '${a.whenUnmet}' vs '${b.whenUnmet}'`);
132
+ }
133
+ if (a.whenFailed !== b.whenFailed) {
134
+ differences.push(`Step at index ${index}: whenFailed differs '${a.whenFailed}' vs '${b.whenFailed}'`);
135
+ }
136
+ // Compare pattern fields (structural - affects DAG execution semantics)
137
+ // Uses wrapper objects: { defined: false } or { defined: true, value: Json }
138
+ const aReqPattern = JSON.stringify(a.requiredInputPattern);
139
+ const bReqPattern = JSON.stringify(b.requiredInputPattern);
140
+ if (aReqPattern !== bReqPattern) {
141
+ differences.push(`Step at index ${index}: requiredInputPattern differs '${aReqPattern}' vs '${bReqPattern}'`);
142
+ }
143
+ const aForbPattern = JSON.stringify(a.forbiddenInputPattern);
144
+ const bForbPattern = JSON.stringify(b.forbiddenInputPattern);
145
+ if (aForbPattern !== bForbPattern) {
146
+ differences.push(`Step at index ${index}: forbiddenInputPattern differs '${aForbPattern}' vs '${bForbPattern}'`);
147
+ }
119
148
  }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgflow/dsl",
3
- "version": "0.0.0-condition-4354fcb6-20260108134756",
3
+ "version": "0.0.0-condition-534994a1-20260113121112",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgflow/dsl",
3
- "version": "0.0.0-condition-4354fcb6-20260108134756",
3
+ "version": "0.0.0-condition-534994a1-20260113121112",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",