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,298 @@
|
|
|
1
|
+
// The per-trace step buffer. Every Flow that runs under tracing carries one;
|
|
2
|
+
// `__flowStep` records into it and the trace's close drains it to the database
|
|
3
|
+
// in a single batch. The buffer is in-memory and single-trace: a branch opens a
|
|
4
|
+
// child Flow with its own buffer, so the rows here never interleave with
|
|
5
|
+
// another trace's.
|
|
6
|
+
//
|
|
7
|
+
// Three pieces of mutable state, all owned here so `__flowStep` stays a thin
|
|
8
|
+
// wrapper: the `seq` counter (spawn order within the trace), `currentStepId`
|
|
9
|
+
// (the step a nested step records as its parent), and the truncation latch
|
|
10
|
+
// (Q7 — once the step cap is blown the buffer goes no-op for the rest of the
|
|
11
|
+
// trace, mirroring the off-the-traced-path code path exactly).
|
|
12
|
+
|
|
13
|
+
import { randomUUID } from 'node:crypto'
|
|
14
|
+
import { projectStepError, type StepError } from './step-error.js'
|
|
15
|
+
import type { MetaTouch } from './step-meta.js'
|
|
16
|
+
|
|
17
|
+
/** A `trace_step` row staged in memory, ready to be flushed. */
|
|
18
|
+
export interface PendingStep {
|
|
19
|
+
readonly id: string
|
|
20
|
+
readonly traceDay: string
|
|
21
|
+
readonly traceId: string
|
|
22
|
+
readonly tenantId: string | null
|
|
23
|
+
readonly seq: number
|
|
24
|
+
readonly parentStepId: string | null
|
|
25
|
+
readonly flowStepRef: string
|
|
26
|
+
readonly status: 'ok' | 'error'
|
|
27
|
+
readonly startedAt: Date
|
|
28
|
+
readonly completedAt: Date
|
|
29
|
+
readonly durationMicros: bigint
|
|
30
|
+
/**
|
|
31
|
+
* Tier-2 input capture (Q5): one bounded-serialized payload per parameter,
|
|
32
|
+
* in declaration order. `null` when the transformer emitted no capture
|
|
33
|
+
* metadata for this step or the `captureInputs` kill-switch is off.
|
|
34
|
+
*/
|
|
35
|
+
readonly capturedInputs: readonly unknown[] | null
|
|
36
|
+
readonly error: StepError | null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** A step that has started but not yet completed — the handle `complete` settles. */
|
|
40
|
+
export interface BegunStep {
|
|
41
|
+
readonly seq: number
|
|
42
|
+
readonly stepId: string
|
|
43
|
+
readonly parentStepId: string | null
|
|
44
|
+
readonly flowStepRef: string
|
|
45
|
+
readonly startedAt: Date
|
|
46
|
+
readonly startHrTime: bigint
|
|
47
|
+
/** Captured at begin time so a mutating impl can't change what the row records. */
|
|
48
|
+
readonly capturedInputs: readonly unknown[] | null
|
|
49
|
+
/**
|
|
50
|
+
* `@touches Entity:verb` targets baked into this step's meta. Empty means
|
|
51
|
+
* no audit projection — the executor takes the vanilla-DML branch and
|
|
52
|
+
* `__flowStep`'s completion path emits no read-touches audit row.
|
|
53
|
+
*/
|
|
54
|
+
readonly touches: readonly MetaTouch[]
|
|
55
|
+
/**
|
|
56
|
+
* The touches the executor audited with a `pipe.*` write under this step.
|
|
57
|
+
* `__flowStep` reads this at completion and emits a read-touches
|
|
58
|
+
* `audit_record` row for every touch not in it. The CTE branch handled the
|
|
59
|
+
* audit for the touches in it.
|
|
60
|
+
*/
|
|
61
|
+
readonly wroteTouches: Set<MetaTouch>
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The active-step handle the write executor reads to compile its CTE. Captures
|
|
66
|
+
* everything the `audit_inserts` SELECT needs from the step's runtime context:
|
|
67
|
+
* the step id and trace id that link the audit row back to the source step,
|
|
68
|
+
* the partition day, the bounded-serialized captured inputs, and the active
|
|
69
|
+
* touches. Returned by `StepBuffer.currentStep()` only while a step is open
|
|
70
|
+
* for audit (touches present); otherwise `null` so the executor falls through
|
|
71
|
+
* to vanilla DML.
|
|
72
|
+
*/
|
|
73
|
+
export interface ActiveAuditStep {
|
|
74
|
+
readonly traceId: string
|
|
75
|
+
readonly traceDay: string
|
|
76
|
+
readonly stepId: string
|
|
77
|
+
readonly touches: readonly MetaTouch[]
|
|
78
|
+
readonly capturedInputs: readonly unknown[] | null
|
|
79
|
+
/** Called by the executor right before it returns — records on the underlying BegunStep that `touch` was audited by a write. */
|
|
80
|
+
markWrote(touch: MetaTouch): void
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface StepBufferParams {
|
|
84
|
+
readonly traceId: string
|
|
85
|
+
/** The parent trace's `openedDay` — the partition every step row lands in. */
|
|
86
|
+
readonly traceDay: string
|
|
87
|
+
/** The trace's tenant, stamped on every staged step row. Default `null`. */
|
|
88
|
+
readonly tenantId?: string | null
|
|
89
|
+
/**
|
|
90
|
+
* The Q7 step cap. The `seq` that first exceeds it trips truncation;
|
|
91
|
+
* `Infinity` disables the cap (no `structuralMax` resolved yet).
|
|
92
|
+
*/
|
|
93
|
+
readonly cap: number
|
|
94
|
+
/**
|
|
95
|
+
* The Q5 input-capture kill-switch, resolved at trace open from
|
|
96
|
+
* `instance.config.trace.captureInputs`. When `false`, every step in this
|
|
97
|
+
* trace stages `capturedInputs: null` regardless of what the transformer
|
|
98
|
+
* emitted — Tier-1 capture is unaffected.
|
|
99
|
+
*/
|
|
100
|
+
readonly captureInputs: boolean
|
|
101
|
+
/**
|
|
102
|
+
* Per-trace limit on steps staged through `stageExternal` (steps reported by
|
|
103
|
+
* a process outside Node). They do not count against `cap`. Default 1000.
|
|
104
|
+
*/
|
|
105
|
+
readonly maxExternalSteps?: number
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** A completed step reported from outside the process, ready for `stageExternal`. */
|
|
109
|
+
export interface ExternalStepInput {
|
|
110
|
+
readonly id: string
|
|
111
|
+
readonly parentStepId: string | null
|
|
112
|
+
readonly flowStepRef: string
|
|
113
|
+
readonly status: 'ok' | 'error'
|
|
114
|
+
readonly startedAt: Date
|
|
115
|
+
readonly completedAt: Date
|
|
116
|
+
readonly durationMicros: bigint
|
|
117
|
+
readonly capturedInputs: readonly unknown[] | null
|
|
118
|
+
readonly error: StepError | null
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export class StepBuffer {
|
|
122
|
+
private readonly traceId: string
|
|
123
|
+
private readonly traceDay: string
|
|
124
|
+
private readonly tenantId: string | null
|
|
125
|
+
private readonly cap: number
|
|
126
|
+
readonly captureInputs: boolean
|
|
127
|
+
private seq = 0
|
|
128
|
+
/** Steps begun through `begin` — the count the step cap applies to. */
|
|
129
|
+
private structuralCount = 0
|
|
130
|
+
private externalCount = 0
|
|
131
|
+
private readonly maxExternalSteps: number
|
|
132
|
+
private currentStepId: string | null = null
|
|
133
|
+
/**
|
|
134
|
+
* The active begun-step at the deepest open nesting level. `__flowStep`
|
|
135
|
+
* pushes on `begin` and pops on `complete`; the write executor reads the
|
|
136
|
+
* top of the stack through `currentStep()` to compile its audit CTE.
|
|
137
|
+
*
|
|
138
|
+
* The stack pairs with `currentStepId` — both describe step nesting — but
|
|
139
|
+
* keeps the full `BegunStep` reference so the executor and the read-touches
|
|
140
|
+
* emitter can reach `touches` and `capturedInputs` without a second lookup.
|
|
141
|
+
*/
|
|
142
|
+
private readonly active: BegunStep[] = []
|
|
143
|
+
private pending: PendingStep[] = []
|
|
144
|
+
private truncatedAtSeqValue: number | null = null
|
|
145
|
+
private truncationDoneValue: Promise<void> | null = null
|
|
146
|
+
|
|
147
|
+
constructor(params: StepBufferParams) {
|
|
148
|
+
this.traceId = params.traceId
|
|
149
|
+
this.traceDay = params.traceDay
|
|
150
|
+
this.tenantId = params.tenantId ?? null
|
|
151
|
+
this.cap = params.cap
|
|
152
|
+
this.captureInputs = params.captureInputs
|
|
153
|
+
this.maxExternalSteps = params.maxExternalSteps ?? 1000
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** The id of the step currently open (innermost), or `null` when none is. */
|
|
157
|
+
get openStepId(): string | null {
|
|
158
|
+
return this.currentStepId
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** True once the step cap has been blown — the trace records no further steps. */
|
|
162
|
+
get truncated(): boolean {
|
|
163
|
+
return this.truncatedAtSeqValue !== null
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** The `seq` that tripped truncation, for `trace.truncated_at_seq`. */
|
|
167
|
+
get truncatedAtSeq(): number | null {
|
|
168
|
+
return this.truncatedAtSeqValue
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Settles when `truncateTrace`'s side effects have landed (flush + status
|
|
173
|
+
* `UPDATE`). `closeTrace` awaits this before its copy-on-error so the cold
|
|
174
|
+
* row reflects `truncated_at_seq`. `null` when the trace was never truncated.
|
|
175
|
+
*/
|
|
176
|
+
get truncationDone(): Promise<void> | null {
|
|
177
|
+
return this.truncationDoneValue
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Records the truncation's settle handle. `truncateTrace` calls this once. */
|
|
181
|
+
markTruncationDone(promise: Promise<void>): void {
|
|
182
|
+
this.truncationDoneValue = promise
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Opens a step: assigns its `seq`, mints its id, and nests it under the step
|
|
187
|
+
* currently executing. Returns `null` when this step is the one that blows
|
|
188
|
+
* the cap — the caller runs the implementation untraced from here on.
|
|
189
|
+
*
|
|
190
|
+
* `capturedInputs` is the bounded-serialized projection of the step's args
|
|
191
|
+
* (built by `__flowStep` from `meta.capture`), or `null` for Tier-1-only.
|
|
192
|
+
* `touches` is the `@touches Entity:verb` set baked into the step's meta,
|
|
193
|
+
* or empty when the step has no audit projection.
|
|
194
|
+
*/
|
|
195
|
+
begin(
|
|
196
|
+
flowStepRef: string,
|
|
197
|
+
capturedInputs: readonly unknown[] | null,
|
|
198
|
+
touches: readonly MetaTouch[] = [],
|
|
199
|
+
): BegunStep | null {
|
|
200
|
+
const seq = ++this.seq
|
|
201
|
+
if (++this.structuralCount > this.cap) {
|
|
202
|
+
this.truncatedAtSeqValue = seq
|
|
203
|
+
return null
|
|
204
|
+
}
|
|
205
|
+
const stepId = randomUUID()
|
|
206
|
+
const begun: BegunStep = {
|
|
207
|
+
seq,
|
|
208
|
+
stepId,
|
|
209
|
+
parentStepId: this.currentStepId,
|
|
210
|
+
flowStepRef,
|
|
211
|
+
startedAt: new Date(),
|
|
212
|
+
startHrTime: process.hrtime.bigint(),
|
|
213
|
+
capturedInputs,
|
|
214
|
+
touches,
|
|
215
|
+
wroteTouches: new Set(),
|
|
216
|
+
}
|
|
217
|
+
this.currentStepId = stepId
|
|
218
|
+
this.active.push(begun)
|
|
219
|
+
return begun
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* The active step's audit handle, or `null` when there is no open step or
|
|
224
|
+
* the open step has no `@touches`. The write executor uses this to decide:
|
|
225
|
+
* `null` → vanilla DML; non-null → compile the `audit_inserts` CTE. The
|
|
226
|
+
* returned handle's `markWrote(touch)` records the touch so `__flowStep`
|
|
227
|
+
* suppresses its read-touches emission at step completion.
|
|
228
|
+
*/
|
|
229
|
+
currentStep(): ActiveAuditStep | null {
|
|
230
|
+
const top = this.active[this.active.length - 1]
|
|
231
|
+
if (top === undefined || top.touches.length === 0) return null
|
|
232
|
+
return {
|
|
233
|
+
traceId: this.traceId,
|
|
234
|
+
traceDay: this.traceDay,
|
|
235
|
+
stepId: top.stepId,
|
|
236
|
+
touches: top.touches,
|
|
237
|
+
capturedInputs: top.capturedInputs,
|
|
238
|
+
markWrote: (touch) => {
|
|
239
|
+
// A write also counts for every enclosing step that declares the same touch.
|
|
240
|
+
for (const step of this.active) {
|
|
241
|
+
for (const t of step.touches) {
|
|
242
|
+
if (t === touch || (t.entity === touch.entity && t.verb === touch.verb)) step.wroteTouches.add(t)
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** Settles a begun step: stamps its outcome and timing, stages the row, unnests. */
|
|
250
|
+
complete(begun: BegunStep, status: 'ok' | 'error', thrown: unknown): void {
|
|
251
|
+
this.currentStepId = begun.parentStepId
|
|
252
|
+
const idx = this.active.lastIndexOf(begun)
|
|
253
|
+
if (idx !== -1) this.active.splice(idx, 1)
|
|
254
|
+
this.pending.push({
|
|
255
|
+
id: begun.stepId,
|
|
256
|
+
traceDay: this.traceDay,
|
|
257
|
+
traceId: this.traceId,
|
|
258
|
+
tenantId: this.tenantId,
|
|
259
|
+
seq: begun.seq,
|
|
260
|
+
parentStepId: begun.parentStepId,
|
|
261
|
+
flowStepRef: begun.flowStepRef,
|
|
262
|
+
status,
|
|
263
|
+
startedAt: begun.startedAt,
|
|
264
|
+
completedAt: new Date(),
|
|
265
|
+
durationMicros: (process.hrtime.bigint() - begun.startHrTime) / 1000n,
|
|
266
|
+
capturedInputs: begun.capturedInputs,
|
|
267
|
+
error: status === 'error' ? projectStepError(thrown) : null,
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Stages an already-completed step reported from outside the process. Assigns
|
|
273
|
+
* its `seq`. Returns the staged row, or `null` when nothing was recorded: the
|
|
274
|
+
* trace is truncated or the external-step limit is reached. External steps
|
|
275
|
+
* never count toward the structural cap.
|
|
276
|
+
*/
|
|
277
|
+
stageExternal(step: ExternalStepInput): PendingStep | null {
|
|
278
|
+
if (this.truncated || this.externalCount >= this.maxExternalSteps) return null
|
|
279
|
+
this.externalCount++
|
|
280
|
+
const row: PendingStep = {
|
|
281
|
+
...step,
|
|
282
|
+
traceDay: this.traceDay,
|
|
283
|
+
traceId: this.traceId,
|
|
284
|
+
tenantId: this.tenantId,
|
|
285
|
+
seq: ++this.seq,
|
|
286
|
+
capturedInputs: this.captureInputs ? step.capturedInputs : null,
|
|
287
|
+
}
|
|
288
|
+
this.pending.push(row)
|
|
289
|
+
return row
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** Removes and returns every staged row — the buffer is empty afterwards. */
|
|
293
|
+
drain(): PendingStep[] {
|
|
294
|
+
const drained = this.pending
|
|
295
|
+
this.pending = []
|
|
296
|
+
return drained
|
|
297
|
+
}
|
|
298
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Tier-1 error capture: the JSON projection of a thrown value for the
|
|
2
|
+
// `trace_step.error` column. Errors are always captured (Tier 1) — unlike
|
|
3
|
+
// inputs, an error carries no tenant data of its own, only the failure shape a
|
|
4
|
+
// reader needs. A non-`Error` throw still gets a record so the step is never
|
|
5
|
+
// silently marked failed with nothing to show.
|
|
6
|
+
|
|
7
|
+
export interface StepError {
|
|
8
|
+
readonly name: string
|
|
9
|
+
readonly message: string
|
|
10
|
+
readonly stack: string | null
|
|
11
|
+
/** Facts about the failure the recorder chose to keep (an http error's route, status and code); absent on a thrown step. */
|
|
12
|
+
readonly detail?: unknown
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** The `trace_step.error` projection of a thrown value. */
|
|
16
|
+
export function projectStepError(thrown: unknown): StepError {
|
|
17
|
+
if (thrown instanceof Error) {
|
|
18
|
+
return { name: thrown.name, message: thrown.message, stack: thrown.stack ?? null }
|
|
19
|
+
}
|
|
20
|
+
return { name: 'NonError', message: String(thrown), stack: null }
|
|
21
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// The compile-time identity of a flow step. The build transformer (component 5)
|
|
2
|
+
// bakes one of these in as a literal at every wrapped call site — `__flowStep`
|
|
3
|
+
// never computes it. `ref` is the `path:symbol` node id, matching the
|
|
4
|
+
// `@upstream` / `@downstream` targets the annotation grammar produces.
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Per-arg projection emitted by the build transformer for Tier-2 input capture.
|
|
8
|
+
*
|
|
9
|
+
* The projection turns a raw argument into a trace-safe payload, derived at
|
|
10
|
+
* compile time from the parameter's type and the `.traceSafe()` markings in
|
|
11
|
+
* the `pipe.define()` registry. The runtime then runs the projected value
|
|
12
|
+
* through the bounded serializer before staging it on
|
|
13
|
+
* `trace_step.captured_inputs`.
|
|
14
|
+
*
|
|
15
|
+
* The projection may return any JSON-shaped value, including `undefined` for
|
|
16
|
+
* "this arg has no safe fields to capture" (fail-closed default).
|
|
17
|
+
*/
|
|
18
|
+
export type CaptureProjection = (arg: unknown) => unknown
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* One `@touches Entity:verb` target baked into a step's meta. Mirrors the
|
|
22
|
+
* `EntityTouch` shape the annotation parser produces — duplicated here so the
|
|
23
|
+
* runtime has no compile-time dependency on `src/trace/annotation/*` (the
|
|
24
|
+
* transformer is the only thing that bridges the two).
|
|
25
|
+
*/
|
|
26
|
+
export interface MetaTouch {
|
|
27
|
+
readonly entity: string
|
|
28
|
+
readonly verb: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Trace metadata for one documented flow-step: its `path:symbol` graph node id and the per-argument capture projections. */
|
|
32
|
+
export interface FlowStepMeta {
|
|
33
|
+
/** The `path:symbol` flow-graph node id of the documented function. */
|
|
34
|
+
readonly ref: string
|
|
35
|
+
/**
|
|
36
|
+
* Per-arg capture projections, in parameter order. `null` at a slot means
|
|
37
|
+
* "no projection — pass the raw arg through to the bounded serializer"
|
|
38
|
+
* (primitives, or `any`-typed parameters with no registry entry).
|
|
39
|
+
*
|
|
40
|
+
* Absent entirely means the transformer chose to skip Tier-2 capture for
|
|
41
|
+
* this step. The runtime stages `capturedInputs: null` and incurs no
|
|
42
|
+
* per-arg cost.
|
|
43
|
+
*/
|
|
44
|
+
readonly capture?: ReadonlyArray<CaptureProjection | null>
|
|
45
|
+
/**
|
|
46
|
+
* `@touches Entity:verb` targets declared on this step. Empty / absent means
|
|
47
|
+
* the step has no audit projection — the write surface emits vanilla DML
|
|
48
|
+
* (no CTE) and the runtime emits no read-touches `audit_record` row.
|
|
49
|
+
*
|
|
50
|
+
* When present, the active step's touches surface through the trace's
|
|
51
|
+
* `StepBuffer` for the executor's CTE generator (write-touches) and for
|
|
52
|
+
* `__flowStep`'s step-completion path (read-touches).
|
|
53
|
+
*/
|
|
54
|
+
readonly touches?: ReadonlyArray<MetaTouch>
|
|
55
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// A flow step's implementation may be synchronous or return a promise, and so
|
|
2
|
+
// may an entry's work. Both `__flowStep` and `finalizeTrace` have to settle the
|
|
3
|
+
// trace exactly when the work does — which means recognising a thenable
|
|
4
|
+
// (anything with a callable `then`, not just a native `Promise`) without
|
|
5
|
+
// awaiting code that never needed to be async.
|
|
6
|
+
|
|
7
|
+
/** True for any thenable — a native `Promise` or a custom PromiseLike. */
|
|
8
|
+
export function isThenable(value: unknown): value is PromiseLike<unknown> {
|
|
9
|
+
return value !== null
|
|
10
|
+
&& (typeof value === 'object' || typeof value === 'function')
|
|
11
|
+
&& typeof (value as { then?: unknown }).then === 'function'
|
|
12
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Q7 truncation. The step cap fired — the trace's longest non-branch path was
|
|
2
|
+
// supposed to be bounded by `structuralMax`, and we just crossed
|
|
3
|
+
// `structuralMax × safetyFactor`. That means the static DAG analysis was wrong
|
|
4
|
+
// (a branch the cardinality check missed) or unannotated recursion slipped
|
|
5
|
+
// validation. Either way it's a bug signal, not a load condition: the cap
|
|
6
|
+
// firing is loud on purpose.
|
|
7
|
+
//
|
|
8
|
+
// The work itself keeps running: `__flowStep` already flips to its
|
|
9
|
+
// off-the-traced-path pass-through, so the rest of the trace costs nothing.
|
|
10
|
+
// Here we finalize the trace as a casualty — flush whatever's buffered so far,
|
|
11
|
+
// stamp `status = 'truncated'` and `truncated_at_seq` on the row, and log loud.
|
|
12
|
+
//
|
|
13
|
+
// `closedAt` is *not* set: the entry hasn't finished yet. When it does,
|
|
14
|
+
// `closeTrace` fills it in and triggers the copy-on-error so the cold row
|
|
15
|
+
// reflects the final state (Q4). The truncation's settle handle is stored on
|
|
16
|
+
// the buffer so `closeTrace` can wait for `truncated_at_seq` to land before it
|
|
17
|
+
// copies.
|
|
18
|
+
|
|
19
|
+
import type { Manifold } from '../../core/pipework.js'
|
|
20
|
+
import { getBaseLogger } from '../../core/logging/index.js'
|
|
21
|
+
import { recordFaultFor, faultMessage } from '../../infra/alerts/faults.js'
|
|
22
|
+
import { eq, and, getTableColumns } from '../../data/query/index.js'
|
|
23
|
+
import type { Column } from '../../data/db/types.js'
|
|
24
|
+
import { trace } from '../schema/trace.js'
|
|
25
|
+
import { trackTraceWrite } from './pending-writes.js'
|
|
26
|
+
import { flushSteps } from './flush-steps.js'
|
|
27
|
+
import { withMaintenance } from '../../data/db/maintenance.js'
|
|
28
|
+
import type { DB } from '../../data/db/index.js'
|
|
29
|
+
import type { TraceContext } from '../entry/trace-context.js'
|
|
30
|
+
|
|
31
|
+
/** Fires Q7 truncation: flushes the buffer and stamps `truncated` on the trace row. */
|
|
32
|
+
export function truncateTrace(instance: Manifold, ctx: TraceContext): Promise<void> {
|
|
33
|
+
const truncatedAtSeq = ctx.buffer.truncatedAtSeq
|
|
34
|
+
getBaseLogger().error(
|
|
35
|
+
{ traceId: ctx.id, truncatedAtSeq },
|
|
36
|
+
'Trace truncated — step cap exceeded; the flow DAG analysis missed a branch or unannotated recursion',
|
|
37
|
+
)
|
|
38
|
+
const done = trackTraceWrite(ctx.persisted
|
|
39
|
+
.then(async () => {
|
|
40
|
+
const stepFlush = flushSteps(instance, ctx.buffer.drain())
|
|
41
|
+
const db = instance.pool.getOrCreate(instance.config.database()).drizzle
|
|
42
|
+
const table = trace.table()
|
|
43
|
+
const cols = getTableColumns(table) as Record<'id' | 'openedDay', Column>
|
|
44
|
+
// The pooled connection carries no tenant setting, so the UPDATE runs as a maintenance pass.
|
|
45
|
+
const traceUpdate = withMaintenance(db as unknown as DB, async tx => {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Drizzle's update needs the concrete runtime table type
|
|
47
|
+
await (tx as any).update(table)
|
|
48
|
+
.set({ status: 'truncated', truncatedAtSeq })
|
|
49
|
+
.where(and(eq(cols.id, ctx.id), eq(cols.openedDay, ctx.openedDay)))
|
|
50
|
+
})
|
|
51
|
+
await Promise.all([stepFlush, traceUpdate])
|
|
52
|
+
})
|
|
53
|
+
.catch((err: unknown) => {
|
|
54
|
+
getBaseLogger().error(
|
|
55
|
+
{ err, traceId: ctx.id },
|
|
56
|
+
'Failed to persist trace truncation — the trace row is missing its `truncated` stamp',
|
|
57
|
+
)
|
|
58
|
+
void recordFaultFor(instance, 'trace-write', `trace truncation not persisted: ${faultMessage(err)}`, { traceId: ctx.id, step: 'truncate' })
|
|
59
|
+
}))
|
|
60
|
+
ctx.buffer.markTruncationDone(done)
|
|
61
|
+
return done
|
|
62
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// The column shape shared by the hot `trace` table and the cold
|
|
2
|
+
// `trace_retained` table. A trace is one execution rooted at an entry point
|
|
3
|
+
// (HTTP request, job, cron tick, test); its steps live in `trace_step`.
|
|
4
|
+
//
|
|
5
|
+
// Field descriptors are immutable, so the same record is handed to both
|
|
6
|
+
// `define()` calls — the hot and retained tables are structurally identical
|
|
7
|
+
// and differ only in retention policy.
|
|
8
|
+
//
|
|
9
|
+
// Self-reference (`rootId`, `parentId` → `trace.id`) and forward-reference
|
|
10
|
+
// (`parentStepId` → `trace_step.id`) resolve their targets lazily via the
|
|
11
|
+
// global registry. Importing `trace` / `traceStep` directly would create a
|
|
12
|
+
// load-order trap: `trace-retained.ts` imports this module before `trace.ts`
|
|
13
|
+
// has run, so a direct cycle leaves `trace` in TDZ when `define()` reads
|
|
14
|
+
// `traceFields`. Resolving by name dodges the cycle entirely; the validator
|
|
15
|
+
// catches a bad name. `enforced: false` keeps the brand inheritance — and
|
|
16
|
+
// therefore the validator's recognition that the reuse is intentional —
|
|
17
|
+
// without emitting a physical FK; retention is free to drop ancestor
|
|
18
|
+
// partitions out from under these columns.
|
|
19
|
+
|
|
20
|
+
import { field, definitions } from '../../data/domain/index.js'
|
|
21
|
+
import type { DefinedTable } from '../../data/domain/types.js'
|
|
22
|
+
|
|
23
|
+
const lazyTrace = (): DefinedTable => definitions().get('trace') as DefinedTable
|
|
24
|
+
const lazyTraceStep = (): DefinedTable => definitions().get('trace_step') as DefinedTable
|
|
25
|
+
|
|
26
|
+
export const traceFields = {
|
|
27
|
+
id: field.uuid().brand('TraceId').defaultRandom(),
|
|
28
|
+
// Partition key — the calendar day the trace opened. Retention drops whole
|
|
29
|
+
// day-partitions, so every row carries the day it belongs to.
|
|
30
|
+
openedDay: field.date(),
|
|
31
|
+
// The root of the trace tree. Equals `id` for a root trace.
|
|
32
|
+
rootId: field.uuid().brand('TraceId').references(lazyTrace, 'id', { enforced: false }),
|
|
33
|
+
parentId: field.uuid().brand('TraceId').references(lazyTrace, 'id', { enforced: false }).nullable(),
|
|
34
|
+
parentStepId: field.uuid().brand('TraceStepId').references(lazyTraceStep, 'id', { enforced: false }).nullable(),
|
|
35
|
+
entryKind: field.enum(['http', 'job', 'cron', 'test']),
|
|
36
|
+
status: field.enum(['open', 'closed', 'error', 'truncated', 'expired']),
|
|
37
|
+
tenantId: field.uuid().tenant().nullable(),
|
|
38
|
+
requestId: field.text().nullable(),
|
|
39
|
+
sessionId: field.text().nullable(),
|
|
40
|
+
userId: field.text().nullable(),
|
|
41
|
+
openedAt: field.timestamp(),
|
|
42
|
+
closedAt: field.timestamp().nullable(),
|
|
43
|
+
// Force-close deadline: openedAt + hotRetentionDays. A trace must not outlive
|
|
44
|
+
// its own oldest day-partition.
|
|
45
|
+
expiresAt: field.timestamp(),
|
|
46
|
+
// Set when the step cap is hit and the trace is truncated — the seq at which
|
|
47
|
+
// capture stopped.
|
|
48
|
+
truncatedAtSeq: field.integer().nullable(),
|
|
49
|
+
// The release of the process that opened the trace; null when the app
|
|
50
|
+
// configures none.
|
|
51
|
+
release: field.text().nullable(),
|
|
52
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// The cold `trace_retained` table — structurally identical to `trace`, but
|
|
2
|
+
// holds traces copied out on error so they survive past `hotRetentionDays`.
|
|
3
|
+
// RANGE-partitioned the same way; retention drops day-partitions older than
|
|
4
|
+
// `errorRetentionDays`.
|
|
5
|
+
|
|
6
|
+
import { define, definitions, field } from "../../data/domain/index.js";
|
|
7
|
+
import { traceFields } from './trace-fields.js'
|
|
8
|
+
|
|
9
|
+
export const traceRetained = define('trace_retained', {
|
|
10
|
+
...traceFields,
|
|
11
|
+
// A retained row is a *copy* of a hot row and holds the same id value — the
|
|
12
|
+
// same TraceId id-space, not a fresh one. The enforced:false reference to
|
|
13
|
+
// `trace.id` emits no physical FK (retention may drop the hot partition out
|
|
14
|
+
// from under the copy) but tells the brand-uniqueness validator the TraceId
|
|
15
|
+
// reuse is intentional (isInheritedFromFK), mirroring trace-fields' rootId.
|
|
16
|
+
// Thunk form defers resolution past the import cycle — `trace.ts` has not run
|
|
17
|
+
// yet when this module loads — so the brand is restated explicitly.
|
|
18
|
+
id: field.uuid().brand('TraceId').references(() => definitions().get('trace')!, 'id', { enforced: false }).defaultRandom(),
|
|
19
|
+
}, {
|
|
20
|
+
primaryKey: ['id', 'openedDay'],
|
|
21
|
+
partitionBy: { strategy: 'range', column: 'openedDay' },
|
|
22
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// The column shape shared by the hot `trace_step` table and the cold
|
|
2
|
+
// `trace_step_retained` table. One row per flow step that executed under an
|
|
3
|
+
// active Flow.
|
|
4
|
+
//
|
|
5
|
+
// Field descriptors are immutable, so the same record is handed to both
|
|
6
|
+
// `define()` calls.
|
|
7
|
+
//
|
|
8
|
+
// `traceId` and `parentStepId` declare logical references resolved lazily via
|
|
9
|
+
// the registry — see the same pattern in `trace-fields.ts`. The actual
|
|
10
|
+
// `trace` FK lives in the composite (`traceId`, `traceDay`) on the table; the
|
|
11
|
+
// field-level reference exists only to inherit the brand and surface a
|
|
12
|
+
// `references` annotation to the validator.
|
|
13
|
+
|
|
14
|
+
import { field, definitions } from '../../data/domain/index.js'
|
|
15
|
+
import { schema } from '../../data/schema/namespace.js'
|
|
16
|
+
import type { DefinedTable } from '../../data/domain/types.js'
|
|
17
|
+
|
|
18
|
+
const lazyTrace = (): DefinedTable => definitions().get('trace') as DefinedTable
|
|
19
|
+
const lazyTraceStep = (): DefinedTable => definitions().get('trace_step') as DefinedTable
|
|
20
|
+
|
|
21
|
+
export const traceStepFields = {
|
|
22
|
+
id: field.uuid().brand('TraceStepId').defaultRandom(),
|
|
23
|
+
// Partition key — the parent trace's `openedDay`, NOT the step's own
|
|
24
|
+
// timestamp. This keeps the foreign key into `trace` partition-local: a
|
|
25
|
+
// step and its trace always sit in the same day-partition, so the two
|
|
26
|
+
// tables' partitions retire together.
|
|
27
|
+
traceDay: field.date(),
|
|
28
|
+
traceId: field.uuid().brand('TraceId').references(lazyTrace, 'id', { enforced: false }),
|
|
29
|
+
// The parent trace's tenant, stamped on every step so the row-level security policy can guard steps like traces.
|
|
30
|
+
tenantId: field.uuid().tenant().nullable(),
|
|
31
|
+
// Spawn order within the trace. Branch vs step is an edge property, not a
|
|
32
|
+
// node property — `seq` only records sequencing.
|
|
33
|
+
seq: field.integer(),
|
|
34
|
+
parentStepId: field.uuid().brand('TraceStepId').references(lazyTraceStep, 'id', { enforced: false }).nullable(),
|
|
35
|
+
// The `path:symbol` identity of the flow step, matching the annotation's
|
|
36
|
+
// upstream/downstream targets.
|
|
37
|
+
flowStepRef: field.text(),
|
|
38
|
+
status: field.enum(['ok', 'error']),
|
|
39
|
+
startedAt: field.timestamp(),
|
|
40
|
+
completedAt: field.timestamp().nullable(),
|
|
41
|
+
durationMicros: field.bigint().nullable(),
|
|
42
|
+
capturedInputs: field.jsonb(schema.check.json()).nullable(),
|
|
43
|
+
error: field.jsonb(schema.check.json()).nullable(),
|
|
44
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// The cold `trace_step_retained` table — structurally identical to
|
|
2
|
+
// `trace_step`, holding steps copied out on error. Its foreign key targets
|
|
3
|
+
// `trace_retained`: copy-on-error writes the trace and its steps together, so
|
|
4
|
+
// referential integrity holds in the cold tables exactly as it does in the hot
|
|
5
|
+
// ones.
|
|
6
|
+
|
|
7
|
+
import { define, definitions, field } from "../../data/domain/index.js";
|
|
8
|
+
import { traceStepFields } from './trace-step-fields.js'
|
|
9
|
+
import { traceRetained } from './trace-retained.js'
|
|
10
|
+
|
|
11
|
+
export const traceStepRetained = define('trace_step_retained', {
|
|
12
|
+
...traceStepFields,
|
|
13
|
+
// Same id-space as the hot `trace_step` row it mirrors — see trace-retained
|
|
14
|
+
// for why the enforced:false self-space reference is what keeps the
|
|
15
|
+
// brand-uniqueness validator from flagging the intentional TraceStepId reuse.
|
|
16
|
+
id: field.uuid().brand('TraceStepId').references(() => definitions().get('trace_step')!, 'id', { enforced: false }).defaultRandom(),
|
|
17
|
+
}, {
|
|
18
|
+
primaryKey: ['id', 'traceDay'],
|
|
19
|
+
partitionBy: { strategy: 'range', column: 'traceDay' },
|
|
20
|
+
foreignKeys: [{
|
|
21
|
+
columns: ['traceId', 'traceDay'],
|
|
22
|
+
references: { definition: traceRetained, columns: ['id', 'openedDay'] },
|
|
23
|
+
onDelete: 'cascade',
|
|
24
|
+
}],
|
|
25
|
+
})
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// The hot `trace_step` table — one row per flow step executed under a Flow.
|
|
2
|
+
// Partitioned by `traceDay` (the parent trace's `openedDay`), so the foreign
|
|
3
|
+
// key into `trace` is partition-local and both tables' partitions retire
|
|
4
|
+
// together.
|
|
5
|
+
|
|
6
|
+
import { define } from '../../data/domain/index.js'
|
|
7
|
+
import { traceStepFields } from './trace-step-fields.js'
|
|
8
|
+
import { trace } from './trace.js'
|
|
9
|
+
|
|
10
|
+
export const traceStep = define('trace_step', traceStepFields, {
|
|
11
|
+
primaryKey: ['id', 'traceDay'],
|
|
12
|
+
partitionBy: { strategy: 'range', column: 'traceDay' },
|
|
13
|
+
foreignKeys: [{
|
|
14
|
+
columns: ['traceId', 'traceDay'],
|
|
15
|
+
references: { definition: trace, columns: ['id', 'openedDay'] },
|
|
16
|
+
onDelete: 'cascade',
|
|
17
|
+
}],
|
|
18
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// The hot `trace` table — one row per execution, rooted at an entry point.
|
|
2
|
+
// RANGE-partitioned by `openedDay`; retention drops day-partitions older than
|
|
3
|
+
// `hotRetentionDays`. Errored traces are copied to `trace_retained` before
|
|
4
|
+
// their partition is dropped.
|
|
5
|
+
|
|
6
|
+
import { define } from '../../data/domain/index.js'
|
|
7
|
+
import { traceFields } from './trace-fields.js'
|
|
8
|
+
|
|
9
|
+
export const trace = define('trace', traceFields, {
|
|
10
|
+
primaryKey: ['id', 'openedDay'],
|
|
11
|
+
partitionBy: { strategy: 'range', column: 'openedDay' },
|
|
12
|
+
})
|