pipework 0.8.20 → 0.10.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.
Files changed (109) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/async/jobs/abortable-delay.d.ts +3 -0
  3. package/dist/async/jobs/abortable-delay.d.ts.map +1 -0
  4. package/dist/async/jobs/abortable-delay.js +19 -0
  5. package/dist/async/jobs/abortable-delay.js.map +1 -0
  6. package/dist/async/jobs/exclusion.d.ts +25 -0
  7. package/dist/async/jobs/exclusion.d.ts.map +1 -0
  8. package/dist/async/jobs/exclusion.js +80 -0
  9. package/dist/async/jobs/exclusion.js.map +1 -0
  10. package/dist/async/jobs/index.d.ts +2 -1
  11. package/dist/async/jobs/index.d.ts.map +1 -1
  12. package/dist/async/jobs/index.js.map +1 -1
  13. package/dist/async/jobs/queue.d.ts +26 -2
  14. package/dist/async/jobs/queue.d.ts.map +1 -1
  15. package/dist/async/jobs/queue.js +129 -36
  16. package/dist/async/jobs/queue.js.map +1 -1
  17. package/dist/async/jobs/table.d.ts +14 -0
  18. package/dist/async/jobs/table.d.ts.map +1 -0
  19. package/dist/async/jobs/table.js +115 -0
  20. package/dist/async/jobs/table.js.map +1 -0
  21. package/dist/auth/tenant/index.d.ts +1 -1
  22. package/dist/auth/tenant/index.d.ts.map +1 -1
  23. package/dist/auth/tenant/index.js +1 -1
  24. package/dist/auth/tenant/index.js.map +1 -1
  25. package/dist/auth/tenant/namespace.d.ts +3 -3
  26. package/dist/auth/tenant/namespace.d.ts.map +1 -1
  27. package/dist/auth/tenant/namespace.js +3 -3
  28. package/dist/auth/tenant/namespace.js.map +1 -1
  29. package/dist/auth/tenant/rls.d.ts +24 -3
  30. package/dist/auth/tenant/rls.d.ts.map +1 -1
  31. package/dist/auth/tenant/rls.js +59 -19
  32. package/dist/auth/tenant/rls.js.map +1 -1
  33. package/dist/cli/commands/db.d.ts +8 -0
  34. package/dist/cli/commands/db.d.ts.map +1 -1
  35. package/dist/cli/commands/db.js +129 -72
  36. package/dist/cli/commands/db.js.map +1 -1
  37. package/dist/core/config/load.d.ts +2 -0
  38. package/dist/core/config/load.d.ts.map +1 -1
  39. package/dist/core/config/load.js +7 -3
  40. package/dist/core/config/load.js.map +1 -1
  41. package/dist/core/config/namespace.d.ts +3 -0
  42. package/dist/core/config/namespace.d.ts.map +1 -1
  43. package/dist/core/config/schema.d.ts +6 -0
  44. package/dist/core/config/schema.d.ts.map +1 -1
  45. package/dist/core/config/schema.js +3 -0
  46. package/dist/core/config/schema.js.map +1 -1
  47. package/dist/core/pipework.d.ts +3 -3
  48. package/dist/core/pipework.d.ts.map +1 -1
  49. package/dist/core/pipework.js +13 -5
  50. package/dist/core/pipework.js.map +1 -1
  51. package/dist/core/surface/worker.d.ts.map +1 -1
  52. package/dist/core/surface/worker.js +26 -9
  53. package/dist/core/surface/worker.js.map +1 -1
  54. package/dist/data/db/expressions.d.ts +17 -5
  55. package/dist/data/db/expressions.d.ts.map +1 -1
  56. package/dist/data/db/expressions.js +30 -5
  57. package/dist/data/db/expressions.js.map +1 -1
  58. package/dist/data/db/filter.d.ts +9 -1
  59. package/dist/data/db/filter.d.ts.map +1 -1
  60. package/dist/data/db/filter.js +9 -1
  61. package/dist/data/db/filter.js.map +1 -1
  62. package/dist/data/db/namespace.d.ts +8 -0
  63. package/dist/data/db/namespace.d.ts.map +1 -1
  64. package/dist/data/db/pool.d.ts +2 -0
  65. package/dist/data/db/pool.d.ts.map +1 -1
  66. package/dist/data/db/pool.js.map +1 -1
  67. package/dist/data/db/serializable.d.ts +2 -0
  68. package/dist/data/db/serializable.d.ts.map +1 -1
  69. package/dist/data/db/serializable.js +2 -1
  70. package/dist/data/db/serializable.js.map +1 -1
  71. package/dist/data/domain/build-factory.js +2 -0
  72. package/dist/data/domain/build-factory.js.map +1 -1
  73. package/dist/data/domain/build-schema.js +7 -0
  74. package/dist/data/domain/build-schema.js.map +1 -1
  75. package/dist/data/domain/build-table.d.ts.map +1 -1
  76. package/dist/data/domain/build-table.js +9 -1
  77. package/dist/data/domain/build-table.js.map +1 -1
  78. package/dist/data/domain/field.d.ts +2 -0
  79. package/dist/data/domain/field.d.ts.map +1 -1
  80. package/dist/data/domain/field.js +4 -0
  81. package/dist/data/domain/field.js.map +1 -1
  82. package/dist/data/domain/types.d.ts +1 -1
  83. package/dist/data/domain/types.d.ts.map +1 -1
  84. package/dist/data/domain/types.js.map +1 -1
  85. package/dist/data/migrate/diff.js +7 -0
  86. package/dist/data/migrate/diff.js.map +1 -1
  87. package/dist/data/migrate/generate.js +1 -1
  88. package/dist/data/migrate/generate.js.map +1 -1
  89. package/dist/data/migrate/internal-definitions.d.ts.map +1 -1
  90. package/dist/data/migrate/internal-definitions.js +9 -0
  91. package/dist/data/migrate/internal-definitions.js.map +1 -1
  92. package/dist/data/migrate/rls-generate.d.ts +1 -1
  93. package/dist/data/migrate/rls-generate.d.ts.map +1 -1
  94. package/dist/data/migrate/rls-generate.js +20 -4
  95. package/dist/data/migrate/rls-generate.js.map +1 -1
  96. package/dist/data/migrate/snapshot.js +7 -5
  97. package/dist/data/migrate/snapshot.js.map +1 -1
  98. package/dist/data/migrate/sql-emit.js +4 -1
  99. package/dist/data/migrate/sql-emit.js.map +1 -1
  100. package/dist/request/context/create.d.ts +6 -0
  101. package/dist/request/context/create.d.ts.map +1 -1
  102. package/dist/request/context/create.js +6 -0
  103. package/dist/request/context/create.js.map +1 -1
  104. package/dist/request/context/run-in-transaction.d.ts.map +1 -1
  105. package/dist/request/context/run-in-transaction.js +8 -2
  106. package/dist/request/context/run-in-transaction.js.map +1 -1
  107. package/dist/request/context/types.d.ts +4 -0
  108. package/dist/request/context/types.d.ts.map +1 -1
  109. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.0
