pipework 0.174.0 → 0.176.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/CHANGELOG.md +13 -0
- package/REFERENCE.md +7 -2
- package/dist/REFERENCE.md +10 -131
- package/dist/async/jobs/scheduler.js +1 -1
- package/dist/async/jobs/scheduler.js.map +1 -1
- package/dist/async/steps/graph.js +9 -9
- package/dist/async/steps/graph.js.map +1 -1
- package/dist/data/query/sql/sql.d.ts +10 -0
- package/dist/data/query/sql/sql.d.ts.map +1 -1
- package/dist/data/query/sql/sql.js +21 -0
- package/dist/data/query/sql/sql.js.map +1 -1
- package/dist/data/write/audit/verb-upsert.d.ts.map +1 -1
- package/dist/data/write/audit/verb-upsert.js +1 -0
- package/dist/data/write/audit/verb-upsert.js.map +1 -1
- package/dist/infra/access-links/handle.js +4 -4
- package/dist/infra/access-links/handle.js.map +1 -1
- package/dist/infra/alerts/infra-sources.d.ts +49 -0
- package/dist/infra/alerts/infra-sources.d.ts.map +1 -0
- package/dist/infra/alerts/infra-sources.js +176 -0
- package/dist/infra/alerts/infra-sources.js.map +1 -0
- package/dist/infra/alerts/namespace.d.ts +9 -0
- package/dist/infra/alerts/namespace.d.ts.map +1 -1
- package/dist/infra/alerts/namespace.js +9 -0
- package/dist/infra/alerts/namespace.js.map +1 -1
- package/dist/infra/alerts/source-options.d.ts +13 -0
- package/dist/infra/alerts/source-options.d.ts.map +1 -0
- package/dist/infra/alerts/source-options.js +19 -0
- package/dist/infra/alerts/source-options.js.map +1 -0
- package/dist/infra/alerts/subsystem-sources.d.ts +1 -8
- package/dist/infra/alerts/subsystem-sources.d.ts.map +1 -1
- package/dist/infra/alerts/subsystem-sources.js +1 -17
- package/dist/infra/alerts/subsystem-sources.js.map +1 -1
- package/dist/infra/email/inbound.js +1 -1
- package/dist/infra/email/inbound.js.map +1 -1
- package/dist/infra/email/mail.js +1 -1
- package/dist/infra/email/mail.js.map +1 -1
- package/dist/infra/email/schema.d.ts +10 -0
- package/dist/infra/email/schema.d.ts.map +1 -1
- package/dist/infra/email/schema.js +2 -0
- package/dist/infra/email/schema.js.map +1 -1
- package/dist/trace/partition/sync.js +2 -4
- package/dist/trace/partition/sync.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.176.0
|
|
4
|
+
|
|
5
|
+
- **Added: alert sources for mail, storage, access links and sign-in lockouts** (failure-alert class, part 2 of 3):
|
|
6
|
+
- `alerts.source.email({ stuckAfterMs?, queuedAfterMs?, receivedAfterMs?, sweepGraceMs? })` raises `email-failed:outbound` and `email-failed:inbound` for messages marked failed since the last tick, `email-stuck:sending` and `email-stuck:queued` while sends stall or nothing drains the queue, `email-inbound-stuck:received` while received mail is not handled, and `email-raw-undrained:all` while raw inbound copies outlive their retention.
|
|
7
|
+
- `alerts.source.storage({ sweepGraceMs? })` raises `storage-expiry-undrained:all` while expired files are not swept.
|
|
8
|
+
- `alerts.source.accessLinks({ graceMs? })` raises `access-link-abandoned:<tenantId>` while link uses stay reserved and never finish.
|
|
9
|
+
- `alerts.source.lockouts({ tables? })` raises `auth-lockout:<table>` (warning) while sign-in or guard lockouts are active: counts only, never an account. Without `tables` it watches whichever lockout tables exist.
|
|
10
|
+
- `pipework_email_messages` and `pipework_email_inbound` gain a nullable `failed_at`, set when a message is marked failed. Run `pipework generate` and migrate.
|
|
11
|
+
|
|
12
|
+
## 0.175.0
|
|
13
|
+
|
|
14
|
+
- **Fixed: a worker surface with `schedules: []` failed every scheduler check** with `syntax error at or near ")"`. The scheduler built `name IN ()` from the empty list. **Added: `sql.inList(values, cast?)`**, the one safe way to match a column against a JS list. `` col ${sql.inList(ids, 'uuid')} `` renders `= ANY(...)` over one jsonb parameter, so an empty list matches nothing instead of failing to parse. A `Date` travels as ISO text. The scheduler, trace partition sync, access-link deletes and step-graph queries now use it; those other sites were already guarded against an empty list.
|
|
15
|
+
|
|
3
16
|
## 0.174.0
|
|
4
17
|
|
|
5
18
|
- **Added: build an alert from any recorded failure, and sources for outbox, webhook and credit failures** (follows #712). Two general builders:
|
package/REFERENCE.md
CHANGED
|
@@ -732,6 +732,7 @@ Expression helpers for `.set()`, `.values()` and `.where()` (a string or number
|
|
|
732
732
|
- `filter.strpos(a, b)`, `filter.textContains(a, b)`, `filter.startsWith(a, prefix)` — exact-text tests, no `%`/`_`/backslash wildcards (unlike `like`). `a`, `b`, `prefix` take a column, expression or string.
|
|
733
733
|
- `filter.left(a, n)`, `filter.right(a, n)`, `filter.length(a)` — text slices and length.
|
|
734
734
|
- `filter.concat(...parts)` — `(p1 || p2 || ...)`, at least two parts, each a string, column or expression (`scalar(...)` for a subquery). A null part makes the result null; wrap it in `coalesce` if not wanted.
|
|
735
|
+
- `pipe.sql.inList(values, cast?)` — list match for a JS list: `` sql`id ${sql.inList(ids, 'uuid')}` `` renders `= ANY(...)`, so an empty list matches nothing; never build `IN (${sql.join(...)})`, which is a syntax error when the list is empty. `cast` is the element type, default `text`.
|
|
735
736
|
- `filter.arrayReplace(col, from, to)` — `array_replace`, every `from` becomes `to`; `filter.arrayHas(col, value)` — `$value = ANY(col)`. `col` must be an array column; values are cast to its element type.
|
|
736
737
|
- `filter.jsonbMerge(col, object)` — same as `jsonb.merge`.
|
|
737
738
|
- `filter.jsonbRemove(col, ...keys)` — same as `jsonb.remove`.
|
|
@@ -1283,7 +1284,7 @@ Signs a payload with HMAC for outbound delivery — returns body, signature, tim
|
|
|
1283
1284
|
|
|
1284
1285
|
Mail namespace — email through a job queue, SES v2 or a dev stand-in, bounce and complaint suppression, and receiving.
|
|
1285
1286
|
|
|
1286
|
-
Opt in with blueprint `email: {}`; the generated migration adds `pipework_email_messages` (`key` unique, `to_address`, `template`, `data`, `status` `queued | sending | sent | suppressed | failed`, `provider_message_id`, `error`, `trace_id`, `created_at`, `sent_at`, `sending_at`) and `pipework_email_suppressions` (`address` primary key, lowercased; `reason` `bounce | complaint`; `detail`; `created_at`), both `IF NOT EXISTS` and not tenant-scoped. `pipework_email_messages` also has `conversation_id` and `in_reply_to_inbound`. Receiving adds `pipework_email_inbound` (see `mail.inbound`).
|
|
1287
|
+
Opt in with blueprint `email: {}`; the generated migration adds `pipework_email_messages` (`key` unique, `to_address`, `template`, `data`, `status` `queued | sending | sent | suppressed | failed`, `provider_message_id`, `error`, `trace_id`, `created_at`, `sent_at`, `sending_at`, `failed_at`) and `pipework_email_suppressions` (`address` primary key, lowercased; `reason` `bounce | complaint`; `detail`; `created_at`), both `IF NOT EXISTS` and not tenant-scoped. `pipework_email_messages` also has `conversation_id` and `in_reply_to_inbound`. Receiving adds `pipework_email_inbound` (see `mail.inbound`).
|
|
1287
1288
|
|
|
1288
1289
|
### `mail.create`
|
|
1289
1290
|
|
|
@@ -1315,7 +1316,7 @@ Inbound handler for SES bounce and complaint events delivered through SNS; suppr
|
|
|
1315
1316
|
|
|
1316
1317
|
Receiving email: `inbound({ source, queue, onMessage, ... })` returns `{ webhook, jobs, scan, sweep, get }`; messages arrive parsed, threaded into conversations, attachments stored as tenant files.
|
|
1317
1318
|
|
|
1318
|
-
`mail.inbound({ source, queue, onMessage, storage?, resolveTenant?, rawRetentionDays? = 30, maxRawBytes? = 41943040, environment? })`. Needs blueprint `email: {}`: the table `pipework_email_inbound` (`source_id` unique, `source` `ses | folder`, `raw_location`, `raw_expires_at`, `raw_deleted_at`, `status` `received | processed | failed`, `error`, `message_id_header`, `in_reply_to`, `references`, `from_address`, `subject`, `conversation_id`, `tenant_id`, `verdicts`, `recipients`, `attachment_files`, `received_at`, `processed_at`, `trace_id`; `references`, `recipients` and `attachment_files` are jsonb arrays). Not tenant-scoped (the row exists before a tenant is known). It holds no bodies: the raw message is the copy, deleted by `sweep` after `rawRetentionDays`.
|
|
1319
|
+
`mail.inbound({ source, queue, onMessage, storage?, resolveTenant?, rawRetentionDays? = 30, maxRawBytes? = 41943040, environment? })`. Needs blueprint `email: {}`: the table `pipework_email_inbound` (`source_id` unique, `source` `ses | folder`, `raw_location`, `raw_expires_at`, `raw_deleted_at`, `status` `received | processed | failed`, `error`, `message_id_header`, `in_reply_to`, `references`, `from_address`, `subject`, `conversation_id`, `tenant_id`, `verdicts`, `recipients`, `attachment_files`, `received_at`, `processed_at`, `failed_at`, `trace_id`; `references`, `recipients` and `attachment_files` are jsonb arrays). Not tenant-scoped (the row exists before a tenant is known). It holds no bodies: the raw message is the copy, deleted by `sweep` after `rawRetentionDays`.
|
|
1319
1320
|
|
|
1320
1321
|
`webhook({ path })` (SES source) returns a public POST handler: the SNS message is verified exactly as for `mail.snsWebhook` (signature, certificate host, `topicArns`; 401 otherwise, nothing recorded), then one `pipework_email_inbound` row keyed by SES's `mail.messageId` and one `pipework.email.receive` job are written in one transaction; the same notification again adds nothing. A notification that is not `Received`, or whose receipt action is not `S3`, is answered 200 and ignored. Spread `jobs` into the worker surface's `jobs` (same queue).
|
|
1321
1322
|
|
|
@@ -1749,6 +1750,10 @@ Pass in `sources`; each raises with a fixed key on a tick and, where it can tell
|
|
|
1749
1750
|
- `alerts.source.deliveryFailed({ tables? = ['pipework_alert_deliveries'], stuckAfterMs? = 900_000, settleMs?, severity? = 'error', owner?, runbook?, database? })` — outbox rows that gave up: `delivery-failed:<table>:<sink>`, message `<n> delivery(ies) to <sink> gave up; last error: <last_error>` (clears by the quiet period); and rows still pending more than `stuckAfterMs` past `next_attempt_at`: `delivery-stuck:<table>:<sink>` (resolves when they drain). Name `support_event_delivery` in `tables` to cover the support outbox.
|
|
1750
1751
|
- `alerts.source.webhookFailed({ table? = '__pipework_webhook_deliveries', stalledAfterMs? = 900_000, settleMs?, severity?, owner?, runbook?, database? })` — outbound webhook deliveries (set `table` to your `deliveryTable`): `webhook-failed:<endpointId>` for deliveries that completed with no 2xx status, message `<n> webhook delivery(ies) to endpoint <id> gave up; last status <code|none>`; `webhook-stalled:<endpointId>` while deliveries are more than `stalledAfterMs` past `next_retry_at`.
|
|
1751
1752
|
- `alerts.source.credits({ heldOlderThanMs? = 3_600_000, expiryGraceMs? = 3_600_000, settleMs?, severity?, owner?, runbook?, database? })` — `credit-overdraft:<tenantId>` for settlements that overdrew a tenant (`<n> settlement(s) overdrew <tenantId> by <sum>`); `credit-held:<tenantId>` while reservations stay held past `heldOlderThanMs`; `credit-expiry-undrained:all` while grants expired more than `expiryGraceMs` ago still have credit (`<n> expired grant(s) not drained; is the credits expiry job scheduled?`). Needs `credits` configured.
|
|
1753
|
+
- `alerts.source.email({ stuckAfterMs? = 900_000, queuedAfterMs? = 3_600_000, receivedAfterMs? = 900_000, sweepGraceMs? = 3_600_000, settleMs?, severity?, owner?, runbook?, database? })` — needs `email: {}`. `email-failed:outbound` / `email-failed:inbound` for messages marked `failed` since the last tick (the new nullable `failed_at` column on both tables; run `pipework generate` and migrate; count and last error, no addresses); `email-stuck:sending` past `stuckAfterMs`; `email-stuck:queued` past `queuedAfterMs` (nothing drains the send queue); `email-inbound-stuck:received` past `receivedAfterMs`; `email-raw-undrained:all` while raw messages are `sweepGraceMs` past `raw_expires_at` and not deleted.
|
|
1754
|
+
- `alerts.source.storage({ sweepGraceMs? = 3_600_000, severity?, owner?, runbook?, database? })` — needs `storage: {}`. `storage-expiry-undrained:all` while `storage_file` rows are `sweepGraceMs` past `expires_at` and not swept.
|
|
1755
|
+
- `alerts.source.accessLinks({ graceMs? = 900_000, severity?, owner?, runbook?, database? })` — needs `accessLinks: {}`. `access-link-abandoned:<tenantId>` while uses stay `pending` `graceMs` past `reserved_until`.
|
|
1756
|
+
- `alerts.source.lockouts({ tables? = the ones that exist, severity? = 'warning', owner?, runbook?, database? })` — `auth-lockout:<table>` while rows have `locked_until` in the future (count only; no account is named). `pipework_signin_attempts` needs `passwords: {}`, `pipework_guard_attempts` needs `guards: {}`; with `tables` omitted, the tables that exist are resolved once on the first evaluate (it throws, naming both keys, if neither does); pass `tables` to override.
|
|
1752
1757
|
- `queue.totals(db)` — `{ overall, byType }`, each `{ ready, running, oldestReadyWaitMs }` (ready: pending and not waiting on a retry time; running: claimed or running; wait from `queued_at`, null when none is ready); `byType` omits a type with neither.
|
|
1753
1758
|
- `alerts.source.health(checks, { severity? = 'error' })` — `health:<name>` while a `HealthCheck` is unhealthy or throws; resolves when it recovers. Degraded is not a fault.
|
|
1754
1759
|
|
package/dist/REFERENCE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Pipework API Reference
|
|
2
2
|
|
|
3
3
|
> Auto-generated from source JSDoc. Do not edit manually.
|
|
4
|
-
> Generated: 2026-10-
|
|
4
|
+
> Generated: 2026-10-20
|
|
5
5
|
|
|
6
6
|
## Contents
|
|
7
7
|
|
|
@@ -816,10 +816,6 @@ Acquires a transaction-scoped advisory lock. Released at commit/rollback.
|
|
|
816
816
|
|
|
817
817
|
Runs a function in a SERIALIZABLE transaction with automatic retry on serialization failures and deadlocks.
|
|
818
818
|
|
|
819
|
-
### `pipe.withTimeouts`
|
|
820
|
-
|
|
821
|
-
Sets statement_timeout and/or lock_timeout for the current transaction in one statement, then runs fn; a statement cancelled for them rejects with StatementTimeoutError or LockTimeoutError.
|
|
822
|
-
|
|
823
819
|
### `pipe.bulkSet`
|
|
824
820
|
|
|
825
821
|
Bulk UPDATE ... FROM (VALUES ...) — updates multiple rows with per-row values in a single statement.
|
|
@@ -828,10 +824,6 @@ Bulk UPDATE ... FROM (VALUES ...) — updates multiple rows with per-row values
|
|
|
828
824
|
|
|
829
825
|
Produces a typed VALUES clause for bulk operations — the base primitive for bulkSet and bulkUpsert.
|
|
830
826
|
|
|
831
|
-
### `pipe.fn`
|
|
832
|
-
|
|
833
|
-
A set-returning SQL function as a typed source for `.from()` and joins — `pipe.fn('schema.f', { args: [field.uuid()], columns: { path: field.text() } })`. Arguments are bound and cast to their declared types.
|
|
834
|
-
|
|
835
827
|
### `pipe.field`
|
|
836
828
|
|
|
837
829
|
Field builders for domain definitions — uuid(), text(), integer(), etc.
|
|
@@ -844,10 +836,6 @@ Registers a domain definition with table, validators, and factory projections. T
|
|
|
844
836
|
|
|
845
837
|
Returns the global registry of all domain definitions.
|
|
846
838
|
|
|
847
|
-
### `pipe.external`
|
|
848
|
-
|
|
849
|
-
Declares a table or view another service owns (`pipe.external(name, fields, { schema, table? })`): typed columns and every query operator, read-only, never migrated, not tenant-scoped.
|
|
850
|
-
|
|
851
839
|
### `pipe.update`
|
|
852
840
|
|
|
853
841
|
Pipework-owned UPDATE builder — the only consumer-facing way to update pipework-managed tables (Q8).
|
|
@@ -878,54 +866,12 @@ interface WindowSpec
|
|
|
878
866
|
interface ValueColumnDef
|
|
879
867
|
```
|
|
880
868
|
|
|
881
|
-
**`JsonbElements`** — A jsonb array read as its elements' text. Produced by {@link jsonbElements}.
|
|
882
|
-
|
|
883
|
-
```typescript
|
|
884
|
-
interface JsonbElements
|
|
885
|
-
```
|
|
886
|
-
|
|
887
|
-
**`ArraySource`** — Something whose elements `arrayAny` / `arrayAll` can test.
|
|
888
|
-
|
|
889
|
-
```typescript
|
|
890
|
-
type ArraySource =
|
|
891
|
-
```
|
|
892
|
-
|
|
893
|
-
**`ElementOf`** — The element type of an {@link ArraySource}.
|
|
894
|
-
|
|
895
|
-
```typescript
|
|
896
|
-
type ElementOf<S> =
|
|
897
|
-
```
|
|
898
|
-
|
|
899
|
-
**`FunctionSpec`** — Declares a SQL function's argument and result-column shapes. See {@link fn}.
|
|
900
|
-
|
|
901
|
-
```typescript
|
|
902
|
-
interface FunctionSpec<TArgs extends readonly AnyField[], TColumns extends Record<string, AnyField>>
|
|
903
|
-
```
|
|
904
|
-
|
|
905
|
-
**`FunctionSourceFields`** — The selected fields of a function source: each result column as a typed SQL expression.
|
|
906
|
-
|
|
907
|
-
```typescript
|
|
908
|
-
type FunctionSourceFields<TColumns extends Record<string, AnyField>> =
|
|
909
|
-
```
|
|
910
|
-
|
|
911
|
-
**`FunctionSource`** — A function call usable in `.from()` and joins; its result columns are properties of it.
|
|
912
|
-
|
|
913
|
-
```typescript
|
|
914
|
-
type FunctionSource<TAlias extends string, TColumns extends Record<string, AnyField>> =
|
|
915
|
-
```
|
|
916
|
-
|
|
917
869
|
**`SerializableOptions`** — Retry policy for {@link serializable}: how many attempts on a serialization failure / deadlock, and the base backoff between them.
|
|
918
870
|
|
|
919
871
|
```typescript
|
|
920
872
|
interface SerializableOptions
|
|
921
873
|
```
|
|
922
874
|
|
|
923
|
-
**`TimeoutOptions`** — Which timeouts {@link withTimeouts} sets; each a positive integer number of milliseconds.
|
|
924
|
-
|
|
925
|
-
```typescript
|
|
926
|
-
interface TimeoutOptions
|
|
927
|
-
```
|
|
928
|
-
|
|
929
875
|
**`ManagedConnection`** — A standalone pooled connection: the raw postgres.js client, its drizzle handle, and a `close()` that ends the pool.
|
|
930
876
|
|
|
931
877
|
```typescript
|
|
@@ -946,10 +892,6 @@ JSONB query operators — typed helpers for PostgreSQL JSONB containment, key ch
|
|
|
946
892
|
|
|
947
893
|
The @> containment operator — tests whether a JSONB column contains the given value.
|
|
948
894
|
|
|
949
|
-
### `jsonb.merge`
|
|
950
|
-
|
|
951
|
-
Merges an object into a JSONB column in `.set()`: `coalesce(col, '{}') || value`. Top-level keys overwrite; others are kept.
|
|
952
|
-
|
|
953
895
|
### `jsonb.containedBy`
|
|
954
896
|
|
|
955
897
|
The <@ contained-by operator — tests whether a JSONB column is contained by the given value.
|
|
@@ -1016,60 +958,6 @@ type Schema<T = unknown> = z.ZodType<T>
|
|
|
1016
958
|
type Infer<T extends Schema> = z.infer<T>
|
|
1017
959
|
```
|
|
1018
960
|
|
|
1019
|
-
**`StringSchema`** — A string validator — what check.string() returns, nameable without importing zod.
|
|
1020
|
-
|
|
1021
|
-
```typescript
|
|
1022
|
-
interface StringSchema extends z.ZodString
|
|
1023
|
-
```
|
|
1024
|
-
|
|
1025
|
-
**`NumberSchema`** — A number validator — what check.number() returns.
|
|
1026
|
-
|
|
1027
|
-
```typescript
|
|
1028
|
-
interface NumberSchema extends z.ZodNumber
|
|
1029
|
-
```
|
|
1030
|
-
|
|
1031
|
-
**`BooleanSchema`** — A boolean validator — what check.boolean() returns.
|
|
1032
|
-
|
|
1033
|
-
```typescript
|
|
1034
|
-
interface BooleanSchema extends z.ZodBoolean
|
|
1035
|
-
```
|
|
1036
|
-
|
|
1037
|
-
**`EnumSchema`** — An enum validator over string literals — what check.enum([...]) returns.
|
|
1038
|
-
|
|
1039
|
-
```typescript
|
|
1040
|
-
interface EnumSchema<V extends string = string> extends z.ZodEnum<
|
|
1041
|
-
```
|
|
1042
|
-
|
|
1043
|
-
**`LiteralSchema`** — A literal validator — what check.literal(v) returns.
|
|
1044
|
-
|
|
1045
|
-
```typescript
|
|
1046
|
-
interface LiteralSchema<V extends string | number | boolean | null = string> extends z.ZodLiteral<V>
|
|
1047
|
-
```
|
|
1048
|
-
|
|
1049
|
-
**`ArraySchema`** — An array validator — what check.array(item) returns.
|
|
1050
|
-
|
|
1051
|
-
```typescript
|
|
1052
|
-
interface ArraySchema<Item extends z.core.SomeType = z.core.SomeType> extends z.ZodArray<Item>
|
|
1053
|
-
```
|
|
1054
|
-
|
|
1055
|
-
**`OptionalSchema`** — An optional validator — what check.optional(inner) returns.
|
|
1056
|
-
|
|
1057
|
-
```typescript
|
|
1058
|
-
interface OptionalSchema<Inner extends z.core.SomeType = z.core.SomeType> extends z.ZodOptional<Inner>
|
|
1059
|
-
```
|
|
1060
|
-
|
|
1061
|
-
**`NullableSchema`** — A nullable validator — what check.nullable(inner) returns.
|
|
1062
|
-
|
|
1063
|
-
```typescript
|
|
1064
|
-
interface NullableSchema<Inner extends z.core.SomeType = z.core.SomeType> extends z.ZodNullable<Inner>
|
|
1065
|
-
```
|
|
1066
|
-
|
|
1067
|
-
**`ObjectSchema`** — An object validator whose .extend, .pick, .omit and .partial results stay ObjectSchema — what check.object({...}) returns.
|
|
1068
|
-
|
|
1069
|
-
```typescript
|
|
1070
|
-
type ObjectSchema<S extends Shape = Shape> =
|
|
1071
|
-
```
|
|
1072
|
-
|
|
1073
961
|
## temporal — Bitemporal Data
|
|
1074
962
|
|
|
1075
963
|
Temporal (bitemporal) data namespace — version history with effective date ranges.
|
|
@@ -1586,11 +1474,7 @@ interface RateLimitConfig
|
|
|
1586
1474
|
interface RateLimitWindow
|
|
1587
1475
|
```
|
|
1588
1476
|
|
|
1589
|
-
**`RateLimitClass`**
|
|
1590
|
-
|
|
1591
|
-
A named limit class: any of a per-user, per-tenant, per-address and total window, each counted on its own.
|
|
1592
|
-
Each key takes one window or an array of windows (distinct `windowSeconds`); a request is counted against
|
|
1593
|
-
all of a key's windows and refused if any is over.
|
|
1477
|
+
**`RateLimitClass`** — A named limit class: any of a per-user, per-tenant and per-address window, each counted on its own.
|
|
1594
1478
|
|
|
1595
1479
|
```typescript
|
|
1596
1480
|
interface RateLimitClass
|
|
@@ -1606,8 +1490,8 @@ interface RateLimitRefusal
|
|
|
1606
1490
|
|
|
1607
1491
|
Named limit classes, checked after auth and counted in Postgres (`pipework_rate_limit_counts`, opted in
|
|
1608
1492
|
with the blueprint's `rateLimits: {}`), so every server process on the same database shares one count.
|
|
1609
|
-
|
|
1610
|
-
refused requests don't spend the tenant's budget.
|
|
1493
|
+
Windows are counted perUser, perTenant, perAddress in turn, up to the first one over its max, so one user's
|
|
1494
|
+
refused requests don't spend the tenant's budget. A route is in `signedIn` (auth required, or optional with
|
|
1611
1495
|
a user), `public` (no auth, or optional without a user) or the class its fitting names with `.rateLimit(name)`.
|
|
1612
1496
|
|
|
1613
1497
|
```typescript
|
|
@@ -1759,20 +1643,15 @@ interface TraceTree
|
|
|
1759
1643
|
|
|
1760
1644
|
## data
|
|
1761
1645
|
|
|
1762
|
-
### `
|
|
1763
|
-
|
|
1764
|
-
A statement was cancelled by Postgres for running past the statement timeout a {@link withTimeouts} call set. `cause` is the driver error.
|
|
1765
|
-
|
|
1766
|
-
```typescript
|
|
1767
|
-
class StatementTimeoutError extends Error constructor(readonly statementTimeoutMs: number, cause: unknown)
|
|
1768
|
-
```
|
|
1769
|
-
|
|
1770
|
-
### `LockTimeoutError`
|
|
1646
|
+
### `tap`
|
|
1771
1647
|
|
|
1772
|
-
|
|
1648
|
+
Opens a standalone managed connection outside the manifold's pools — the
|
|
1649
|
+
sanctioned door for contexts where `pipe()` structurally cannot resolve:
|
|
1650
|
+
`worker_threads`, detached monitors, one-off scripts. Callers own the
|
|
1651
|
+
lifecycle: always `await conn.close()`.
|
|
1773
1652
|
|
|
1774
1653
|
```typescript
|
|
1775
|
-
|
|
1654
|
+
function tap(url: string, options?: ConnectOptions): ManagedConnection
|
|
1776
1655
|
```
|
|
1777
1656
|
|
|
1778
1657
|
## request
|
|
@@ -67,7 +67,7 @@ export function createScheduler(enqueuer, jobsTableQ) {
|
|
|
67
67
|
async function fireOneDue(db, names) {
|
|
68
68
|
return db.transaction(async (tx) => {
|
|
69
69
|
const filter = names !== undefined
|
|
70
|
-
? sql `AND name
|
|
70
|
+
? sql `AND name ${sql.inList(names)}`
|
|
71
71
|
: sql ``;
|
|
72
72
|
const due = await tx.execute(sql `
|
|
73
73
|
SELECT name, cron_expression, timezone, payload
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/async/jobs/scheduler.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/async/jobs/scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -258,7 +258,7 @@ export function defineGraph(config) {
|
|
|
258
258
|
await tx.execute(sql `
|
|
259
259
|
UPDATE ${sql.raw(table)} SET status = 'cancelled', completed_at = now(), claim_token = NULL
|
|
260
260
|
WHERE id IN (SELECT id FROM ${sql.raw(table)}
|
|
261
|
-
WHERE id
|
|
261
|
+
WHERE id ${sql.inList(jobIds, 'uuid')} AND status = 'pending'
|
|
262
262
|
FOR UPDATE SKIP LOCKED)`);
|
|
263
263
|
}
|
|
264
264
|
async function lockRun(tx, runId) {
|
|
@@ -304,7 +304,7 @@ export function defineGraph(config) {
|
|
|
304
304
|
return out;
|
|
305
305
|
const rows = await tx.execute(sql `
|
|
306
306
|
SELECT id::text, value, value_hash FROM ${sql.raw(RESULT)}
|
|
307
|
-
WHERE id
|
|
307
|
+
WHERE id ${sql.inList(ids, 'uuid')}`);
|
|
308
308
|
for (const r of rows)
|
|
309
309
|
out.set(r['id'], { value: r['value'], hash: r['value_hash'] });
|
|
310
310
|
return out;
|
|
@@ -781,7 +781,7 @@ export function defineGraph(config) {
|
|
|
781
781
|
throw new Error(`[pipework] ${graph}.ended: limit must be a positive integer.\n`);
|
|
782
782
|
const only = tenant === null ? sql `` : sql ` AND tenant_id = ${tenant}::uuid`;
|
|
783
783
|
const byIds = opts?.ids === undefined ? sql `` : opts.ids.length === 0 ? sql ` AND false`
|
|
784
|
-
: sql ` AND id
|
|
784
|
+
: sql ` AND id ${sql.inList(opts.ids, 'uuid')}`;
|
|
785
785
|
const before = opts?.finishedBefore === undefined ? sql `` : sql ` AND finished_at < ${opts.finishedBefore.toISOString()}::timestamptz`;
|
|
786
786
|
const rows = await inTenantTx(db, tenant, tx => tx.execute(sql `
|
|
787
787
|
SELECT id::text, tenant_id::text, item, status, finished_at, notified FROM ${sql.raw(RUN)}
|
|
@@ -877,9 +877,9 @@ export function defineGraph(config) {
|
|
|
877
877
|
SELECT id::text FROM ${sql.raw(RUN)}
|
|
878
878
|
WHERE graph = ${graph} AND status <> 'running' AND finished_at < ${cutoff}::timestamptz${only}`);
|
|
879
879
|
if (old.length > 0) {
|
|
880
|
-
const ids = sql.
|
|
881
|
-
await tx.execute(sql `DELETE FROM ${sql.raw(TASK)} WHERE run_id
|
|
882
|
-
await tx.execute(sql `DELETE FROM ${sql.raw(RUN)} WHERE id
|
|
880
|
+
const ids = sql.inList(old.map(r => r['id']), 'uuid');
|
|
881
|
+
await tx.execute(sql `DELETE FROM ${sql.raw(TASK)} WHERE run_id ${ids}`);
|
|
882
|
+
await tx.execute(sql `DELETE FROM ${sql.raw(RUN)} WHERE id ${ids}`);
|
|
883
883
|
}
|
|
884
884
|
const rows = await tx.execute(sql `
|
|
885
885
|
DELETE FROM ${sql.raw(RESULT)} WHERE graph = ${graph} AND created_at < ${cutoff}::timestamptz${only} RETURNING id`);
|
|
@@ -938,9 +938,9 @@ export function defineGraph(config) {
|
|
|
938
938
|
}
|
|
939
939
|
let tasks = 0;
|
|
940
940
|
if (runs.length > 0) {
|
|
941
|
-
const ids = sql.
|
|
942
|
-
tasks = (await tx.execute(sql `DELETE FROM ${sql.raw(TASK)} WHERE run_id
|
|
943
|
-
await tx.execute(sql `DELETE FROM ${sql.raw(RUN)} WHERE id
|
|
941
|
+
const ids = sql.inList(runs.map(r => r['id']), 'uuid');
|
|
942
|
+
tasks = (await tx.execute(sql `DELETE FROM ${sql.raw(TASK)} WHERE run_id ${ids} RETURNING id`)).length;
|
|
943
|
+
await tx.execute(sql `DELETE FROM ${sql.raw(RUN)} WHERE id ${ids}`);
|
|
944
944
|
}
|
|
945
945
|
const gone = await tx.execute(sql `
|
|
946
946
|
DELETE FROM ${sql.raw(RESULT)} WHERE graph = ${graph} AND item = ${item} AND tenant_id = ${tenant}::uuid RETURNING id`);
|