pipework 0.251.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 +11 -0
- package/dist/core/config/load.d.ts +2 -0
- package/dist/core/config/load.d.ts.map +1 -1
- package/dist/core/config/load.js +1 -0
- package/dist/core/config/load.js.map +1 -1
- package/dist/core/config/namespace.d.ts +1 -0
- package/dist/core/config/namespace.d.ts.map +1 -1
- package/dist/core/config/schema.d.ts +2 -0
- package/dist/core/config/schema.d.ts.map +1 -1
- package/dist/core/config/schema.js +1 -0
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/surface/types.d.ts +1 -0
- package/dist/core/surface/types.d.ts.map +1 -1
- package/dist/data/db/namespace.d.ts +3 -0
- package/dist/data/db/namespace.d.ts.map +1 -1
- package/dist/data/db/namespace.js +3 -0
- package/dist/data/db/namespace.js.map +1 -1
- package/dist/data/db/pool.d.ts.map +1 -1
- package/dist/data/db/pool.js +6 -1
- package/dist/data/db/pool.js.map +1 -1
- package/dist/data/db/query-label.d.ts +5 -0
- package/dist/data/db/query-label.d.ts.map +1 -0
- package/dist/data/db/query-label.js +11 -0
- package/dist/data/db/query-label.js.map +1 -0
- package/dist/data/db/query-watch.d.ts +21 -0
- package/dist/data/db/query-watch.d.ts.map +1 -0
- package/dist/data/db/query-watch.js +90 -0
- package/dist/data/db/query-watch.js.map +1 -0
- package/dist/data/query/postgres-js/driver.js +1 -1
- package/dist/data/query/postgres-js/driver.js.map +1 -1
- package/dist/data/query/postgres-js/session.d.ts +5 -1
- package/dist/data/query/postgres-js/session.d.ts.map +1 -1
- package/dist/data/query/postgres-js/session.js +16 -11
- package/dist/data/query/postgres-js/session.js.map +1 -1
- package/dist/data/query/utils.d.ts +2 -0
- package/dist/data/query/utils.d.ts.map +1 -1
- package/dist/data/query/utils.js.map +1 -1
- package/dist/infra/credits/schema.d.ts +1 -1
- package/dist/test/plugin.d.ts.map +1 -1
- package/dist/test/plugin.js +10 -4
- package/dist/test/plugin.js.map +1 -1
- 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,22 @@
|
|
|
1
|
+
import type { DB, SQL, Table } from '../db/types.js'
|
|
2
|
+
|
|
3
|
+
export interface TemporalOptions {
|
|
4
|
+
readonly tx: DB
|
|
5
|
+
readonly table: string | Table
|
|
6
|
+
readonly where: SQL
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ReviseOptions extends TemporalOptions {
|
|
10
|
+
readonly data: Record<string, unknown>
|
|
11
|
+
readonly userId?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ReviseResult {
|
|
15
|
+
readonly id: string
|
|
16
|
+
readonly version: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface GetCurrentResult {
|
|
20
|
+
readonly id: string
|
|
21
|
+
readonly version: number
|
|
22
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { schema } from '../schema/namespace.js'
|
|
2
|
+
import type { JsonSchema } from '../schema/namespace.js'
|
|
3
|
+
import type { SupplyDefinition, ValveKind, ValveTopology } from './types.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The lightweight artifact a supply declaration emits — JSON Schema plus valve
|
|
7
|
+
* metadata, zero logic and zero transitive producer dependencies. A consumer's
|
|
8
|
+
* faucet imports only this, never the producer silo.
|
|
9
|
+
*/
|
|
10
|
+
export interface ContractArtifact {
|
|
11
|
+
readonly valve: string
|
|
12
|
+
readonly kind: ValveKind
|
|
13
|
+
readonly topology: ValveTopology
|
|
14
|
+
readonly version: number
|
|
15
|
+
readonly schema: JsonSchema
|
|
16
|
+
readonly invariants: readonly string[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Project a handoff supply to its contract artifact. */
|
|
20
|
+
export function emitArtifact<TSource, TPayload>(
|
|
21
|
+
definition: SupplyDefinition<TSource, TPayload>,
|
|
22
|
+
): ContractArtifact {
|
|
23
|
+
return {
|
|
24
|
+
valve: definition.name,
|
|
25
|
+
kind: definition.kind,
|
|
26
|
+
topology: definition.topology,
|
|
27
|
+
// Explicit contract versioning (a `.version()` builder step) is a later
|
|
28
|
+
// refinement; the field exists so the artifact is diffable from day one.
|
|
29
|
+
version: 1,
|
|
30
|
+
schema: schema.check.toJsonSchema(schema.check.object(definition.contract)),
|
|
31
|
+
invariants: [...definition.invariants],
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ContractShape } from './types.js'
|
|
2
|
+
|
|
3
|
+
export interface ContractDiff {
|
|
4
|
+
readonly added: readonly string[]
|
|
5
|
+
readonly removed: readonly string[]
|
|
6
|
+
readonly retained: readonly string[]
|
|
7
|
+
/** True when the diff removes a field — consumers reading it break. */
|
|
8
|
+
readonly breaking: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Diff a valve contract between two versions. Removing a field breaks any
|
|
13
|
+
* consumer that reads it; adding a field is additive. Field-level — deep
|
|
14
|
+
* schema-change detection within a retained field is a later refinement.
|
|
15
|
+
*/
|
|
16
|
+
export function diffContract(before: ContractShape, after: ContractShape): ContractDiff {
|
|
17
|
+
const added = Object.keys(after).filter((key) => !(key in before))
|
|
18
|
+
const removed = Object.keys(before).filter((key) => !(key in after))
|
|
19
|
+
const retained = Object.keys(before).filter((key) => key in after)
|
|
20
|
+
return { added, removed, retained, breaking: removed.length > 0 }
|
|
21
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { faucetsOf } from './registry.js'
|
|
2
|
+
import { schema } from '../schema/namespace.js'
|
|
3
|
+
import type { DB } from '../db/namespace.js'
|
|
4
|
+
import type { GateCrossingResult, GateDefinition, SupplyCrossingResult, SupplyDefinition } from './types.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Execute a handoff crossing in the caller's transaction: run the guard, project
|
|
8
|
+
* the payload, validate it against the contract, and deliver it to every faucet
|
|
9
|
+
* — each faucet re-validating, because it does not trust the supply.
|
|
10
|
+
*/
|
|
11
|
+
export async function crossSupply<TSource, TPayload>(
|
|
12
|
+
definition: SupplyDefinition<TSource, TPayload>,
|
|
13
|
+
source: TSource,
|
|
14
|
+
tx: DB,
|
|
15
|
+
): Promise<SupplyCrossingResult> {
|
|
16
|
+
if (definition.guard !== undefined && !definition.guard(source)) {
|
|
17
|
+
return { kind: 'blocked' }
|
|
18
|
+
}
|
|
19
|
+
const payload = definition.project(source)
|
|
20
|
+
const contractSchema = schema.check.object(definition.contract)
|
|
21
|
+
schema.check.parse(contractSchema, payload)
|
|
22
|
+
for (const consumer of faucetsOf(definition.name)) {
|
|
23
|
+
const revalidated = schema.check.parse(contractSchema, payload)
|
|
24
|
+
await consumer.handler(revalidated, tx)
|
|
25
|
+
}
|
|
26
|
+
return { kind: 'crossed', payload }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Execute a transition-gate crossing: fan the event out to N items, run the
|
|
31
|
+
* async decision per item, and partition each outcome — cross / held / failed —
|
|
32
|
+
* into a crossing result.
|
|
33
|
+
*/
|
|
34
|
+
export async function crossGate<TEvent>(
|
|
35
|
+
definition: GateDefinition<TEvent>,
|
|
36
|
+
event: TEvent,
|
|
37
|
+
context: Readonly<Record<string, unknown>>,
|
|
38
|
+
): Promise<readonly GateCrossingResult[]> {
|
|
39
|
+
const items: readonly unknown[] = definition.fanOut !== undefined
|
|
40
|
+
? definition.fanOut(event)
|
|
41
|
+
: [event]
|
|
42
|
+
const results: GateCrossingResult[] = []
|
|
43
|
+
for (const item of items) {
|
|
44
|
+
// Fan-out re-scopes the trigger into per-item decision events; #307 leaves
|
|
45
|
+
// the item/event type relation open, so the executor treats each item as
|
|
46
|
+
// the decision's event.
|
|
47
|
+
const outcome = await definition.decision(item as TEvent, context)
|
|
48
|
+
if (outcome.kind === 'cross') {
|
|
49
|
+
results.push({ kind: 'crossed', payload: outcome.payload })
|
|
50
|
+
} else if (outcome.kind === 'held') {
|
|
51
|
+
results.push({ kind: 'held', reason: outcome.reason })
|
|
52
|
+
} else {
|
|
53
|
+
results.push({ kind: 'failed', error: outcome.error })
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return results
|
|
57
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { sql } from '../db/sql.js'
|
|
2
|
+
import type { DB } from '../db/namespace.js'
|
|
3
|
+
|
|
4
|
+
/** A provenance row to append to the `valve_crossing` ledger. */
|
|
5
|
+
export interface CrossingRecord {
|
|
6
|
+
readonly valve: string
|
|
7
|
+
readonly idempotencyKey: string | null
|
|
8
|
+
readonly outcome: 'crossed' | 'blocked' | 'held' | 'failed'
|
|
9
|
+
readonly payload: unknown
|
|
10
|
+
readonly detail: unknown
|
|
11
|
+
readonly lineageId: string | null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Append a crossing's provenance row to the ledger. `valve_crossing` is
|
|
16
|
+
* framework substrate, so — like trace and audit — it is written with raw SQL
|
|
17
|
+
* rather than the audited write surface. Runs on the caller's transaction, so
|
|
18
|
+
* the row commits atomically with the crossing it records.
|
|
19
|
+
*/
|
|
20
|
+
export async function recordCrossing(db: DB, record: CrossingRecord): Promise<void> {
|
|
21
|
+
const payload = record.payload === undefined || record.payload === null
|
|
22
|
+
? null
|
|
23
|
+
: JSON.stringify(record.payload)
|
|
24
|
+
const detail = record.detail === undefined || record.detail === null
|
|
25
|
+
? null
|
|
26
|
+
: JSON.stringify(record.detail)
|
|
27
|
+
await db.execute(sql`
|
|
28
|
+
INSERT INTO valve_crossing (valve, idempotency_key, outcome, payload, detail, lineage_id, crossed_at)
|
|
29
|
+
VALUES (
|
|
30
|
+
${record.valve}, ${record.idempotencyKey}, ${record.outcome},
|
|
31
|
+
${payload === null ? sql`NULL` : sql`${payload}::jsonb`},
|
|
32
|
+
${detail === null ? sql`NULL` : sql`${detail}::jsonb`},
|
|
33
|
+
${record.lineageId}, now()
|
|
34
|
+
)
|
|
35
|
+
`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Whether a keyed crossing has already crossed — the idempotency check. A
|
|
40
|
+
* `crossed` ledger row for `(valve, idempotencyKey)` means the crossing's
|
|
41
|
+
* effect already landed and must not be replayed.
|
|
42
|
+
*/
|
|
43
|
+
export async function findCrossing(db: DB, valve: string, idempotencyKey: string): Promise<boolean> {
|
|
44
|
+
const rows = await db.execute(sql`
|
|
45
|
+
SELECT 1 FROM valve_crossing
|
|
46
|
+
WHERE valve = ${valve} AND idempotency_key = ${idempotencyKey} AND outcome = 'crossed'
|
|
47
|
+
LIMIT 1
|
|
48
|
+
`)
|
|
49
|
+
return rows.length > 0
|
|
50
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The decision outcome — the load-bearing seam of the transition-gate form
|
|
3
|
+
* (#307 field 13). A gate's `.decision()` hook returns one of three branches.
|
|
4
|
+
* The three-way partition is fixed here by the primitive; the business verdict
|
|
5
|
+
* that *picks* a branch is consumer-silo application code.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** The crossing proceeds — `payload` is delivered to the consumer. */
|
|
9
|
+
export interface Crossed<TPayload> {
|
|
10
|
+
readonly kind: 'cross'
|
|
11
|
+
readonly payload: TPayload
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** The crossing is blocked into a provisional, reviewable state carrying `reason`. */
|
|
15
|
+
export interface Held<TReason> {
|
|
16
|
+
readonly kind: 'held'
|
|
17
|
+
readonly reason: TReason
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Evaluation itself failed — a durable, retryable outcome, not a thrown exception. */
|
|
21
|
+
export interface Failed {
|
|
22
|
+
readonly kind: 'failed'
|
|
23
|
+
readonly error: Error
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type DecisionOutcome<TPayload, TReason> =
|
|
27
|
+
| Crossed<TPayload>
|
|
28
|
+
| Held<TReason>
|
|
29
|
+
| Failed
|
|
30
|
+
|
|
31
|
+
/** Cross the valve: deliver `payload` to the consumer. */
|
|
32
|
+
export function cross<TPayload>(payload: TPayload): Crossed<TPayload> {
|
|
33
|
+
return { kind: 'cross', payload }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Hold the crossing: it enters a provisional, reviewable state carrying `reason`. */
|
|
37
|
+
export function held<TReason>(reason: TReason): Held<TReason> {
|
|
38
|
+
return { kind: 'held', reason }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Evaluation failed: a retryable, dead-letterable outcome — never a thrown exception. */
|
|
42
|
+
export function failed(error: Error): Failed {
|
|
43
|
+
return { kind: 'failed', error }
|
|
44
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getValve } from './registry.js'
|
|
2
|
+
import { executeSupplyCrossing } from './execute-crossing.js'
|
|
3
|
+
import type { DB } from '../db/namespace.js'
|
|
4
|
+
import type { Queue } from '../../async/jobs/queue.js'
|
|
5
|
+
import type { CrossingResult, SupplyDefinition } from './types.js'
|
|
6
|
+
|
|
7
|
+
/** Job type for a durable valve crossing. */
|
|
8
|
+
export const VALVE_CROSSING_JOB_TYPE = 'pipework:valve-crossing'
|
|
9
|
+
|
|
10
|
+
/** The payload of a durable-crossing job. */
|
|
11
|
+
export interface CrossingJobPayload {
|
|
12
|
+
readonly valve: string
|
|
13
|
+
readonly source: unknown
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Enqueue a handoff crossing to run durably. The job queue retries it with
|
|
18
|
+
* backoff and dead-letters it on retry exhaustion — failure-to-cross becomes a
|
|
19
|
+
* terminal job outcome, not an exception that vanishes.
|
|
20
|
+
*/
|
|
21
|
+
export async function enqueueCrossing(
|
|
22
|
+
queue: Queue,
|
|
23
|
+
db: DB,
|
|
24
|
+
valve: string,
|
|
25
|
+
source: unknown,
|
|
26
|
+
): Promise<string> {
|
|
27
|
+
const payload: CrossingJobPayload = { valve, source }
|
|
28
|
+
return queue.enqueue(db, { type: VALVE_CROSSING_JOB_TYPE, payload })
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The job-handler body for a durable crossing. Wire it into a worker — e.g.
|
|
33
|
+
* `fitting().job(VALVE_CROSSING_JOB_TYPE).fit(({ input, db }) => runCrossingJob(input, db))`.
|
|
34
|
+
* The valve must be registered in the worker process; the crossing runs
|
|
35
|
+
* recorded and idempotent on the job's transaction. A throw fails the job,
|
|
36
|
+
* which the queue retries and finally dead-letters.
|
|
37
|
+
*/
|
|
38
|
+
export async function runCrossingJob(payload: CrossingJobPayload, tx: DB): Promise<CrossingResult> {
|
|
39
|
+
const definition = getValve(payload.valve)
|
|
40
|
+
if (definition === undefined) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`[pipework] Durable crossing names an unregistered valve: "${payload.valve}".\n\n` +
|
|
43
|
+
' The valve declaration must be imported in the worker process so it registers.\n',
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
if (definition.kind !== 'handoff') {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`[pipework] Durable crossing supports handoff valves; "${payload.valve}" is a ${definition.kind}.\n`,
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
return executeSupplyCrossing(definition as SupplyDefinition<unknown, unknown>, payload.source, tx)
|
|
52
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { crossSupply, crossGate } from './cross.js'
|
|
2
|
+
import { recordCrossing, findCrossing } from './crossing-ledger.js'
|
|
3
|
+
import type { DB } from '../db/namespace.js'
|
|
4
|
+
import type {
|
|
5
|
+
CrossingResult,
|
|
6
|
+
GateCrossingResult,
|
|
7
|
+
GateDefinition,
|
|
8
|
+
SupplyDefinition,
|
|
9
|
+
} from './types.js'
|
|
10
|
+
|
|
11
|
+
function lineageOf<TSource, TPayload>(
|
|
12
|
+
definition: SupplyDefinition<TSource, TPayload>,
|
|
13
|
+
source: TSource,
|
|
14
|
+
): string | null {
|
|
15
|
+
if (definition.lineageField === undefined) return null
|
|
16
|
+
const value = (source as Record<string, unknown>)[definition.lineageField]
|
|
17
|
+
return typeof value === 'string' ? value : null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function detailOf(result: GateCrossingResult): unknown {
|
|
21
|
+
if (result.kind === 'held') return { reason: result.reason }
|
|
22
|
+
if (result.kind === 'failed') return { error: result.error.message }
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Execute a handoff crossing with idempotency and provenance, on the caller's
|
|
28
|
+
* transaction. If the supply declares an idempotency key and a `crossed` row
|
|
29
|
+
* already exists for it, the crossing is skipped — its effect already landed.
|
|
30
|
+
* Otherwise the crossing runs and its outcome is appended to the ledger
|
|
31
|
+
* atomically with it.
|
|
32
|
+
*/
|
|
33
|
+
export async function executeSupplyCrossing<TSource, TPayload>(
|
|
34
|
+
definition: SupplyDefinition<TSource, TPayload>,
|
|
35
|
+
source: TSource,
|
|
36
|
+
tx: DB,
|
|
37
|
+
): Promise<CrossingResult> {
|
|
38
|
+
const key = definition.idempotentBy !== undefined ? definition.idempotentBy(source) : null
|
|
39
|
+
if (key !== null && await findCrossing(tx, definition.name, key)) {
|
|
40
|
+
return { kind: 'skipped' }
|
|
41
|
+
}
|
|
42
|
+
const result = await crossSupply(definition, source, tx)
|
|
43
|
+
await recordCrossing(tx, {
|
|
44
|
+
valve: definition.name,
|
|
45
|
+
idempotencyKey: key,
|
|
46
|
+
outcome: result.kind,
|
|
47
|
+
payload: result.kind === 'crossed' ? result.payload : null,
|
|
48
|
+
detail: null,
|
|
49
|
+
lineageId: lineageOf(definition, source),
|
|
50
|
+
})
|
|
51
|
+
return result
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Execute a transition-gate crossing with provenance. Each fanned-out crossing
|
|
56
|
+
* — crossed, held, or failed — is appended to the ledger as its own row, on the
|
|
57
|
+
* caller's transaction.
|
|
58
|
+
*/
|
|
59
|
+
export async function executeGateCrossing<TEvent>(
|
|
60
|
+
definition: GateDefinition<TEvent>,
|
|
61
|
+
event: TEvent,
|
|
62
|
+
context: Readonly<Record<string, unknown>>,
|
|
63
|
+
tx: DB,
|
|
64
|
+
): Promise<readonly GateCrossingResult[]> {
|
|
65
|
+
const results = await crossGate(definition, event, context)
|
|
66
|
+
for (const result of results) {
|
|
67
|
+
await recordCrossing(tx, {
|
|
68
|
+
valve: definition.name,
|
|
69
|
+
idempotencyKey: null,
|
|
70
|
+
outcome: result.kind,
|
|
71
|
+
payload: result.kind === 'crossed' ? result.payload : null,
|
|
72
|
+
detail: detailOf(result),
|
|
73
|
+
lineageId: null,
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
return results
|
|
77
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { registerFaucet } from './registry.js'
|
|
2
|
+
import type { FaucetDefinition, FaucetHandler } from './types.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The consumer-side builder. A faucet binds to a valve by name — never to the
|
|
6
|
+
* producer silo — and lands every (re-validated) payload in a consumer entity.
|
|
7
|
+
* `.on()` is terminal: supplying the intake handler registers the faucet.
|
|
8
|
+
*/
|
|
9
|
+
export interface FaucetBuilder<TPayload> {
|
|
10
|
+
/** The consumer entity the payload lands in. */
|
|
11
|
+
into(target: string): FaucetBuilder<TPayload>
|
|
12
|
+
/** The intake handler. Terminal — registers the faucet and returns its definition. */
|
|
13
|
+
on(handler: FaucetHandler<TPayload>): FaucetDefinition<TPayload>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface FaucetState {
|
|
17
|
+
readonly valve: string
|
|
18
|
+
target: string | undefined
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function finalizeFaucet(state: FaucetState, handler: FaucetHandler<unknown>): FaucetDefinition<unknown> {
|
|
22
|
+
if (state.target === undefined) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`[pipework] Faucet for valve "${state.valve}" is missing .into(...).\n\n` +
|
|
25
|
+
' A faucet must declare the consumer entity its payload lands in before .on(...).\n' +
|
|
26
|
+
' Example: faucet("frozen-outcome").into("ledger-entries").on(handler)\n',
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
const definition: FaucetDefinition<unknown> = {
|
|
30
|
+
valve: state.valve,
|
|
31
|
+
target: state.target,
|
|
32
|
+
handler,
|
|
33
|
+
}
|
|
34
|
+
registerFaucet(definition)
|
|
35
|
+
return definition
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Declare a faucet — the consumer side of a `supply -> faucet` edge. `valve` is
|
|
40
|
+
* the name of the producer valve this faucet consumes.
|
|
41
|
+
*/
|
|
42
|
+
export function faucet<TPayload = unknown>(valve: string): FaucetBuilder<TPayload> {
|
|
43
|
+
const state: FaucetState = { valve, target: undefined }
|
|
44
|
+
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- the builder erases the payload generic; FaucetBuilder is the precise public surface
|
|
46
|
+
const builder: any = {
|
|
47
|
+
into(target: string) {
|
|
48
|
+
state.target = target
|
|
49
|
+
return builder
|
|
50
|
+
},
|
|
51
|
+
on(handler: FaucetHandler<unknown>) {
|
|
52
|
+
return finalizeFaucet(state, handler)
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
return builder as FaucetBuilder<TPayload>
|
|
56
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { registerValve } from './registry.js'
|
|
2
|
+
import type { GateDecision, GateDefinition, GateRetraction, GateTrigger } from './types.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The producer-side builder for a transition-gate valve. `.on()` fixes the
|
|
6
|
+
* source event type; `.fanOut()` and `.decision()` are checked against it.
|
|
7
|
+
* `.decision()` is terminal — the async hook is the load-bearing seam, and
|
|
8
|
+
* supplying it registers the gate.
|
|
9
|
+
*/
|
|
10
|
+
export interface GateBuilder<TEvent> {
|
|
11
|
+
/** The source entity and the set of triggers that fire the gate. */
|
|
12
|
+
on<TOnEvent = TEvent>(source: string, triggers: readonly GateTrigger[]): GateBuilder<TOnEvent>
|
|
13
|
+
/** Enrichment context — context key -> inbound valve name. Fed by inbound faucets. */
|
|
14
|
+
context(inbound: Record<string, string>): GateBuilder<TEvent>
|
|
15
|
+
/** Names the computed signals the decision may read. */
|
|
16
|
+
signals(names: readonly string[]): GateBuilder<TEvent>
|
|
17
|
+
/** Fans one trigger out to N independently-keyed crossings. */
|
|
18
|
+
fanOut(items: (event: TEvent) => readonly unknown[]): GateBuilder<TEvent>
|
|
19
|
+
/** Declares that a trigger supersedes and retracts the prior crossing. */
|
|
20
|
+
retracts(config: GateRetraction): GateBuilder<TEvent>
|
|
21
|
+
/** The async decision hook. Terminal — registers the gate and returns its definition. */
|
|
22
|
+
decision(hook: GateDecision<TEvent>): GateDefinition<TEvent>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface GateState {
|
|
26
|
+
readonly name: string
|
|
27
|
+
readonly silo: string
|
|
28
|
+
source: string | undefined
|
|
29
|
+
triggers: readonly GateTrigger[] | undefined
|
|
30
|
+
context: Record<string, string>
|
|
31
|
+
signals: readonly string[]
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- the builder erases the per-stage event generic; GateBuilder is the precise public surface
|
|
33
|
+
fanOut: ((event: any) => readonly unknown[]) | undefined
|
|
34
|
+
retraction: GateRetraction | undefined
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function finalizeGate(state: GateState, hook: GateDecision<unknown>): GateDefinition<unknown> {
|
|
38
|
+
if (state.source === undefined || state.triggers === undefined) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`[pipework] Valve "${state.name}" is missing .on(...).\n\n` +
|
|
41
|
+
' A gate must declare its source entity and trigger set before .decision(...).\n' +
|
|
42
|
+
' Example: gate("event-verification", "events")\n' +
|
|
43
|
+
' .on("event-versions", [{ trigger: "admission" }])\n',
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
if (state.triggers.length === 0) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`[pipework] Valve "${state.name}" has an empty trigger set.\n\n` +
|
|
49
|
+
' .on(...) must declare at least one trigger — a gate that never fires is dead.\n',
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
const definition: GateDefinition<unknown> = {
|
|
53
|
+
name: state.name,
|
|
54
|
+
kind: 'transition-gate',
|
|
55
|
+
topology: { producer: state.silo, consumer: state.silo },
|
|
56
|
+
source: state.source,
|
|
57
|
+
triggers: state.triggers,
|
|
58
|
+
context: { ...state.context },
|
|
59
|
+
signals: [...state.signals],
|
|
60
|
+
fanOut: state.fanOut,
|
|
61
|
+
decision: hook,
|
|
62
|
+
retraction: state.retraction,
|
|
63
|
+
}
|
|
64
|
+
registerValve(definition)
|
|
65
|
+
return definition
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Declare a transition-gate valve. A gate modulates a state change within one
|
|
70
|
+
* silo, so `silo` is both producer and consumer. Chain the anatomy and finish
|
|
71
|
+
* with `.decision(hook)`.
|
|
72
|
+
*/
|
|
73
|
+
export function gate(name: string, silo: string): GateBuilder<unknown> {
|
|
74
|
+
const state: GateState = {
|
|
75
|
+
name,
|
|
76
|
+
silo,
|
|
77
|
+
source: undefined,
|
|
78
|
+
triggers: undefined,
|
|
79
|
+
context: {},
|
|
80
|
+
signals: [],
|
|
81
|
+
fanOut: undefined,
|
|
82
|
+
retraction: undefined,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- builder type param narrows per stage; the public GateBuilder type is precise
|
|
86
|
+
const builder: any = {
|
|
87
|
+
on(source: string, triggers: readonly GateTrigger[]) {
|
|
88
|
+
state.source = source
|
|
89
|
+
state.triggers = triggers
|
|
90
|
+
return builder
|
|
91
|
+
},
|
|
92
|
+
context(inbound: Record<string, string>) {
|
|
93
|
+
state.context = inbound
|
|
94
|
+
return builder
|
|
95
|
+
},
|
|
96
|
+
signals(names: readonly string[]) {
|
|
97
|
+
state.signals = names
|
|
98
|
+
return builder
|
|
99
|
+
},
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- fan-out event generic erased into state; see GateState
|
|
101
|
+
fanOut(items: (event: any) => readonly unknown[]) {
|
|
102
|
+
state.fanOut = items
|
|
103
|
+
return builder
|
|
104
|
+
},
|
|
105
|
+
retracts(config: GateRetraction) {
|
|
106
|
+
state.retraction = config
|
|
107
|
+
return builder
|
|
108
|
+
},
|
|
109
|
+
decision(hook: GateDecision<unknown>) {
|
|
110
|
+
return finalizeGate(state, hook)
|
|
111
|
+
},
|
|
112
|
+
}
|
|
113
|
+
return builder as GateBuilder<unknown>
|
|
114
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { valves, faucetsOf } from './registry.js'
|
|
2
|
+
import type { GateDefinition } from './types.js'
|
|
3
|
+
|
|
4
|
+
export type ValveNodeKind = 'supply' | 'gate' | 'faucet'
|
|
5
|
+
|
|
6
|
+
export interface ValveGraphNode {
|
|
7
|
+
readonly id: string
|
|
8
|
+
readonly kind: ValveNodeKind
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* `crossing` — a producer delivers to a faucet. `context` — a gate's enrichment
|
|
13
|
+
* depends on an inbound valve. `retraction` — a superseded crossing invalidates
|
|
14
|
+
* the downstream it fed.
|
|
15
|
+
*/
|
|
16
|
+
export type ValveEdgeKind = 'crossing' | 'context' | 'retraction'
|
|
17
|
+
|
|
18
|
+
export interface ValveGraphEdge {
|
|
19
|
+
readonly kind: ValveEdgeKind
|
|
20
|
+
readonly from: string
|
|
21
|
+
readonly to: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** The directional data-dependency graph, distinct from the package graph. */
|
|
25
|
+
export interface ValveGraph {
|
|
26
|
+
readonly nodes: readonly ValveGraphNode[]
|
|
27
|
+
readonly edges: readonly ValveGraphEdge[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function faucetNodeId(valve: string, target: string): string {
|
|
31
|
+
return `${valve}::${target}`
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Assemble the valve graph from every registered valve and faucet. */
|
|
35
|
+
export function buildValveGraph(): ValveGraph {
|
|
36
|
+
const nodes = new Map<string, ValveGraphNode>()
|
|
37
|
+
const edges: ValveGraphEdge[] = []
|
|
38
|
+
|
|
39
|
+
for (const [name, definition] of valves()) {
|
|
40
|
+
nodes.set(name, { id: name, kind: definition.kind === 'transition-gate' ? 'gate' : 'supply' })
|
|
41
|
+
|
|
42
|
+
const consumers = faucetsOf(name)
|
|
43
|
+
for (const consumer of consumers) {
|
|
44
|
+
const faucetId = faucetNodeId(name, consumer.target)
|
|
45
|
+
nodes.set(faucetId, { id: faucetId, kind: 'faucet' })
|
|
46
|
+
edges.push({ kind: 'crossing', from: name, to: faucetId })
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (definition.kind === 'transition-gate') {
|
|
50
|
+
const gateDef = definition as GateDefinition<unknown>
|
|
51
|
+
for (const inbound of Object.values(gateDef.context)) {
|
|
52
|
+
edges.push({ kind: 'context', from: name, to: inbound })
|
|
53
|
+
}
|
|
54
|
+
if (gateDef.retraction !== undefined) {
|
|
55
|
+
for (const consumer of consumers) {
|
|
56
|
+
edges.push({ kind: 'retraction', from: name, to: faucetNodeId(name, consumer.target) })
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { nodes: [...nodes.values()], edges }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Faucet node ids fed by the named valve — the direct downstream of a crossing. */
|
|
66
|
+
export function downstreamFaucets(graph: ValveGraph, valveName: string): readonly string[] {
|
|
67
|
+
return graph.edges
|
|
68
|
+
.filter((edge) => edge.kind === 'crossing' && edge.from === valveName)
|
|
69
|
+
.map((edge) => edge.to)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Gate valve names whose enrichment context depends on the named valve. */
|
|
73
|
+
export function contextDependents(graph: ValveGraph, valveName: string): readonly string[] {
|
|
74
|
+
return graph.edges
|
|
75
|
+
.filter((edge) => edge.kind === 'context' && edge.to === valveName)
|
|
76
|
+
.map((edge) => edge.from)
|
|
77
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export { cross, held, failed } from './decision.js'
|
|
2
|
+
export type { Crossed, Held, Failed, DecisionOutcome } from './decision.js'
|
|
3
|
+
export {
|
|
4
|
+
registerValve,
|
|
5
|
+
valves,
|
|
6
|
+
getValve,
|
|
7
|
+
registerFaucet,
|
|
8
|
+
faucetsOf,
|
|
9
|
+
clearValveRegistry,
|
|
10
|
+
} from './registry.js'
|
|
11
|
+
export { supply } from './supply.js'
|
|
12
|
+
export type { SupplyBuilder } from './supply.js'
|
|
13
|
+
export { gate } from './gate.js'
|
|
14
|
+
export type { GateBuilder } from './gate.js'
|
|
15
|
+
export { faucet } from './faucet.js'
|
|
16
|
+
export type { FaucetBuilder } from './faucet.js'
|
|
17
|
+
export { crossSupply, crossGate } from './cross.js'
|
|
18
|
+
export { executeSupplyCrossing, executeGateCrossing } from './execute-crossing.js'
|
|
19
|
+
export { enqueueCrossing, runCrossingJob, VALVE_CROSSING_JOB_TYPE } from './durable-crossing.js'
|
|
20
|
+
export type { CrossingJobPayload } from './durable-crossing.js'
|
|
21
|
+
export { recordCrossing, findCrossing } from './crossing-ledger.js'
|
|
22
|
+
export type { CrossingRecord } from './crossing-ledger.js'
|
|
23
|
+
export { valveCrossing } from './schema/valve-crossing.js'
|
|
24
|
+
export { buildValveGraph, downstreamFaucets, contextDependents } from './graph.js'
|
|
25
|
+
export type { ValveGraph, ValveGraphNode, ValveGraphEdge, ValveNodeKind, ValveEdgeKind } from './graph.js'
|
|
26
|
+
export { diffContract } from './contract-diff.js'
|
|
27
|
+
export type { ContractDiff } from './contract-diff.js'
|
|
28
|
+
export { emitArtifact } from './artifact.js'
|
|
29
|
+
export type { ContractArtifact } from './artifact.js'
|
|
30
|
+
export type {
|
|
31
|
+
ValveKind,
|
|
32
|
+
ValveTopology,
|
|
33
|
+
ValveDefinition,
|
|
34
|
+
HandoffTrigger,
|
|
35
|
+
CrossingMode,
|
|
36
|
+
ContractShape,
|
|
37
|
+
ContractPayload,
|
|
38
|
+
SupplyDefinition,
|
|
39
|
+
GateTrigger,
|
|
40
|
+
GateRetraction,
|
|
41
|
+
GateDecision,
|
|
42
|
+
GateDefinition,
|
|
43
|
+
FaucetHandler,
|
|
44
|
+
FaucetDefinition,
|
|
45
|
+
CrossedResult,
|
|
46
|
+
BlockedResult,
|
|
47
|
+
HeldResult,
|
|
48
|
+
FailedResult,
|
|
49
|
+
SkippedResult,
|
|
50
|
+
SupplyCrossingResult,
|
|
51
|
+
GateCrossingResult,
|
|
52
|
+
CrossingResult,
|
|
53
|
+
} from './types.js'
|