Allow runs.list({ status }) to accept an array - #3707
Conversation
🦋 Changeset detectedLatest commit: bfa7e86 The changes in this PR will be included in the next version bump. This PR includes changesets to release 20 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@unusdon is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
ListWorkflowRunsParams.status now accepts WorkflowRunStatus | WorkflowRunStatus[] so callers can express set filters (e.g. 'not terminal') without having to issue one paginated list() per status. Both world backends fan the array out server-side. - @workflow/world: widen the type - @workflow/world-local: fs filter uses Array.isArray + includes - @workflow/world-postgres: dispatch to inArray() when the caller passes an array, eq() otherwise — inArray is already imported for the TERMINAL_WORKFLOW_RUN_STATUSES path so no new deps - @workflow/world (recovery.ts): reenqueueActiveRuns collapses its per-status loop into a single call with status: ['pending', 'running'], which is what vercel#3667 identified as the immediate consumer benefit Backwards-compatible: the single-string form still works — existing callers and existing tests need no updates apart from the two reenqueue tests whose call-count assertions reflected the old 2×2 shape. Tests updated + added: - packages/world/src/recovery.test.ts: mock accepts array or string; new test asserts the single-call behaviour with status: ['pending', 'running'] - packages/world-postgres/src/reenqueue.test.ts: mockRunsList and the 'pages through all active runs' assertion updated for the single-call shape All 3 world tests + 549 world-local tests + 12 world-postgres reenqueue tests pass. All 3 touched packages typecheck clean. Signed-off-by: unusdon <unusdon@gmail.com>
895b74e to
0da6539
Compare
karthikscale3
left a comment
There was a problem hiding this comment.
thanks for the PR. this change mostly looks good to me except for 2 issues that i have flagged. before we can merge this, we need to build parity for this capability for workflows running on vercel too so we do not advertise a public API capability that the vercel world doesn't implement. will take it back to the team and get back to you by early next week. please take care of the review comments in the meantime.
karthikscale3
left a comment
There was a problem hiding this comment.
world-local: status: [] skips the filter and returns every run. Since omitted status already means “unfiltered,” an explicit empty set should return no runs (or be rejected), and must match Postgres behavior.
world-postgres: inArray(..., []) returns no rows, unlike world-local. The shared Storage['runs'].list contract needs one documented empty-array semantic and a cross-backend test.
Per @karthikscale3's review — the empty-array semantic was divergent: - world-local: skipped the filter (returned every run) - world-postgres: SQL `inArray(..., [])` → `IN ()` → returned no rows Fixed world-local to match world-postgres: empty array matches no runs. Callers who want the unfiltered set must omit the field, same as the single-status form. Documented the contract on ListWorkflowRunsParams. Added mirrored 'runs > list' tests to both backends' storage.test.ts: - single-status filter - array-of-statuses filter (matches any) - empty array → 0 runs (the specific case @karthikscale3 flagged) - omitted status field → filter unset world-local + world recovery tests: 252/252 pass locally. world-postgres storage tests need Docker/testcontainers so I couldn't run them, but the test additions mirror world-local's shape 1:1. world-vercel parity noted separately in the review — leaving that piece for the team as discussed. Signed-off-by: unusdon <unusdon@gmail.com>
|
Thanks @karthikscale3 — pushed f53fba7 addressing both flagged issues. Empty-array semantic normalised to "no runs" in both backends. Root cause was on my side: the world-local filter had a
Cross-backend tests added. Mirrored 4
world-local + world recovery tests: 252/252 pass locally. world-postgres storage tests need Docker/testcontainers so I couldn't run them from my machine, but the test additions mirror world-local's shape 1:1 — happy to iterate if CI surfaces anything. On world-vercel parity — understood, leaving that for the team as you suggested. If it's useful, the postgres-side approach transfers directly: dispatch to whatever the vercel world's equivalent of |
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
|
@unusdon Commits must have a verified signature for us to be able to merge them. Can you have your agent force-push this PR with a new squashed and signed commit? |
Fixes #3667.
What changed
ListWorkflowRunsParams.statusnow acceptsWorkflowRunStatus | WorkflowRunStatus[], so callers can express set filters (e.g. "not terminal") without restating the status vocabulary in application code.Both world backends fan the array out server-side:
@workflow/world-local—Array.isArray+.includeson the fs filter@workflow/world-postgres— dispatches to Drizzle'sinArray()when the caller passes an array,eq()otherwise (both already imported for theTERMINAL_WORKFLOW_RUN_STATUSESpath, so no new deps)Backwards-compatible — the single-string form still works, and existing callers/tests need no updates apart from the two
reenqueuetests whose call-count assertions reflected the old 2×2-page shape.reenqueueActiveRunsnow issues a single callThe immediate consumer: the recovery path in
@workflow/world. Its per-status loop collapses into one call:Tests
@workflow/world(recovery.test.ts):createRunsmock updated to accept array or stringruns.listis called exactly once withstatus: ['pending', 'running']@workflow/world-postgres(reenqueue.test.ts):mockRunsListhandles both single-string and arraypages through all active runsretargeted: expects 2 list calls (single filter × 2 pages) instead of 4 (2 statuses × 2 pages), and 2 enqueues both from the first pageVerified locally:
@workflow/worldrecovery tests: 3/3 pass@workflow/world-localfull suite: 549/549 pass@workflow/world-postgresreenqueue tests: 12/12 pass(I could not run the
test:e2ematrix or the postgres testcontainer suite locally — those need Docker + a preview deploy.)Changeset
.changeset/runs-list-status-array.md—@workflow/worldminor (public API widened),@workflow/world-localand@workflow/world-postgrespatch (impl-side).Notes
status?: WorkflowRunStatus | WorkflowRunStatus[]) rather than the alternativeterminal?: boolean, since the array form composes with any subset (not just terminal/non-terminal) and keeps status ownership inside the package#2978's startup-recovery scope concern; happy to follow up if you have a preferred direction