@pgflow/core 0.0.0-array-map-steps-cd94242a-20251008042921 → 0.0.0-condition-4354fcb6-20260108134756

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/README.md CHANGED
@@ -5,10 +5,6 @@ PostgreSQL-native workflow engine for defining, managing, and tracking DAG-based
5
5
  > [!NOTE]
6
6
  > This project and all its components are licensed under [Apache 2.0](./LICENSE) license.
7
7
 
8
- > [!WARNING]
9
- > This project uses [Atlas](https://atlasgo.io/docs) to manage the schemas and migrations.
10
- > See [ATLAS.md](ATLAS.md) for more details.
11
-
12
8
  ## Table of Contents
13
9
 
14
10
  - [Overview](#overview)
@@ -47,6 +43,16 @@ This package focuses on:
47
43
 
48
44
  The actual execution of workflow tasks is handled by the [Edge Worker](../edge-worker/README.md), which calls back to the SQL Core to acknowledge task completion or failure.
49
45
 
46
+ ## Requirements
47
+
48
+ > [!IMPORTANT] > **pgmq Version Requirement** (since v0.8.0)
49
+ >
50
+ > pgflow v0.8.0 and later requires **pgmq 1.5.0 or higher**. This version of pgflow will NOT work with pgmq 1.4.x or earlier.
51
+ >
52
+ > - **Supabase Cloud**: Recent versions include pgmq 1.5.0+ by default
53
+ > - **Self-hosted**: You must upgrade pgmq to version 1.5.0+ before upgrading pgflow
54
+ > - **Version Check**: Run `SELECT extversion FROM pg_extension WHERE extname = 'pgmq';` to verify your pgmq version
55
+
50
56
  ## Key Features
51
57
 
52
58
  - **Declarative Workflows**: Define flows and steps via SQL tables
@@ -140,6 +146,7 @@ SELECT pgflow.add_step(
140
146
  #### Root Map vs Dependent Map
141
147
 
142
148
  **Root Map Steps** process the flow's input array directly:
149
+
143
150
  ```sql
144
151
  -- Root map: no dependencies, processes flow input
145
152
  SELECT pgflow.add_step(
@@ -156,6 +163,7 @@ SELECT pgflow.start_flow(
156
163
  ```
157
164
 
158
165
  **Dependent Map Steps** process another step's array output:
166
+
159
167
  ```sql
160
168
  -- Dependent map: processes the array from 'fetch_items'
161
169
  SELECT pgflow.add_step(
@@ -169,6 +177,7 @@ SELECT pgflow.add_step(
169
177
  #### Edge Cases and Special Behaviors
170
178
 
171
179
  1. **Empty Array Cascade**: When a map step receives an empty array (`[]`):
180
+
172
181
  - The SQL core completes it immediately without creating tasks
173
182
  - The completed map step outputs an empty array
174
183
  - Any dependent map steps also receive empty arrays and complete immediately
@@ -184,12 +193,14 @@ SELECT pgflow.add_step(
184
193
  #### Implementation Details
185
194
 
186
195
  Map steps utilize several database fields for state management:
196
+
187
197
  - `initial_tasks`: Number of tasks to create (NULL until array size is known)
188
198
  - `remaining_tasks`: Tracks incomplete tasks for the step
189
199
  - `task_index`: Identifies which array element each task processes
190
200
  - `step_type`: Column value 'map' triggers map behavior
191
201
 
192
202
  The aggregation process ensures:
203
+
193
204
  - **Order Preservation**: Task outputs maintain array element ordering
194
205
  - **NULL Handling**: NULL outputs are included in the aggregated array
195
206
  - **Atomicity**: Aggregation occurs within the same transaction as task completion
@@ -262,8 +273,9 @@ When a workflow starts:
262
273
  The Edge Worker uses a two-phase approach to retrieve and start tasks:
263
274
 
264
275
  **Phase 1 - Reserve Messages:**
276
+
265
277
  ```sql
266
- SELECT * FROM pgflow.read_with_poll(
278
+ SELECT * FROM pgmq.read_with_poll(
267
279
  queue_name => 'analyze_website',
268
280
  vt => 60, -- visibility timeout in seconds
269
281
  qty => 5 -- maximum number of messages to fetch
@@ -271,6 +283,7 @@ SELECT * FROM pgflow.read_with_poll(
271
283
  ```
272
284
 
273
285
  **Phase 2 - Start Tasks:**
286
+
274
287
  ```sql
275
288
  SELECT * FROM pgflow.start_tasks(
276
289
  flow_slug => 'analyze_website',
@@ -379,6 +392,7 @@ Timeouts are enforced by setting the message visibility timeout to the step's ti
379
392
  The SQL Core is the DAG orchestration engine that handles dependency resolution, step state management, and task spawning. However, workflows are defined using the TypeScript Flow DSL, which compiles user intent into the SQL primitives that populate the definition tables (`flows`, `steps`, `deps`).
380
393
 
381
394
  See the [@pgflow/dsl package](../dsl/README.md) for complete documentation on:
395
+
382
396
  - Expressing workflows with type-safe method chaining
383
397
  - Step types (`.step()`, `.array()`, `.map()`)
384
398
  - Compilation to SQL migrations
@@ -441,6 +455,7 @@ Map step tasks receive a fundamentally different input structure than single ste
441
455
  ```
442
456
 
443
457
  This means:
458
+
444
459
  - Map handlers process individual elements in isolation
445
460
  - Map handlers cannot access the original flow input (`run`)
446
461
  - Map handlers cannot access other dependencies
@@ -456,8 +471,10 @@ When a step depends on a map step, it receives the aggregated array output:
456
471
 
457
472
  // A step depending on 'process_users' receives:
458
473
  {
459
- "run": { /* original flow input */ },
460
- "process_users": [{"name": "Alice"}, {"name": "Bob"}] // Full array
474
+ "run": {
475
+ /* original flow input */
476
+ },
477
+ "process_users": [{ "name": "Alice" }, { "name": "Bob" }] // Full array
461
478
  }
462
479
  ```
463
480
 
package/dist/CHANGELOG.md CHANGED
@@ -1,29 +1,203 @@
1
1
  # @pgflow/core
2
2
 
3
- ## 0.0.0-array-map-steps-cd94242a-20251008042921
3
+ ## 0.0.0-condition-4354fcb6-20260108134756
4
+
5
+ ### Patch Changes
6
+
7
+ - c25ab9f: Add whenFailed option for error handling after retries exhausted (fail, skip, skip-cascade)
8
+ - 74202cd: Add skip infrastructure schema for conditional execution - new columns (condition_pattern, when_unmet, when_failed, skip_reason, skipped_at), 'skipped' status, and cascade_skip_steps function
9
+ - Updated dependencies [c25ab9f]
10
+ - @pgflow/dsl@0.0.0-condition-4354fcb6-20260108134756
11
+
12
+ ## 0.13.1
13
+
14
+ ### Patch Changes
15
+
16
+ - 199fbe1: Note: Version 0.13.0 was yanked due to broken local environment detection. This release (0.13.1) includes both the fix and the features from 0.13.0.
17
+
18
+ - Fix local environment detection to use SUPABASE_URL instead of API keys
19
+ - Add step output storage optimization for 2x faster Map chains (outputs now stored in step_states.output instead of aggregated on-demand)
20
+ - @pgflow/dsl@0.13.1
21
+
22
+ ## 0.13.0
23
+
24
+ ### Minor Changes
25
+
26
+ - 05738ed: Performance: Store step outputs atomically for 2x faster downstream task startup
27
+
28
+ Step outputs are now stored in step_states.output when steps complete, eliminating expensive aggregation queries. Benchmarks show 2.17x improvement for Map->Map chains. Includes data migration to backfill existing completed steps.
29
+
30
+ ### Patch Changes
31
+
32
+ - @pgflow/dsl@0.13.0
33
+
34
+ ## 0.12.0
35
+
36
+ ### Minor Changes
37
+
38
+ - 37402eb: BREAKING: Asymmetric handler signatures - remove `run` key from step inputs
39
+
40
+ - Root steps: `(flowInput, ctx) => ...` - flow input directly as first param
41
+ - Dependent steps: `(deps, ctx) => ...` - only dependency outputs as first param
42
+ - Access flow input in dependent steps via `await ctx.flowInput` (async/lazy-loaded)
43
+ - Lazy loading prevents data duplication for map steps processing large arrays
44
+ - Enables functional composition and simplifies types for future subflows
45
+
46
+ ### Patch Changes
47
+
48
+ - Updated dependencies [37402eb]
49
+ - Updated dependencies [5dc5cfc]
50
+ - @pgflow/dsl@0.12.0
51
+
52
+ ## 0.11.0
53
+
54
+ ### Minor Changes
55
+
56
+ - 0cb5500: New compilation config with allowDataLoss option for rapid iteration platforms. Breaking: ensureCompiledOnStartup removed in favor of compilation option.
57
+
58
+ ### Patch Changes
59
+
60
+ - @pgflow/dsl@0.11.0
61
+
62
+ ## 0.10.0
63
+
64
+ ### Minor Changes
65
+
66
+ - 90276ce: Add automatic worker restart via `ensure_workers()` cron job that keeps edge functions running. Add `worker_functions` table for tracking registered edge functions and their health status. Add `stopped_at` column to workers table for graceful shutdown detection. Integrate `trackWorkerFunction` and `markWorkerStopped` into edge worker lifecycle for automatic registration and shutdown signaling.
67
+
68
+ ### Patch Changes
69
+
70
+ - 0b84bb0: Add automatic flow compilation at worker startup. Workers now call ensure_flow_compiled to verify flows are up-to-date. In development, mismatched flows are recompiled automatically. In production, mismatches cause errors. Use ensureCompiledOnStartup: false to opt-out.
71
+ - Updated dependencies [0b84bb0]
72
+ - @pgflow/dsl@0.10.0
73
+
74
+ ## 0.9.1
75
+
76
+ ### Patch Changes
77
+
78
+ - Updated dependencies [992a86b]
79
+ - @pgflow/dsl@0.9.1
80
+
81
+ ## 0.9.0
82
+
83
+ ### Patch Changes
84
+
85
+ - @pgflow/dsl@0.9.0
86
+
87
+ ## 0.8.1
88
+
89
+ ### Patch Changes
90
+
91
+ - f1d3c32: Fix incorrect Supabase CLI version requirement from 2.34.3 to 2.50.3. CLI 2.50.3 is the first version to include pgmq 1.5.0+, which is required for pgflow 0.8.0+.
92
+ - @pgflow/dsl@0.8.1
93
+
94
+ ## 0.8.0
95
+
96
+ ### Minor Changes
97
+
98
+ - 7380237: BREAKING CHANGE: pgflow 0.8.0 requires pgmq 1.5.0+, PostgreSQL 17, and Supabase CLI 2.50.3+
99
+
100
+ This version modernizes infrastructure dependencies and will NOT work with pgmq 1.4.x or earlier. The migration includes a compatibility check that aborts with a clear error message if requirements are not met.
101
+
102
+ **Requirements:**
103
+
104
+ - pgmq 1.5.0 or higher (previously supported 1.4.x)
105
+ - PostgreSQL 17 (from 15)
106
+ - Supabase CLI 2.50.3 or higher (includes pgmq 1.5.0+)
107
+
108
+ **For Supabase users:** Upgrade your Supabase CLI to 2.50.3+ which includes pgmq 1.5.0 by default.
109
+
110
+ **For self-hosted users:** Upgrade pgmq to 1.5.0+ and PostgreSQL to 17 before upgrading pgflow.
111
+
112
+ **If you cannot upgrade immediately:** Stay on pgflow 0.7.x until your infrastructure is ready. The migration safety check ensures you cannot accidentally upgrade to an incompatible version.
113
+
114
+ ### Patch Changes
115
+
116
+ - @pgflow/dsl@0.8.0
117
+
118
+ ## 0.7.3
119
+
120
+ ### Patch Changes
121
+
122
+ - @pgflow/dsl@0.7.3
123
+
124
+ ## 0.7.2
125
+
126
+ ### Patch Changes
127
+
128
+ - c22a1e5: Fix missing realtime broadcasts for step:started and step:completed events
129
+
130
+ **Critical bug fix:** Clients were not receiving `step:started` events when steps transitioned to Started status, and `step:completed` events for empty map steps and cascade completions were also missing.
131
+
132
+ **Root cause:** PostgreSQL query optimizer was eliminating CTEs containing `realtime.send()` calls because they were not referenced by subsequent operations or the final RETURN statement.
133
+
134
+ **Solution:** Moved `realtime.send()` calls directly into RETURNING clauses of UPDATE statements, ensuring they execute atomically with state changes and cannot be optimized away.
135
+
136
+ **Changes:**
137
+
138
+ - `start_ready_steps()`: Broadcasts step:started and step:completed events in RETURNING clauses
139
+ - `cascade_complete_taskless_steps()`: Broadcasts step:completed events atomically with cascade completion
140
+ - `complete_task()`: Added PERFORM statements for run:failed and step:failed broadcasts
141
+ - Client: Added `applySnapshot()` methods to FlowRun and FlowStep for proper initial state hydration without event emission
142
+ - @pgflow/dsl@0.7.2
143
+
144
+ ## 0.7.1
145
+
146
+ ### Patch Changes
147
+
148
+ - a71b371: Fix installation failures on new Supabase projects by removing pgmq version pin.
149
+
150
+ Supabase upgraded to pgmq 1.5.1 in Postgres 17.6.1.016+ (https://github.com/supabase/postgres/pull/1668), but pgflow was pinned to 1.4.4, causing "extension has no installation script" errors on fresh instances.
151
+
152
+ Only affects new projects - existing installations are unaffected and require no action.
153
+
154
+ Thanks to @kallebysantos for reporting this issue!
155
+
156
+ - @pgflow/dsl@0.7.1
157
+
158
+ ## 0.7.0
4
159
 
5
160
  ### Minor Changes
6
161
 
7
162
  - 524db03: Add map step type infrastructure in SQL core
8
163
 
9
- ## 🚨🚨🚨 CRITICAL MIGRATION WARNING 🚨🚨🚨
164
+ ⚠️ **This migration includes automatic data migration**
165
+
166
+ The migration will automatically update existing `step_states` rows to satisfy new constraints. This should complete without issues due to strict check constraints enforced in previous versions.
10
167
 
11
- **THIS MIGRATION REQUIRES MANUAL DATA UPDATE BEFORE DEPLOYMENT!**
168
+ 💡 **Recommended: Verify before deploying to production**
12
169
 
13
- The migration adds a new constraint `remaining_tasks_state_consistency` that will **FAIL ON EXISTING DATA** if not handled properly.
170
+ If you have existing production data and want to verify the migration will succeed cleanly, run this **read-only check query** (does not modify data) in **Supabase Studio** against your **production database**:
14
171
 
15
- ### Required Data Migration:
172
+ 1. Open Supabase Studio → SQL Editor
173
+ 2. Copy contents of `pkgs/core/queries/PRE_MIGRATION_CHECK_20251006073122.sql`
174
+ 3. Execute against your production database (not local dev!)
175
+ 4. Review results
16
176
 
17
- Before applying this migration to any environment with existing data, you MUST include:
177
+ **Expected output for successful migration:**
18
178
 
19
- ```sql
20
- -- CRITICAL: Update existing step_states to satisfy new constraint
21
- UPDATE pgflow.step_states
22
- SET remaining_tasks = NULL
23
- WHERE status = 'created';
24
179
  ```
180
+ type | identifier | details
181
+ ---------------------------|---------------------------|------------------------------------------
182
+ DATA_BACKFILL_STARTED | run=def67890 step=process | initial_tasks will be set to 1 (...)
183
+ DATA_BACKFILL_COMPLETED | Found 100 completed steps | initial_tasks will be set to 1 (...)
184
+ INFO_SUMMARY | total_step_states=114 | created=0 started=1 completed=113 failed=0
185
+ ```
186
+
187
+ **Interpretation:**
188
+
189
+ - ✅ Only `DATA_BACKFILL_*` and `INFO_SUMMARY` rows? **Safe to migrate**
190
+ - ⚠️ These are expected data migrations handled automatically by the migration
191
+ - 🆘 Unexpected rows or errors? Copy output and share on Discord for help
192
+
193
+ 📝 **Note:** This check identifies data that needs migration but does not modify anything. Only useful for production databases with existing runs.
194
+
195
+ **Automatic data updates:**
196
+
197
+ - Sets `initial_tasks = 1` for all existing steps (correct for pre-map-step schema)
198
+ - Sets `remaining_tasks = NULL` for 'created' status steps (new semantics)
25
199
 
26
- **Without this update, the migration WILL FAIL in production!** The new constraint requires that `remaining_tasks` can only be set when `status != 'created'`.
200
+ No manual intervention required.
27
201
 
28
202
  ***
29
203
 
@@ -66,7 +240,7 @@
66
240
 
67
241
  - Updated dependencies [524db03]
68
242
  - Updated dependencies [524db03]
69
- - @pgflow/dsl@0.0.0-array-map-steps-cd94242a-20251008042921
243
+ - @pgflow/dsl@0.7.0
70
244
 
71
245
  ## 0.6.1
72
246
 
@@ -9,7 +9,7 @@ export class PgflowSqlClient {
9
9
  async readMessages(queueName, visibilityTimeout, batchSize, maxPollSeconds = 5, pollIntervalMs = 200) {
10
10
  return await this.sql `
11
11
  SELECT *
12
- FROM pgflow.read_with_poll(
12
+ FROM pgmq.read_with_poll(
13
13
  queue_name => ${queueName},
14
14
  vt => ${visibilityTimeout},
15
15
  qty => ${batchSize},
package/dist/README.md CHANGED
@@ -5,10 +5,6 @@ PostgreSQL-native workflow engine for defining, managing, and tracking DAG-based
5
5
  > [!NOTE]
6
6
  > This project and all its components are licensed under [Apache 2.0](./LICENSE) license.
7
7
 
8
- > [!WARNING]
9
- > This project uses [Atlas](https://atlasgo.io/docs) to manage the schemas and migrations.
10
- > See [ATLAS.md](ATLAS.md) for more details.
11
-
12
8
  ## Table of Contents
13
9
 
14
10
  - [Overview](#overview)
@@ -47,6 +43,16 @@ This package focuses on:
47
43
 
48
44
  The actual execution of workflow tasks is handled by the [Edge Worker](../edge-worker/README.md), which calls back to the SQL Core to acknowledge task completion or failure.
49
45
 
46
+ ## Requirements
47
+
48
+ > [!IMPORTANT] > **pgmq Version Requirement** (since v0.8.0)
49
+ >
50
+ > pgflow v0.8.0 and later requires **pgmq 1.5.0 or higher**. This version of pgflow will NOT work with pgmq 1.4.x or earlier.
51
+ >
52
+ > - **Supabase Cloud**: Recent versions include pgmq 1.5.0+ by default
53
+ > - **Self-hosted**: You must upgrade pgmq to version 1.5.0+ before upgrading pgflow
54
+ > - **Version Check**: Run `SELECT extversion FROM pg_extension WHERE extname = 'pgmq';` to verify your pgmq version
55
+
50
56
  ## Key Features
51
57
 
52
58
  - **Declarative Workflows**: Define flows and steps via SQL tables
@@ -140,6 +146,7 @@ SELECT pgflow.add_step(
140
146
  #### Root Map vs Dependent Map
141
147
 
142
148
  **Root Map Steps** process the flow's input array directly:
149
+
143
150
  ```sql
144
151
  -- Root map: no dependencies, processes flow input
145
152
  SELECT pgflow.add_step(
@@ -156,6 +163,7 @@ SELECT pgflow.start_flow(
156
163
  ```
157
164
 
158
165
  **Dependent Map Steps** process another step's array output:
166
+
159
167
  ```sql
160
168
  -- Dependent map: processes the array from 'fetch_items'
161
169
  SELECT pgflow.add_step(
@@ -169,6 +177,7 @@ SELECT pgflow.add_step(
169
177
  #### Edge Cases and Special Behaviors
170
178
 
171
179
  1. **Empty Array Cascade**: When a map step receives an empty array (`[]`):
180
+
172
181
  - The SQL core completes it immediately without creating tasks
173
182
  - The completed map step outputs an empty array
174
183
  - Any dependent map steps also receive empty arrays and complete immediately
@@ -184,12 +193,14 @@ SELECT pgflow.add_step(
184
193
  #### Implementation Details
185
194
 
186
195
  Map steps utilize several database fields for state management:
196
+
187
197
  - `initial_tasks`: Number of tasks to create (NULL until array size is known)
188
198
  - `remaining_tasks`: Tracks incomplete tasks for the step
189
199
  - `task_index`: Identifies which array element each task processes
190
200
  - `step_type`: Column value 'map' triggers map behavior
191
201
 
192
202
  The aggregation process ensures:
203
+
193
204
  - **Order Preservation**: Task outputs maintain array element ordering
194
205
  - **NULL Handling**: NULL outputs are included in the aggregated array
195
206
  - **Atomicity**: Aggregation occurs within the same transaction as task completion
@@ -262,8 +273,9 @@ When a workflow starts:
262
273
  The Edge Worker uses a two-phase approach to retrieve and start tasks:
263
274
 
264
275
  **Phase 1 - Reserve Messages:**
276
+
265
277
  ```sql
266
- SELECT * FROM pgflow.read_with_poll(
278
+ SELECT * FROM pgmq.read_with_poll(
267
279
  queue_name => 'analyze_website',
268
280
  vt => 60, -- visibility timeout in seconds
269
281
  qty => 5 -- maximum number of messages to fetch
@@ -271,6 +283,7 @@ SELECT * FROM pgflow.read_with_poll(
271
283
  ```
272
284
 
273
285
  **Phase 2 - Start Tasks:**
286
+
274
287
  ```sql
275
288
  SELECT * FROM pgflow.start_tasks(
276
289
  flow_slug => 'analyze_website',
@@ -379,6 +392,7 @@ Timeouts are enforced by setting the message visibility timeout to the step's ti
379
392
  The SQL Core is the DAG orchestration engine that handles dependency resolution, step state management, and task spawning. However, workflows are defined using the TypeScript Flow DSL, which compiles user intent into the SQL primitives that populate the definition tables (`flows`, `steps`, `deps`).
380
393
 
381
394
  See the [@pgflow/dsl package](../dsl/README.md) for complete documentation on:
395
+
382
396
  - Expressing workflows with type-safe method chaining
383
397
  - Step types (`.step()`, `.array()`, `.map()`)
384
398
  - Compilation to SQL migrations
@@ -441,6 +455,7 @@ Map step tasks receive a fundamentally different input structure than single ste
441
455
  ```
442
456
 
443
457
  This means:
458
+
444
459
  - Map handlers process individual elements in isolation
445
460
  - Map handlers cannot access the original flow input (`run`)
446
461
  - Map handlers cannot access other dependencies
@@ -456,8 +471,10 @@ When a step depends on a map step, it receives the aggregated array output:
456
471
 
457
472
  // A step depending on 'process_users' receives:
458
473
  {
459
- "run": { /* original flow input */ },
460
- "process_users": [{"name": "Alice"}, {"name": "Bob"}] // Full array
474
+ "run": {
475
+ /* original flow input */
476
+ },
477
+ "process_users": [{ "name": "Alice" }, { "name": "Bob" }] // Full array
461
478
  }
462
479
  ```
463
480