pipework 0.252.0 → 0.252.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/package.json +4 -3
- package/src/async/jobs/abortable-delay.ts +18 -0
- package/src/async/jobs/claims.ts +52 -0
- package/src/async/jobs/cron.ts +179 -0
- package/src/async/jobs/errors.ts +56 -0
- package/src/async/jobs/exclusion.ts +117 -0
- package/src/async/jobs/execute.ts +219 -0
- package/src/async/jobs/index.ts +10 -0
- package/src/async/jobs/listener.ts +135 -0
- package/src/async/jobs/namespace.ts +20 -0
- package/src/async/jobs/queue-door.ts +44 -0
- package/src/async/jobs/queue.ts +1012 -0
- package/src/async/jobs/run-script.ts +67 -0
- package/src/async/jobs/scheduler.ts +218 -0
- package/src/async/jobs/schedules-table.ts +37 -0
- package/src/async/jobs/serialize-error.ts +48 -0
- package/src/async/jobs/table.ts +191 -0
- package/src/async/pipeline/define.ts +53 -0
- package/src/async/pipeline/errors.ts +35 -0
- package/src/async/pipeline/execute.ts +53 -0
- package/src/async/pipeline/index.ts +13 -0
- package/src/async/pipeline/namespace.ts +12 -0
- package/src/async/pipeline/resume.ts +67 -0
- package/src/async/pipeline/run-steps.ts +98 -0
- package/src/async/pipeline/types.ts +57 -0
- package/src/async/state-machine/define.ts +64 -0
- package/src/async/state-machine/errors.ts +29 -0
- package/src/async/state-machine/index.ts +3 -0
- package/src/async/state-machine/namespace.ts +12 -0
- package/src/async/state-machine/transition.ts +90 -0
- package/src/async/state-machine/types.ts +37 -0
- package/src/async/steps/errors.ts +31 -0
- package/src/async/steps/graph.ts +1214 -0
- package/src/async/steps/hash.ts +40 -0
- package/src/async/steps/index.ts +7 -0
- package/src/async/steps/namespace.ts +7 -0
- package/src/async/steps/table.ts +97 -0
- package/src/async/steps/types.ts +318 -0
- package/src/audit/chain/index.ts +9 -0
- package/src/audit/chain/install.ts +113 -0
- package/src/audit/chain/retire.ts +52 -0
- package/src/audit/chain/verify.ts +257 -0
- package/src/audit/query/cursor.ts +37 -0
- package/src/audit/query/index.ts +9 -0
- package/src/audit/query/query.ts +223 -0
- package/src/audit/schema/audit-record-fields.ts +68 -0
- package/src/audit/schema/audit-record.ts +23 -0
- package/src/auth/auth/audit.ts +31 -0
- package/src/auth/auth/chain.ts +84 -0
- package/src/auth/auth/cookie.ts +136 -0
- package/src/auth/auth/email-links.ts +311 -0
- package/src/auth/auth/guard.ts +128 -0
- package/src/auth/auth/index.ts +18 -0
- package/src/auth/auth/multi-org.ts +337 -0
- package/src/auth/auth/namespace.ts +34 -0
- package/src/auth/auth/parse-expiry.ts +13 -0
- package/src/auth/auth/passwords.ts +110 -0
- package/src/auth/auth/schema.ts +110 -0
- package/src/auth/auth/sessions.ts +565 -0
- package/src/auth/auth/sign-in.ts +156 -0
- package/src/auth/auth/signing-keys.ts +69 -0
- package/src/auth/auth/types.ts +26 -0
- package/src/auth/auth/uuid.ts +10 -0
- package/src/auth/rbac/cache.ts +55 -0
- package/src/auth/rbac/check.ts +30 -0
- package/src/auth/rbac/create.ts +35 -0
- package/src/auth/rbac/index.ts +5 -0
- package/src/auth/rbac/middleware.ts +20 -0
- package/src/auth/rbac/namespace.ts +15 -0
- package/src/auth/rbac/resolve.ts +31 -0
- package/src/auth/rbac/schema.sql +31 -0
- package/src/auth/rbac/seed.ts +67 -0
- package/src/auth/rbac/tables.ts +32 -0
- package/src/auth/rbac/types.ts +65 -0
- package/src/auth/tenant/extract.ts +33 -0
- package/src/auth/tenant/in-tenant.ts +49 -0
- package/src/auth/tenant/index.ts +7 -0
- package/src/auth/tenant/namespace.ts +23 -0
- package/src/auth/tenant/propagate.ts +20 -0
- package/src/auth/tenant/rls.ts +120 -0
- package/src/auth/tenant/scope.ts +33 -0
- package/src/auth/tenant/scoped-db.ts +581 -0
- package/src/auth/tenant/types.ts +14 -0
- package/src/auth/tenant/validate.ts +27 -0
- package/src/cli/commands/add.ts +158 -0
- package/src/cli/commands/alerts.ts +98 -0
- package/src/cli/commands/check.ts +1418 -0
- package/src/cli/commands/codemod.ts +78 -0
- package/src/cli/commands/db.ts +356 -0
- package/src/cli/commands/dev.ts +101 -0
- package/src/cli/commands/generate.ts +75 -0
- package/src/cli/commands/init.ts +36 -0
- package/src/cli/commands/install.ts +28 -0
- package/src/cli/commands/lint.ts +62 -0
- package/src/cli/commands/migrate.ts +132 -0
- package/src/cli/commands/openapi.ts +63 -0
- package/src/cli/commands/remove.ts +72 -0
- package/src/cli/commands/run.ts +50 -0
- package/src/cli/commands/scope.ts +54 -0
- package/src/cli/commands/serve.ts +68 -0
- package/src/cli/commands/shard.ts +31 -0
- package/src/cli/commands/shared/config-pipework-version.ts +28 -0
- package/src/cli/commands/shared/find-config.ts +22 -0
- package/src/cli/commands/shared/load-config.ts +35 -0
- package/src/cli/commands/shared/pnpm-install.ts +95 -0
- package/src/cli/commands/shared/report-removed.ts +8 -0
- package/src/cli/commands/sync.ts +32 -0
- package/src/cli/commands/test.ts +307 -0
- package/src/cli/commands/upgrade.ts +48 -0
- package/src/cli/dev-bootstrap.ts +24 -0
- package/src/cli/errors.ts +10 -0
- package/src/cli/index.ts +303 -0
- package/src/cli/output.ts +17 -0
- package/src/cli/port.ts +15 -0
- package/src/cli/surface-kinds.ts +20 -0
- package/src/client/index.ts +4 -0
- package/src/client/poll.ts +130 -0
- package/src/client/report-fault.ts +119 -0
- package/src/core/config/app-pool.ts +19 -0
- package/src/core/config/aws-env.ts +29 -0
- package/src/core/config/base-dir.ts +24 -0
- package/src/core/config/discover.ts +64 -0
- package/src/core/config/env-resolve.ts +87 -0
- package/src/core/config/env-types.ts +116 -0
- package/src/core/config/env.ts +55 -0
- package/src/core/config/errors.ts +9 -0
- package/src/core/config/import-config.ts +40 -0
- package/src/core/config/index.ts +8 -0
- package/src/core/config/load.ts +417 -0
- package/src/core/config/namespace.ts +14 -0
- package/src/core/config/resolve.ts +195 -0
- package/src/core/config/schema.ts +488 -0
- package/src/core/config/statement-observer.ts +48 -0
- package/src/core/config/ts-inline-hooks.ts +75 -0
- package/src/core/config/ts-register.ts +4 -0
- package/src/core/config/ts-resolve-hooks.ts +101 -0
- package/src/core/errors/base.ts +49 -0
- package/src/core/errors/http.ts +146 -0
- package/src/core/errors/index.ts +2 -0
- package/src/core/errors/namespace.ts +31 -0
- package/src/core/lifecycle/drain.ts +33 -0
- package/src/core/lifecycle/health.ts +72 -0
- package/src/core/lifecycle/index.ts +4 -0
- package/src/core/lifecycle/namespace.ts +7 -0
- package/src/core/lifecycle/startup.ts +102 -0
- package/src/core/lifecycle/types.ts +36 -0
- package/src/core/logging/context.ts +60 -0
- package/src/core/logging/error-chain.ts +68 -0
- package/src/core/logging/index.ts +5 -0
- package/src/core/logging/logger.ts +65 -0
- package/src/core/logging/namespace.ts +16 -0
- package/src/core/logging/proxy.ts +22 -0
- package/src/core/logging/redact-match.ts +24 -0
- package/src/core/logging/types.ts +47 -0
- package/src/core/pipework.ts +566 -0
- package/src/core/runtime/broker.ts +69 -0
- package/src/core/surface/http.ts +133 -0
- package/src/core/surface/index.ts +11 -0
- package/src/core/surface/job-timeout.ts +40 -0
- package/src/core/surface/namespace.ts +13 -0
- package/src/core/surface/script.ts +33 -0
- package/src/core/surface/start.ts +142 -0
- package/src/core/surface/types.ts +225 -0
- package/src/core/surface/validate.ts +88 -0
- package/src/core/surface/worker.ts +528 -0
- package/src/core/validation/connectivity.ts +49 -0
- package/src/core/validation/domain.ts +99 -0
- package/src/core/validation/index.ts +5 -0
- package/src/core/validation/queue-tables.ts +312 -0
- package/src/core/validation/rls-role.ts +138 -0
- package/src/core/validation/startup.ts +51 -0
- package/src/core/validation/surfaces.ts +65 -0
- package/src/core/validation/types.ts +25 -0
- package/src/data/db/advisory-lock.ts +55 -0
- package/src/data/db/aggregates.ts +172 -0
- package/src/data/db/array-elements.ts +111 -0
- package/src/data/db/bulk-set.ts +53 -0
- package/src/data/db/col/index.ts +14 -0
- package/src/data/db/composed.ts +53 -0
- package/src/data/db/db.ts +276 -0
- package/src/data/db/excluded.ts +16 -0
- package/src/data/db/expressions.ts +473 -0
- package/src/data/db/filter.ts +90 -0
- package/src/data/db/function-source.ts +114 -0
- package/src/data/db/identifiers.ts +16 -0
- package/src/data/db/idx/index.ts +9 -0
- package/src/data/db/in-list.ts +49 -0
- package/src/data/db/index.ts +9 -0
- package/src/data/db/insert-split.ts +137 -0
- package/src/data/db/instrumentation.ts +82 -0
- package/src/data/db/maintenance.ts +28 -0
- package/src/data/db/namespace.ts +107 -0
- package/src/data/db/owner-labels.ts +9 -0
- package/src/data/db/pool.ts +187 -0
- package/src/data/db/query-label.ts +13 -0
- package/src/data/db/query-watch.ts +116 -0
- package/src/data/db/raw-client-warning.ts +37 -0
- package/src/data/db/readonly.ts +23 -0
- package/src/data/db/reservation.ts +151 -0
- package/src/data/db/schema-features.ts +14 -0
- package/src/data/db/serializable.ts +83 -0
- package/src/data/db/sql.ts +1 -0
- package/src/data/db/timeouts.ts +76 -0
- package/src/data/db/types.ts +18 -0
- package/src/data/db/unbound.ts +33 -0
- package/src/data/db/values.ts +29 -0
- package/src/data/domain/brand.ts +15 -0
- package/src/data/domain/build-factory.ts +193 -0
- package/src/data/domain/build-schema.ts +161 -0
- package/src/data/domain/build-table.ts +355 -0
- package/src/data/domain/define.ts +239 -0
- package/src/data/domain/external-registry.ts +34 -0
- package/src/data/domain/external.ts +77 -0
- package/src/data/domain/field.ts +279 -0
- package/src/data/domain/index.ts +13 -0
- package/src/data/domain/naming.ts +6 -0
- package/src/data/domain/projections.ts +57 -0
- package/src/data/domain/trace-safe-projection.ts +31 -0
- package/src/data/domain/traits.ts +108 -0
- package/src/data/domain/types.ts +289 -0
- package/src/data/jsonb/composed.ts +18 -0
- package/src/data/jsonb/index.ts +1 -0
- package/src/data/jsonb/namespace.ts +30 -0
- package/src/data/jsonb/query.ts +86 -0
- package/src/data/migrate/append-only-generate.ts +47 -0
- package/src/data/migrate/applied.ts +47 -0
- package/src/data/migrate/apply.ts +309 -0
- package/src/data/migrate/check.ts +119 -0
- package/src/data/migrate/diff.ts +357 -0
- package/src/data/migrate/door-generate.ts +130 -0
- package/src/data/migrate/framework-rls.ts +58 -0
- package/src/data/migrate/generate.ts +201 -0
- package/src/data/migrate/history.ts +215 -0
- package/src/data/migrate/index.ts +9 -0
- package/src/data/migrate/internal-definitions.ts +175 -0
- package/src/data/migrate/post-process.ts +73 -0
- package/src/data/migrate/pragma.ts +73 -0
- package/src/data/migrate/provision-framework.ts +147 -0
- package/src/data/migrate/rls-generate.ts +61 -0
- package/src/data/migrate/run.ts +124 -0
- package/src/data/migrate/safety.ts +167 -0
- package/src/data/migrate/snapshot.ts +368 -0
- package/src/data/migrate/sql-emit.ts +392 -0
- package/src/data/migrate/statements.ts +312 -0
- package/src/data/query/alias.ts +126 -0
- package/src/data/query/batch.ts +8 -0
- package/src/data/query/cache/core/cache.ts +78 -0
- package/src/data/query/cache/core/index.ts +1 -0
- package/src/data/query/cache/core/types.ts +29 -0
- package/src/data/query/cache/readme.md +230 -0
- package/src/data/query/casing.ts +76 -0
- package/src/data/query/collation.ts +11 -0
- package/src/data/query/column-builder.ts +370 -0
- package/src/data/query/column.ts +150 -0
- package/src/data/query/entity.ts +42 -0
- package/src/data/query/errors.ts +33 -0
- package/src/data/query/index.ts +14 -0
- package/src/data/query/logger.ts +47 -0
- package/src/data/query/operations.ts +45 -0
- package/src/data/query/pg-core/alias.ts +12 -0
- package/src/data/query/pg-core/checks.ts +32 -0
- package/src/data/query/pg-core/columns/all.ts +71 -0
- package/src/data/query/pg-core/columns/bigint.ts +110 -0
- package/src/data/query/pg-core/columns/bigserial.ts +128 -0
- package/src/data/query/pg-core/columns/boolean.ts +43 -0
- package/src/data/query/pg-core/columns/char.ts +85 -0
- package/src/data/query/pg-core/columns/cidr.ts +43 -0
- package/src/data/query/pg-core/columns/common.ts +366 -0
- package/src/data/query/pg-core/columns/custom.ts +232 -0
- package/src/data/query/pg-core/columns/date.common.ts +15 -0
- package/src/data/query/pg-core/columns/date.ts +112 -0
- package/src/data/query/pg-core/columns/double-precision.ts +55 -0
- package/src/data/query/pg-core/columns/enum.ts +201 -0
- package/src/data/query/pg-core/columns/index.ts +35 -0
- package/src/data/query/pg-core/columns/inet.ts +43 -0
- package/src/data/query/pg-core/columns/int.common.ts +57 -0
- package/src/data/query/pg-core/columns/integer.ts +53 -0
- package/src/data/query/pg-core/columns/interval.ts +83 -0
- package/src/data/query/pg-core/columns/json.ts +58 -0
- package/src/data/query/pg-core/columns/jsonb.ts +56 -0
- package/src/data/query/pg-core/columns/line.ts +117 -0
- package/src/data/query/pg-core/columns/macaddr.ts +43 -0
- package/src/data/query/pg-core/columns/macaddr8.ts +43 -0
- package/src/data/query/pg-core/columns/numeric.ts +227 -0
- package/src/data/query/pg-core/columns/point.ts +127 -0
- package/src/data/query/pg-core/columns/postgis_extension/geometry.ts +119 -0
- package/src/data/query/pg-core/columns/postgis_extension/utils.ts +47 -0
- package/src/data/query/pg-core/columns/real.ts +58 -0
- package/src/data/query/pg-core/columns/serial.ts +55 -0
- package/src/data/query/pg-core/columns/smallint.ts +53 -0
- package/src/data/query/pg-core/columns/smallserial.ts +60 -0
- package/src/data/query/pg-core/columns/text.ts +67 -0
- package/src/data/query/pg-core/columns/time.ts +72 -0
- package/src/data/query/pg-core/columns/timestamp.ts +163 -0
- package/src/data/query/pg-core/columns/uuid.ts +51 -0
- package/src/data/query/pg-core/columns/varchar.ts +89 -0
- package/src/data/query/pg-core/columns/vector_extension/bit.ts +68 -0
- package/src/data/query/pg-core/columns/vector_extension/halfvec.ts +80 -0
- package/src/data/query/pg-core/columns/vector_extension/sparsevec.ts +67 -0
- package/src/data/query/pg-core/columns/vector_extension/vector.ts +80 -0
- package/src/data/query/pg-core/db.ts +674 -0
- package/src/data/query/pg-core/dialect.ts +1404 -0
- package/src/data/query/pg-core/expressions.ts +25 -0
- package/src/data/query/pg-core/foreign-keys.ts +130 -0
- package/src/data/query/pg-core/index.ts +21 -0
- package/src/data/query/pg-core/indexes.ts +276 -0
- package/src/data/query/pg-core/policies.ts +56 -0
- package/src/data/query/pg-core/primary-keys.ts +62 -0
- package/src/data/query/pg-core/query-builders/count.ts +86 -0
- package/src/data/query/pg-core/query-builders/delete.ts +293 -0
- package/src/data/query/pg-core/query-builders/index.ts +7 -0
- package/src/data/query/pg-core/query-builders/insert.ts +452 -0
- package/src/data/query/pg-core/query-builders/query-builder.ts +123 -0
- package/src/data/query/pg-core/query-builders/query.ts +157 -0
- package/src/data/query/pg-core/query-builders/raw.ts +49 -0
- package/src/data/query/pg-core/query-builders/refresh-materialized-view.ts +108 -0
- package/src/data/query/pg-core/query-builders/select.ts +1346 -0
- package/src/data/query/pg-core/query-builders/select.types.ts +437 -0
- package/src/data/query/pg-core/query-builders/update.ts +626 -0
- package/src/data/query/pg-core/roles.ts +41 -0
- package/src/data/query/pg-core/schema.ts +72 -0
- package/src/data/query/pg-core/sequence.ts +41 -0
- package/src/data/query/pg-core/session.ts +292 -0
- package/src/data/query/pg-core/subquery.ts +46 -0
- package/src/data/query/pg-core/table.ts +252 -0
- package/src/data/query/pg-core/unique-constraint.ts +73 -0
- package/src/data/query/pg-core/utils/array.ts +95 -0
- package/src/data/query/pg-core/utils/index.ts +1 -0
- package/src/data/query/pg-core/utils.ts +104 -0
- package/src/data/query/pg-core/view-base.ts +14 -0
- package/src/data/query/pg-core/view-common.ts +1 -0
- package/src/data/query/pg-core/view.ts +435 -0
- package/src/data/query/pg-core/with-builder.ts +41 -0
- package/src/data/query/postgres-js/README.md +46 -0
- package/src/data/query/postgres-js/array-parser.ts +45 -0
- package/src/data/query/postgres-js/driver-error-boundary.ts +149 -0
- package/src/data/query/postgres-js/driver.ts +163 -0
- package/src/data/query/postgres-js/index.ts +2 -0
- package/src/data/query/postgres-js/session.ts +234 -0
- package/src/data/query/primary-key.ts +11 -0
- package/src/data/query/query-builders/query-builder.ts +19 -0
- package/src/data/query/query-builders/select.types.ts +175 -0
- package/src/data/query/query-promise.ts +35 -0
- package/src/data/query/relations.ts +725 -0
- package/src/data/query/runnable-query.ts +12 -0
- package/src/data/query/selection-proxy.ts +121 -0
- package/src/data/query/session.ts +8 -0
- package/src/data/query/sql/expressions/conditions.ts +741 -0
- package/src/data/query/sql/expressions/index.ts +2 -0
- package/src/data/query/sql/expressions/select.ts +45 -0
- package/src/data/query/sql/functions/aggregate.ts +129 -0
- package/src/data/query/sql/functions/index.ts +2 -0
- package/src/data/query/sql/functions/vector.ts +178 -0
- package/src/data/query/sql/index.ts +3 -0
- package/src/data/query/sql/sql.ts +794 -0
- package/src/data/query/subquery.ts +53 -0
- package/src/data/query/table.ts +208 -0
- package/src/data/query/table.utils.ts +2 -0
- package/src/data/query/tracing-utils.ts +3 -0
- package/src/data/query/tracing.ts +11 -0
- package/src/data/query/utils.ts +357 -0
- package/src/data/query/version.ts +4 -0
- package/src/data/query/view-common.ts +1 -0
- package/src/data/schema/branded.ts +13 -0
- package/src/data/schema/generated/coerce.ts +5 -0
- package/src/data/schema/generated/combinator.ts +6 -0
- package/src/data/schema/generated/encoding.ts +5 -0
- package/src/data/schema/generated/error.ts +6 -0
- package/src/data/schema/generated/format.ts +5 -0
- package/src/data/schema/generated/type-constructor.ts +10 -0
- package/src/data/schema/generated/type.ts +6 -0
- package/src/data/schema/index.ts +6 -0
- package/src/data/schema/json-schema.ts +33 -0
- package/src/data/schema/namespace.ts +55 -0
- package/src/data/schema/parse.ts +39 -0
- package/src/data/schema/types.ts +39 -0
- package/src/data/temporal/append-only.ts +134 -0
- package/src/data/temporal/close.ts +27 -0
- package/src/data/temporal/columns.ts +10 -0
- package/src/data/temporal/definition-queries.ts +70 -0
- package/src/data/temporal/errors.ts +10 -0
- package/src/data/temporal/get-current.ts +22 -0
- package/src/data/temporal/index.ts +9 -0
- package/src/data/temporal/namespace.ts +36 -0
- package/src/data/temporal/query.ts +25 -0
- package/src/data/temporal/resolve.ts +17 -0
- package/src/data/temporal/revise.ts +67 -0
- package/src/data/temporal/types.ts +22 -0
- package/src/data/valve/artifact.ts +33 -0
- package/src/data/valve/contract-diff.ts +21 -0
- package/src/data/valve/cross.ts +57 -0
- package/src/data/valve/crossing-ledger.ts +50 -0
- package/src/data/valve/decision.ts +44 -0
- package/src/data/valve/durable-crossing.ts +52 -0
- package/src/data/valve/execute-crossing.ts +77 -0
- package/src/data/valve/faucet.ts +56 -0
- package/src/data/valve/gate.ts +114 -0
- package/src/data/valve/graph.ts +77 -0
- package/src/data/valve/index.ts +53 -0
- package/src/data/valve/namespace.ts +57 -0
- package/src/data/valve/registry.ts +50 -0
- package/src/data/valve/schema/valve-crossing-fields.ts +23 -0
- package/src/data/valve/schema/valve-crossing.ts +9 -0
- package/src/data/valve/supply.ts +154 -0
- package/src/data/valve/types.ts +143 -0
- package/src/data/vector/columns.ts +27 -0
- package/src/data/vector/index.ts +4 -0
- package/src/data/vector/namespace.ts +33 -0
- package/src/data/vector/query.ts +85 -0
- package/src/data/vector/validate.ts +16 -0
- package/src/data/write/audit/actor.ts +15 -0
- package/src/data/write/audit/audit-columns.ts +18 -0
- package/src/data/write/audit/audit-select.ts +111 -0
- package/src/data/write/audit/bound-transaction.ts +14 -0
- package/src/data/write/audit/cte-compile.ts +32 -0
- package/src/data/write/audit/decode-returning.ts +47 -0
- package/src/data/write/audit/final-select.ts +43 -0
- package/src/data/write/audit/infra-audit.ts +36 -0
- package/src/data/write/audit/primary-key.ts +65 -0
- package/src/data/write/audit/projection.ts +41 -0
- package/src/data/write/audit/read-touches.ts +86 -0
- package/src/data/write/audit/touch-match.ts +78 -0
- package/src/data/write/audit/verb-delete.ts +62 -0
- package/src/data/write/audit/verb-insert.ts +36 -0
- package/src/data/write/audit/verb-select.ts +47 -0
- package/src/data/write/audit/verb-update.ts +60 -0
- package/src/data/write/audit/verb-upsert.ts +104 -0
- package/src/data/write/conflict.ts +43 -0
- package/src/data/write/delete.ts +38 -0
- package/src/data/write/execute.ts +243 -0
- package/src/data/write/index.ts +11 -0
- package/src/data/write/insert.ts +63 -0
- package/src/data/write/state.ts +43 -0
- package/src/data/write/update.ts +54 -0
- package/src/data/write/upsert.ts +58 -0
- package/src/data/write/values.ts +19 -0
- package/src/index.ts +230 -0
- package/src/infra/access-links/code.ts +70 -0
- package/src/infra/access-links/handle.ts +892 -0
- package/src/infra/access-links/index.ts +9 -0
- package/src/infra/access-links/namespace.ts +30 -0
- package/src/infra/access-links/person-check.ts +177 -0
- package/src/infra/access-links/schema.ts +71 -0
- package/src/infra/alerts/async-sources.ts +231 -0
- package/src/infra/alerts/audit.ts +36 -0
- package/src/infra/alerts/beat.ts +123 -0
- package/src/infra/alerts/client-faults.ts +111 -0
- package/src/infra/alerts/faults.ts +156 -0
- package/src/infra/alerts/handle.ts +778 -0
- package/src/infra/alerts/http.ts +192 -0
- package/src/infra/alerts/index.ts +12 -0
- package/src/infra/alerts/infra-sources.ts +180 -0
- package/src/infra/alerts/namespace.ts +81 -0
- package/src/infra/alerts/redact.ts +21 -0
- package/src/infra/alerts/request-faults.ts +41 -0
- package/src/infra/alerts/schema.ts +124 -0
- package/src/infra/alerts/sinks.ts +125 -0
- package/src/infra/alerts/source-options.ts +26 -0
- package/src/infra/alerts/sources.ts +503 -0
- package/src/infra/alerts/subsystem-sources.ts +137 -0
- package/src/infra/audit/emit.ts +87 -0
- package/src/infra/audit/index.ts +2 -0
- package/src/infra/audit/namespace.ts +22 -0
- package/src/infra/audit/schema.sql +35 -0
- package/src/infra/audit/types.ts +18 -0
- package/src/infra/aws/credentials.ts +147 -0
- package/src/infra/aws/sigv4.ts +140 -0
- package/src/infra/cache/create.ts +58 -0
- package/src/infra/cache/entry.ts +81 -0
- package/src/infra/cache/index.ts +4 -0
- package/src/infra/cache/namespace.ts +10 -0
- package/src/infra/cache/tenant.ts +93 -0
- package/src/infra/cache/types.ts +24 -0
- package/src/infra/crawl/audit.ts +35 -0
- package/src/infra/crawl/errors.ts +25 -0
- package/src/infra/crawl/handle.ts +693 -0
- package/src/infra/crawl/index.ts +9 -0
- package/src/infra/crawl/links.ts +160 -0
- package/src/infra/crawl/namespace.ts +36 -0
- package/src/infra/crawl/robots.ts +100 -0
- package/src/infra/crawl/schema.ts +89 -0
- package/src/infra/credit-line/handle.ts +883 -0
- package/src/infra/credit-line/index.ts +6 -0
- package/src/infra/credit-line/namespace.ts +7 -0
- package/src/infra/credit-line/schema.ts +96 -0
- package/src/infra/credits/handle.ts +706 -0
- package/src/infra/credits/index.ts +5 -0
- package/src/infra/credits/namespace.ts +7 -0
- package/src/infra/credits/schema.ts +83 -0
- package/src/infra/email/audit.ts +36 -0
- package/src/infra/email/inbound.ts +622 -0
- package/src/infra/email/index.ts +11 -0
- package/src/infra/email/mail.ts +517 -0
- package/src/infra/email/mime.ts +447 -0
- package/src/infra/email/namespace.ts +22 -0
- package/src/infra/email/providers.ts +111 -0
- package/src/infra/email/schema.ts +96 -0
- package/src/infra/email/sns.ts +200 -0
- package/src/infra/email/unsubscribe.ts +44 -0
- package/src/infra/fetch/address.ts +88 -0
- package/src/infra/fetch/connect-retry.ts +87 -0
- package/src/infra/fetch/handle.ts +329 -0
- package/src/infra/fetch/index.ts +7 -0
- package/src/infra/fetch/namespace.ts +70 -0
- package/src/infra/idempotency/index.ts +3 -0
- package/src/infra/idempotency/middleware.ts +87 -0
- package/src/infra/idempotency/store.ts +92 -0
- package/src/infra/idempotency/types.ts +30 -0
- package/src/infra/join-requests/handle.ts +312 -0
- package/src/infra/join-requests/index.ts +2 -0
- package/src/infra/join-requests/namespace.ts +7 -0
- package/src/infra/join-requests/schema.ts +33 -0
- package/src/infra/outbox/core.ts +165 -0
- package/src/infra/quota/errors.ts +32 -0
- package/src/infra/quota/handle.ts +215 -0
- package/src/infra/quota/index.ts +5 -0
- package/src/infra/quota/namespace.ts +7 -0
- package/src/infra/quota/schema.ts +15 -0
- package/src/infra/storage/backend.ts +34 -0
- package/src/infra/storage/handle.ts +513 -0
- package/src/infra/storage/index.ts +9 -0
- package/src/infra/storage/local.ts +104 -0
- package/src/infra/storage/namespace.ts +13 -0
- package/src/infra/storage/s3.ts +257 -0
- package/src/infra/storage/schema.ts +24 -0
- package/src/infra/support/handle.ts +854 -0
- package/src/infra/support/http.ts +229 -0
- package/src/infra/support/index.ts +7 -0
- package/src/infra/support/namespace.ts +12 -0
- package/src/infra/support/schema.ts +96 -0
- package/src/infra/webhook/inbound.ts +45 -0
- package/src/infra/webhook/index.ts +5 -0
- package/src/infra/webhook/namespace.ts +24 -0
- package/src/infra/webhook/outbound.ts +315 -0
- package/src/infra/webhook/sign.ts +32 -0
- package/src/infra/webhook/verify.ts +82 -0
- package/src/invariants/assert.ts +26 -0
- package/src/invariants/index.ts +1 -0
- package/src/lint/config.ts +56 -0
- package/src/lint/doctrine.ts +163 -0
- package/src/lint/include.ts +97 -0
- package/src/lint/index.ts +3 -0
- package/src/lint/preset.ts +10 -0
- package/src/lint/resolver.ts +218 -0
- package/src/lint/rules/no-reexports.ts +46 -0
- package/src/request/behavior/audited.ts +85 -0
- package/src/request/behavior/cached.ts +62 -0
- package/src/request/behavior/compose.ts +28 -0
- package/src/request/behavior/index.ts +5 -0
- package/src/request/behavior/namespace.ts +16 -0
- package/src/request/behavior/types.ts +26 -0
- package/src/request/behavior/versioned.ts +54 -0
- package/src/request/context/create.ts +103 -0
- package/src/request/context/guard.ts +49 -0
- package/src/request/context/index.ts +4 -0
- package/src/request/context/run-in-transaction.ts +200 -0
- package/src/request/context/store.ts +28 -0
- package/src/request/context/types.ts +50 -0
- package/src/request/di/builder.ts +535 -0
- package/src/request/di/index.ts +8 -0
- package/src/request/di/resolve.ts +271 -0
- package/src/request/di/types.ts +262 -0
- package/src/request/fitting/namespace.ts +7 -0
- package/src/request/fixture/batch.ts +71 -0
- package/src/request/fixture/builder.ts +26 -0
- package/src/request/fixture/errors.ts +10 -0
- package/src/request/fixture/index.ts +8 -0
- package/src/request/fixture/namespace.ts +23 -0
- package/src/request/fixture/paginate.ts +44 -0
- package/src/request/fixture/to-handlers.ts +260 -0
- package/src/request/fixture/types.ts +79 -0
- package/src/request/flow/act-as.ts +78 -0
- package/src/request/flow/namespace.ts +17 -0
- package/src/request/http/error-step.ts +42 -0
- package/src/request/http/file.ts +141 -0
- package/src/request/http/index.ts +4 -0
- package/src/request/http/middleware.ts +141 -0
- package/src/request/http/namespace.ts +5 -0
- package/src/request/http/rate-limit-classes.ts +170 -0
- package/src/request/http/response.ts +82 -0
- package/src/request/http/server.ts +916 -0
- package/src/request/http/sniff.ts +261 -0
- package/src/request/http/types.ts +250 -0
- package/src/request/http/upload.ts +284 -0
- package/src/request/internal/text.ts +6 -0
- package/src/request/openapi/generate.ts +205 -0
- package/src/request/openapi/index.ts +2 -0
- package/src/request/openapi/namespace.ts +7 -0
- package/src/test/auth.ts +13 -0
- package/src/test/auto-setup.ts +45 -0
- package/src/test/context.ts +91 -0
- package/src/test/crawl-fixture.ts +157 -0
- package/src/test/discover-fork.ts +17 -0
- package/src/test/fingerprint.ts +135 -0
- package/src/test/globals.d.ts +7 -0
- package/src/test/index.ts +19 -0
- package/src/test/namespace.ts +87 -0
- package/src/test/plugin.ts +189 -0
- package/src/test/progress.ts +185 -0
- package/src/test/reap-after-run.ts +28 -0
- package/src/test/reap.ts +286 -0
- package/src/test/reset.ts +253 -0
- package/src/test/savepoints.ts +172 -0
- package/src/test/setup.ts +1422 -0
- package/src/test/system-channel.ts +50 -0
- package/src/test/vitest-plugin.ts +142 -0
- package/src/test/vitest-workspace.ts +507 -0
- package/src/test/vitest.ts +333 -0
- package/src/test/watch.ts +105 -0
- package/src/trace/capture/bounded-serializer.ts +146 -0
- package/src/trace/cardinality/analyze.ts +173 -0
- package/src/trace/cardinality/branch-context.ts +214 -0
- package/src/trace/cardinality/check.ts +33 -0
- package/src/trace/cardinality/classify-edge.ts +64 -0
- package/src/trace/cardinality/structural-max.ts +107 -0
- package/src/trace/check/coverage-check.ts +188 -0
- package/src/trace/check/flow-check.ts +103 -0
- package/src/trace/check/flow-step-site.ts +234 -0
- package/src/trace/check/io-pattern.ts +116 -0
- package/src/trace/codemod/add-cardinality.ts +152 -0
- package/src/trace/codemod/run.ts +80 -0
- package/src/trace/entry/child-trace.ts +21 -0
- package/src/trace/entry/close-trace.ts +87 -0
- package/src/trace/entry/finalize-trace.ts +28 -0
- package/src/trace/entry/open-trace.ts +138 -0
- package/src/trace/entry/parent-trace.ts +20 -0
- package/src/trace/entry/parse-traceparent.ts +39 -0
- package/src/trace/entry/process-start.ts +38 -0
- package/src/trace/entry/trace-context.ts +26 -0
- package/src/trace/entry/tracing-enabled.ts +10 -0
- package/src/trace/external/record.ts +195 -0
- package/src/trace/external/report.ts +66 -0
- package/src/trace/namespace.ts +19 -0
- package/src/trace/partition/day.ts +47 -0
- package/src/trace/partition/index.ts +14 -0
- package/src/trace/partition/partition-name.ts +23 -0
- package/src/trace/partition/plan.ts +82 -0
- package/src/trace/partition/schedule.ts +26 -0
- package/src/trace/partition/startup-hook.ts +39 -0
- package/src/trace/partition/sync.ts +154 -0
- package/src/trace/partition/tables.ts +53 -0
- package/src/trace/read/tree.ts +83 -0
- package/src/trace/retain/copy-on-error.ts +76 -0
- package/src/trace/runtime/expire-stale-traces.ts +54 -0
- package/src/trace/runtime/flow-step.ts +147 -0
- package/src/trace/runtime/flush-steps.ts +31 -0
- package/src/trace/runtime/pending-writes.ts +54 -0
- package/src/trace/runtime/step-buffer.ts +298 -0
- package/src/trace/runtime/step-error.ts +21 -0
- package/src/trace/runtime/step-meta.ts +55 -0
- package/src/trace/runtime/thenable.ts +12 -0
- package/src/trace/runtime/truncate-trace.ts +62 -0
- package/src/trace/schema/trace-fields.ts +52 -0
- package/src/trace/schema/trace-retained.ts +22 -0
- package/src/trace/schema/trace-step-fields.ts +44 -0
- package/src/trace/schema/trace-step-retained.ts +25 -0
- package/src/trace/schema/trace-step.ts +18 -0
- package/src/trace/schema/trace.ts +12 -0
- package/src/trace/transformer/apply.ts +79 -0
- package/src/trace/transformer/build-meta-literal.ts +30 -0
- package/src/trace/transformer/find-flow-step-sites.ts +85 -0
- package/src/trace/transformer/inject-flow-step-import.ts +39 -0
- package/src/trace/transformer/transform-error.ts +14 -0
- package/src/trace/transformer/transform-flow-steps.ts +123 -0
- package/src/trace/transformer/wrap-function-declaration.ts +62 -0
- package/src/trace/transformer/wrap-variable-declaration.ts +67 -0
- package/src/workspace/affected.ts +110 -0
- package/src/workspace/changed-files.ts +163 -0
- package/src/workspace/check-deps.ts +213 -0
- package/src/workspace/checksum.ts +20 -0
- package/src/workspace/dependency-graph.ts +67 -0
- package/src/workspace/detect-pipework-copies.ts +93 -0
- package/src/workspace/discover.ts +206 -0
- package/src/workspace/generate.ts +401 -0
- package/src/workspace/index.ts +7 -0
- package/src/workspace/module-imports-pipework.ts +39 -0
- package/src/workspace/module-package-name.ts +12 -0
- package/src/workspace/scrub-git-env.ts +23 -0
- package/src/workspace/source-paths.ts +36 -0
- package/src/workspace/sync.ts +182 -0
- package/dist/REFERENCE.md +0 -1477
- package/dist/infra/access-links/rate-limit.d.ts +0 -10
- package/dist/infra/access-links/rate-limit.d.ts.map +0 -1
- package/dist/infra/access-links/rate-limit.js +0 -28
- package/dist/infra/access-links/rate-limit.js.map +0 -1
- package/dist/infra/email/sigv4.d.ts +0 -24
- package/dist/infra/email/sigv4.d.ts.map +0 -1
- package/dist/infra/email/sigv4.js +0 -55
- package/dist/infra/email/sigv4.js.map +0 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// The cardinality codemod (component 4). For every `@downstream path:symbol`
|
|
2
|
+
// JSDoc line that omits its cardinality, classify the edge structurally and
|
|
3
|
+
// append `step` or `branch`. Edges the analyzer cannot classify (indirection)
|
|
4
|
+
// and edges declared on non-trivial textual forms (continuation lines) are
|
|
5
|
+
// left untouched and reported as `unresolved` for the user to address by hand.
|
|
6
|
+
//
|
|
7
|
+
// Scope is deliberately narrow: the codemod only *fills blanks*. It never
|
|
8
|
+
// rewrites an existing cardinality, never touches a method flow step (those
|
|
9
|
+
// are banned by the `flow` check), and never re-flows the surrounding JSDoc.
|
|
10
|
+
// Minimal churn — one token per line, in place.
|
|
11
|
+
|
|
12
|
+
import { collectFlowStepSites, type FlowStepSite } from '../check/flow-step-site.js'
|
|
13
|
+
import { classifyEdge } from '../cardinality/classify-edge.js'
|
|
14
|
+
|
|
15
|
+
export interface CardinalityFill {
|
|
16
|
+
/** 1-based file line of the `@downstream` tag the codemod filled. */
|
|
17
|
+
readonly line: number
|
|
18
|
+
/** `path:symbol` target of the edge that received a cardinality. */
|
|
19
|
+
readonly target: string
|
|
20
|
+
/** The cardinality that was appended. */
|
|
21
|
+
readonly kind: 'step' | 'branch'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface UnresolvedEdge {
|
|
25
|
+
/** 1-based file line of the `@downstream` tag the codemod left untouched. */
|
|
26
|
+
readonly line: number
|
|
27
|
+
/** `path:symbol` target the codemod could not fill. */
|
|
28
|
+
readonly target: string
|
|
29
|
+
/**
|
|
30
|
+
* - `ambiguous` — analyzer could not classify the edge; needs a human.
|
|
31
|
+
* - `non-trivial-form` — the `@downstream` declaration spans lines or
|
|
32
|
+
* carries trailing text the codemod won't blindly rewrite.
|
|
33
|
+
*/
|
|
34
|
+
readonly reason: 'ambiguous' | 'non-trivial-form'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface RewriteResult {
|
|
38
|
+
/** The rewritten source — strictly equal to the input when nothing changed. */
|
|
39
|
+
readonly text: string
|
|
40
|
+
/** Every edge whose cardinality the codemod filled in. */
|
|
41
|
+
readonly fills: readonly CardinalityFill[]
|
|
42
|
+
/** Every edge the codemod left untouched but a human still needs to address. */
|
|
43
|
+
readonly unresolved: readonly UnresolvedEdge[]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Walks `source` for `@flow_step` sites, classifies each `@downstream` edge
|
|
48
|
+
* whose cardinality is missing, and returns the rewritten text plus a record
|
|
49
|
+
* of what was filled and what remains for the user.
|
|
50
|
+
*
|
|
51
|
+
* `source` must be parseable TypeScript. Files whose parse fails are the
|
|
52
|
+
* caller's concern — the codemod surfaces `collectFlowStepSites`'s throw.
|
|
53
|
+
*/
|
|
54
|
+
export function rewriteFlowCardinality(source: string, fileName?: string): RewriteResult {
|
|
55
|
+
const sites = collectFlowStepSites(source, fileName)
|
|
56
|
+
if (sites.length === 0) {
|
|
57
|
+
return { text: source, fills: [], unresolved: [] }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const lineEnding = detectLineEnding(source)
|
|
61
|
+
const lines = source.split(/\r?\n/)
|
|
62
|
+
const replacements = new Map<number, string>()
|
|
63
|
+
const fills: CardinalityFill[] = []
|
|
64
|
+
const unresolved: UnresolvedEdge[] = []
|
|
65
|
+
|
|
66
|
+
for (const site of sites) {
|
|
67
|
+
processSite(site, lines, replacements, fills, unresolved)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (replacements.size === 0) return { text: source, fills: [], unresolved }
|
|
71
|
+
|
|
72
|
+
const rewritten = lines.map((line, i) => replacements.get(i) ?? line)
|
|
73
|
+
return { text: rewritten.join(lineEnding), fills, unresolved }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function processSite(
|
|
77
|
+
site: FlowStepSite,
|
|
78
|
+
lines: readonly string[],
|
|
79
|
+
replacements: Map<number, string>,
|
|
80
|
+
fills: CardinalityFill[],
|
|
81
|
+
unresolved: UnresolvedEdge[],
|
|
82
|
+
): void {
|
|
83
|
+
// The `flow` check rejects invalid annotations, method shapes, and orphans
|
|
84
|
+
// as their own diagnostics — fixing them is the user's job. The codemod's
|
|
85
|
+
// only job is to fill missing cardinality on legal flow-step functions.
|
|
86
|
+
if (site.annotation.kind !== 'annotation') return
|
|
87
|
+
if (site.subject.shape !== 'function') return
|
|
88
|
+
|
|
89
|
+
const edges = site.annotation.annotation.downstream
|
|
90
|
+
if (edges.length === 0) return
|
|
91
|
+
|
|
92
|
+
const blockStart = site.commentLine - 1
|
|
93
|
+
const blockEnd = findBlockEnd(lines, blockStart)
|
|
94
|
+
|
|
95
|
+
// The parser produces one `DownstreamEdge` per `@downstream` tag in source
|
|
96
|
+
// order; scanning the JSDoc lines in the same order keeps the two streams
|
|
97
|
+
// aligned, so the Nth `@downstream` line corresponds to `edges[N]`.
|
|
98
|
+
let edgeIndex = -1
|
|
99
|
+
for (let i = blockStart; i <= blockEnd; i++) {
|
|
100
|
+
const raw = lines[i]
|
|
101
|
+
if (raw === undefined) continue
|
|
102
|
+
if (!isDownstreamLine(raw)) continue
|
|
103
|
+
edgeIndex++
|
|
104
|
+
|
|
105
|
+
const edge = edges[edgeIndex]
|
|
106
|
+
if (edge === undefined) continue
|
|
107
|
+
if (edge.cardinality !== null) continue
|
|
108
|
+
|
|
109
|
+
const target = `${edge.path}:${edge.symbol}`
|
|
110
|
+
const match = BARE_DOWNSTREAM.exec(raw)
|
|
111
|
+
if (match === null) {
|
|
112
|
+
unresolved.push({ line: i + 1, target, reason: 'non-trivial-form' })
|
|
113
|
+
continue
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const classification = classifyEdge('', site, edge)
|
|
117
|
+
if (classification.structural === 'ambiguous') {
|
|
118
|
+
unresolved.push({ line: i + 1, target, reason: 'ambiguous' })
|
|
119
|
+
continue
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const prefix = match[1] ?? ''
|
|
123
|
+
const targetText = match[2] ?? ''
|
|
124
|
+
replacements.set(i, `${prefix}${targetText} ${classification.structural}`)
|
|
125
|
+
fills.push({ line: i + 1, target, kind: classification.structural })
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function findBlockEnd(lines: readonly string[], start: number): number {
|
|
130
|
+
for (let i = start; i < lines.length; i++) {
|
|
131
|
+
if ((lines[i] ?? '').includes('*/')) return i
|
|
132
|
+
}
|
|
133
|
+
return lines.length - 1
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function detectLineEnding(source: string): string {
|
|
137
|
+
return source.includes('\r\n') ? '\r\n' : '\n'
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Matches `@downstream path:symbol` on a line by itself (with optional JSDoc
|
|
141
|
+
// leader and trailing whitespace). The capture groups preserve the prefix and
|
|
142
|
+
// the target verbatim so the rebuilt line differs from the original only by a
|
|
143
|
+
// trailing ` step` or ` branch`.
|
|
144
|
+
const BARE_DOWNSTREAM = /^(\s*\*?\s*@downstream\s+)(\S+:\S+)\s*$/
|
|
145
|
+
|
|
146
|
+
// A weaker match used only to count `@downstream` lines so the codemod's
|
|
147
|
+
// scanner stays aligned with the parser's edge ordering.
|
|
148
|
+
const DOWNSTREAM_TAG = /^\s*\*?\s*@downstream\b/
|
|
149
|
+
|
|
150
|
+
function isDownstreamLine(text: string): boolean {
|
|
151
|
+
return DOWNSTREAM_TAG.test(text)
|
|
152
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// File-scanning wrapper around the cardinality codemod: reads each source
|
|
2
|
+
// file, applies `rewriteFlowCardinality`, and writes the result back unless
|
|
3
|
+
// `dryRun` is set. Mirrors `flow-check.ts`'s shape — file I/O lives here, the
|
|
4
|
+
// rewrite logic stays pure in add-cardinality.ts.
|
|
5
|
+
|
|
6
|
+
import { readFileSync, writeFileSync, existsSync } from 'node:fs'
|
|
7
|
+
import { join } from 'node:path'
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
rewriteFlowCardinality,
|
|
11
|
+
type CardinalityFill,
|
|
12
|
+
type UnresolvedEdge,
|
|
13
|
+
} from './add-cardinality.js'
|
|
14
|
+
|
|
15
|
+
export interface CodemodRunOptions {
|
|
16
|
+
readonly cwd: string
|
|
17
|
+
readonly files: readonly string[]
|
|
18
|
+
/** When true, compute everything but do not write to disk. */
|
|
19
|
+
readonly dryRun: boolean
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface FileResult {
|
|
23
|
+
/** Source path relative to `cwd`. */
|
|
24
|
+
readonly file: string
|
|
25
|
+
readonly fills: readonly CardinalityFill[]
|
|
26
|
+
readonly unresolved: readonly UnresolvedEdge[]
|
|
27
|
+
/** True when the codemod produced a different text than the input. */
|
|
28
|
+
readonly changed: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface CodemodRunResult {
|
|
32
|
+
/** One entry per file that had at least one fill or unresolved edge. */
|
|
33
|
+
readonly files: readonly FileResult[]
|
|
34
|
+
readonly totalFills: number
|
|
35
|
+
readonly totalUnresolved: number
|
|
36
|
+
readonly filesChanged: number
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Runs the cardinality codemod across `files`. Missing or unparseable files are skipped. */
|
|
40
|
+
export function runFlowCardinalityCodemod(opts: CodemodRunOptions): CodemodRunResult {
|
|
41
|
+
const fileResults: FileResult[] = []
|
|
42
|
+
let totalFills = 0
|
|
43
|
+
let totalUnresolved = 0
|
|
44
|
+
let filesChanged = 0
|
|
45
|
+
|
|
46
|
+
for (const file of opts.files) {
|
|
47
|
+
const abs = join(opts.cwd, file)
|
|
48
|
+
if (!existsSync(abs)) continue
|
|
49
|
+
|
|
50
|
+
const source = readFileSync(abs, 'utf-8')
|
|
51
|
+
|
|
52
|
+
let rewrite
|
|
53
|
+
try {
|
|
54
|
+
rewrite = rewriteFlowCardinality(source, file)
|
|
55
|
+
} catch {
|
|
56
|
+
// A file the AST parser cannot read — leave its syntax errors to the
|
|
57
|
+
// type checker, exactly as `flow-check.ts` does.
|
|
58
|
+
continue
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (rewrite.fills.length === 0 && rewrite.unresolved.length === 0) continue
|
|
62
|
+
|
|
63
|
+
const changed = rewrite.text !== source
|
|
64
|
+
if (changed && !opts.dryRun) {
|
|
65
|
+
writeFileSync(abs, rewrite.text, 'utf-8')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
fileResults.push({
|
|
69
|
+
file,
|
|
70
|
+
fills: rewrite.fills,
|
|
71
|
+
unresolved: rewrite.unresolved,
|
|
72
|
+
changed,
|
|
73
|
+
})
|
|
74
|
+
totalFills += rewrite.fills.length
|
|
75
|
+
totalUnresolved += rewrite.unresolved.length
|
|
76
|
+
if (changed) filesChanged++
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return { files: fileResults, totalFills, totalUnresolved, filesChanged }
|
|
80
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// A trace for work a Flow runs under another tenant and principal. It hangs off
|
|
2
|
+
// the Flow's own trace at the step open now, so the tenant it names can read it.
|
|
3
|
+
|
|
4
|
+
import type { Flow } from '../../request/context/types.js'
|
|
5
|
+
import { openTrace } from './open-trace.js'
|
|
6
|
+
import type { TraceContext } from './trace-context.js'
|
|
7
|
+
|
|
8
|
+
/** Opens a child of `flow`'s trace for `tenant` and `auth`, or returns `null` when the Flow is untraced. */
|
|
9
|
+
export function openChildTrace(flow: Flow, tenant: string, auth: unknown): TraceContext | null {
|
|
10
|
+
const parent = flow.trace
|
|
11
|
+
if (parent === null) return null
|
|
12
|
+
return openTrace({
|
|
13
|
+
instance: flow.instance,
|
|
14
|
+
entryKind: parent.entryKind,
|
|
15
|
+
parent: { id: parent.id, rootId: parent.rootId, stepId: parent.buffer.openStepId },
|
|
16
|
+
tenant,
|
|
17
|
+
auth,
|
|
18
|
+
requestId: flow.requestId,
|
|
19
|
+
sessionId: flow.metadata?.sessionId ?? null,
|
|
20
|
+
})
|
|
21
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Closes the `trace` row an entry opened: stamps the final status and the
|
|
2
|
+
// close time, and flushes the in-memory `trace_step` buffer in the same beat.
|
|
3
|
+
// Like the open, the write is fire-and-forget and never throws — but it first
|
|
4
|
+
// waits on `persisted`, so neither the closing `UPDATE` nor the step `INSERT`s
|
|
5
|
+
// can outrun the opening `INSERT` and miss the row.
|
|
6
|
+
//
|
|
7
|
+
// **Ordering: step inserts settle before the status UPDATE.** Without this,
|
|
8
|
+
// an outside observer polling the trace row sees `status='error'/'closed'`
|
|
9
|
+
// the moment the UPDATE commits, but the step rows for that trace can still
|
|
10
|
+
// be in flight — a race that flakes any test of the shape "wait for status,
|
|
11
|
+
// then assert on step rows." Sequencing here makes the published status the
|
|
12
|
+
// settled-trace signal it visually appears to be. The hot path is unaffected
|
|
13
|
+
// because the caller ignores the returned promise; step-write failures are
|
|
14
|
+
// already swallowed inside `flushSteps`, so the UPDATE still runs.
|
|
15
|
+
//
|
|
16
|
+
// A truncated trace (Q7) keeps its `truncated` status here: `truncateTrace`
|
|
17
|
+
// already settled the cap-blowing path, and `closeTrace` running last must not
|
|
18
|
+
// downgrade a casualty to `closed` / `error`. The buffer drain is still safe —
|
|
19
|
+
// `truncateTrace` already drained it, and `__flowStep` records nothing after
|
|
20
|
+
// truncation, so `drain()` returns the empty array.
|
|
21
|
+
//
|
|
22
|
+
// The returned promise settles once the step `INSERT`s and then the `UPDATE`
|
|
23
|
+
// have — callers on the hot path ignore it (the close must not block the
|
|
24
|
+
// entry's response), but it gives a test a handle to await before asserting
|
|
25
|
+
// on rows.
|
|
26
|
+
|
|
27
|
+
import type { Manifold } from '../../core/pipework.js'
|
|
28
|
+
import { getBaseLogger } from '../../core/logging/index.js'
|
|
29
|
+
import { recordFaultFor, faultMessage } from '../../infra/alerts/faults.js'
|
|
30
|
+
import { eq, and, getTableColumns } from '../../data/query/index.js'
|
|
31
|
+
import type { Column } from '../../data/db/types.js'
|
|
32
|
+
import { trace } from '../schema/trace.js'
|
|
33
|
+
import { trackTraceWrite } from '../runtime/pending-writes.js'
|
|
34
|
+
import { flushSteps } from '../runtime/flush-steps.js'
|
|
35
|
+
import { copyTraceOnError } from '../retain/copy-on-error.js'
|
|
36
|
+
import { withMaintenance } from '../../data/db/maintenance.js'
|
|
37
|
+
import type { DB } from '../../data/db/index.js'
|
|
38
|
+
import type { TraceContext } from './trace-context.js'
|
|
39
|
+
|
|
40
|
+
/** How an entry ended — a clean return, or a thrown error. */
|
|
41
|
+
export type TraceOutcome = 'closed' | 'error'
|
|
42
|
+
|
|
43
|
+
/** Closes `ctx`'s trace row with `outcome` and flushes its step buffer. No-op when the entry ran untraced. */
|
|
44
|
+
export function closeTrace(
|
|
45
|
+
instance: Manifold,
|
|
46
|
+
ctx: TraceContext | null,
|
|
47
|
+
outcome: TraceOutcome,
|
|
48
|
+
): Promise<void> {
|
|
49
|
+
if (ctx === null) return Promise.resolve()
|
|
50
|
+
const closedAt = new Date()
|
|
51
|
+
return trackTraceWrite(ctx.persisted
|
|
52
|
+
.then(async () => {
|
|
53
|
+
const status: 'closed' | 'error' | 'truncated' = ctx.buffer.truncated ? 'truncated' : outcome
|
|
54
|
+
// Step inserts MUST settle before the status UPDATE — see file header
|
|
55
|
+
// for the race this prevents. `flushSteps` swallows its own errors, so
|
|
56
|
+
// a failed batch still lets the UPDATE proceed.
|
|
57
|
+
await flushSteps(instance, ctx.buffer.drain())
|
|
58
|
+
const db = instance.pool.getOrCreate(instance.config.database()).drizzle
|
|
59
|
+
const table = trace.table()
|
|
60
|
+
// The composite primary key is `[id, openedDay]` — both are matched so the
|
|
61
|
+
// UPDATE targets exactly one partition's one row.
|
|
62
|
+
const cols = getTableColumns(table) as Record<'id' | 'openedDay', Column>
|
|
63
|
+
// The pooled connection carries no tenant setting, so the UPDATE runs as a maintenance pass.
|
|
64
|
+
await withMaintenance(db as unknown as DB, async tx => {
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Drizzle's update needs the concrete runtime table type
|
|
66
|
+
await (tx as any).update(table)
|
|
67
|
+
.set({ status, closedAt })
|
|
68
|
+
.where(and(eq(cols.id, ctx.id), eq(cols.openedDay, ctx.openedDay)))
|
|
69
|
+
})
|
|
70
|
+
// Copy errored / truncated traces to the cold set before their hot
|
|
71
|
+
// partition retires (Q4). For a truncated trace, `truncationDone` is the
|
|
72
|
+
// settle handle from `truncateTrace`; awaiting it ensures the cold row
|
|
73
|
+
// reflects `truncated_at_seq`. For a normal error close the handle is
|
|
74
|
+
// `null`, and `await null` is a no-op — no branch needed.
|
|
75
|
+
if (status !== 'closed') {
|
|
76
|
+
await ctx.buffer.truncationDone
|
|
77
|
+
await copyTraceOnError(db as unknown as DB, ctx.id)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
.catch((err: unknown) => {
|
|
81
|
+
getBaseLogger().error(
|
|
82
|
+
{ err, traceId: ctx.id },
|
|
83
|
+
'Failed to persist trace close — the trace row is stuck open',
|
|
84
|
+
)
|
|
85
|
+
void recordFaultFor(instance, 'trace-write', `trace close not persisted: ${faultMessage(err)}`, { traceId: ctx.id, step: 'close' })
|
|
86
|
+
}))
|
|
87
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Ties a trace's close to the settling of the entry's work: `closed` on a
|
|
2
|
+
// clean return, `error` on a throw. An entry's work may be synchronous or a
|
|
3
|
+
// promise — this handles both and hands the result straight back, so an
|
|
4
|
+
// ingress can wrap its return value inline without restructuring.
|
|
5
|
+
|
|
6
|
+
import type { Manifold } from '../../core/pipework.js'
|
|
7
|
+
import { closeTrace } from './close-trace.js'
|
|
8
|
+
import { isThenable } from '../runtime/thenable.js'
|
|
9
|
+
import type { TraceContext } from './trace-context.js'
|
|
10
|
+
|
|
11
|
+
/** Wraps `result`, closing `ctx`'s trace when it settles. Returns `result` unchanged. */
|
|
12
|
+
export function finalizeTrace<T>(instance: Manifold, ctx: TraceContext | null, result: T): T {
|
|
13
|
+
if (ctx === null) return result
|
|
14
|
+
if (isThenable(result)) {
|
|
15
|
+
return result.then(
|
|
16
|
+
(value: unknown) => {
|
|
17
|
+
void closeTrace(instance, ctx, 'closed')
|
|
18
|
+
return value
|
|
19
|
+
},
|
|
20
|
+
(err: unknown) => {
|
|
21
|
+
void closeTrace(instance, ctx, 'error')
|
|
22
|
+
throw err
|
|
23
|
+
},
|
|
24
|
+
) as T
|
|
25
|
+
}
|
|
26
|
+
void closeTrace(instance, ctx, 'closed')
|
|
27
|
+
return result
|
|
28
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Opens the `trace` row for an entry. The row is written eagerly — a trace
|
|
2
|
+
// exists the moment an entry is reached — but the write itself is fire-and-
|
|
3
|
+
// forget: the id and the tree wiring are computed synchronously, so the entry
|
|
4
|
+
// pays no latency, and the `INSERT` runs in the background. Failure to persist
|
|
5
|
+
// is logged, never thrown: a broken trace table must not break the request.
|
|
6
|
+
//
|
|
7
|
+
// The write goes through `instance.pool` directly, not the request transaction
|
|
8
|
+
// — an errored request rolls back, but its trace must survive to be inspected.
|
|
9
|
+
|
|
10
|
+
import { trackTraceWrite } from '../runtime/pending-writes.js'
|
|
11
|
+
import { randomUUID } from 'node:crypto'
|
|
12
|
+
import type { Manifold } from '../../core/pipework.js'
|
|
13
|
+
import { getBaseLogger } from '../../core/logging/index.js'
|
|
14
|
+
import { recordFaultFor, faultMessage } from '../../infra/alerts/faults.js'
|
|
15
|
+
import { trace } from '../schema/trace.js'
|
|
16
|
+
import { toDay } from '../partition/day.js'
|
|
17
|
+
import { StepBuffer } from '../runtime/step-buffer.js'
|
|
18
|
+
import type { TraceContext, TraceEntryKind } from './trace-context.js'
|
|
19
|
+
|
|
20
|
+
const MS_PER_DAY = 86_400_000
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The parent reference openTrace actually consumes. Two shapes satisfy it:
|
|
24
|
+
* an in-process `TraceContext` (the active trace on the surrounding Flow) and
|
|
25
|
+
* a synthesized `{ id, rootId }` derived from an ingested W3C `traceparent`
|
|
26
|
+
* header. Either way, only the two fields are needed to wire the trace tree.
|
|
27
|
+
*/
|
|
28
|
+
export interface ParentTraceRef {
|
|
29
|
+
readonly id: string
|
|
30
|
+
readonly rootId: string
|
|
31
|
+
/** The step open on the parent when this entry began — written to `trace.parent_step_id`. */
|
|
32
|
+
readonly stepId?: string | null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface OpenTraceParams {
|
|
36
|
+
readonly instance: Manifold
|
|
37
|
+
readonly entryKind: TraceEntryKind
|
|
38
|
+
/** The parent trace, or `null` for a root entry. */
|
|
39
|
+
readonly parent: ParentTraceRef | null
|
|
40
|
+
readonly tenant: string | null
|
|
41
|
+
/** The entry's auth principal — `userId` is read off it when present. */
|
|
42
|
+
readonly auth: unknown
|
|
43
|
+
readonly requestId: string | null
|
|
44
|
+
readonly sessionId: string | null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Generates a trace id, wires it into the tree, and kicks off the opening `INSERT`. */
|
|
48
|
+
export function openTrace(params: OpenTraceParams): TraceContext {
|
|
49
|
+
const id = randomUUID()
|
|
50
|
+
const openedAt = new Date()
|
|
51
|
+
const openedDay = toDay(openedAt)
|
|
52
|
+
const rootId = params.parent?.rootId ?? id
|
|
53
|
+
const expiresAt = new Date(
|
|
54
|
+
openedAt.getTime() + params.instance.config.trace.hotRetentionDays * MS_PER_DAY,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
const persisted = insertTraceRow(params.instance, {
|
|
58
|
+
id,
|
|
59
|
+
openedDay,
|
|
60
|
+
rootId,
|
|
61
|
+
parentId: params.parent?.id ?? null,
|
|
62
|
+
parentStepId: params.parent?.stepId ?? null,
|
|
63
|
+
entryKind: params.entryKind,
|
|
64
|
+
status: 'open',
|
|
65
|
+
tenantId: params.tenant,
|
|
66
|
+
requestId: params.requestId,
|
|
67
|
+
sessionId: params.sessionId,
|
|
68
|
+
userId: extractUserId(params.auth),
|
|
69
|
+
openedAt,
|
|
70
|
+
closedAt: null,
|
|
71
|
+
expiresAt,
|
|
72
|
+
truncatedAtSeq: null,
|
|
73
|
+
release: params.instance.release,
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
// The step cap is `structuralMax × safetyFactor` (Q7). `structuralMax` is the
|
|
77
|
+
// longest chain of `step` edges through the flow graph, derived by
|
|
78
|
+
// `pipework check` from the `@downstream` annotations and pinned in
|
|
79
|
+
// `config.trace.structuralMax`. Unset → no cap; the truncation mechanism is
|
|
80
|
+
// live but never fires. The cap firing is a bug signal — DAG analysis was
|
|
81
|
+
// wrong, or unannotated recursion slipped validation — not a load condition.
|
|
82
|
+
const traceConfig = params.instance.config.trace
|
|
83
|
+
const cap = traceConfig.structuralMax !== undefined
|
|
84
|
+
? traceConfig.structuralMax * traceConfig.safetyFactor
|
|
85
|
+
: Infinity
|
|
86
|
+
const buffer = new StepBuffer({
|
|
87
|
+
traceId: id,
|
|
88
|
+
traceDay: openedDay,
|
|
89
|
+
tenantId: params.tenant,
|
|
90
|
+
cap,
|
|
91
|
+
captureInputs: traceConfig.captureInputs,
|
|
92
|
+
maxExternalSteps: traceConfig.maxExternalSteps,
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
return { id, rootId, entryKind: params.entryKind, openedDay, persisted, buffer }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface TraceRow {
|
|
99
|
+
readonly id: string
|
|
100
|
+
readonly openedDay: string
|
|
101
|
+
readonly rootId: string
|
|
102
|
+
readonly parentId: string | null
|
|
103
|
+
readonly parentStepId: string | null
|
|
104
|
+
readonly entryKind: TraceEntryKind
|
|
105
|
+
readonly status: 'open'
|
|
106
|
+
readonly tenantId: string | null
|
|
107
|
+
readonly requestId: string | null
|
|
108
|
+
readonly sessionId: string | null
|
|
109
|
+
readonly userId: string | null
|
|
110
|
+
readonly openedAt: Date
|
|
111
|
+
readonly closedAt: null
|
|
112
|
+
readonly expiresAt: Date
|
|
113
|
+
readonly truncatedAtSeq: null
|
|
114
|
+
readonly release: string | null
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function insertTraceRow(instance: Manifold, row: TraceRow): Promise<void> {
|
|
118
|
+
const db = instance.pool.getOrCreate(instance.config.database()).drizzle
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Drizzle's insert needs the concrete runtime table type
|
|
120
|
+
return trackTraceWrite((db as any).insert(trace.table()).values(row)
|
|
121
|
+
.then(() => undefined)
|
|
122
|
+
.catch((err: unknown) => {
|
|
123
|
+
getBaseLogger().error(
|
|
124
|
+
{ err, traceId: row.id },
|
|
125
|
+
'Failed to persist trace open — the trace row is missing',
|
|
126
|
+
)
|
|
127
|
+
void recordFaultFor(instance, 'trace-write', `trace open not persisted: ${faultMessage(err)}`, { traceId: row.id, step: 'open' })
|
|
128
|
+
}))
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Reads `userId` off the auth principal, following the same convention the logger uses. */
|
|
132
|
+
function extractUserId(auth: unknown): string | null {
|
|
133
|
+
if (auth !== null && typeof auth === 'object' && 'userId' in auth) {
|
|
134
|
+
const userId = (auth as { userId: unknown }).userId
|
|
135
|
+
if (typeof userId === 'string') return userId
|
|
136
|
+
}
|
|
137
|
+
return null
|
|
138
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Traces form a tree. A new entry's parent is the trace already running on the
|
|
2
|
+
// active Flow — a job enqueued and awaited inside a request, a nested test
|
|
3
|
+
// context. With no active Flow (the common case for an inbound HTTP request or
|
|
4
|
+
// a worker-claimed job), the new entry is a root.
|
|
5
|
+
|
|
6
|
+
import { getContext } from '../../request/context/store.js'
|
|
7
|
+
import type { TraceContext } from './trace-context.js'
|
|
8
|
+
import type { ParentTraceRef } from './open-trace.js'
|
|
9
|
+
|
|
10
|
+
/** The trace on the active Flow, or `null` when there is none — the new entry's parent. */
|
|
11
|
+
export function parentTrace(): TraceContext | null {
|
|
12
|
+
return getContext()?.trace ?? null
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** The active trace as a parent reference carrying the step open on it, or `null` when there is none. */
|
|
16
|
+
export function parentTraceRef(): ParentTraceRef | null {
|
|
17
|
+
const active = parentTrace()
|
|
18
|
+
if (active === null) return null
|
|
19
|
+
return { id: active.id, rootId: active.rootId, stepId: active.buffer.openStepId }
|
|
20
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Parses the W3C `traceparent` HTTP header (Q10 — cross-team contract with
|
|
2
|
+
// plumb). Format: `version-trace-id-parent-id-trace-flags`, version-00 only.
|
|
3
|
+
// The spec is strict: any deviation from the format means the header is
|
|
4
|
+
// invalid and the receiver MUST start a new trace as if it weren't there.
|
|
5
|
+
// We return the trace-id formatted as a UUID so it can land in
|
|
6
|
+
// `trace.parent_id` directly; the parent-id and trace-flags fields are
|
|
7
|
+
// validated but not surfaced — pipework's parent_id wiring uses the
|
|
8
|
+
// distributed trace-id, not the W3C parent-span-id.
|
|
9
|
+
//
|
|
10
|
+
// Spec: https://www.w3.org/TR/trace-context/#traceparent-header
|
|
11
|
+
|
|
12
|
+
const TRACE_ID_RE = /^[0-9a-f]{32}$/
|
|
13
|
+
const PARENT_ID_RE = /^[0-9a-f]{16}$/
|
|
14
|
+
const FLAGS_RE = /^[0-9a-f]{2}$/
|
|
15
|
+
const TRACE_ID_ZERO = '0'.repeat(32)
|
|
16
|
+
const PARENT_ID_ZERO = '0'.repeat(16)
|
|
17
|
+
|
|
18
|
+
/** A parsed traceparent — only the fields pipework actually wires through. */
|
|
19
|
+
export interface ParsedTraceparent {
|
|
20
|
+
/** The W3C trace-id, formatted as a UUID for direct use in `trace.parent_id`. */
|
|
21
|
+
readonly traceId: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Parses a `traceparent` header value; returns `null` for missing or malformed input. */
|
|
25
|
+
export function parseTraceparent(header: string | string[] | undefined): ParsedTraceparent | null {
|
|
26
|
+
if (typeof header !== 'string') return null
|
|
27
|
+
const parts = header.split('-')
|
|
28
|
+
if (parts.length !== 4) return null
|
|
29
|
+
const [version, traceId, parentId, flags] = parts as [string, string, string, string]
|
|
30
|
+
if (version !== '00') return null
|
|
31
|
+
if (!TRACE_ID_RE.test(traceId) || traceId === TRACE_ID_ZERO) return null
|
|
32
|
+
if (!PARENT_ID_RE.test(parentId) || parentId === PARENT_ID_ZERO) return null
|
|
33
|
+
if (!FLAGS_RE.test(flags)) return null
|
|
34
|
+
return { traceId: formatAsUuid(traceId) }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function formatAsUuid(hex32: string): string {
|
|
38
|
+
return `${hex32.slice(0, 8)}-${hex32.slice(8, 12)}-${hex32.slice(12, 16)}-${hex32.slice(16, 20)}-${hex32.slice(20, 32)}`
|
|
39
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// The opening step of a trace that is not an ingress: a process start, a script
|
|
2
|
+
// surface, a public script entry. It names which process did the work.
|
|
3
|
+
|
|
4
|
+
import { randomUUID } from 'node:crypto'
|
|
5
|
+
import { hostname } from 'node:os'
|
|
6
|
+
import type { Manifold } from '../../core/pipework.js'
|
|
7
|
+
import { serializeForTrace } from '../capture/bounded-serializer.js'
|
|
8
|
+
import type { TraceContext } from './trace-context.js'
|
|
9
|
+
|
|
10
|
+
export const PROCESS_START_REF = 'external:pipework.process.start'
|
|
11
|
+
|
|
12
|
+
export interface ProcessStartInfo {
|
|
13
|
+
readonly phase: 'preStart' | 'script'
|
|
14
|
+
readonly surfaces: readonly string[]
|
|
15
|
+
readonly release: Manifold['release']
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Stages the zero-length `external:pipework.process.start` step naming this process (host, pid, surfaces, release, phase). */
|
|
19
|
+
export function stageProcessStart(trace: TraceContext, info: ProcessStartInfo): void {
|
|
20
|
+
const now = new Date()
|
|
21
|
+
trace.buffer.stageExternal({
|
|
22
|
+
id: randomUUID(),
|
|
23
|
+
parentStepId: null,
|
|
24
|
+
flowStepRef: PROCESS_START_REF,
|
|
25
|
+
status: 'ok',
|
|
26
|
+
startedAt: now,
|
|
27
|
+
completedAt: now,
|
|
28
|
+
durationMicros: 0n,
|
|
29
|
+
capturedInputs: [serializeForTrace({
|
|
30
|
+
host: hostname(),
|
|
31
|
+
pid: process.pid,
|
|
32
|
+
surfaces: info.surfaces,
|
|
33
|
+
release: info.release,
|
|
34
|
+
phase: info.phase,
|
|
35
|
+
})],
|
|
36
|
+
error: null,
|
|
37
|
+
})
|
|
38
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// The trace's runtime handle on the Flow. Every Flow that runs under tracing
|
|
2
|
+
// carries one; flow steps record `trace_step` rows into `buffer`, and a child
|
|
3
|
+
// entry reads `id` / `rootId` to wire itself into the trace tree.
|
|
4
|
+
|
|
5
|
+
import type { StepBuffer } from '../runtime/step-buffer.js'
|
|
6
|
+
|
|
7
|
+
/** The ingress point a trace was opened at. Mirrors `traceFields.entryKind`. */
|
|
8
|
+
export type TraceEntryKind = 'http' | 'job' | 'cron' | 'test'
|
|
9
|
+
|
|
10
|
+
export interface TraceContext {
|
|
11
|
+
/** This trace's id — the `trace.id` of the row opened at the entry. */
|
|
12
|
+
readonly id: string
|
|
13
|
+
/** The root of the trace tree. Equals `id` for a root trace. */
|
|
14
|
+
readonly rootId: string
|
|
15
|
+
/** The ingress kind the trace was opened at — a child trace opened inside the entry (asLink) copies it. */
|
|
16
|
+
readonly entryKind: TraceEntryKind
|
|
17
|
+
/** The UTC calendar day the trace opened — the partition its row lives in. */
|
|
18
|
+
readonly openedDay: string
|
|
19
|
+
/**
|
|
20
|
+
* Resolves once the opening `INSERT` has settled. The closing `UPDATE` waits
|
|
21
|
+
* on this so it can never race ahead of the row it means to close.
|
|
22
|
+
*/
|
|
23
|
+
readonly persisted: Promise<void>
|
|
24
|
+
/** The in-memory `trace_step` buffer flow steps record into — drained at close. */
|
|
25
|
+
readonly buffer: StepBuffer
|
|
26
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Tracing is opt-in: a Blueprint with no `trace` block runs untraced and pays
|
|
2
|
+
// zero overhead at the ingress points. Configuring `trace` — even as `{}`, which
|
|
3
|
+
// resolves entirely to defaults — turns it on.
|
|
4
|
+
|
|
5
|
+
import type { Manifold } from '../../core/pipework.js'
|
|
6
|
+
|
|
7
|
+
/** Whether trace rows should be opened for this manifold's entries. */
|
|
8
|
+
export function isTracingEnabled(instance: Manifold): boolean {
|
|
9
|
+
return instance.config.raw.trace !== undefined
|
|
10
|
+
}
|