pipework 0.252.0 → 0.252.1
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 +5 -0
- package/package.json +4 -3
- package/src/async/jobs/abortable-delay.ts +18 -0
- package/src/async/jobs/claims.ts +52 -0
- package/src/async/jobs/cron.ts +179 -0
- package/src/async/jobs/errors.ts +56 -0
- package/src/async/jobs/exclusion.ts +117 -0
- package/src/async/jobs/execute.ts +219 -0
- package/src/async/jobs/index.ts +10 -0
- package/src/async/jobs/listener.ts +135 -0
- package/src/async/jobs/namespace.ts +20 -0
- package/src/async/jobs/queue-door.ts +44 -0
- package/src/async/jobs/queue.ts +1012 -0
- package/src/async/jobs/run-script.ts +67 -0
- package/src/async/jobs/scheduler.ts +218 -0
- package/src/async/jobs/schedules-table.ts +37 -0
- package/src/async/jobs/serialize-error.ts +48 -0
- package/src/async/jobs/table.ts +191 -0
- package/src/async/pipeline/define.ts +53 -0
- package/src/async/pipeline/errors.ts +35 -0
- package/src/async/pipeline/execute.ts +53 -0
- package/src/async/pipeline/index.ts +13 -0
- package/src/async/pipeline/namespace.ts +12 -0
- package/src/async/pipeline/resume.ts +67 -0
- package/src/async/pipeline/run-steps.ts +98 -0
- package/src/async/pipeline/types.ts +57 -0
- package/src/async/state-machine/define.ts +64 -0
- package/src/async/state-machine/errors.ts +29 -0
- package/src/async/state-machine/index.ts +3 -0
- package/src/async/state-machine/namespace.ts +12 -0
- package/src/async/state-machine/transition.ts +90 -0
- package/src/async/state-machine/types.ts +37 -0
- package/src/async/steps/errors.ts +31 -0
- package/src/async/steps/graph.ts +1214 -0
- package/src/async/steps/hash.ts +40 -0
- package/src/async/steps/index.ts +7 -0
- package/src/async/steps/namespace.ts +7 -0
- package/src/async/steps/table.ts +97 -0
- package/src/async/steps/types.ts +318 -0
- package/src/audit/chain/index.ts +9 -0
- package/src/audit/chain/install.ts +113 -0
- package/src/audit/chain/retire.ts +52 -0
- package/src/audit/chain/verify.ts +257 -0
- package/src/audit/query/cursor.ts +37 -0
- package/src/audit/query/index.ts +9 -0
- package/src/audit/query/query.ts +223 -0
- package/src/audit/schema/audit-record-fields.ts +68 -0
- package/src/audit/schema/audit-record.ts +23 -0
- package/src/auth/auth/audit.ts +31 -0
- package/src/auth/auth/chain.ts +84 -0
- package/src/auth/auth/cookie.ts +136 -0
- package/src/auth/auth/email-links.ts +311 -0
- package/src/auth/auth/guard.ts +128 -0
- package/src/auth/auth/index.ts +18 -0
- package/src/auth/auth/multi-org.ts +337 -0
- package/src/auth/auth/namespace.ts +34 -0
- package/src/auth/auth/parse-expiry.ts +13 -0
- package/src/auth/auth/passwords.ts +110 -0
- package/src/auth/auth/schema.ts +110 -0
- package/src/auth/auth/sessions.ts +565 -0
- package/src/auth/auth/sign-in.ts +156 -0
- package/src/auth/auth/signing-keys.ts +69 -0
- package/src/auth/auth/types.ts +26 -0
- package/src/auth/auth/uuid.ts +10 -0
- package/src/auth/rbac/cache.ts +55 -0
- package/src/auth/rbac/check.ts +30 -0
- package/src/auth/rbac/create.ts +35 -0
- package/src/auth/rbac/index.ts +5 -0
- package/src/auth/rbac/middleware.ts +20 -0
- package/src/auth/rbac/namespace.ts +15 -0
- package/src/auth/rbac/resolve.ts +31 -0
- package/src/auth/rbac/schema.sql +31 -0
- package/src/auth/rbac/seed.ts +67 -0
- package/src/auth/rbac/tables.ts +32 -0
- package/src/auth/rbac/types.ts +65 -0
- package/src/auth/tenant/extract.ts +33 -0
- package/src/auth/tenant/in-tenant.ts +49 -0
- package/src/auth/tenant/index.ts +7 -0
- package/src/auth/tenant/namespace.ts +23 -0
- package/src/auth/tenant/propagate.ts +20 -0
- package/src/auth/tenant/rls.ts +120 -0
- package/src/auth/tenant/scope.ts +33 -0
- package/src/auth/tenant/scoped-db.ts +581 -0
- package/src/auth/tenant/types.ts +14 -0
- package/src/auth/tenant/validate.ts +27 -0
- package/src/cli/commands/add.ts +158 -0
- package/src/cli/commands/alerts.ts +98 -0
- package/src/cli/commands/check.ts +1418 -0
- package/src/cli/commands/codemod.ts +78 -0
- package/src/cli/commands/db.ts +356 -0
- package/src/cli/commands/dev.ts +101 -0
- package/src/cli/commands/generate.ts +75 -0
- package/src/cli/commands/init.ts +36 -0
- package/src/cli/commands/install.ts +28 -0
- package/src/cli/commands/lint.ts +62 -0
- package/src/cli/commands/migrate.ts +132 -0
- package/src/cli/commands/openapi.ts +63 -0
- package/src/cli/commands/remove.ts +72 -0
- package/src/cli/commands/run.ts +50 -0
- package/src/cli/commands/scope.ts +54 -0
- package/src/cli/commands/serve.ts +68 -0
- package/src/cli/commands/shard.ts +31 -0
- package/src/cli/commands/shared/config-pipework-version.ts +28 -0
- package/src/cli/commands/shared/find-config.ts +22 -0
- package/src/cli/commands/shared/load-config.ts +35 -0
- package/src/cli/commands/shared/pnpm-install.ts +95 -0
- package/src/cli/commands/shared/report-removed.ts +8 -0
- package/src/cli/commands/sync.ts +32 -0
- package/src/cli/commands/test.ts +307 -0
- package/src/cli/commands/upgrade.ts +48 -0
- package/src/cli/dev-bootstrap.ts +24 -0
- package/src/cli/errors.ts +10 -0
- package/src/cli/index.ts +303 -0
- package/src/cli/output.ts +17 -0
- package/src/cli/port.ts +15 -0
- package/src/cli/surface-kinds.ts +20 -0
- package/src/client/index.ts +4 -0
- package/src/client/poll.ts +130 -0
- package/src/client/report-fault.ts +119 -0
- package/src/core/config/app-pool.ts +19 -0
- package/src/core/config/aws-env.ts +29 -0
- package/src/core/config/base-dir.ts +24 -0
- package/src/core/config/discover.ts +64 -0
- package/src/core/config/env-resolve.ts +87 -0
- package/src/core/config/env-types.ts +116 -0
- package/src/core/config/env.ts +55 -0
- package/src/core/config/errors.ts +9 -0
- package/src/core/config/import-config.ts +40 -0
- package/src/core/config/index.ts +8 -0
- package/src/core/config/load.ts +417 -0
- package/src/core/config/namespace.ts +14 -0
- package/src/core/config/resolve.ts +195 -0
- package/src/core/config/schema.ts +488 -0
- package/src/core/config/statement-observer.ts +48 -0
- package/src/core/config/ts-inline-hooks.ts +75 -0
- package/src/core/config/ts-register.ts +4 -0
- package/src/core/config/ts-resolve-hooks.ts +101 -0
- package/src/core/errors/base.ts +49 -0
- package/src/core/errors/http.ts +146 -0
- package/src/core/errors/index.ts +2 -0
- package/src/core/errors/namespace.ts +31 -0
- package/src/core/lifecycle/drain.ts +33 -0
- package/src/core/lifecycle/health.ts +72 -0
- package/src/core/lifecycle/index.ts +4 -0
- package/src/core/lifecycle/namespace.ts +7 -0
- package/src/core/lifecycle/startup.ts +102 -0
- package/src/core/lifecycle/types.ts +36 -0
- package/src/core/logging/context.ts +60 -0
- package/src/core/logging/error-chain.ts +68 -0
- package/src/core/logging/index.ts +5 -0
- package/src/core/logging/logger.ts +65 -0
- package/src/core/logging/namespace.ts +16 -0
- package/src/core/logging/proxy.ts +22 -0
- package/src/core/logging/redact-match.ts +24 -0
- package/src/core/logging/types.ts +47 -0
- package/src/core/pipework.ts +566 -0
- package/src/core/runtime/broker.ts +69 -0
- package/src/core/surface/http.ts +133 -0
- package/src/core/surface/index.ts +11 -0
- package/src/core/surface/job-timeout.ts +40 -0
- package/src/core/surface/namespace.ts +13 -0
- package/src/core/surface/script.ts +33 -0
- package/src/core/surface/start.ts +142 -0
- package/src/core/surface/types.ts +225 -0
- package/src/core/surface/validate.ts +88 -0
- package/src/core/surface/worker.ts +528 -0
- package/src/core/validation/connectivity.ts +49 -0
- package/src/core/validation/domain.ts +99 -0
- package/src/core/validation/index.ts +5 -0
- package/src/core/validation/queue-tables.ts +312 -0
- package/src/core/validation/rls-role.ts +138 -0
- package/src/core/validation/startup.ts +51 -0
- package/src/core/validation/surfaces.ts +65 -0
- package/src/core/validation/types.ts +25 -0
- package/src/data/db/advisory-lock.ts +55 -0
- package/src/data/db/aggregates.ts +172 -0
- package/src/data/db/array-elements.ts +111 -0
- package/src/data/db/bulk-set.ts +53 -0
- package/src/data/db/col/index.ts +14 -0
- package/src/data/db/composed.ts +53 -0
- package/src/data/db/db.ts +276 -0
- package/src/data/db/excluded.ts +16 -0
- package/src/data/db/expressions.ts +473 -0
- package/src/data/db/filter.ts +90 -0
- package/src/data/db/function-source.ts +114 -0
- package/src/data/db/identifiers.ts +16 -0
- package/src/data/db/idx/index.ts +9 -0
- package/src/data/db/in-list.ts +49 -0
- package/src/data/db/index.ts +9 -0
- package/src/data/db/insert-split.ts +137 -0
- package/src/data/db/instrumentation.ts +82 -0
- package/src/data/db/maintenance.ts +28 -0
- package/src/data/db/namespace.ts +107 -0
- package/src/data/db/owner-labels.ts +9 -0
- package/src/data/db/pool.ts +187 -0
- package/src/data/db/query-label.ts +13 -0
- package/src/data/db/query-watch.ts +116 -0
- package/src/data/db/raw-client-warning.ts +37 -0
- package/src/data/db/readonly.ts +23 -0
- package/src/data/db/reservation.ts +151 -0
- package/src/data/db/schema-features.ts +14 -0
- package/src/data/db/serializable.ts +83 -0
- package/src/data/db/sql.ts +1 -0
- package/src/data/db/timeouts.ts +76 -0
- package/src/data/db/types.ts +18 -0
- package/src/data/db/unbound.ts +33 -0
- package/src/data/db/values.ts +29 -0
- package/src/data/domain/brand.ts +15 -0
- package/src/data/domain/build-factory.ts +193 -0
- package/src/data/domain/build-schema.ts +161 -0
- package/src/data/domain/build-table.ts +355 -0
- package/src/data/domain/define.ts +239 -0
- package/src/data/domain/external-registry.ts +34 -0
- package/src/data/domain/external.ts +77 -0
- package/src/data/domain/field.ts +279 -0
- package/src/data/domain/index.ts +13 -0
- package/src/data/domain/naming.ts +6 -0
- package/src/data/domain/projections.ts +57 -0
- package/src/data/domain/trace-safe-projection.ts +31 -0
- package/src/data/domain/traits.ts +108 -0
- package/src/data/domain/types.ts +289 -0
- package/src/data/jsonb/composed.ts +18 -0
- package/src/data/jsonb/index.ts +1 -0
- package/src/data/jsonb/namespace.ts +30 -0
- package/src/data/jsonb/query.ts +86 -0
- package/src/data/migrate/append-only-generate.ts +47 -0
- package/src/data/migrate/applied.ts +47 -0
- package/src/data/migrate/apply.ts +309 -0
- package/src/data/migrate/check.ts +119 -0
- package/src/data/migrate/diff.ts +357 -0
- package/src/data/migrate/door-generate.ts +130 -0
- package/src/data/migrate/framework-rls.ts +58 -0
- package/src/data/migrate/generate.ts +201 -0
- package/src/data/migrate/history.ts +215 -0
- package/src/data/migrate/index.ts +9 -0
- package/src/data/migrate/internal-definitions.ts +175 -0
- package/src/data/migrate/post-process.ts +73 -0
- package/src/data/migrate/pragma.ts +73 -0
- package/src/data/migrate/provision-framework.ts +147 -0
- package/src/data/migrate/rls-generate.ts +61 -0
- package/src/data/migrate/run.ts +124 -0
- package/src/data/migrate/safety.ts +167 -0
- package/src/data/migrate/snapshot.ts +368 -0
- package/src/data/migrate/sql-emit.ts +392 -0
- package/src/data/migrate/statements.ts +312 -0
- package/src/data/query/alias.ts +126 -0
- package/src/data/query/batch.ts +8 -0
- package/src/data/query/cache/core/cache.ts +78 -0
- package/src/data/query/cache/core/index.ts +1 -0
- package/src/data/query/cache/core/types.ts +29 -0
- package/src/data/query/cache/readme.md +230 -0
- package/src/data/query/casing.ts +76 -0
- package/src/data/query/collation.ts +11 -0
- package/src/data/query/column-builder.ts +370 -0
- package/src/data/query/column.ts +150 -0
- package/src/data/query/entity.ts +42 -0
- package/src/data/query/errors.ts +33 -0
- package/src/data/query/index.ts +14 -0
- package/src/data/query/logger.ts +47 -0
- package/src/data/query/operations.ts +45 -0
- package/src/data/query/pg-core/alias.ts +12 -0
- package/src/data/query/pg-core/checks.ts +32 -0
- package/src/data/query/pg-core/columns/all.ts +71 -0
- package/src/data/query/pg-core/columns/bigint.ts +110 -0
- package/src/data/query/pg-core/columns/bigserial.ts +128 -0
- package/src/data/query/pg-core/columns/boolean.ts +43 -0
- package/src/data/query/pg-core/columns/char.ts +85 -0
- package/src/data/query/pg-core/columns/cidr.ts +43 -0
- package/src/data/query/pg-core/columns/common.ts +366 -0
- package/src/data/query/pg-core/columns/custom.ts +232 -0
- package/src/data/query/pg-core/columns/date.common.ts +15 -0
- package/src/data/query/pg-core/columns/date.ts +112 -0
- package/src/data/query/pg-core/columns/double-precision.ts +55 -0
- package/src/data/query/pg-core/columns/enum.ts +201 -0
- package/src/data/query/pg-core/columns/index.ts +35 -0
- package/src/data/query/pg-core/columns/inet.ts +43 -0
- package/src/data/query/pg-core/columns/int.common.ts +57 -0
- package/src/data/query/pg-core/columns/integer.ts +53 -0
- package/src/data/query/pg-core/columns/interval.ts +83 -0
- package/src/data/query/pg-core/columns/json.ts +58 -0
- package/src/data/query/pg-core/columns/jsonb.ts +56 -0
- package/src/data/query/pg-core/columns/line.ts +117 -0
- package/src/data/query/pg-core/columns/macaddr.ts +43 -0
- package/src/data/query/pg-core/columns/macaddr8.ts +43 -0
- package/src/data/query/pg-core/columns/numeric.ts +227 -0
- package/src/data/query/pg-core/columns/point.ts +127 -0
- package/src/data/query/pg-core/columns/postgis_extension/geometry.ts +119 -0
- package/src/data/query/pg-core/columns/postgis_extension/utils.ts +47 -0
- package/src/data/query/pg-core/columns/real.ts +58 -0
- package/src/data/query/pg-core/columns/serial.ts +55 -0
- package/src/data/query/pg-core/columns/smallint.ts +53 -0
- package/src/data/query/pg-core/columns/smallserial.ts +60 -0
- package/src/data/query/pg-core/columns/text.ts +67 -0
- package/src/data/query/pg-core/columns/time.ts +72 -0
- package/src/data/query/pg-core/columns/timestamp.ts +163 -0
- package/src/data/query/pg-core/columns/uuid.ts +51 -0
- package/src/data/query/pg-core/columns/varchar.ts +89 -0
- package/src/data/query/pg-core/columns/vector_extension/bit.ts +68 -0
- package/src/data/query/pg-core/columns/vector_extension/halfvec.ts +80 -0
- package/src/data/query/pg-core/columns/vector_extension/sparsevec.ts +67 -0
- package/src/data/query/pg-core/columns/vector_extension/vector.ts +80 -0
- package/src/data/query/pg-core/db.ts +674 -0
- package/src/data/query/pg-core/dialect.ts +1404 -0
- package/src/data/query/pg-core/expressions.ts +25 -0
- package/src/data/query/pg-core/foreign-keys.ts +130 -0
- package/src/data/query/pg-core/index.ts +21 -0
- package/src/data/query/pg-core/indexes.ts +276 -0
- package/src/data/query/pg-core/policies.ts +56 -0
- package/src/data/query/pg-core/primary-keys.ts +62 -0
- package/src/data/query/pg-core/query-builders/count.ts +86 -0
- package/src/data/query/pg-core/query-builders/delete.ts +293 -0
- package/src/data/query/pg-core/query-builders/index.ts +7 -0
- package/src/data/query/pg-core/query-builders/insert.ts +452 -0
- package/src/data/query/pg-core/query-builders/query-builder.ts +123 -0
- package/src/data/query/pg-core/query-builders/query.ts +157 -0
- package/src/data/query/pg-core/query-builders/raw.ts +49 -0
- package/src/data/query/pg-core/query-builders/refresh-materialized-view.ts +108 -0
- package/src/data/query/pg-core/query-builders/select.ts +1346 -0
- package/src/data/query/pg-core/query-builders/select.types.ts +437 -0
- package/src/data/query/pg-core/query-builders/update.ts +626 -0
- package/src/data/query/pg-core/roles.ts +41 -0
- package/src/data/query/pg-core/schema.ts +72 -0
- package/src/data/query/pg-core/sequence.ts +41 -0
- package/src/data/query/pg-core/session.ts +292 -0
- package/src/data/query/pg-core/subquery.ts +46 -0
- package/src/data/query/pg-core/table.ts +252 -0
- package/src/data/query/pg-core/unique-constraint.ts +73 -0
- package/src/data/query/pg-core/utils/array.ts +95 -0
- package/src/data/query/pg-core/utils/index.ts +1 -0
- package/src/data/query/pg-core/utils.ts +104 -0
- package/src/data/query/pg-core/view-base.ts +14 -0
- package/src/data/query/pg-core/view-common.ts +1 -0
- package/src/data/query/pg-core/view.ts +435 -0
- package/src/data/query/pg-core/with-builder.ts +41 -0
- package/src/data/query/postgres-js/README.md +46 -0
- package/src/data/query/postgres-js/array-parser.ts +45 -0
- package/src/data/query/postgres-js/driver-error-boundary.ts +149 -0
- package/src/data/query/postgres-js/driver.ts +163 -0
- package/src/data/query/postgres-js/index.ts +2 -0
- package/src/data/query/postgres-js/session.ts +234 -0
- package/src/data/query/primary-key.ts +11 -0
- package/src/data/query/query-builders/query-builder.ts +19 -0
- package/src/data/query/query-builders/select.types.ts +175 -0
- package/src/data/query/query-promise.ts +35 -0
- package/src/data/query/relations.ts +725 -0
- package/src/data/query/runnable-query.ts +12 -0
- package/src/data/query/selection-proxy.ts +121 -0
- package/src/data/query/session.ts +8 -0
- package/src/data/query/sql/expressions/conditions.ts +741 -0
- package/src/data/query/sql/expressions/index.ts +2 -0
- package/src/data/query/sql/expressions/select.ts +45 -0
- package/src/data/query/sql/functions/aggregate.ts +129 -0
- package/src/data/query/sql/functions/index.ts +2 -0
- package/src/data/query/sql/functions/vector.ts +178 -0
- package/src/data/query/sql/index.ts +3 -0
- package/src/data/query/sql/sql.ts +794 -0
- package/src/data/query/subquery.ts +53 -0
- package/src/data/query/table.ts +208 -0
- package/src/data/query/table.utils.ts +2 -0
- package/src/data/query/tracing-utils.ts +3 -0
- package/src/data/query/tracing.ts +11 -0
- package/src/data/query/utils.ts +357 -0
- package/src/data/query/version.ts +4 -0
- package/src/data/query/view-common.ts +1 -0
- package/src/data/schema/branded.ts +13 -0
- package/src/data/schema/generated/coerce.ts +5 -0
- package/src/data/schema/generated/combinator.ts +6 -0
- package/src/data/schema/generated/encoding.ts +5 -0
- package/src/data/schema/generated/error.ts +6 -0
- package/src/data/schema/generated/format.ts +5 -0
- package/src/data/schema/generated/type-constructor.ts +10 -0
- package/src/data/schema/generated/type.ts +6 -0
- package/src/data/schema/index.ts +6 -0
- package/src/data/schema/json-schema.ts +33 -0
- package/src/data/schema/namespace.ts +55 -0
- package/src/data/schema/parse.ts +39 -0
- package/src/data/schema/types.ts +39 -0
- package/src/data/temporal/append-only.ts +134 -0
- package/src/data/temporal/close.ts +27 -0
- package/src/data/temporal/columns.ts +10 -0
- package/src/data/temporal/definition-queries.ts +70 -0
- package/src/data/temporal/errors.ts +10 -0
- package/src/data/temporal/get-current.ts +22 -0
- package/src/data/temporal/index.ts +9 -0
- package/src/data/temporal/namespace.ts +36 -0
- package/src/data/temporal/query.ts +25 -0
- package/src/data/temporal/resolve.ts +17 -0
- package/src/data/temporal/revise.ts +67 -0
- package/src/data/temporal/types.ts +22 -0
- package/src/data/valve/artifact.ts +33 -0
- package/src/data/valve/contract-diff.ts +21 -0
- package/src/data/valve/cross.ts +57 -0
- package/src/data/valve/crossing-ledger.ts +50 -0
- package/src/data/valve/decision.ts +44 -0
- package/src/data/valve/durable-crossing.ts +52 -0
- package/src/data/valve/execute-crossing.ts +77 -0
- package/src/data/valve/faucet.ts +56 -0
- package/src/data/valve/gate.ts +114 -0
- package/src/data/valve/graph.ts +77 -0
- package/src/data/valve/index.ts +53 -0
- package/src/data/valve/namespace.ts +57 -0
- package/src/data/valve/registry.ts +50 -0
- package/src/data/valve/schema/valve-crossing-fields.ts +23 -0
- package/src/data/valve/schema/valve-crossing.ts +9 -0
- package/src/data/valve/supply.ts +154 -0
- package/src/data/valve/types.ts +143 -0
- package/src/data/vector/columns.ts +27 -0
- package/src/data/vector/index.ts +4 -0
- package/src/data/vector/namespace.ts +33 -0
- package/src/data/vector/query.ts +85 -0
- package/src/data/vector/validate.ts +16 -0
- package/src/data/write/audit/actor.ts +15 -0
- package/src/data/write/audit/audit-columns.ts +18 -0
- package/src/data/write/audit/audit-select.ts +111 -0
- package/src/data/write/audit/bound-transaction.ts +14 -0
- package/src/data/write/audit/cte-compile.ts +32 -0
- package/src/data/write/audit/decode-returning.ts +47 -0
- package/src/data/write/audit/final-select.ts +43 -0
- package/src/data/write/audit/infra-audit.ts +36 -0
- package/src/data/write/audit/primary-key.ts +65 -0
- package/src/data/write/audit/projection.ts +41 -0
- package/src/data/write/audit/read-touches.ts +86 -0
- package/src/data/write/audit/touch-match.ts +78 -0
- package/src/data/write/audit/verb-delete.ts +62 -0
- package/src/data/write/audit/verb-insert.ts +36 -0
- package/src/data/write/audit/verb-select.ts +47 -0
- package/src/data/write/audit/verb-update.ts +60 -0
- package/src/data/write/audit/verb-upsert.ts +104 -0
- package/src/data/write/conflict.ts +43 -0
- package/src/data/write/delete.ts +38 -0
- package/src/data/write/execute.ts +243 -0
- package/src/data/write/index.ts +11 -0
- package/src/data/write/insert.ts +63 -0
- package/src/data/write/state.ts +43 -0
- package/src/data/write/update.ts +54 -0
- package/src/data/write/upsert.ts +58 -0
- package/src/data/write/values.ts +19 -0
- package/src/index.ts +230 -0
- package/src/infra/access-links/code.ts +70 -0
- package/src/infra/access-links/handle.ts +892 -0
- package/src/infra/access-links/index.ts +9 -0
- package/src/infra/access-links/namespace.ts +30 -0
- package/src/infra/access-links/person-check.ts +177 -0
- package/src/infra/access-links/schema.ts +71 -0
- package/src/infra/alerts/async-sources.ts +231 -0
- package/src/infra/alerts/audit.ts +36 -0
- package/src/infra/alerts/beat.ts +123 -0
- package/src/infra/alerts/client-faults.ts +111 -0
- package/src/infra/alerts/faults.ts +156 -0
- package/src/infra/alerts/handle.ts +778 -0
- package/src/infra/alerts/http.ts +192 -0
- package/src/infra/alerts/index.ts +12 -0
- package/src/infra/alerts/infra-sources.ts +180 -0
- package/src/infra/alerts/namespace.ts +81 -0
- package/src/infra/alerts/redact.ts +21 -0
- package/src/infra/alerts/request-faults.ts +41 -0
- package/src/infra/alerts/schema.ts +124 -0
- package/src/infra/alerts/sinks.ts +125 -0
- package/src/infra/alerts/source-options.ts +26 -0
- package/src/infra/alerts/sources.ts +503 -0
- package/src/infra/alerts/subsystem-sources.ts +137 -0
- package/src/infra/audit/emit.ts +87 -0
- package/src/infra/audit/index.ts +2 -0
- package/src/infra/audit/namespace.ts +22 -0
- package/src/infra/audit/schema.sql +35 -0
- package/src/infra/audit/types.ts +18 -0
- package/src/infra/aws/credentials.ts +147 -0
- package/src/infra/aws/sigv4.ts +140 -0
- package/src/infra/cache/create.ts +58 -0
- package/src/infra/cache/entry.ts +81 -0
- package/src/infra/cache/index.ts +4 -0
- package/src/infra/cache/namespace.ts +10 -0
- package/src/infra/cache/tenant.ts +93 -0
- package/src/infra/cache/types.ts +24 -0
- package/src/infra/crawl/audit.ts +35 -0
- package/src/infra/crawl/errors.ts +25 -0
- package/src/infra/crawl/handle.ts +693 -0
- package/src/infra/crawl/index.ts +9 -0
- package/src/infra/crawl/links.ts +160 -0
- package/src/infra/crawl/namespace.ts +36 -0
- package/src/infra/crawl/robots.ts +100 -0
- package/src/infra/crawl/schema.ts +89 -0
- package/src/infra/credit-line/handle.ts +883 -0
- package/src/infra/credit-line/index.ts +6 -0
- package/src/infra/credit-line/namespace.ts +7 -0
- package/src/infra/credit-line/schema.ts +96 -0
- package/src/infra/credits/handle.ts +706 -0
- package/src/infra/credits/index.ts +5 -0
- package/src/infra/credits/namespace.ts +7 -0
- package/src/infra/credits/schema.ts +83 -0
- package/src/infra/email/audit.ts +36 -0
- package/src/infra/email/inbound.ts +622 -0
- package/src/infra/email/index.ts +11 -0
- package/src/infra/email/mail.ts +517 -0
- package/src/infra/email/mime.ts +447 -0
- package/src/infra/email/namespace.ts +22 -0
- package/src/infra/email/providers.ts +111 -0
- package/src/infra/email/schema.ts +96 -0
- package/src/infra/email/sns.ts +200 -0
- package/src/infra/email/unsubscribe.ts +44 -0
- package/src/infra/fetch/address.ts +88 -0
- package/src/infra/fetch/connect-retry.ts +87 -0
- package/src/infra/fetch/handle.ts +329 -0
- package/src/infra/fetch/index.ts +7 -0
- package/src/infra/fetch/namespace.ts +70 -0
- package/src/infra/idempotency/index.ts +3 -0
- package/src/infra/idempotency/middleware.ts +87 -0
- package/src/infra/idempotency/store.ts +92 -0
- package/src/infra/idempotency/types.ts +30 -0
- package/src/infra/join-requests/handle.ts +312 -0
- package/src/infra/join-requests/index.ts +2 -0
- package/src/infra/join-requests/namespace.ts +7 -0
- package/src/infra/join-requests/schema.ts +33 -0
- package/src/infra/outbox/core.ts +165 -0
- package/src/infra/quota/errors.ts +32 -0
- package/src/infra/quota/handle.ts +215 -0
- package/src/infra/quota/index.ts +5 -0
- package/src/infra/quota/namespace.ts +7 -0
- package/src/infra/quota/schema.ts +15 -0
- package/src/infra/storage/backend.ts +34 -0
- package/src/infra/storage/handle.ts +513 -0
- package/src/infra/storage/index.ts +9 -0
- package/src/infra/storage/local.ts +104 -0
- package/src/infra/storage/namespace.ts +13 -0
- package/src/infra/storage/s3.ts +257 -0
- package/src/infra/storage/schema.ts +24 -0
- package/src/infra/support/handle.ts +854 -0
- package/src/infra/support/http.ts +229 -0
- package/src/infra/support/index.ts +7 -0
- package/src/infra/support/namespace.ts +12 -0
- package/src/infra/support/schema.ts +96 -0
- package/src/infra/webhook/inbound.ts +45 -0
- package/src/infra/webhook/index.ts +5 -0
- package/src/infra/webhook/namespace.ts +24 -0
- package/src/infra/webhook/outbound.ts +315 -0
- package/src/infra/webhook/sign.ts +32 -0
- package/src/infra/webhook/verify.ts +82 -0
- package/src/invariants/assert.ts +26 -0
- package/src/invariants/index.ts +1 -0
- package/src/lint/config.ts +56 -0
- package/src/lint/doctrine.ts +163 -0
- package/src/lint/include.ts +97 -0
- package/src/lint/index.ts +3 -0
- package/src/lint/preset.ts +10 -0
- package/src/lint/resolver.ts +218 -0
- package/src/lint/rules/no-reexports.ts +46 -0
- package/src/request/behavior/audited.ts +85 -0
- package/src/request/behavior/cached.ts +62 -0
- package/src/request/behavior/compose.ts +28 -0
- package/src/request/behavior/index.ts +5 -0
- package/src/request/behavior/namespace.ts +16 -0
- package/src/request/behavior/types.ts +26 -0
- package/src/request/behavior/versioned.ts +54 -0
- package/src/request/context/create.ts +103 -0
- package/src/request/context/guard.ts +49 -0
- package/src/request/context/index.ts +4 -0
- package/src/request/context/run-in-transaction.ts +200 -0
- package/src/request/context/store.ts +28 -0
- package/src/request/context/types.ts +50 -0
- package/src/request/di/builder.ts +535 -0
- package/src/request/di/index.ts +8 -0
- package/src/request/di/resolve.ts +271 -0
- package/src/request/di/types.ts +262 -0
- package/src/request/fitting/namespace.ts +7 -0
- package/src/request/fixture/batch.ts +71 -0
- package/src/request/fixture/builder.ts +26 -0
- package/src/request/fixture/errors.ts +10 -0
- package/src/request/fixture/index.ts +8 -0
- package/src/request/fixture/namespace.ts +23 -0
- package/src/request/fixture/paginate.ts +44 -0
- package/src/request/fixture/to-handlers.ts +260 -0
- package/src/request/fixture/types.ts +79 -0
- package/src/request/flow/act-as.ts +78 -0
- package/src/request/flow/namespace.ts +17 -0
- package/src/request/http/error-step.ts +42 -0
- package/src/request/http/file.ts +141 -0
- package/src/request/http/index.ts +4 -0
- package/src/request/http/middleware.ts +141 -0
- package/src/request/http/namespace.ts +5 -0
- package/src/request/http/rate-limit-classes.ts +170 -0
- package/src/request/http/response.ts +82 -0
- package/src/request/http/server.ts +916 -0
- package/src/request/http/sniff.ts +261 -0
- package/src/request/http/types.ts +250 -0
- package/src/request/http/upload.ts +284 -0
- package/src/request/internal/text.ts +6 -0
- package/src/request/openapi/generate.ts +205 -0
- package/src/request/openapi/index.ts +2 -0
- package/src/request/openapi/namespace.ts +7 -0
- package/src/test/auth.ts +13 -0
- package/src/test/auto-setup.ts +45 -0
- package/src/test/context.ts +91 -0
- package/src/test/crawl-fixture.ts +157 -0
- package/src/test/discover-fork.ts +17 -0
- package/src/test/fingerprint.ts +135 -0
- package/src/test/globals.d.ts +7 -0
- package/src/test/index.ts +19 -0
- package/src/test/namespace.ts +87 -0
- package/src/test/plugin.ts +189 -0
- package/src/test/progress.ts +185 -0
- package/src/test/reap-after-run.ts +28 -0
- package/src/test/reap.ts +286 -0
- package/src/test/reset.ts +253 -0
- package/src/test/savepoints.ts +172 -0
- package/src/test/setup.ts +1422 -0
- package/src/test/system-channel.ts +50 -0
- package/src/test/vitest-plugin.ts +142 -0
- package/src/test/vitest-workspace.ts +507 -0
- package/src/test/vitest.ts +333 -0
- package/src/test/watch.ts +105 -0
- package/src/trace/capture/bounded-serializer.ts +146 -0
- package/src/trace/cardinality/analyze.ts +173 -0
- package/src/trace/cardinality/branch-context.ts +214 -0
- package/src/trace/cardinality/check.ts +33 -0
- package/src/trace/cardinality/classify-edge.ts +64 -0
- package/src/trace/cardinality/structural-max.ts +107 -0
- package/src/trace/check/coverage-check.ts +188 -0
- package/src/trace/check/flow-check.ts +103 -0
- package/src/trace/check/flow-step-site.ts +234 -0
- package/src/trace/check/io-pattern.ts +116 -0
- package/src/trace/codemod/add-cardinality.ts +152 -0
- package/src/trace/codemod/run.ts +80 -0
- package/src/trace/entry/child-trace.ts +21 -0
- package/src/trace/entry/close-trace.ts +87 -0
- package/src/trace/entry/finalize-trace.ts +28 -0
- package/src/trace/entry/open-trace.ts +138 -0
- package/src/trace/entry/parent-trace.ts +20 -0
- package/src/trace/entry/parse-traceparent.ts +39 -0
- package/src/trace/entry/process-start.ts +38 -0
- package/src/trace/entry/trace-context.ts +26 -0
- package/src/trace/entry/tracing-enabled.ts +10 -0
- package/src/trace/external/record.ts +195 -0
- package/src/trace/external/report.ts +66 -0
- package/src/trace/namespace.ts +19 -0
- package/src/trace/partition/day.ts +47 -0
- package/src/trace/partition/index.ts +14 -0
- package/src/trace/partition/partition-name.ts +23 -0
- package/src/trace/partition/plan.ts +82 -0
- package/src/trace/partition/schedule.ts +26 -0
- package/src/trace/partition/startup-hook.ts +39 -0
- package/src/trace/partition/sync.ts +154 -0
- package/src/trace/partition/tables.ts +53 -0
- package/src/trace/read/tree.ts +83 -0
- package/src/trace/retain/copy-on-error.ts +76 -0
- package/src/trace/runtime/expire-stale-traces.ts +54 -0
- package/src/trace/runtime/flow-step.ts +147 -0
- package/src/trace/runtime/flush-steps.ts +31 -0
- package/src/trace/runtime/pending-writes.ts +54 -0
- package/src/trace/runtime/step-buffer.ts +298 -0
- package/src/trace/runtime/step-error.ts +21 -0
- package/src/trace/runtime/step-meta.ts +55 -0
- package/src/trace/runtime/thenable.ts +12 -0
- package/src/trace/runtime/truncate-trace.ts +62 -0
- package/src/trace/schema/trace-fields.ts +52 -0
- package/src/trace/schema/trace-retained.ts +22 -0
- package/src/trace/schema/trace-step-fields.ts +44 -0
- package/src/trace/schema/trace-step-retained.ts +25 -0
- package/src/trace/schema/trace-step.ts +18 -0
- package/src/trace/schema/trace.ts +12 -0
- package/src/trace/transformer/apply.ts +79 -0
- package/src/trace/transformer/build-meta-literal.ts +30 -0
- package/src/trace/transformer/find-flow-step-sites.ts +85 -0
- package/src/trace/transformer/inject-flow-step-import.ts +39 -0
- package/src/trace/transformer/transform-error.ts +14 -0
- package/src/trace/transformer/transform-flow-steps.ts +123 -0
- package/src/trace/transformer/wrap-function-declaration.ts +62 -0
- package/src/trace/transformer/wrap-variable-declaration.ts +67 -0
- package/src/workspace/affected.ts +110 -0
- package/src/workspace/changed-files.ts +163 -0
- package/src/workspace/check-deps.ts +213 -0
- package/src/workspace/checksum.ts +20 -0
- package/src/workspace/dependency-graph.ts +67 -0
- package/src/workspace/detect-pipework-copies.ts +93 -0
- package/src/workspace/discover.ts +206 -0
- package/src/workspace/generate.ts +401 -0
- package/src/workspace/index.ts +7 -0
- package/src/workspace/module-imports-pipework.ts +39 -0
- package/src/workspace/module-package-name.ts +12 -0
- package/src/workspace/scrub-git-env.ts +23 -0
- package/src/workspace/source-paths.ts +36 -0
- package/src/workspace/sync.ts +182 -0
- package/dist/REFERENCE.md +0 -1477
- package/dist/infra/access-links/rate-limit.d.ts +0 -10
- package/dist/infra/access-links/rate-limit.d.ts.map +0 -1
- package/dist/infra/access-links/rate-limit.js +0 -28
- package/dist/infra/access-links/rate-limit.js.map +0 -1
- package/dist/infra/email/sigv4.d.ts +0 -24
- package/dist/infra/email/sigv4.d.ts.map +0 -1
- package/dist/infra/email/sigv4.js +0 -55
- package/dist/infra/email/sigv4.js.map +0 -1
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import type { Manifold } from '../../core/pipework.js'
|
|
2
|
+
import type { Handler } from '../../request/di/types.js'
|
|
3
|
+
import type { TenantConfig } from '../../auth/tenant/types.js'
|
|
4
|
+
import { runInContext } from '../../request/context/store.js'
|
|
5
|
+
import { createJobContext } from '../../request/context/create.js'
|
|
6
|
+
import { executeInTransaction } from '../../request/context/run-in-transaction.js'
|
|
7
|
+
import { resolveAndExecute, resolveHandlerDatabases, buildCheckpoint } from '../../request/di/resolve.js'
|
|
8
|
+
import { isTracingEnabled } from '../../trace/entry/tracing-enabled.js'
|
|
9
|
+
import { openTrace } from '../../trace/entry/open-trace.js'
|
|
10
|
+
import { parentTraceRef } from '../../trace/entry/parent-trace.js'
|
|
11
|
+
import type { ParentTraceRef } from '../../trace/entry/open-trace.js'
|
|
12
|
+
import { finalizeTrace } from '../../trace/entry/finalize-trace.js'
|
|
13
|
+
import { JobAbortedError } from './errors.js'
|
|
14
|
+
import { randomUUID } from 'node:crypto'
|
|
15
|
+
import { serializeForTrace } from '../../trace/capture/bounded-serializer.js'
|
|
16
|
+
|
|
17
|
+
/** Default timeout for setting up a tenant job's database transaction(s). */
|
|
18
|
+
const DEFAULT_JOB_TRANSACTION_TIMEOUT_MS = 5000
|
|
19
|
+
|
|
20
|
+
export interface ExecuteJobOptions {
|
|
21
|
+
instance: Manifold
|
|
22
|
+
jobId?: string
|
|
23
|
+
jobType?: string
|
|
24
|
+
/** 1-based attempt number, exposed as `flow.jobAttempt`. */
|
|
25
|
+
attempt?: number
|
|
26
|
+
/** The job's attempt limit, exposed as `flow.jobMaxAttempts`. */
|
|
27
|
+
maxAttempts?: number
|
|
28
|
+
auth?: unknown
|
|
29
|
+
tenant?: string | null
|
|
30
|
+
/**
|
|
31
|
+
* Tenant config carrying custom `sessionVars`. When provided alongside
|
|
32
|
+
* `tenant`, the custom session variables are propagated in addition to
|
|
33
|
+
* `pipework.tenant_id` — matching the HTTP surface's behaviour.
|
|
34
|
+
*/
|
|
35
|
+
tenantConfig?: TenantConfig | null
|
|
36
|
+
input?: unknown
|
|
37
|
+
/** Timeout for multi-database transaction setup when running a tenant job. */
|
|
38
|
+
transactionTimeoutMs?: number
|
|
39
|
+
/**
|
|
40
|
+
* The trace this job continues. Omitted: the trace on the active Flow, if any.
|
|
41
|
+
* `null`: a root trace even inside a Flow. The worker surface passes the
|
|
42
|
+
* trace recorded when the job was enqueued.
|
|
43
|
+
*/
|
|
44
|
+
parent?: ParentTraceRef | null
|
|
45
|
+
/** The ingress kind for the opened trace — `'cron'` for schedule-fired jobs, `'job'` otherwise. */
|
|
46
|
+
entryKind?: 'job' | 'cron'
|
|
47
|
+
/**
|
|
48
|
+
* Set when this attempt follows one that ended without failing on its own (a
|
|
49
|
+
* reap or a hand-back): the attempt's trace opens with a `pipework.job.restart`
|
|
50
|
+
* external step naming the reason and the worker that held the previous claim.
|
|
51
|
+
*/
|
|
52
|
+
restart?: { readonly reason: 'reaped' | 'handed-back' | 'later'; readonly previousWorkerId: string | null }
|
|
53
|
+
/**
|
|
54
|
+
* Ends the job at the caller's deadline. On abort the job's in-flight query is
|
|
55
|
+
* cancelled server-side so its transaction rolls back and its connection
|
|
56
|
+
* returns to the pool, and `executeJob` rejects — with `signal.reason` when
|
|
57
|
+
* that is an `Error`, otherwise a `JobAbortedError` (`name: 'AbortError'`)
|
|
58
|
+
* naming the job. A handler that ignores the cancelled query keeps running;
|
|
59
|
+
* the rejection is still delivered on time.
|
|
60
|
+
*/
|
|
61
|
+
signal?: AbortSignal
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function executeJob<TDeps extends Record<string, unknown>, TReturn>(
|
|
65
|
+
handler: Handler<TDeps, TReturn>,
|
|
66
|
+
options: ExecuteJobOptions,
|
|
67
|
+
): Promise<TReturn> {
|
|
68
|
+
const label = jobLabel(options)
|
|
69
|
+
if (options.signal?.aborted === true) throw abortReason(options.signal, label)
|
|
70
|
+
|
|
71
|
+
const jobCtxOptions: Parameters<typeof createJobContext>[0] = {
|
|
72
|
+
instance: options.instance,
|
|
73
|
+
}
|
|
74
|
+
if (options.jobId !== undefined) jobCtxOptions.jobId = options.jobId
|
|
75
|
+
if (options.jobType !== undefined) jobCtxOptions.jobType = options.jobType
|
|
76
|
+
if (options.attempt !== undefined) jobCtxOptions.attempt = options.attempt
|
|
77
|
+
if (options.maxAttempts !== undefined) jobCtxOptions.maxAttempts = options.maxAttempts
|
|
78
|
+
if (options.auth !== undefined) jobCtxOptions.auth = options.auth
|
|
79
|
+
if (options.tenant !== undefined) jobCtxOptions.tenant = options.tenant
|
|
80
|
+
if (options.tenantConfig !== undefined) jobCtxOptions.tenantConfig = options.tenantConfig
|
|
81
|
+
if (isTracingEnabled(options.instance)) {
|
|
82
|
+
jobCtxOptions.trace = openTrace({
|
|
83
|
+
instance: options.instance,
|
|
84
|
+
entryKind: options.entryKind ?? 'job',
|
|
85
|
+
parent: options.parent !== undefined ? options.parent : parentTraceRef(),
|
|
86
|
+
tenant: options.tenant ?? null,
|
|
87
|
+
auth: options.auth ?? null,
|
|
88
|
+
requestId: options.jobId ?? null,
|
|
89
|
+
sessionId: null,
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (options.restart !== undefined && jobCtxOptions.trace !== undefined && jobCtxOptions.trace !== null) {
|
|
94
|
+
const now = new Date()
|
|
95
|
+
jobCtxOptions.trace.buffer.stageExternal({
|
|
96
|
+
id: randomUUID(),
|
|
97
|
+
parentStepId: null,
|
|
98
|
+
flowStepRef: 'external:pipework.job.restart',
|
|
99
|
+
status: 'ok',
|
|
100
|
+
startedAt: now,
|
|
101
|
+
completedAt: now,
|
|
102
|
+
durationMicros: 0n,
|
|
103
|
+
capturedInputs: [serializeForTrace({ reason: options.restart.reason, previousWorkerId: options.restart.previousWorkerId })],
|
|
104
|
+
error: null,
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// The handler's own signal: aborted, with the error `executeJob` rejects with,
|
|
109
|
+
// whenever the job stops being the handler's while it may still be running.
|
|
110
|
+
const own = new AbortController()
|
|
111
|
+
const ctx = createJobContext(jobCtxOptions)
|
|
112
|
+
const databases = resolveHandlerDatabases(handler, options.instance)
|
|
113
|
+
const timeoutMs = options.transactionTimeoutMs ?? DEFAULT_JOB_TRANSACTION_TIMEOUT_MS
|
|
114
|
+
|
|
115
|
+
// Manual transaction mode: the framework opens no outer transaction. The
|
|
116
|
+
// handler owns its commit boundaries through `checkpoint`, which opens a fresh
|
|
117
|
+
// tenant-scoped transaction per call (re-establishing the tenant session vars
|
|
118
|
+
// so database-side RLS sees the tenant) and commits it independently.
|
|
119
|
+
if (handler.meta.jobTransaction === 'manual') {
|
|
120
|
+
const checkpoint = buildCheckpoint(
|
|
121
|
+
handler,
|
|
122
|
+
ctx,
|
|
123
|
+
databases,
|
|
124
|
+
options.tenantConfig ?? null,
|
|
125
|
+
timeoutMs,
|
|
126
|
+
options.signal,
|
|
127
|
+
own.signal,
|
|
128
|
+
)
|
|
129
|
+
return finalizeTrace(
|
|
130
|
+
options.instance,
|
|
131
|
+
ctx.trace,
|
|
132
|
+
untilAborted(
|
|
133
|
+
runInContext(ctx, () => resolveAndExecute(handler, options.input, undefined, undefined, { checkpoint, signal: own.signal })),
|
|
134
|
+
options.signal,
|
|
135
|
+
label,
|
|
136
|
+
own,
|
|
137
|
+
),
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const run = (): Promise<TReturn> => resolveAndExecute(handler, options.input, undefined, undefined, { signal: own.signal })
|
|
142
|
+
|
|
143
|
+
// No tenant: app-level scoping does not apply, so there is nothing to
|
|
144
|
+
// propagate to Postgres — run the handler directly as before.
|
|
145
|
+
if (ctx.tenant === null || databases.length === 0) {
|
|
146
|
+
return finalizeTrace(options.instance, ctx.trace, untilAborted(runInContext(ctx, run), options.signal, label, own))
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Tenant job: wrap in a transaction and propagate session vars so
|
|
150
|
+
// database-side RLS sees the tenant — consistent with the HTTP surface.
|
|
151
|
+
return finalizeTrace(
|
|
152
|
+
options.instance,
|
|
153
|
+
ctx.trace,
|
|
154
|
+
untilAborted(
|
|
155
|
+
executeInTransaction(
|
|
156
|
+
ctx,
|
|
157
|
+
databases,
|
|
158
|
+
options.tenantConfig ?? null,
|
|
159
|
+
timeoutMs,
|
|
160
|
+
run,
|
|
161
|
+
options.signal,
|
|
162
|
+
),
|
|
163
|
+
options.signal,
|
|
164
|
+
label,
|
|
165
|
+
own,
|
|
166
|
+
),
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** `[type] id`, `[type]`, `id`, or `(anonymous)` — whatever the caller gave us to name the job by. */
|
|
171
|
+
function jobLabel(options: ExecuteJobOptions): string {
|
|
172
|
+
const parts: string[] = []
|
|
173
|
+
if (options.jobType !== undefined) parts.push(`"${options.jobType}"`)
|
|
174
|
+
if (options.jobId !== undefined) parts.push(`(${options.jobId})`)
|
|
175
|
+
return parts.length === 0 ? '(anonymous)' : parts.join(' ')
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The error an abort rejects with: the caller's own `Error` reason when they set
|
|
180
|
+
* one (the worker passes its timeout error this way), otherwise a
|
|
181
|
+
* `JobAbortedError` naming the job. `abort()` with no reason leaves a generic
|
|
182
|
+
* DOMException that names nothing — that is the case worth replacing.
|
|
183
|
+
*/
|
|
184
|
+
function abortReason(signal: AbortSignal, label: string): Error {
|
|
185
|
+
const reason: unknown = signal.reason
|
|
186
|
+
const isDefaultReason =
|
|
187
|
+
typeof DOMException === 'function' && reason instanceof DOMException && reason.name === 'AbortError'
|
|
188
|
+
|
|
189
|
+
return reason instanceof Error && !isDefaultReason
|
|
190
|
+
? reason
|
|
191
|
+
: new JobAbortedError(label, reason)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Rejects when the signal aborts, even if the handler is still running — the
|
|
196
|
+
* caller's deadline is the caller's, not the handler's. The work promise's own
|
|
197
|
+
* rejection is swallowed once we have rejected, so a later unwind (the cancelled
|
|
198
|
+
* query surfacing) does not become an unhandled rejection. The handler's own
|
|
199
|
+
* signal aborts with that same rejection first, so it sees the abort while it runs on.
|
|
200
|
+
*/
|
|
201
|
+
function untilAborted<T>(work: Promise<T>, signal: AbortSignal | undefined, label: string, own: AbortController): Promise<T> {
|
|
202
|
+
if (signal === undefined) return work
|
|
203
|
+
|
|
204
|
+
return new Promise<T>((resolve, reject) => {
|
|
205
|
+
const onAbort = (): void => {
|
|
206
|
+
work.catch(() => {})
|
|
207
|
+
const reason = abortReason(signal, label)
|
|
208
|
+
own.abort(reason)
|
|
209
|
+
reject(reason)
|
|
210
|
+
}
|
|
211
|
+
if (signal.aborted) {
|
|
212
|
+
onAbort()
|
|
213
|
+
return
|
|
214
|
+
}
|
|
215
|
+
signal.addEventListener('abort', onAbort, { once: true })
|
|
216
|
+
work.then(resolve, reject).finally(() => { signal.removeEventListener('abort', onAbort) })
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { executeJob } from './execute.js'
|
|
2
|
+
export type { ExecuteJobOptions } from './execute.js'
|
|
3
|
+
export { JobAbortedError, JobLaterError, JobPermanentError } from './errors.js'
|
|
4
|
+
export { createQueue } from './queue.js'
|
|
5
|
+
export type { Queue, QueueConfig, EnqueueOptions, EnqueueExclusion, ClaimedJob, JobClaim, JobClaimReason, ClaimedExclusion, DeadLetterInfo, ReapedJob, FailedAttempt, QueueTotals, QueueTypeTotals, JobResult, BackoffConfig } from './queue.js'
|
|
6
|
+
export type { ExclusionConfig } from './exclusion.js'
|
|
7
|
+
export type { WaitOptions, WaitResult, ListenClient, ListenHandle } from './listener.js'
|
|
8
|
+
export { parseCron, nextTick } from './cron.js'
|
|
9
|
+
export type { CronSchedule } from './cron.js'
|
|
10
|
+
export type { ScheduleSpec, ScheduleInfo, SchedulerOptions } from './scheduler.js'
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { sql } from '../../data/db/sql.js'
|
|
2
|
+
import type { DB } from '../../data/db/index.js'
|
|
3
|
+
import type { JobClaim } from './claims.js'
|
|
4
|
+
import { parseClaims } from './claims.js'
|
|
5
|
+
|
|
6
|
+
export interface WaitOptions {
|
|
7
|
+
readonly timeoutMs: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface WaitResult {
|
|
11
|
+
readonly jobId: string
|
|
12
|
+
readonly status: 'completed' | 'failed' | 'dead_letter' | 'cancelled' | 'timeout'
|
|
13
|
+
readonly output?: unknown
|
|
14
|
+
readonly error?: unknown
|
|
15
|
+
/** Every claim the job has had, oldest first. Absent on a timeout. */
|
|
16
|
+
readonly claims?: readonly JobClaim[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ListenHandle {
|
|
20
|
+
unlisten(): Promise<void>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ListenClient {
|
|
24
|
+
listen(channel: string, cb: (payload: string) => void): Promise<ListenHandle>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface Waiter {
|
|
28
|
+
readonly resolve: (result: WaitResult) => void
|
|
29
|
+
readonly timer: ReturnType<typeof setTimeout>
|
|
30
|
+
readonly db: DB
|
|
31
|
+
readonly tenant: string | null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class JobListener {
|
|
35
|
+
private readonly channel: string
|
|
36
|
+
private readonly tableQ: string
|
|
37
|
+
private readonly waiters = new Map<string, Waiter>()
|
|
38
|
+
private handle: ListenHandle | null = null
|
|
39
|
+
private listening = false
|
|
40
|
+
|
|
41
|
+
constructor(channel: string, tableQ: string) {
|
|
42
|
+
this.channel = channel
|
|
43
|
+
this.tableQ = tableQ
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async start(client: ListenClient): Promise<void> {
|
|
47
|
+
if (this.listening) return
|
|
48
|
+
this.handle = await client.listen(this.channel, (payload: string) => {
|
|
49
|
+
this.dispatch(payload)
|
|
50
|
+
})
|
|
51
|
+
this.listening = true
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async stop(): Promise<void> {
|
|
55
|
+
if (!this.listening || !this.handle) return
|
|
56
|
+
await this.handle.unlisten()
|
|
57
|
+
this.handle = null
|
|
58
|
+
this.listening = false
|
|
59
|
+
|
|
60
|
+
for (const [jobId, waiter] of this.waiters) {
|
|
61
|
+
clearTimeout(waiter.timer)
|
|
62
|
+
waiter.resolve({ jobId, status: 'timeout' })
|
|
63
|
+
}
|
|
64
|
+
this.waiters.clear()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get isListening(): boolean {
|
|
68
|
+
return this.listening
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async waitFor(db: DB, jobId: string, opts: WaitOptions, tenant: string | null = null): Promise<WaitResult> {
|
|
72
|
+
if (!this.listening) {
|
|
73
|
+
const existing = await this.pollJob(db, jobId, tenant)
|
|
74
|
+
if (existing !== null) return existing
|
|
75
|
+
return this.pollUntil(db, jobId, opts.timeoutMs, tenant)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return new Promise<WaitResult>((resolve) => {
|
|
79
|
+
const timer = setTimeout(() => {
|
|
80
|
+
this.waiters.delete(jobId)
|
|
81
|
+
resolve({ jobId, status: 'timeout' })
|
|
82
|
+
}, opts.timeoutMs)
|
|
83
|
+
|
|
84
|
+
const waiter: Waiter = { resolve, timer, db, tenant }
|
|
85
|
+
this.waiters.set(jobId, waiter)
|
|
86
|
+
|
|
87
|
+
void this.pollJob(db, jobId, tenant).then((result) => {
|
|
88
|
+
if (result !== null && this.waiters.has(jobId)) {
|
|
89
|
+
this.waiters.delete(jobId)
|
|
90
|
+
clearTimeout(timer)
|
|
91
|
+
resolve(result)
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private dispatch(jobId: string): void {
|
|
98
|
+
const waiter = this.waiters.get(jobId)
|
|
99
|
+
if (!waiter) return
|
|
100
|
+
this.waiters.delete(jobId)
|
|
101
|
+
clearTimeout(waiter.timer)
|
|
102
|
+
|
|
103
|
+
void this.pollJob(waiter.db, jobId, waiter.tenant).then((result) => {
|
|
104
|
+
waiter.resolve(result ?? { jobId, status: 'completed' })
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async pollJob(db: DB, jobId: string, tenant: string | null = null): Promise<WaitResult | null> {
|
|
109
|
+
const rows = await db.execute(
|
|
110
|
+
sql`SELECT status, output, error_payload, claims FROM ${sql.raw(this.tableQ)} WHERE id = ${jobId}::uuid${tenant === null ? sql`` : sql` AND flow_tenant = ${tenant}::text`}`
|
|
111
|
+
)
|
|
112
|
+
if (rows.length === 0) return null
|
|
113
|
+
const row = rows[0]!
|
|
114
|
+
const status = row['status'] as string
|
|
115
|
+
if (status === 'pending' || status === 'claimed' || status === 'running') return null
|
|
116
|
+
return {
|
|
117
|
+
jobId,
|
|
118
|
+
status: status as WaitResult['status'],
|
|
119
|
+
output: row['output'] ?? undefined,
|
|
120
|
+
error: row['error_payload'] ?? undefined,
|
|
121
|
+
claims: parseClaims(row['claims']),
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private async pollUntil(db: DB, jobId: string, timeoutMs: number, tenant: string | null): Promise<WaitResult> {
|
|
126
|
+
const deadline = Date.now() + timeoutMs
|
|
127
|
+
const interval = 500
|
|
128
|
+
while (Date.now() < deadline) {
|
|
129
|
+
const result = await this.pollJob(db, jobId, tenant)
|
|
130
|
+
if (result !== null) return result
|
|
131
|
+
await new Promise(r => setTimeout(r, Math.min(interval, deadline - Date.now())))
|
|
132
|
+
}
|
|
133
|
+
return { jobId, status: 'timeout' }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createQueue } from './queue.js'
|
|
2
|
+
import { executeJob } from './execute.js'
|
|
3
|
+
import { JobLaterError, JobPermanentError } from './errors.js'
|
|
4
|
+
import { parseCron, nextTick } from './cron.js'
|
|
5
|
+
|
|
6
|
+
/** Background job queue namespace — Postgres-backed with SKIP LOCKED, LISTEN/NOTIFY, cron scheduling. */
|
|
7
|
+
export const jobs = {
|
|
8
|
+
/** Creates a job queue with claim/complete/fail lifecycle, heartbeat, and dead letter requeue. */
|
|
9
|
+
createQueue,
|
|
10
|
+
/** Executes a fitting handler as a background job with its own Flow context. */
|
|
11
|
+
execute: executeJob,
|
|
12
|
+
/** The error to throw to end an attempt as "later": pending again after `delayMs`, no attempt counted. */
|
|
13
|
+
later: (message: string, opts?: { delayMs?: number; cause?: unknown }): JobLaterError => new JobLaterError(message, opts),
|
|
14
|
+
/** The error to throw to dead-letter the job now, whatever attempts remain. */
|
|
15
|
+
permanent: (message: string, opts?: { cause?: unknown }): JobPermanentError => new JobPermanentError(message, opts),
|
|
16
|
+
/** Parses a 5-field cron expression into a CronSchedule (minute, hour, dom, month, dow). */
|
|
17
|
+
parseCron,
|
|
18
|
+
/** Computes the next fire time for a CronSchedule after a given date, with optional timezone. */
|
|
19
|
+
nextTick,
|
|
20
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ResolvedDoor } from '../../core/config/load.js'
|
|
2
|
+
import type { DefinedTable } from '../../data/domain/types.js'
|
|
3
|
+
import { queueDefinitions } from './table.js'
|
|
4
|
+
|
|
5
|
+
/** The framework door a tenant-column queue table's claim, reap, heartbeat and complete run through. */
|
|
6
|
+
export function queueDoorName(table: string): string {
|
|
7
|
+
return `pipework.queue.${table}`
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** A queue only selects and updates its rows: it never deletes one. */
|
|
11
|
+
export function queueFrameworkDoor(table: string, database: string): ResolvedDoor {
|
|
12
|
+
return Object.freeze({
|
|
13
|
+
name: queueDoorName(table), table, database,
|
|
14
|
+
reason: 'the queue claims, reaps and completes jobs across tenants',
|
|
15
|
+
framework: true as const, ops: ['select', 'update'] as const,
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const hasTenant = (definition: DefinedTable): boolean =>
|
|
20
|
+
Object.values(definition.$fields).some(field => field._meta.tenant === true)
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The queue doors pipework declares: one per registered queue table with a
|
|
24
|
+
* tenant column, where the default database sets `rls.platformRole`. Queue
|
|
25
|
+
* tables register when a worker surface or graph is constructed, so ask after
|
|
26
|
+
* the app's modules are loaded.
|
|
27
|
+
*/
|
|
28
|
+
export function queueFrameworkDoors(config: {
|
|
29
|
+
defaultDatabaseName(): string
|
|
30
|
+
database(name?: string): { readonly rls?: { readonly platformRole?: string } | undefined }
|
|
31
|
+
}): Record<string, ResolvedDoor> {
|
|
32
|
+
const out: Record<string, ResolvedDoor> = {}
|
|
33
|
+
let database: string
|
|
34
|
+
try {
|
|
35
|
+
database = config.defaultDatabaseName()
|
|
36
|
+
} catch {
|
|
37
|
+
return out
|
|
38
|
+
}
|
|
39
|
+
if (config.database(database).rls?.platformRole === undefined) return out
|
|
40
|
+
for (const [table, definition] of queueDefinitions()) {
|
|
41
|
+
if (hasTenant(definition)) out[queueDoorName(table)] = queueFrameworkDoor(table, database)
|
|
42
|
+
}
|
|
43
|
+
return out
|
|
44
|
+
}
|