4
+
5
+ - **Breaking: `createQueue` tables are now emitted by `pipework generate`.** A queue's table was previously hand-written DDL (`schema.sql`) that `generate` never saw, so the table existed nowhere in a consumer's migration baseline — a latent footgun: any test or fresh database that exercised the queue hit `relation "<table>" does not exist` (42P01). The queue table is now built as a `pipe.define()` definition registered at `createQueue` construction and merged into `loadInternalDefinitions`, so `generate` emits its DDL like any other table. **Consumers must regenerate migrations** after upgrading so their queue tables (and the new exclusion columns/indexes) land in the baseline.
6
+ - **New: structured cross-job exclusion for queues.** `createQueue({ exclusion: { arrayColumn, arrayElementType?, blocksAllColumn, tenantColumn } })` — strictly generic, the consumer names the conflict columns; no domain vocabulary in pipework. A job participates when its array is non-null or its blocks-all flag is true; a blocks-all candidate waits for every participating concurrent job, an array candidate is blocked by concurrent blocks-all jobs and by `&&`-overlapping arrays, all tenant-scoped when `tenantColumn` is set. When exclusion is configured the claim runs under `SERIALIZABLE` to defeat write-skew between two claimers passing the same `NOT EXISTS` snapshot, with a partial GIN index (`fastupdate = off`, scoped to claimed/running rows) on the array column and a partial blocks-all index so the predicate locks stay granular at scale. `enqueue` takes `exclusion: { array, blocksAll, tenant }`; claimed jobs carry their exclusion values back.
7
+ - **New: `claim()` is starvation-proof and shutdown-cancellable.** The claim no longer gives up after a fixed retry budget — a serialization failure carries Postgres's safe-retry guarantee (the conflicting transaction committed, so progress was made), so `claim()` retries to a clean attempt with full-jitter backoff and `null` means exactly "nothing claimable," never "gave up under contention." `claim(db, workerId, signal?)` takes an `AbortSignal`; on a worker `stop()` the signal cancels both the retry loop and the poll sleeps so an in-flight or idle worker exits immediately, and `stop()` bounds the wait by `shutdownDeadlineMs` (its deadline timer is cleared the instant the loops exit, so a clean shutdown leaves no armed timer holding the event loop open).
8
+ - **New: filter/expression primitives.** `caseWhen`, JSONB `extract`/`contains` aliases through `filter`, `walReplayLsn`/`replicaFresh` for WAL-LSN read-your-writes checks (typed `SQL<string | null>` / `SQL<boolean | null>` — both are NULL on a primary), and `pipe.field.pgLsn()`. `identifier()` accepts multiple parts and emits a dot-qualified reference — `identifier('chain', 'depth')` renders `"chain"."depth"` so recursive-CTE consumers can qualify CTE columns (which have no `Column` object for `aliasedTableColumn`); single-part behavior unchanged.
9
+ - **Migrate emit fixes (required to express the queue indexes):** `emitCreateIndex` now emits index `WITH (...)` storage options (previously captured in the snapshot but dropped on emit), `indexEqual` compares them (a storage-param change now diffs), and the snapshot no longer emits `ASC NULLS LAST` for non-btree access methods (GIN rejects it — the existing hnsw/ivfflat special-case is generalized to btree-only).
10
+ - **Removed: `clearQueueDefinitions`** (zero callers; was never in the published exports map). Registry access is direct-module only.
11
+ - **Fix: `dropTraceTables` deadlocked against stray fire-and-forget trace writes** in test teardown — teardown now retries on `40P01`/`40001`, symmetric with how the write side already survives.
12
+
13
+ ## 0.9.0
14
+
15
+ - **New: runtime role separation — RLS is now actually enforced.** Until now the app connected to Postgres as the database owner, and an owner is `BYPASSRLS` — so every generated RLS policy was inert in production: the 144 policies isolated nothing. This release splits the single per-database role into two. `db setup` now provisions an **owner** role (`<name>_owner`, `BYPASSRLS`) that owns the database, runs migrations, and bootstraps; and a non-owner **runtime** role (`<name>_app`, `NOBYPASSRLS`) that runtime request/job transactions authenticate as and that RLS policies enforce against. Isolation now comes from Postgres itself on a role that cannot bypass it, not from app-side filtering alone. The runtime DML grants (`SELECT, INSERT, UPDATE, DELETE` on tables, `USAGE, SELECT` on sequences) are applied at provision time on an owner-authenticated connection, plus `ALTER DEFAULT PRIVILEGES FOR ROLE <owner>` so every future migration-created table is auto-granted to the runtime role — an RLS-enabled table can never be left ungranted (which would blank rows the app is entitled to). New `buildRuntimeGrants` helper.
16
+ - **Breaking: `db setup` role naming and new config fields.** The single per-database role is gone; `db setup` now creates `<name>_owner` and `<name>_app`. Two new optional `database` config fields name the env vars for the runtime connection URL: `appUrl` (and `appTestUrl` for the test database). When `appUrl` is unset the runtime falls back to the owner `url` and `db setup` warns — RLS is then inert, preserving the old single-role behavior, but role separation is off. To get enforcement, set `appUrl`/`appTestUrl` and re-run `db setup`. Any deployment that hard-coded the old role name must update to `<name>_owner`.
17
+ - **New: principal context (user + as-of) propagation for user-level and temporal RLS.** `Flow` now carries `user` (the acting principal's id) and `asOf` (the instant access is evaluated against; null = current), threaded through `createRequestContext` / `createJobContext` / `createTestContext`. The runtime chokepoint propagates them to the connection as the `pipework.user_id` and `pipework.asof` GUCs alongside `pipework.tenant_id`, so RLS policies can enforce per-user and temporal (as-of) visibility, not just tenant. `verifyPrincipalContext` cross-checks the GUCs against the active Flow, fail-closed.
18
+
3
19
  ## 0.8.20
4
20
 
5
21
  - **Fix: test-database cloning aborted when it couldn't terminate an autovacuum backend** — `cloneTestDatabase` ran `pg_terminate_backend` over *every* session attached to the per-process template before `CREATE DATABASE ... WITH TEMPLATE`. On a shared cluster an autovacuum worker attaches to every database and runs as superuser, so a non-superuser test role (`*_test`) hit `permission denied to terminate process` (42501) and the whole clone — and the test file — failed intermittently. The terminate is now scoped to `backend_type = 'client backend'` (never a background worker) and is best-effort, and the `CREATE DATABASE` retries on SQLSTATE 55006 (`object_in_use`) with capped backoff, waiting out any session it couldn't close rather than depending on superuser termination rights. New `withTemplateRetry` helper, unit-tested.
@@ -0,0 +1,3 @@
1
+ /** setTimeout delay that resolves early when the signal aborts — shutdown must not wait out a backoff or poll interval. */
2
+ export declare function abortableDelay(ms: number, signal?: AbortSignal): Promise<void>;
3
+ //# sourceMappingURL=abortable-delay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abortable-delay.d.ts","sourceRoot":"","sources":["../../../src/async/jobs/abortable-delay.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAC3H,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB9E"}
@@ -0,0 +1,19 @@
1
+ /** setTimeout delay that resolves early when the signal aborts — shutdown must not wait out a backoff or poll interval. */
2
+ export function abortableDelay(ms, signal) {
3
+ return new Promise((resolve) => {
4
+ if (signal?.aborted === true) {
5
+ resolve();
6
+ return;
7
+ }
8
+ const onAbort = () => {
9
+ clearTimeout(timer);
10
+ resolve();
11
+ };
12
+ const timer = setTimeout(() => {
13
+ signal?.removeEventListener('abort', onAbort);
14
+ resolve();
15
+ }, ms);
16
+ signal?.addEventListener('abort', onAbort, { once: true });
17
+ });
18
+ }
19
+ //# sourceMappingURL=abortable-delay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abortable-delay.js","sourceRoot":"","sources":["../../../src/async/jobs/abortable-delay.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAC3H,MAAM,UAAU,cAAc,CAAC,EAAU,EAAE,MAAoB;IAC7D,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAA;YACT,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,OAAO,EAAE,CAAA;QACX,CAAC,CAAA;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC7C,OAAO,EAAE,CAAA;QACX,CAAC,EAAE,EAAE,CAAC,CAAA;QACN,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5D,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ /** Cross-job exclusion config — names the consumer's conflict columns; the mechanism is pipework's. */
2
+ export interface ExclusionConfig {
3
+ /** Array column — two jobs whose arrays overlap (`&&`) are mutually exclusive. */
4
+ readonly arrayColumn?: string;
5
+ /** Element type of `arrayColumn`. Default `'uuid'`. */
6
+ readonly arrayElementType?: 'uuid' | 'text';
7
+ /** Boolean column — a TRUE job is exclusive against every participating job in its scope. */
8
+ readonly blocksAllColumn?: string;
9
+ /** Tenant column — exclusion checks compare only jobs with the same tenant value. */
10
+ readonly tenantColumn?: string;
11
+ }
12
+ export interface ResolvedExclusion {
13
+ readonly arrayColumn?: string;
14
+ readonly arrayElementType: 'uuid' | 'text';
15
+ readonly blocksAllColumn?: string;
16
+ readonly tenantColumn?: string;
17
+ }
18
+ export declare function resolveExclusion(config: ExclusionConfig | undefined): ResolvedExclusion | undefined;
19
+ /**
20
+ * The claimability predicate for the claim query's candidate SELECT. Pure
21
+ * identifiers — all quoted, no values — so the result composes as a raw SQL
22
+ * fragment. The candidate row is aliased `candidate`, concurrent rows `r`.
23
+ */
24
+ export declare function exclusionClaimClause(tableQ: string, exclusion: ResolvedExclusion): string;
25
+ //# sourceMappingURL=exclusion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclusion.d.ts","sourceRoot":"","sources":["../../../src/async/jobs/exclusion.ts"],"names":[],"mappings":"AAkBA,uGAAuG;AACvG,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC3C,6FAA6F;IAC7F,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,qFAAqF;IACrF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAA;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,CA8CnG;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,GAAG,MAAM,CA0BzF"}
@@ -0,0 +1,80 @@
1
+ // Cross-job exclusion gate for the claim query.
2
+ //
3
+ // A job "participates" in exclusion when its array column is non-NULL or its
4
+ // blocks-all flag is true. Against the concurrent set R (claimed/running jobs,
5
+ // tenant-scoped when a tenant column is configured), a pending candidate is
6
+ // claimable when:
7
+ // - it does not participate: always claimable, and it never blocks others
8
+ // - it is blocks-all: R contains no participating job
9
+ // - it carries an array: R contains no blocks-all job and no job whose
10
+ // array overlaps (&&) the candidate's
11
+ //
12
+ // Two concurrent workers can evaluate these NOT EXISTS checks against the same
13
+ // MVCC snapshot and both pass (write skew) — the claim query must run under
14
+ // SERIALIZABLE; queue.ts handles that.
15
+ import { assertValidIdentifier, quoteIdentifier } from '../../data/db/identifiers.js';
16
+ import { QUEUE_BASE_COLUMNS } from './table.js';
17
+ export function resolveExclusion(config) {
18
+ if (config === undefined)
19
+ return undefined;
20
+ if (config.arrayColumn === undefined && config.blocksAllColumn === undefined) {
21
+ throw new Error('[pipework] exclusion requires arrayColumn and/or blocksAllColumn.\n\n' +
22
+ ' A tenantColumn alone only scopes checks — it expresses no conflict.\n' +
23
+ " Configure the conflict columns: exclusion: { arrayColumn: 'conflict_keys' }\n" +
24
+ " or exclusion: { blocksAllColumn: 'exclusive' }.\n");
25
+ }
26
+ if (config.arrayElementType !== undefined && config.arrayColumn === undefined) {
27
+ throw new Error('[pipework] exclusion.arrayElementType is set but arrayColumn is not.\n\n' +
28
+ ' arrayElementType only describes arrayColumn.\n' +
29
+ ' Add arrayColumn, or remove arrayElementType.\n');
30
+ }
31
+ const named = [config.arrayColumn, config.blocksAllColumn, config.tenantColumn]
32
+ .filter((c) => c !== undefined);
33
+ for (const column of named) {
34
+ assertValidIdentifier(column, 'exclusion column');
35
+ if (QUEUE_BASE_COLUMNS.has(column)) {
36
+ throw new Error(`[pipework] exclusion column "${column}" collides with a base queue column.\n\n` +
37
+ ` The queue table already owns: ${[...QUEUE_BASE_COLUMNS].join(', ')}\n` +
38
+ ' Pick a different column name.\n');
39
+ }
40
+ }
41
+ if (new Set(named).size !== named.length) {
42
+ throw new Error('[pipework] exclusion columns must be distinct.\n\n' +
43
+ ` Got: arrayColumn=${config.arrayColumn ?? '—'}, blocksAllColumn=${config.blocksAllColumn ?? '—'}, tenantColumn=${config.tenantColumn ?? '—'}\n` +
44
+ ' Each role needs its own column.\n');
45
+ }
46
+ return {
47
+ ...(config.arrayColumn !== undefined ? { arrayColumn: config.arrayColumn } : {}),
48
+ arrayElementType: config.arrayElementType ?? 'uuid',
49
+ ...(config.blocksAllColumn !== undefined ? { blocksAllColumn: config.blocksAllColumn } : {}),
50
+ ...(config.tenantColumn !== undefined ? { tenantColumn: config.tenantColumn } : {}),
51
+ };
52
+ }
53
+ /**
54
+ * The claimability predicate for the claim query's candidate SELECT. Pure
55
+ * identifiers — all quoted, no values — so the result composes as a raw SQL
56
+ * fragment. The candidate row is aliased `candidate`, concurrent rows `r`.
57
+ */
58
+ export function exclusionClaimClause(tableQ, exclusion) {
59
+ const arr = exclusion.arrayColumn !== undefined ? quoteIdentifier(exclusion.arrayColumn, 'exclusion column') : undefined;
60
+ const blocks = exclusion.blocksAllColumn !== undefined ? quoteIdentifier(exclusion.blocksAllColumn, 'exclusion column') : undefined;
61
+ const tenant = exclusion.tenantColumn !== undefined ? quoteIdentifier(exclusion.tenantColumn, 'exclusion column') : undefined;
62
+ const tenantScope = tenant !== undefined ? `r.${tenant} = candidate.${tenant} AND ` : '';
63
+ const noConcurrent = (condition) => `NOT EXISTS (SELECT 1 FROM ${tableQ} r WHERE ${tenantScope}r.status IN ('claimed', 'running') AND ${condition})`;
64
+ if (arr !== undefined && blocks !== undefined) {
65
+ return '(' +
66
+ `(candidate.${blocks} = false AND candidate.${arr} IS NULL)` +
67
+ ` OR (candidate.${blocks} = true AND ${noConcurrent(`(r.${arr} IS NOT NULL OR r.${blocks} = true)`)})` +
68
+ ` OR (candidate.${blocks} = false AND candidate.${arr} IS NOT NULL` +
69
+ ` AND ${noConcurrent(`r.${blocks} = true`)}` +
70
+ ` AND ${noConcurrent(`r.${arr} IS NOT NULL AND r.${arr} && candidate.${arr}`)})` +
71
+ ')';
72
+ }
73
+ if (arr !== undefined) {
74
+ return `(candidate.${arr} IS NULL OR ${noConcurrent(`r.${arr} IS NOT NULL AND r.${arr} && candidate.${arr}`)})`;
75
+ }
76
+ // blocks-all only: participation reduces to the flag itself, so a false
77
+ // candidate never conflicts and a true candidate waits for true jobs.
78
+ return `(candidate.${blocks} = false OR ${noConcurrent(`r.${blocks} = true`)})`;
79
+ }
80
+ //# sourceMappingURL=exclusion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclusion.js","sourceRoot":"","sources":["../../../src/async/jobs/exclusion.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  export { executeJob } from './execute.js';
2
2
  export { createQueue } from './queue.js';
3
- export type { Queue, QueueConfig, EnqueueOptions, ClaimedJob, JobResult, BackoffConfig } from './queue.js';
3
+ export type { Queue, QueueConfig, EnqueueOptions, EnqueueExclusion, ClaimedJob, ClaimedExclusion, JobResult, BackoffConfig } from './queue.js';
4
+ export type { ExclusionConfig } from './exclusion.js';
4
5
  export type { WaitOptions, WaitResult, ListenClient, ListenHandle } from './listener.js';
5
6
  export { parseCron, nextTick } from './cron.js';
6
7
  export type { CronSchedule } from './cron.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/async/jobs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1G,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACxF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC/C,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/async/jobs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC9I,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACrD,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACxF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC/C,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/async/jobs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAGxC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/async/jobs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAIxC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA"}
@@ -1,12 +1,14 @@
1
1
  import type { DB } from '../../data/db/index.js';
2
+ import type { DefinedTable } from '../../data/domain/types.js';
2
3
  import type { ListenClient, WaitOptions, WaitResult } from './listener.js';
3
4
  import type { ScheduleSpec, ScheduleInfo, SchedulerOptions } from './scheduler.js';
5
+ import type { ExclusionConfig } from './exclusion.js';
4
6
  export interface BackoffConfig {
5
7
  readonly type: 'exponential' | 'fixed';
6
8
  readonly delayMs: number;
7
9
  readonly maxDelayMs?: number;
8
10
  }
9
- /** Queue configuration — table name, stale timeout, max attempts, backoff strategy. */
11
+ /** Queue configuration — table name, stale timeout, max attempts, backoff strategy, cross-job exclusion. */
10
12
  export interface QueueConfig {
11
13
  readonly table?: string;
12
14
  readonly staleTimeoutMs?: number;
@@ -14,6 +16,17 @@ export interface QueueConfig {
14
16
  readonly claimFilter?: (candidateAlias: string) => string;
15
17
  readonly maxAttempts?: number;
16
18
  readonly backoff?: BackoffConfig;
19
+ /** Cross-job exclusion gate — overlap/blocks-all/tenant columns checked against claimed/running jobs at claim time. */
20
+ readonly exclusion?: ExclusionConfig;
21
+ }
22
+ /** Exclusion values for one job — mapped onto the configured exclusion columns. */
23
+ export interface EnqueueExclusion {
24
+ /** Conflict set for the configured arrayColumn; null/omitted = non-participating. */
25
+ readonly array?: readonly string[] | null;
26
+ /** TRUE makes this job exclusive against every participating job in its scope. */
27
+ readonly blocksAll?: boolean;
28
+ /** Tenant value for the configured tenantColumn — required when one is configured. */
29
+ readonly tenant?: string;
17
30
  }
18
31
  /** Options for enqueuing a job — type, payload, priority, max attempts. */
19
32
  export interface EnqueueOptions {
@@ -21,6 +34,13 @@ export interface EnqueueOptions {
21
34
  readonly priority?: number;
22
35
  readonly payload: unknown;
23
36
  readonly maxAttempts?: number;
37
+ readonly exclusion?: EnqueueExclusion;
38
+ }
39
+ /** The exclusion values a claimed job carries — present when the queue configures exclusion. */
40
+ export interface ClaimedExclusion {
41
+ readonly array: readonly string[] | null;
42
+ readonly blocksAll: boolean;
43
+ readonly tenant: string | null;
24
44
  }
25
45
  /** A job claimed by a worker — includes ID, type, payload, and created LSN. */
26
46
  export interface ClaimedJob {
@@ -29,6 +49,7 @@ export interface ClaimedJob {
29
49
  readonly priority: number;
30
50
  readonly payload: unknown;
31
51
  readonly createdLsn: string;
52
+ readonly exclusion?: ClaimedExclusion;
32
53
  }
33
54
  export interface JobResult {
34
55
  readonly status: 'completed' | 'failed' | 'cancelled' | 'timeout' | 'dead_letter';
@@ -37,8 +58,11 @@ export interface JobResult {
37
58
  }
38
59
  /** Job queue instance with claim/complete/fail lifecycle, LISTEN/NOTIFY, and cron scheduling. */
39
60
  export interface Queue {
61
+ /** The queue table as a pipe.define() definition — `pipework generate` emits its DDL. */
62
+ readonly definition: DefinedTable;
40
63
  enqueue(db: DB, opts: EnqueueOptions): Promise<string>;
41
- claim(db: DB, workerId: string): Promise<ClaimedJob | null>;
64
+ /** Claims the next eligible job, retrying transient conflicts until clean. The signal ends the retry loop on shutdown — claim resolves null promptly. */
65
+ claim(db: DB, workerId: string, signal?: AbortSignal): Promise<ClaimedJob | null>;
42
66
  heartbeat(db: DB, jobId: string): Promise<void>;
43
67
  complete(db: DB, jobId: string, output?: unknown): Promise<void>;
44
68
  fail(db: DB, jobId: string, error: unknown): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/async/jobs/queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/async/jobs/queue.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,16 @@
1
1
  import { sql } from '../../data/db/sql.js';
2
2
  import { assertValidIdentifier, quoteIdentifier } from '../../data/db/identifiers.js';
3
+ import { serializable, isTransientConcurrencyError } from '../../data/db/serializable.js';
4
+ import { abortableDelay } from './abortable-delay.js';
3
5
  import { JobListener } from './listener.js';
4
6
  import { createScheduler } from './scheduler.js';
7
+ import { resolveExclusion, exclusionClaimClause } from './exclusion.js';
8
+ import { queueDefinition } from './table.js';
9
+ /** Serializes values into a Postgres array literal (`{"a","b"}`) — sent as one text param and cast to the element type. */
10
+ function pgArrayLiteral(values) {
11
+ const escaped = values.map(v => `"${v.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`);
12
+ return `{${escaped.join(',')}}`;
13
+ }
5
14
  export function createQueue(config = {}) {
6
15
  const table = config.table ?? 'pipework_jobs';
7
16
  const staleTimeoutMs = config.staleTimeoutMs ?? 120_000;
@@ -12,56 +21,139 @@ export function createQueue(config = {}) {
12
21
  assertValidIdentifier(channel, 'notify channel');
13
22
  const tableQ = quoteIdentifier(table, 'queue table');
14
23
  const listener = new JobListener(channel, tableQ);
24
+ const exclusion = resolveExclusion(config.exclusion);
25
+ const definition = queueDefinition(table, exclusion);
15
26
  async function enqueue(db, opts) {
16
27
  const priority = opts.priority ?? 0;
17
28
  const payload = JSON.stringify(opts.payload);
18
29
  const attempts = opts.maxAttempts ?? maxAttempts;
19
- const rows = await db.execute(sql `INSERT INTO ${sql.raw(tableQ)} (job_type, priority, payload, max_attempts)
20
- VALUES (${opts.type}, ${priority}, ${payload}::jsonb, ${attempts})
30
+ const columns = ['job_type', 'priority', 'payload', 'max_attempts'];
31
+ const values = [sql `${opts.type}`, sql `${priority}`, sql `${payload}::jsonb`, sql `${attempts}`];
32
+ if (exclusion === undefined) {
33
+ if (opts.exclusion !== undefined) {
34
+ throw new Error(`[pipework] enqueue() received exclusion values, but queue "${table}" has no exclusion config.\n\n` +
35
+ ' Silently dropping them would enqueue a job without its conflict data.\n' +
36
+ ' Configure the queue: createQueue({ exclusion: { arrayColumn: ..., blocksAllColumn: ..., tenantColumn: ... } }).\n');
37
+ }
38
+ }
39
+ else {
40
+ const given = opts.exclusion ?? {};
41
+ if (given.array !== undefined && given.array !== null && exclusion.arrayColumn === undefined) {
42
+ throw new Error(`[pipework] enqueue() received exclusion.array, but queue "${table}" configures no arrayColumn.\n\n` +
43
+ ' Add arrayColumn to the queue exclusion config, or drop the value.\n');
44
+ }
45
+ if (given.blocksAll !== undefined && exclusion.blocksAllColumn === undefined) {
46
+ throw new Error(`[pipework] enqueue() received exclusion.blocksAll, but queue "${table}" configures no blocksAllColumn.\n\n` +
47
+ ' Add blocksAllColumn to the queue exclusion config, or drop the value.\n');
48
+ }
49
+ if (given.tenant !== undefined && exclusion.tenantColumn === undefined) {
50
+ throw new Error(`[pipework] enqueue() received exclusion.tenant, but queue "${table}" configures no tenantColumn.\n\n` +
51
+ ' Add tenantColumn to the queue exclusion config, or drop the value.\n');
52
+ }
53
+ if (exclusion.tenantColumn !== undefined) {
54
+ if (given.tenant === undefined) {
55
+ throw new Error(`[pipework] enqueue() requires exclusion.tenant — queue "${table}" scopes exclusion by "${exclusion.tenantColumn}".\n\n` +
56
+ ' Every job needs a tenant: enqueue(db, { ..., exclusion: { tenant: <id> } }).\n');
57
+ }
58
+ columns.push(quoteIdentifier(exclusion.tenantColumn, 'exclusion column'));
59
+ values.push(sql `${given.tenant}::uuid`);
60
+ }
61
+ if (exclusion.arrayColumn !== undefined && given.array !== undefined && given.array !== null) {
62
+ columns.push(quoteIdentifier(exclusion.arrayColumn, 'exclusion column'));
63
+ values.push(sql `${pgArrayLiteral(given.array)}::${sql.raw(exclusion.arrayElementType)}[]`);
64
+ }
65
+ if (exclusion.blocksAllColumn !== undefined && given.blocksAll !== undefined) {
66
+ columns.push(quoteIdentifier(exclusion.blocksAllColumn, 'exclusion column'));
67
+ values.push(sql `${given.blocksAll}`);
68
+ }
69
+ }
70
+ const rows = await db.execute(sql `INSERT INTO ${sql.raw(tableQ)} (${sql.raw(columns.join(', '))})
71
+ VALUES (${sql.join(values, sql `, `)})
21
72
  RETURNING id::text`);
22
73
  return rows[0]['id'];
23
74
  }
24
- async function claim(db, workerId) {
25
- const maxRetries = 3;
26
- for (let attempt = 0; attempt < maxRetries; attempt++) {
75
+ function buildClaimQuery(workerId) {
76
+ const claimFilterClause = config.claimFilter
77
+ ? ` AND (${config.claimFilter('candidate')})`
78
+ : '';
79
+ const exclusionClause = exclusion !== undefined
80
+ ? ` AND ${exclusionClaimClause(tableQ, exclusion)}`
81
+ : '';
82
+ const exclusionReturning = exclusion !== undefined
83
+ ? [exclusion.tenantColumn, exclusion.arrayColumn, exclusion.blocksAllColumn]
84
+ .filter((c) => c !== undefined)
85
+ .map(c => `, ${quoteIdentifier(c, 'exclusion column')}`)
86
+ .join('')
87
+ : '';
88
+ return sql `
89
+ UPDATE ${sql.raw(tableQ)} SET
90
+ status = 'claimed',
91
+ claimed_at = now(),
92
+ heartbeat_at = now(),
93
+ worker_id = ${workerId}
94
+ WHERE id = (
95
+ SELECT candidate.id FROM ${sql.raw(tableQ)} candidate
96
+ WHERE candidate.status = 'pending' AND (candidate.next_retry_at IS NULL OR candidate.next_retry_at <= now())${sql.raw(exclusionClause)}${sql.raw(claimFilterClause)}
97
+ ORDER BY candidate.priority DESC, candidate.queued_at ASC
98
+ FOR UPDATE SKIP LOCKED
99
+ LIMIT 1
100
+ )
101
+ RETURNING id::text, job_type, priority, payload, created_lsn::text${sql.raw(exclusionReturning)}`;
102
+ }
103
+ function mapClaimedRow(row) {
104
+ const base = {
105
+ id: row['id'],
106
+ type: row['job_type'],
107
+ priority: row['priority'],
108
+ payload: row['payload'],
109
+ createdLsn: row['created_lsn'],
110
+ };
111
+ if (exclusion === undefined)
112
+ return base;
113
+ return {
114
+ ...base,
115
+ exclusion: {
116
+ array: exclusion.arrayColumn !== undefined ? row[exclusion.arrayColumn] : null,
117
+ blocksAll: exclusion.blocksAllColumn !== undefined ? row[exclusion.blocksAllColumn] : false,
118
+ tenant: exclusion.tenantColumn !== undefined ? row[exclusion.tenantColumn] : null,
119
+ },
120
+ };
121
+ }
122
+ /** Full-jitter backoff for transient claim conflicts — identical schedules re-collide, jitter decorrelates the herd. */
123
+ function conflictDelay(attempt) {
124
+ return Math.random() * Math.min(1000, 50 * 2 ** attempt);
125
+ }
126
+ async function claim(db, workerId, signal) {
127
+ const query = buildClaimQuery(workerId);
128
+ // Serialization failures (40001) carry Postgres's safe-retry guarantee:
129
+ // the conflicting transaction committed, so every abort means another
130
+ // claimer made progress and a retry cannot fail the same way again.
131
+ // Retrying until a clean attempt keeps the contract exact — null means
132
+ // "nothing claimable", never "gave up under contention". A fixed retry
133
+ // budget here starves non-conflicting claimers under sustained load.
134
+ // The loop's only other exit is shutdown: the signal cancels the backoff
135
+ // sleep and the next attempt, returning null — without it a worker stuck
136
+ // under sustained contention can never observe shutdown.
137
+ for (let attempt = 0;; attempt++) {
138
+ if (signal?.aborted === true)
139
+ return null;
27
140
  try {
28
- const claimFilterClause = config.claimFilter
29
- ? sql ` AND (${sql.raw(config.claimFilter(table))})`
30
- : sql ``;
31
- const rows = await db.execute(sql `
32
- UPDATE ${sql.raw(tableQ)} SET
33
- status = 'claimed',
34
- claimed_at = now(),
35
- heartbeat_at = now(),
36
- worker_id = ${workerId}
37
- WHERE id = (
38
- SELECT id FROM ${sql.raw(tableQ)}
39
- WHERE status = 'pending' AND (next_retry_at IS NULL OR next_retry_at <= now())${claimFilterClause}
40
- ORDER BY priority DESC, queued_at ASC
41
- FOR UPDATE SKIP LOCKED
42
- LIMIT 1
43
- )
44
- RETURNING id::text, job_type, priority, payload, created_lsn::text`);
141
+ // Two workers evaluating the exclusion NOT EXISTS checks against the
142
+ // same MVCC snapshot can both pass and claim conflicting jobs (write
143
+ // skew) — the exclusion claim query must run under SERIALIZABLE.
144
+ const rows = exclusion !== undefined
145
+ ? await serializable(db, async (tx) => tx.execute(query), { maxAttempts: 1 })
146
+ : await db.execute(query);
45
147
  if (rows.length === 0)
46
148
  return null;
47
- const row = rows[0];
48
- return {
49
- id: row['id'],
50
- type: row['job_type'],
51
- priority: row['priority'],
52
- payload: row['payload'],
53
- createdLsn: row['created_lsn'],
54
- };
149
+ return mapClaimedRow(rows[0]);
55
150
  }
56
151
  catch (err) {
57
- const code = err.code;
58
- if ((code === '40001' || code === '40P01') && attempt < maxRetries - 1) {
59
- continue;
60
- }
61
- throw err;
152
+ if (!isTransientConcurrencyError(err))
153
+ throw err;
154
+ await abortableDelay(conflictDelay(attempt), signal);
62
155
  }
63
156
  }
64
- return null;
65
157
  }
66
158
  async function heartbeat(db, jobId) {
67
159
  await db.execute(sql `UPDATE ${sql.raw(tableQ)} SET heartbeat_at = now() WHERE id = ${jobId}::uuid`);
@@ -152,6 +244,7 @@ export function createQueue(config = {}) {
152
244
  }
153
245
  const sched = createScheduler({ enqueue }, tableQ);
154
246
  return {
247
+ definition,
155
248
  enqueue, claim, heartbeat, complete, fail, cancel, reap, requeueDeadLetter,
156
249
  startListener, stopListener, waitFor, enqueueAndWait,
157
250
  schedule: (db, spec) => sched.schedule(db, spec),
@@ -1 +1 @@
1
- {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../src/async/jobs/queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../src/async/jobs/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAE1C,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AACrF,OAAO,EAAE,YAAY,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAA;AAEzF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAEvE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAsF5C,2HAA2H;AAC3H,SAAS,cAAc,CAAC,MAAyB;IAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;IACrF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;AACjC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAsB,EAAE;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,eAAe,CAAA;IAC7C,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,OAAO,CAAA;IACvD,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,IAAI,uBAAuB,CAAA;IAC/D,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,CAAA;IAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;IAE9B,qBAAqB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;IAC3C,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAA;IAEhD,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;IACpD,MAAM,QAAQ,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAEjD,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IACpD,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IAEpD,KAAK,UAAU,OAAO,CAAC,EAAM,EAAE,IAAoB;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAA;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,IAAI,WAAW,CAAA;QAEhD,MAAM,OAAO,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC,CAAA;QACnE,MAAM,MAAM,GAAU,CAAC,GAAG,CAAA,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,CAAA,GAAG,QAAQ,EAAE,EAAE,GAAG,CAAA,GAAG,OAAO,SAAS,EAAE,GAAG,CAAA,GAAG,QAAQ,EAAE,CAAC,CAAA;QAErG,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBACjC,MAAM,IAAI,KAAK,CACb,8DAA8D,KAAK,gCAAgC;oBACnG,2EAA2E;oBAC3E,qHAAqH,CACtH,CAAA;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAA;YAClC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,SAAS,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC7F,MAAM,IAAI,KAAK,CACb,6DAA6D,KAAK,kCAAkC;oBACpG,uEAAuE,CACxE,CAAA;YACH,CAAC;YACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;gBAC7E,MAAM,IAAI,KAAK,CACb,iEAAiE,KAAK,sCAAsC;oBAC5G,2EAA2E,CAC5E,CAAA;YACH,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,SAAS,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBACvE,MAAM,IAAI,KAAK,CACb,8DAA8D,KAAK,mCAAmC;oBACtG,wEAAwE,CACzE,CAAA;YACH,CAAC;YACD,IAAI,SAAS,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBACzC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CACb,2DAA2D,KAAK,0BAA0B,SAAS,CAAC,YAAY,QAAQ;wBACxH,kFAAkF,CACnF,CAAA;gBACH,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAA;gBACzE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAA,GAAG,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAA;YACzC,CAAC;YACD,IAAI,SAAS,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;gBAC7F,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAA;gBACxE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAA,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;YAC5F,CAAC;YACD,IAAI,SAAS,CAAC,eAAe,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC7E,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC,CAAA;gBAC5E,MAAM,CAAC,IAAI,CAAC,GAAG,CAAA,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAC3B,GAAG,CAAA,eAAe,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;yBAC9C,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAA,IAAI,CAAC;kCAChB,CAC7B,CAAA;QACD,OAAO,IAAI,CAAC,CAAC,CAAE,CAAC,IAAI,CAAW,CAAA;IACjC,CAAC;IAED,SAAS,eAAe,CAAC,QAAgB;QACvC,MAAM,iBAAiB,GAAG,MAAM,CAAC,WAAW;YAC1C,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG;YAC7C,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,eAAe,GAAG,SAAS,KAAK,SAAS;YAC7C,CAAC,CAAC,QAAQ,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;YACnD,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,kBAAkB,GAAG,SAAS,KAAK,SAAS;YAChD,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,EAAE,SAAS,CAAC,WAAW,EAAE,SAAS,CAAC,eAAe,CAAC;iBACzE,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;iBAC3C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,eAAe,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAE,CAAC;iBACvD,IAAI,CAAC,EAAE,CAAC;YACX,CAAC,CAAC,EAAE,CAAA;QAEN,OAAO,GAAG,CAAA;eACC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;;;;sBAIR,QAAQ;;mCAEK,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;sHACoE,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC;;;;;0EAKjG,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAA;IACrG,CAAC;IAED,SAAS,aAAa,CAAC,GAA4B;QACjD,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,GAAG,CAAC,IAAI,CAAW;YACvB,IAAI,EAAE,GAAG,CAAC,UAAU,CAAW;YAC/B,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAW;YACnC,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC;YACvB,UAAU,EAAE,GAAG,CAAC,aAAa,CAAW;SACzC,CAAA;QACD,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QACxC,OAAO;YACL,GAAG,IAAI;YACP,SAAS,EAAE;gBACT,KAAK,EAAE,SAAS,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAE,GAAG,CAAC,SAAS,CAAC,WAAW,CAAqB,CAAC,CAAC,CAAC,IAAI;gBACnG,SAAS,EAAE,SAAS,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAE,GAAG,CAAC,SAAS,CAAC,eAAe,CAAa,CAAC,CAAC,CAAC,KAAK;gBACxG,MAAM,EAAE,SAAS,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAE,GAAG,CAAC,SAAS,CAAC,YAAY,CAAY,CAAC,CAAC,CAAC,IAAI;aAC9F;SACF,CAAA;IACH,CAAC;IAED,wHAAwH;IACxH,SAAS,aAAa,CAAC,OAAe;QACpC,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,CAAA;IAC1D,CAAC;IAED,KAAK,UAAU,KAAK,CAAC,EAAM,EAAE,QAAgB,EAAE,MAAoB;QACjE,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAA;QAEvC,wEAAwE;QACxE,sEAAsE;QACtE,oEAAoE;QACpE,uEAAuE;QACvE,uEAAuE;QACvE,qEAAqE;QACrE,yEAAyE;QACzE,yEAAyE;QACzE,yDAAyD;QACzD,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;YAClC,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAA;YACzC,IAAI,CAAC;gBACH,qEAAqE;gBACrE,qEAAqE;gBACrE,iEAAiE;gBACjE,MAAM,IAAI,GAAG,SAAS,KAAK,SAAS;oBAClC,CAAC,CAAC,MAAM,YAAY,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;oBAC7E,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;gBAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,IAAI,CAAA;gBAClC,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAA;YAChC,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC;oBAAE,MAAM,GAAG,CAAA;gBAChD,MAAM,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAA;YACtD,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,UAAU,SAAS,CAAC,EAAM,EAAE,KAAa;QAC5C,MAAM,EAAE,CAAC,OAAO,CACd,GAAG,CAAA,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,wCAAwC,KAAK,QAAQ,CAClF,CAAA;IACH,CAAC;IAED,KAAK,UAAU,QAAQ,CAAC,EAAM,EAAE,KAAa,EAAE,MAAgB;QAC7D,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACvE,MAAM,EAAE,CAAC,OAAO,CACd,GAAG,CAAA,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,6DAA6D,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAA,GAAG,UAAU,SAAS,CAAC,CAAC,CAAC,GAAG,CAAA,MAAM;4BAC9H,KAAK,QAAQ,CACpC,CAAA;QACD,MAAM,EAAE,CAAC,OAAO,CACd,GAAG,CAAA,oBAAoB,OAAO,KAAK,KAAK,GAAG,CAC5C,CAAA;IACH,CAAC;IAED,SAAS,cAAc,CAAC,YAAoB;QAC1C,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,CAAA;QACtB,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC,OAAO,CAAA;QACpD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;QACzD,OAAO,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IACvF,CAAC;IAED,KAAK,UAAU,IAAI,CAAC,EAAM,EAAE,KAAa,EAAE,KAAc;QACvD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QAEjH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAC9B,GAAG,CAAA,2CAA2C,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,KAAK,QAAQ,CAC1F,CAAA;QACD,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACtB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,oBAAoB,CAAC,CAAA;QAC3E,CAAC;QAED,MAAM,YAAY,GAAG,GAAG,CAAC,eAAe,CAAW,CAAA;QACnD,MAAM,cAAc,GAAG,GAAG,CAAC,cAAc,CAAW,CAAA;QACpD,MAAM,WAAW,GAAG,YAAY,GAAG,CAAC,CAAA;QAEpC,IAAI,WAAW,GAAG,cAAc,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,cAAc,CAAC,YAAY,CAAC,CAAA;YAC5C,MAAM,YAAY,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAA;YAC3D,MAAM,EAAE,CAAC,OAAO,CACd,GAAG,CAAA,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;;gCAEJ,WAAW;gCACX,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA,WAAW,YAAY,YAAY,CAAC,CAAC,CAAC,GAAG,CAAA,MAAM;gCAChE,SAAS;;;;yBAIhB,KAAK,QAAQ,CAC/B,CAAA;QACH,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC,OAAO,CACd,GAAG,CAAA,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;;gCAEJ,WAAW;;gCAEX,SAAS;yBAChB,KAAK,QAAQ,CAC/B,CAAA;YACD,MAAM,EAAE,CAAC,OAAO,CACd,GAAG,CAAA,oBAAoB,OAAO,KAAK,KAAK,GAAG,CAC5C,CAAA;QACH,CAAC;IACH,CAAC;IAED,KAAK,UAAU,MAAM,CAAC,EAAM,EAAE,KAAa;QACzC,MAAM,EAAE,CAAC,OAAO,CACd,GAAG,CAAA,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;4BACN,KAAK,6CAA6C,CACzE,CAAA;IACH,CAAC;IAED,KAAK,UAAU,IAAI,CAAC,EAAM;QACxB,MAAM,aAAa,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,UAAU,CAAA;QACpE,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAC3B,GAAG,CAAA,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;mCACC,yCAAyC;;8CAE9B,aAAa;4BAC/B,CACvB,CAAA;QACD,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAED,KAAK,UAAU,iBAAiB,CAAC,EAAM,EAAE,KAAa;QACpD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAC3B,GAAG,CAAA,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;kEACgC,WAAW;;;qBAGxD,KAAK;qBACL,CAChB,CAAA;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,iDAAiD,CAAC,CAAA;QAC3G,CAAC;IACH,CAAC;IAED,KAAK,UAAU,aAAa,CAAC,MAAoB;QAC/C,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,UAAU,YAAY;QACzB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IACvB,CAAC;IAED,KAAK,UAAU,OAAO,CAAC,EAAM,EAAE,KAAa,EAAE,IAAiB;QAC7D,OAAO,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IAC1C,CAAC;IAED,KAAK,UAAU,cAAc,CAAC,EAAM,EAAE,IAAoB,EAAE,QAAqB;QAC/E,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;QACrC,OAAO,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;IAC9C,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC,CAAA;IAElD,OAAO;QACL,UAAU;QACV,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB;QAC1E,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc;QACpD,QAAQ,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;QAChD,UAAU,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC;QACpD,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9C,cAAc,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC;QACnD,aAAa,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE;KAClC,CAAA;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { DefinedTable } from '../../data/domain/types.js';
2
+ import type { ResolvedExclusion } from './exclusion.js';
3
+ export declare const QUEUE_STATUSES: readonly ["pending", "claimed", "running", "completed", "failed", "cancelled", "dead_letter"];
4
+ /** Column names every queue table owns — exclusion columns must not collide with these. */
5
+ export declare const QUEUE_BASE_COLUMNS: ReadonlySet<string>;
6
+ /**
7
+ * Builds (or reuses) the DefinedTable for a queue. Cached per table name so
8
+ * repeated createQueue() calls share one definition; the same name with a
9
+ * different shape is a config error, not a silent overwrite.
10
+ */
11
+ export declare function queueDefinition(tableName: string, exclusion: ResolvedExclusion | undefined): DefinedTable;
12
+ /** Registered queue definitions — merged into `pipework generate` via internalDefinitions. */
13
+ export declare function queueDefinitions(): ReadonlyMap<string, DefinedTable>;
14
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/async/jobs/table.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,4BAA4B,CAAA;AAK/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAEvD,eAAO,MAAM,cAAc,+FAAgG,CAAA;AAE3H,2FAA2F;AAC3F,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAIjD,CAAA;AA6CF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,GAAG,SAAS,GAAG,YAAY,CAwDzG;AAED,8FAA8F;AAC9F,wBAAgB,gBAAgB,IAAI,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAEpE"}