@cosmicdrift/kumiko-framework 0.389.0 → 0.390.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/AGENTS.md +9 -4
- package/README.md +1 -1
- package/agents/examples/apex-surface-auth.md +2 -3
- package/agents/examples/api-worker-split.md +9 -2
- package/agents/examples/auth-claims.md +1 -1
- package/agents/examples/cross-feature-events.md +12 -12
- package/agents/examples/crypto-shredding-hr.md +2 -2
- package/agents/examples/encrypted-tenant-config.md +1 -1
- package/agents/examples/error-contract.md +12 -7
- package/agents/examples/event-sourcing.md +29 -29
- package/agents/examples/files-post-processing.md +10 -8
- package/agents/examples/inbound-mail-triage.md +1 -0
- package/agents/examples/lane-routing.md +2 -1
- package/agents/examples/legal-pages.md +2 -2
- package/agents/examples/lifecycle-hooks.md +3 -3
- package/agents/examples/managed-config.md +4 -4
- package/agents/examples/managed-pages.md +1 -1
- package/agents/examples/relations.md +19 -4
- package/agents/examples/search.md +4 -4
- package/agents/examples/secrets-demo.md +9 -6
- package/agents/examples/state-machine.md +2 -2
- package/agents/examples/tenant-settings.md +1 -1
- package/agents/examples/user-data-rights.md +3 -6
- package/agents/examples/workflow-engine.md +53 -47
- package/agents/examples.md +4 -4
- package/agents/features.md +1 -1
- package/dist/api/auth-middleware.js +1 -1
- package/dist/api/auth-routes-invite.js +2 -1
- package/dist/api/entity-read-access.d.ts +3 -1
- package/dist/api/export/export-columns.d.ts +3 -1
- package/dist/api/export/export-route.js +3 -2
- package/dist/api/export/export-screen.d.ts +2 -1
- package/dist/api/extra-route.d.ts +3 -1
- package/dist/api/index.d.ts +23 -27
- package/dist/api/index.js +13 -15
- package/dist/api/jwt.js +1 -1
- package/dist/api/observability-middleware.d.ts +1 -1
- package/dist/api/observability-middleware.js +2 -1
- package/dist/api/request-context-internals.d.ts +31 -0
- package/dist/api/request-context-internals.js +11 -0
- package/dist/api/request-context-scopes.d.ts +14 -0
- package/dist/api/request-context-scopes.js +69 -0
- package/dist/api/request-context.d.ts +1 -40
- package/dist/api/request-context.js +22 -51
- package/dist/api/request-id-middleware.d.ts +1 -1
- package/dist/api/route-registrars.d.ts +2 -1
- package/dist/api/route-registrars.js +1 -1
- package/dist/api/routes.js +7 -3
- package/dist/api/server-boot-checks.d.ts +1 -1
- package/dist/api/server-boot-checks.js +2 -2
- package/dist/api/server-event-dispatcher.d.ts +6 -1
- package/dist/api/server-event-dispatcher.js +3 -4
- package/dist/api/server-extra-routes.d.ts +1 -1
- package/dist/api/server-extra-routes.js +2 -1
- package/dist/api/server-middleware.js +3 -1
- package/dist/api/server-routes.d.ts +2 -1
- package/dist/api/server-wiring.js +6 -4
- package/dist/api/server.d.ts +2 -1
- package/dist/api/sse-route.d.ts +2 -1
- package/dist/api/tenant-scoped-secrets.d.ts +2 -0
- package/dist/api/tenant-scoped-secrets.js +13 -0
- package/dist/api/websocket-route.d.ts +1 -1
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/roles.d.ts +0 -5
- package/dist/compliance/duration-spec.d.ts +0 -1
- package/dist/compliance/duration-spec.js +0 -5
- package/dist/compliance/index.d.ts +4 -4
- package/dist/compliance/index.js +2 -2
- package/dist/compliance/profiles.d.ts +0 -15
- package/dist/compliance/profiles.js +0 -23
- package/dist/config/index.d.ts +10 -10
- package/dist/config/index.js +13 -1
- package/dist/config/internals.d.ts +9 -0
- package/dist/config/internals.js +1 -0
- package/dist/consumer-cli-internals.d.ts +4 -0
- package/dist/consumer-cli-internals.js +1 -0
- package/dist/consumer-cli.d.ts +1 -4
- package/dist/consumer-cli.js +5 -1
- package/dist/crypto/event-pii.js +1 -1
- package/dist/crypto/index.d.ts +8 -9
- package/dist/crypto/index.js +7 -8
- package/dist/crypto/pg-kms-adapter.js +6 -1
- package/dist/db/apply-entity-event.d.ts +1 -1
- package/dist/db/apply-entity-event.js +15 -47
- package/dist/db/blind-index-cleanup.js +91 -77
- package/dist/db/collect-table-metas.js +1 -1
- package/dist/db/compound-types.d.ts +1 -1
- package/dist/db/compound-types.js +0 -7
- package/dist/db/config-seed.d.ts +2 -1
- package/dist/db/config-seed.js +6 -1
- package/dist/db/connection.d.ts +3 -1
- package/dist/db/connection.js +15 -5
- package/dist/db/cross-tenant-reads.d.ts +1 -1
- package/dist/db/cross-tenant-reads.js +1 -1
- package/dist/db/dialect.d.ts +0 -5
- package/dist/db/dialect.js +0 -3
- package/dist/db/driver-value-preparation.js +23 -2
- package/dist/db/eagerload.d.ts +2 -1
- package/dist/db/entity-field-encryption.d.ts +1 -1
- package/dist/db/entity-table-meta.d.ts +1 -1
- package/dist/db/event-store-executor-context.d.ts +3 -1
- package/dist/db/event-store-executor-context.js +4 -3
- package/dist/db/event-store-executor-read-filter.d.ts +1 -1
- package/dist/db/event-store-executor-read-rows.d.ts +2 -1
- package/dist/db/event-store-executor-read-search.d.ts +2 -1
- package/dist/db/event-store-executor-read-sort.d.ts +2 -1
- package/dist/db/event-store-executor-read.js +2 -2
- package/dist/db/event-store-executor-write-atomic.js +8 -7
- package/dist/db/event-store-executor-write-steps.d.ts +3 -2
- package/dist/db/event-store-executor-write.js +7 -4
- package/dist/db/event-store-executor.d.ts +1 -1
- package/dist/db/executor-managed-tables.d.ts +7 -1
- package/dist/db/executor-managed-tables.js +11 -2
- package/dist/db/index.d.ts +29 -28
- package/dist/db/index.js +22 -20
- package/dist/db/known-table-names.d.ts +6 -0
- package/dist/db/known-table-names.js +21 -0
- package/dist/db/list-aggregate-labels.d.ts +1 -1
- package/dist/db/located-timestamp.d.ts +1 -1
- package/dist/db/located-timestamp.js +0 -5
- package/dist/db/migrate-generator.d.ts +17 -1
- package/dist/db/migrate-generator.js +50 -20
- package/dist/db/migrate-primary-key.d.ts +12 -0
- package/dist/db/migrate-primary-key.js +45 -0
- package/dist/db/migrate-rls-diff.d.ts +20 -0
- package/dist/db/migrate-rls-diff.js +61 -0
- package/dist/db/migrate-runner.js +4 -0
- package/dist/db/money.d.ts +1 -1
- package/dist/db/money.js +1 -1
- package/dist/db/parent-ref-clause.d.ts +2 -1
- package/dist/db/pg-error.d.ts +2 -0
- package/dist/db/pg-error.js +11 -0
- package/dist/db/queries/ddl.d.ts +3 -0
- package/dist/db/queries/ddl.js +34 -1
- package/dist/db/queries/event-store.js +4 -2
- package/dist/db/queries/event-tenants.d.ts +2 -0
- package/dist/db/queries/event-tenants.js +17 -0
- package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
- package/dist/db/queries/rebuild-rls-guard.js +29 -0
- package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
- package/dist/db/queries/rls-boot-catalog.js +39 -0
- package/dist/db/queries/rls-catalog.d.ts +6 -0
- package/dist/db/queries/rls-catalog.js +82 -0
- package/dist/db/queries/rls-scope.d.ts +3 -0
- package/dist/db/queries/rls-scope.js +17 -0
- package/dist/db/queries/rls-shape.d.ts +10 -0
- package/dist/db/queries/rls-shape.js +42 -0
- package/dist/db/queries/session-advisory-lock.d.ts +2 -0
- package/dist/db/queries/session-advisory-lock.js +23 -0
- package/dist/db/queries/shadow-swap.d.ts +1 -2
- package/dist/db/queries/shadow-swap.js +9 -25
- package/dist/db/queries/test-stack.d.ts +4 -1
- package/dist/db/queries/test-stack.js +84 -2
- package/dist/db/query.js +11 -7
- package/dist/db/reference-data.d.ts +1 -1
- package/dist/db/reference-data.js +6 -1
- package/dist/db/render-ddl.d.ts +6 -2
- package/dist/db/render-ddl.js +7 -7
- package/dist/db/render-rls-ddl.d.ts +35 -0
- package/dist/db/render-rls-ddl.js +127 -0
- package/dist/db/replay-migration-sql.d.ts +3 -1
- package/dist/db/replay-migration-sql.js +22 -5
- package/dist/db/replay-rls.d.ts +25 -0
- package/dist/db/replay-rls.js +156 -0
- package/dist/db/row-level-security-boot-check.d.ts +6 -0
- package/dist/db/row-level-security-boot-check.js +86 -0
- package/dist/db/row-level-security-connection.d.ts +3 -0
- package/dist/db/row-level-security-connection.js +213 -0
- package/dist/db/row-level-security-scope.d.ts +33 -0
- package/dist/db/row-level-security-scope.js +127 -0
- package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
- package/dist/db/scope-tenant-db-to-tenant.js +14 -0
- package/dist/db/sql-identifier.d.ts +1 -0
- package/dist/db/sql-identifier.js +3 -0
- package/dist/db/table-builder.d.ts +2 -1
- package/dist/db/table-builder.js +1 -1
- package/dist/db/table-info.js +1 -1
- package/dist/db/table-push.d.ts +11 -2
- package/dist/db/table-push.js +15 -2
- package/dist/db/tenant-db-runner.d.ts +3 -1
- package/dist/db/tenant-db-runner.js +4 -3
- package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
- package/dist/db/tenant-db-scoped-rebind.js +33 -0
- package/dist/db/tenant-db-statement-runner.d.ts +13 -0
- package/dist/db/tenant-db-statement-runner.js +48 -0
- package/dist/db/tenant-db.d.ts +17 -12
- package/dist/db/tenant-db.js +49 -120
- package/dist/db/tenant-id-filter.d.ts +3 -0
- package/dist/db/tenant-id-filter.js +30 -0
- package/dist/db/transaction-serialization.d.ts +6 -0
- package/dist/db/transaction-serialization.js +60 -0
- package/dist/derivatives/delete-stored-file.js +1 -1
- package/dist/derivatives/index.d.ts +2 -5
- package/dist/derivatives/index.js +2 -3
- package/dist/engine/access.d.ts +2 -1
- package/dist/engine/access.js +1 -1
- package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
- package/dist/engine/boot-validator/entity-handler.js +1 -1
- package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +1 -1
- package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +1 -1
- package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +2 -1
- package/dist/engine/boot-validator/nav.d.ts +3 -1
- package/dist/engine/boot-validator/nav.js +1 -1
- package/dist/engine/boot-validator/ownership.d.ts +2 -1
- package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
- package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
- package/dist/engine/boot-validator/query-refs.d.ts +2 -1
- package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
- package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
- package/dist/engine/boot-validator/screens.d.ts +2 -1
- package/dist/engine/boot-validator/workspaces.d.ts +3 -1
- package/dist/engine/bridge-stub.d.ts +5 -2
- package/dist/engine/bridge-stub.js +39 -24
- package/dist/engine/config-helpers.d.ts +2 -2
- package/dist/engine/config-helpers.js +0 -9
- package/dist/engine/constants.d.ts +0 -10
- package/dist/engine/constants.js +0 -8
- package/dist/engine/create-app.js +1 -1
- package/dist/engine/define-feature.d.ts +2 -1
- package/dist/engine/define-feature.js +1 -2
- package/dist/engine/define-handler.d.ts +1 -1
- package/dist/engine/define-step.d.ts +0 -1
- package/dist/engine/define-step.js +0 -3
- package/dist/engine/embedded-derived.d.ts +1 -1
- package/dist/engine/entity-handlers.d.ts +2 -1
- package/dist/engine/entity-handlers.js +7 -7
- package/dist/engine/entity-list-runtime-options.js +3 -1
- package/dist/engine/entity-list-searchability.d.ts +2 -1
- package/dist/engine/event-def.d.ts +2 -1
- package/dist/engine/event-helpers.d.ts +3 -1
- package/dist/engine/event-helpers.js +3 -3
- package/dist/engine/extension-names.d.ts +2 -8
- package/dist/engine/extension-names.js +2 -2
- package/dist/engine/extension-selector-plugins.d.ts +1 -1
- package/dist/engine/extensions/storage-provider.d.ts +1 -2
- package/dist/engine/extensions/user-data.d.ts +0 -8
- package/dist/engine/factories.d.ts +2 -1
- package/dist/engine/feature-builder-state.d.ts +8 -1
- package/dist/engine/feature-changelog.d.ts +1 -1
- package/dist/engine/feature-config-events-jobs.d.ts +4 -1
- package/dist/engine/feature-entity-handlers.d.ts +5 -1
- package/dist/engine/feature-manifest.js +1 -1
- package/dist/engine/feature-ui-extensions.d.ts +7 -1
- package/dist/engine/feature-ui-extensions.js +6 -4
- package/dist/engine/field-access.d.ts +2 -1
- package/dist/engine/handler-field-references.d.ts +0 -4
- package/dist/engine/index.d.ts +57 -54
- package/dist/engine/index.js +22 -27
- package/dist/engine/instruction-fields.d.ts +1 -1
- package/dist/engine/personal-data-fields.d.ts +1 -1
- package/dist/engine/qualified-name.d.ts +0 -1
- package/dist/engine/read-claim.d.ts +2 -1
- package/dist/engine/registry-facade.js +0 -3
- package/dist/engine/registry-ingest.d.ts +2 -1
- package/dist/engine/registry-ingest.js +1 -2
- package/dist/engine/registry-state.d.ts +12 -2
- package/dist/engine/registry-state.js +2 -3
- package/dist/engine/registry-validate.d.ts +3 -1
- package/dist/engine/registry-validate.js +7 -7
- package/dist/engine/run-in.d.ts +1 -1
- package/dist/engine/run-in.js +0 -1
- package/dist/engine/schema-builder.d.ts +1 -1
- package/dist/engine/schema-builder.js +1 -1
- package/dist/engine/screen-filter-ops.d.ts +2 -1
- package/dist/engine/screen-filter-ops.js +0 -5
- package/dist/engine/soft-delete-cleanup.d.ts +1 -1
- package/dist/engine/soft-delete-cleanup.js +4 -4
- package/dist/engine/state-machine.js +2 -1
- package/dist/engine/steps/_read-source.js +1 -1
- package/dist/engine/steps/aggregate-append-event.js +2 -2
- package/dist/engine/steps/call-feature.js +2 -2
- package/dist/engine/steps/mail-send.js +1 -1
- package/dist/engine/steps/retry.js +1 -1
- package/dist/engine/steps/wait-for-event.js +1 -1
- package/dist/engine/steps/wait.js +1 -1
- package/dist/engine/steps/webhook-send.js +1 -1
- package/dist/engine/template-variables.d.ts +2 -1
- package/dist/engine/transfer-adjacency.d.ts +1 -1
- package/dist/engine/types/index.d.ts +8 -31
- package/dist/engine/types/index.js +2 -10
- package/dist/engine/validation.d.ts +2 -1
- package/dist/entrypoint/index.d.ts +7 -35
- package/dist/entrypoint/index.js +7 -1
- package/dist/entrypoint/internals.d.ts +40 -0
- package/dist/entrypoint/internals.js +1 -0
- package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
- package/dist/entrypoint/row-level-security-mode-check.js +19 -0
- package/dist/env/dry-run-internals.d.ts +10 -0
- package/dist/env/dry-run-internals.js +1 -0
- package/dist/env/dry-run.d.ts +1 -10
- package/dist/env/dry-run.js +2 -1
- package/dist/env/index.d.ts +1 -85
- package/dist/env/index.js +6 -50
- package/dist/env/internals.d.ts +87 -0
- package/dist/env/internals.js +53 -0
- package/dist/errors/classes.js +2 -2
- package/dist/errors/index.d.ts +5 -14
- package/dist/errors/index.js +4 -9
- package/dist/errors/member-resolution.js +1 -1
- package/dist/errors/reasons.d.ts +0 -1
- package/dist/errors/reasons.js +7 -7
- package/dist/errors/serialize.d.ts +0 -18
- package/dist/errors/serialize.js +0 -27
- package/dist/es-ops/index.d.ts +4 -4
- package/dist/es-ops/index.js +2 -2
- package/dist/es-ops/operations-schema.d.ts +1 -1
- package/dist/es-ops/types.d.ts +4 -5
- package/dist/event-store/admin-api-internals.d.ts +14 -0
- package/dist/event-store/admin-api-internals.js +1 -0
- package/dist/event-store/admin-api.d.ts +1 -14
- package/dist/event-store/admin-api.js +11 -6
- package/dist/event-store/archive.js +4 -2
- package/dist/event-store/errors.js +2 -2
- package/dist/event-store/event-store.js +41 -34
- package/dist/event-store/events-schema.js +4 -1
- package/dist/event-store/index.d.ts +11 -13
- package/dist/event-store/index.js +7 -9
- package/dist/event-store/rebuild-dead-letter.js +4 -2
- package/dist/event-store/snapshot.js +4 -3
- package/dist/event-store/stream-scope.d.ts +2 -0
- package/dist/event-store/stream-scope.js +6 -0
- package/dist/event-store/upcaster-dead-letter.js +4 -2
- package/dist/event-store/upcaster.d.ts +2 -1
- package/dist/files/action-form-upload.d.ts +2 -1
- package/dist/files/action-form-upload.js +1 -1
- package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
- package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
- package/dist/files/bind-pending-file-refs.d.ts +2 -1
- package/dist/files/bind-pending-file-refs.js +2 -1
- package/dist/files/bind-referenced-files.write.js +1 -1
- package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
- package/dist/files/create-file-ref-from-bytes.js +3 -3
- package/dist/files/create-file-ref.d.ts +3 -2
- package/dist/files/create-file-ref.js +2 -2
- package/dist/files/dispose-removed-file-refs.d.ts +2 -1
- package/dist/files/dispose-removed-file-refs.js +1 -1
- package/dist/files/feature.js +2 -2
- package/dist/files/file-handle.js +1 -1
- package/dist/files/file-routes.d.ts +1 -1
- package/dist/files/file-routes.js +12 -2
- package/dist/files/index.d.ts +11 -13
- package/dist/files/index.js +5 -7
- package/dist/files/load-save-file-refs.d.ts +2 -1
- package/dist/files/load-save-file-refs.js +1 -1
- package/dist/files/provider-resolver.d.ts +5 -4
- package/dist/files/provider-resolver.js +4 -4
- package/dist/files/storage-tracking.js +4 -2
- package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
- package/dist/files/sweep-orphaned-uploads.js +1 -1
- package/dist/i18n/index.d.ts +2 -8
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/internals.d.ts +7 -0
- package/dist/i18n/internals.js +1 -0
- package/dist/i18n/required-surface-keys.d.ts +4 -1
- package/dist/internal/row-level-security.d.ts +3 -0
- package/dist/internal/row-level-security.js +3 -0
- package/dist/internal/stack-support.d.ts +1 -1
- package/dist/internal/stack-support.js +1 -1
- package/dist/internal/testing.d.ts +1 -0
- package/dist/internal/testing.js +9 -5
- package/dist/jobs/index.d.ts +1 -1
- package/dist/jobs/job-append-event.d.ts +12 -0
- package/dist/jobs/job-append-event.js +30 -0
- package/dist/jobs/job-runner-context.d.ts +2 -2
- package/dist/jobs/job-runner-context.js +46 -16
- package/dist/jobs/job-runner-execution.d.ts +1 -1
- package/dist/jobs/job-runner-execution.js +6 -4
- package/dist/jobs/job-runner-gates.d.ts +1 -1
- package/dist/jobs/job-runner-gates.js +0 -1
- package/dist/jobs/job-runner-helpers.d.ts +11 -4
- package/dist/jobs/job-runner-helpers.js +10 -1
- package/dist/jobs/job-runner-scope.d.ts +5 -2
- package/dist/jobs/job-runner-types.d.ts +2 -1
- package/dist/jobs/job-runner.js +19 -6
- package/dist/jobs/max-per-tenant.d.ts +1 -1
- package/dist/logging/index.d.ts +1 -2
- package/dist/logging/index.js +1 -1
- package/dist/logging/pino-logger.js +1 -1
- package/dist/logging/utils.d.ts +1 -0
- package/dist/logging/utils.js +6 -0
- package/dist/migrations/index.d.ts +3 -3
- package/dist/migrations/index.js +3 -3
- package/dist/migrations/pending-rebuilds.d.ts +1 -1
- package/dist/migrations/pending-rebuilds.js +1 -1
- package/dist/migrations/pii-event-backfill.js +4 -1
- package/dist/observability/escape-hatch-report.d.ts +2 -1
- package/dist/observability/index.d.ts +7 -15
- package/dist/observability/index.js +4 -12
- package/dist/observability/metric-validator.js +1 -1
- package/dist/observability/metrics-handle.d.ts +0 -1
- package/dist/observability/metrics-handle.js +2 -15
- package/dist/observability/recording-tracer.d.ts +1 -2
- package/dist/observability/recording-tracer.js +0 -6
- package/dist/observability/sensitive-filter.d.ts +0 -2
- package/dist/observability/sensitive-filter.js +0 -29
- package/dist/pipeline/active-membership.d.ts +2 -1
- package/dist/pipeline/active-membership.js +6 -2
- package/dist/pipeline/append-event-core.d.ts +2 -1
- package/dist/pipeline/append-event-core.js +2 -2
- package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
- package/dist/pipeline/attach-outside-transaction.js +13 -0
- package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
- package/dist/pipeline/cascade-handler.d.ts +2 -1
- package/dist/pipeline/cascade-handler.js +3 -2
- package/dist/pipeline/config-accessor-factory.d.ts +1 -1
- package/dist/pipeline/config-accessor-factory.js +1 -1
- package/dist/pipeline/context-services.d.ts +56 -0
- package/dist/pipeline/context-services.js +73 -0
- package/dist/pipeline/dispatch-batch.d.ts +2 -1
- package/dist/pipeline/dispatch-batch.js +31 -18
- package/dist/pipeline/dispatch-query.js +5 -4
- package/dist/pipeline/dispatch-scope.d.ts +6 -0
- package/dist/pipeline/dispatch-scope.js +27 -0
- package/dist/pipeline/dispatch-shared.d.ts +13 -9
- package/dist/pipeline/dispatch-shared.js +75 -198
- package/dist/pipeline/dispatch-stream.js +8 -4
- package/dist/pipeline/dispatch-write.d.ts +2 -1
- package/dist/pipeline/dispatch-write.js +10 -8
- package/dist/pipeline/dispatcher-utils.d.ts +3 -1
- package/dist/pipeline/dispatcher-utils.js +8 -2
- package/dist/pipeline/dispatcher.d.ts +3 -2
- package/dist/pipeline/dispatcher.js +4 -3
- package/dist/pipeline/event-consumer-state.d.ts +0 -1
- package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
- package/dist/pipeline/event-dispatcher-delivery.js +4 -2
- package/dist/pipeline/event-dispatcher.d.ts +2 -2
- package/dist/pipeline/event-dispatcher.js +7 -3
- package/dist/pipeline/event-retention.js +59 -56
- package/dist/pipeline/handler-access-error.js +2 -1
- package/dist/pipeline/handler-context-auth.d.ts +5 -6
- package/dist/pipeline/handler-context-auth.js +7 -4
- package/dist/pipeline/handler-context-config.d.ts +2 -5
- package/dist/pipeline/handler-context-config.js +2 -2
- package/dist/pipeline/handler-context-db.d.ts +32 -7
- package/dist/pipeline/handler-context-db.js +26 -17
- package/dist/pipeline/handler-context-dispatch.d.ts +13 -7
- package/dist/pipeline/handler-context-dispatch.js +9 -8
- package/dist/pipeline/handler-context-events.d.ts +22 -36
- package/dist/pipeline/handler-context-events.js +36 -31
- package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
- package/dist/pipeline/handler-context-member-resolution.js +110 -0
- package/dist/pipeline/handler-context-notify.d.ts +3 -2
- package/dist/pipeline/handler-context-notify.js +1 -1
- package/dist/pipeline/handler-context-observability.d.ts +2 -4
- package/dist/pipeline/handler-context-observability.js +7 -5
- package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
- package/dist/pipeline/handler-context-phase-denials.js +98 -0
- package/dist/pipeline/handler-context-scope.d.ts +7 -10
- package/dist/pipeline/handler-context-scope.js +18 -20
- package/dist/pipeline/index.d.ts +9 -21
- package/dist/pipeline/index.js +5 -7
- package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
- package/dist/pipeline/irreversible-operation-gate.js +2 -2
- package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
- package/dist/pipeline/lifecycle-pipeline.js +9 -15
- package/dist/pipeline/member-read-only-transaction.js +11 -3
- package/dist/pipeline/member-reader.d.ts +1 -1
- package/dist/pipeline/member-reader.js +2 -2
- package/dist/pipeline/msp-rebuild.js +5 -3
- package/dist/pipeline/multi-stream-apply-context.js +3 -2
- package/dist/pipeline/notify-scope.d.ts +2 -1
- package/dist/pipeline/pre-handler-gates.d.ts +2 -1
- package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
- package/dist/pipeline/pre-transaction-reservations.js +9 -7
- package/dist/pipeline/projection-rebuild.js +12 -5
- package/dist/pipeline/projection-state.d.ts +0 -6
- package/dist/pipeline/projection-state.js +0 -5
- package/dist/pipeline/projections-runner.d.ts +2 -1
- package/dist/pipeline/projections-runner.js +10 -6
- package/dist/pipeline/system-hooks.d.ts +3 -1
- package/dist/pipeline/system-hooks.js +6 -4
- package/dist/pipeline/system-identity-switch.d.ts +4 -2
- package/dist/pipeline/system-identity-switch.js +51 -36
- package/dist/pipeline/typed-append-event.d.ts +2 -0
- package/dist/pipeline/typed-append-event.js +4 -0
- package/dist/pipeline/write-origin.js +2 -2
- package/dist/pipeline/write-result-masking.d.ts +1 -1
- package/dist/random/index.d.ts +1 -2
- package/dist/random/index.js +1 -2
- package/dist/rate-limit/bucket.d.ts +2 -1
- package/dist/rate-limit/middleware.js +2 -1
- package/dist/redis/index.d.ts +3 -4
- package/dist/redis/index.js +2 -2
- package/dist/schema-cli/apply-command.js +5 -2
- package/dist/schema-cli/baseline-command.js +7 -2
- package/dist/schema-cli/generate-command.js +7 -9
- package/dist/schema-cli/shared.d.ts +12 -2
- package/dist/schema-cli/shared.js +24 -2
- package/dist/schema-cli/status-command.js +8 -2
- package/dist/schema-cli/validate-command.js +48 -4
- package/dist/schema-cli.d.ts +0 -1
- package/dist/search/configure-tenant-index.d.ts +1 -3
- package/dist/search/configure-tenant-index.js +0 -4
- package/dist/search/index.d.ts +1 -4
- package/dist/search/index.js +0 -2
- package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
- package/dist/search/meilisearch-adapter-internals.js +9 -0
- package/dist/search/meilisearch-adapter.d.ts +1 -8
- package/dist/search/meilisearch-adapter.js +6 -7
- package/dist/search/meilisearch-peer.d.ts +2 -0
- package/dist/search/meilisearch-peer.js +5 -0
- package/dist/search/reindex-entity.js +93 -87
- package/dist/secrets/index.d.ts +3 -4
- package/dist/secrets/index.js +2 -3
- package/dist/seeding/index.d.ts +2 -2
- package/dist/seeding/index.js +1 -2
- package/dist/time/index.d.ts +2 -2
- package/dist/time/index.js +1 -1
- package/dist/time/tz-context.d.ts +0 -5
- package/dist/time/tz-context.js +0 -9
- package/dist/ui-types/index.d.ts +8 -11
- package/dist/ui-types/index.js +3 -3
- package/dist/upgrade-changelog.d.ts +3 -2
- package/dist/upgrade-changelog.js +12 -8
- package/dist/upgrade-cli-internals.d.ts +8 -0
- package/dist/upgrade-cli-internals.js +63 -0
- package/dist/upgrade-cli.d.ts +2 -9
- package/dist/upgrade-cli.js +28 -70
- package/dist/utils/import-optional-peer.d.ts +6 -0
- package/dist/utils/import-optional-peer.js +19 -0
- package/dist/utils/index.d.ts +1 -4
- package/dist/utils/index.js +1 -4
- package/package.json +23 -19
- package/src/changes.json +236 -0
- package/dist/crypto/request-kms-cache.d.ts +0 -8
- package/dist/crypto/request-kms-cache.js +0 -21
- package/dist/engine/codemod/index.d.ts +0 -2
- package/dist/engine/codemod/index.js +0 -1
- package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
- package/dist/engine/codemod/pipeline-codemod.js +0 -536
- package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
- package/dist/engine/feature-ast/entity-field-types.js +0 -35
- package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
- package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
- package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
- package/dist/engine/feature-ast/extractors/events.js +0 -275
- package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
- package/dist/engine/feature-ast/extractors/handlers.js +0 -358
- package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
- package/dist/engine/feature-ast/extractors/hooks.js +0 -248
- package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
- package/dist/engine/feature-ast/extractors/index.js +0 -13
- package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
- package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
- package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
- package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
- package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
- package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
- package/dist/engine/feature-ast/extractors/round1.d.ts +0 -11
- package/dist/engine/feature-ast/extractors/round1.js +0 -87
- package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
- package/dist/engine/feature-ast/extractors/round2.js +0 -191
- package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
- package/dist/engine/feature-ast/extractors/round3.js +0 -292
- package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
- package/dist/engine/feature-ast/extractors/round5.js +0 -68
- package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
- package/dist/engine/feature-ast/extractors/round6.js +0 -17
- package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
- package/dist/engine/feature-ast/extractors/shared.js +0 -343
- package/dist/engine/feature-ast/index.d.ts +0 -16
- package/dist/engine/feature-ast/index.js +0 -10
- package/dist/engine/feature-ast/parse.d.ts +0 -31
- package/dist/engine/feature-ast/parse.js +0 -485
- package/dist/engine/feature-ast/patch.d.ts +0 -212
- package/dist/engine/feature-ast/patch.js +0 -611
- package/dist/engine/feature-ast/patcher.d.ts +0 -217
- package/dist/engine/feature-ast/patcher.js +0 -281
- package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1238
- package/dist/engine/feature-ast/pattern-change-schema.js +0 -1072
- package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
- package/dist/engine/feature-ast/pattern-id-matchers.js +0 -211
- package/dist/engine/feature-ast/pattern-id-schema.d.ts +0 -251
- package/dist/engine/feature-ast/pattern-id-schema.js +0 -166
- package/dist/engine/feature-ast/patterns.d.ts +0 -322
- package/dist/engine/feature-ast/patterns.js +0 -107
- package/dist/engine/feature-ast/render.d.ts +0 -47
- package/dist/engine/feature-ast/render.js +0 -666
- package/dist/engine/feature-ast/source-location.d.ts +0 -17
- package/dist/engine/feature-ast/source-location.js +0 -27
- package/dist/engine/pattern-library/index.d.ts +0 -2
- package/dist/engine/pattern-library/index.js +0 -3
- package/dist/engine/pattern-library/library.d.ts +0 -14
- package/dist/engine/pattern-library/library.js +0 -94
- package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
- package/dist/engine/pattern-library/mixed-schemas.js +0 -559
- package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
- package/dist/engine/pattern-library/opaque-schemas.js +0 -115
- package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
- package/dist/engine/pattern-library/shared-fields.js +0 -88
- package/dist/engine/pattern-library/static-schemas.d.ts +0 -21
- package/dist/engine/pattern-library/static-schemas.js +0 -487
- package/dist/engine/pattern-library/types.d.ts +0 -158
- package/dist/engine/pattern-library/types.js +0 -36
- package/dist/engine/resolve-config-or-param.d.ts +0 -18
- package/dist/engine/resolve-config-or-param.js +0 -76
- package/src/scripts/codemod/README.md +0 -187
- package/src/scripts/codemod/codemod-support.ts +0 -334
- package/src/scripts/codemod/collect-source-files.ts +0 -48
- package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
- package/src/scripts/codemod/db-factory.ts +0 -810
- package/src/scripts/codemod/feature-factory.ts +0 -429
- package/src/scripts/codemod/feature-layout.ts +0 -424
- package/src/scripts/codemod/import-extensions.ts +0 -118
- package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
- package/src/scripts/codemod/migrate-db-raw.ts +0 -401
- package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
- package/src/scripts/codemod/object-form.ts +0 -746
- package/src/scripts/codemod/package-merge.ts +0 -299
- package/src/scripts/codemod/pii-personal-migration.ts +0 -816
- package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
- package/src/scripts/codemod/s3-imports.ts +0 -236
- package/src/scripts/codemod/tenant-db-options.ts +0 -454
- package/src/scripts/codemod/testing-injection.ts +0 -215
- package/src/scripts/codemod/testing-move-targets.ts +0 -161
- package/src/scripts/codemod/testing-move.ts +0 -542
- package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
package/dist/pipeline/index.js
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
|
-
export { createEscapeHatchReporter,
|
|
1
|
+
export { createEscapeHatchReporter, ESCAPE_HATCH_USED_SIGNAL, flushEscapeHatchAudits, UNATTRIBUTED_ACTOR, } from "../observability/escape-hatch-report.js";
|
|
2
2
|
export { normalizePayloadBucketValue } from "../rate-limit/bucket.js";
|
|
3
3
|
export { createUnlimitedRateLimitResolver } from "../rate-limit/unlimited-resolver.js";
|
|
4
4
|
export { appendDomainEventCore } from "./append-event-core.js";
|
|
5
5
|
export { resolveAuthClaims } from "./auth-claims-resolver.js";
|
|
6
6
|
export { createCascadeDeleteHook } from "./cascade-handler.js";
|
|
7
7
|
export { createDispatcher, dispatcherToWriteRef } from "./dispatcher.js";
|
|
8
|
-
export { isFailedWriteResult } from "./dispatcher-utils.js";
|
|
9
8
|
export { createDistributedLock } from "./distributed-lock.js";
|
|
10
9
|
export { createEntityCache } from "./entity-cache.js";
|
|
11
10
|
export { ConsumerStatuses, createEventConsumerStateTable, eventConsumerStateTable, SHARED_INSTANCE_SENTINEL, } from "./event-consumer-state.js";
|
|
12
11
|
export { createEventDedup } from "./event-dedup.js";
|
|
13
|
-
export { ConsumerTransitionError,
|
|
14
|
-
export { selectConsumerCursorForUpdate } from "./event-dispatcher-delivery.js";
|
|
12
|
+
export { ConsumerTransitionError, disableConsumer, enableConsumer, getAllConsumerProgress, getConsumerState, listConsumersWithState, restartConsumer, skipPoisonEvent, } from "./event-dispatcher.js";
|
|
15
13
|
export { ConsumerLagError, pruneEvents } from "./event-retention.js";
|
|
16
14
|
export { createIdempotencyGuard } from "./idempotency.js";
|
|
17
|
-
export {
|
|
15
|
+
export { assertIrreversibleOperationAllowed } from "./irreversible-operation-gate.js";
|
|
18
16
|
export { createLifecycleHooks } from "./lifecycle-pipeline.js";
|
|
19
17
|
export { rebuildMultiStreamProjection } from "./msp-rebuild.js";
|
|
20
18
|
export { createMultiStreamApplyContext } from "./multi-stream-apply-context.js";
|
|
21
19
|
export { assertNotifyTargetsOwnTenant, createDeferringNotify } from "./notify-scope.js";
|
|
22
20
|
export { getAllProjectionProgress, getProjectionState, listProjectionsWithState, rebuildProjection, } from "./projection-rebuild.js";
|
|
23
|
-
export { createProjectionStateTable,
|
|
21
|
+
export { createProjectionStateTable, projectionStateTable, } from "./projection-state.js";
|
|
24
22
|
export { runProjectionsForEvent } from "./projections-runner.js";
|
|
25
|
-
export {
|
|
23
|
+
export { SEARCH_CONSUMER_NAME, SSE_BROADCAST_CONSUMER_NAME, } from "./system-hooks.js";
|
|
26
24
|
export { TENANT_TIMEZONE_CONFIG_KEY } from "./tenant-timezone-config-key.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityDefinition } from "
|
|
1
|
+
import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
|
|
2
2
|
export declare function isIrreversibleEntityVerb(verb: "delete" | "forget", entity: EntityDefinition): boolean;
|
|
3
3
|
export declare function assertIrreversibleOperationAllowed(operation: string): void;
|
|
4
4
|
export declare function assertInstructionFieldWriteAllowed(entityName: string, verb: "create" | "update", writtenFieldNames: readonly string[], instructionFieldNames: readonly string[]): void;
|
|
@@ -39,7 +39,7 @@ export function assertIrreversibleOperationAllowed(operation) {
|
|
|
39
39
|
reason: FrameworkReasons.irreversibleOperationRequiresHighRisk,
|
|
40
40
|
buildMessage: (entryHandler) => `Handler "${entryHandler.qn}" performs an irreversible ${operation} but resolves agent risk ` +
|
|
41
41
|
`"${entryHandler.risk}" — ${highRiskRemedy(entryHandler)}. The ` +
|
|
42
|
-
"directly called handler must carry it; delegating via ctx.write/writeAs does not.",
|
|
42
|
+
"directly called handler must carry it; delegating via ctx.dispatch.write/writeAs does not.",
|
|
43
43
|
details: { operation },
|
|
44
44
|
});
|
|
45
45
|
}
|
|
@@ -57,7 +57,7 @@ export function assertInstructionFieldWriteAllowed(entityName, verb, writtenFiel
|
|
|
57
57
|
buildMessage: (entryHandler) => `Handler "${entryHandler.qn}" ${verb}s "${entityName}" field(s) ${fields.join(", ")} ` +
|
|
58
58
|
`flagged readAsInstruction: true but resolves agent risk "${entryHandler.risk}" — ` +
|
|
59
59
|
`${highRiskRemedy(entryHandler)}. The directly called handler must carry ` +
|
|
60
|
-
"it; delegating via ctx.write/writeAs does not.",
|
|
60
|
+
"it; delegating via ctx.dispatch.write/writeAs does not.",
|
|
61
61
|
details: { entityName, verb, fields },
|
|
62
62
|
});
|
|
63
63
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DeleteContext, HookPhase, PostDeleteBatchHookFn, PostDeleteHookFn, PostSaveBatchHookFn, PostSaveHookFn, PreDeleteHookFn, PreSaveHookFn, SaveContext } from "@cosmicdrift/kumiko-types/hooks";
|
|
2
|
+
import type { HandlerContext, Registry } from "../engine/types/index.ts";
|
|
2
3
|
import type { EventDedup } from "./event-dedup.ts";
|
|
3
4
|
export type SystemHookDef<TFn> = {
|
|
4
5
|
readonly name: string;
|
|
@@ -15,12 +16,12 @@ export type SystemHooks = {
|
|
|
15
16
|
readonly postDeleteBatch?: readonly SystemHookDef<PostDeleteBatchHookFn>[];
|
|
16
17
|
};
|
|
17
18
|
export type LifecycleHooks = {
|
|
18
|
-
runPreSave(handlerName: string, changes: Record<string, unknown>, previous: Readonly<Record<string, unknown>>, isNew: boolean, context:
|
|
19
|
-
runPostSave(handlerName: string, result: SaveContext, context:
|
|
20
|
-
runPreDelete(handlerName: string, payload: DeleteContext, context:
|
|
21
|
-
runPostDelete(handlerName: string, payload: DeleteContext, context:
|
|
22
|
-
runPostSaveBatch(results: readonly SaveContext[], context:
|
|
23
|
-
runPostDeleteBatch(payloads: readonly DeleteContext[], context:
|
|
19
|
+
runPreSave(handlerName: string, changes: Record<string, unknown>, previous: Readonly<Record<string, unknown>>, isNew: boolean, context: HandlerContext): Promise<Record<string, unknown>>;
|
|
20
|
+
runPostSave(handlerName: string, result: SaveContext, context: HandlerContext, phase?: HookPhase): Promise<void>;
|
|
21
|
+
runPreDelete(handlerName: string, payload: DeleteContext, context: HandlerContext): Promise<void>;
|
|
22
|
+
runPostDelete(handlerName: string, payload: DeleteContext, context: HandlerContext, phase?: HookPhase): Promise<void>;
|
|
23
|
+
runPostSaveBatch(results: readonly SaveContext[], context: HandlerContext): Promise<void>;
|
|
24
|
+
runPostDeleteBatch(payloads: readonly DeleteContext[], context: HandlerContext): Promise<void>;
|
|
24
25
|
};
|
|
25
26
|
export type LifecycleOptions = {
|
|
26
27
|
eventDedup?: EventDedup;
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import { HookPhases } from "../engine/
|
|
1
|
+
import { HookPhases } from "../engine/hook-helpers.js";
|
|
2
2
|
import { createFallbackLogger } from "../logging/utils.js";
|
|
3
|
-
import { getFallbackTracer } from "../observability/index.js";
|
|
4
3
|
function resolveTracer(context) {
|
|
5
|
-
return context.tracer
|
|
4
|
+
return context.obs.tracer;
|
|
6
5
|
}
|
|
7
6
|
/**
|
|
8
7
|
* Resolves the effective feature set for the active context's tenant.
|
|
9
8
|
*
|
|
10
|
-
*
|
|
11
|
-
* HandlerContext. Legacy call sites without a user (system jobs, boot-time
|
|
12
|
-
* pipeline) leave it undefined; `effectiveFeatures(undefined)` is type-unsafe,
|
|
13
|
-
* so this returns undefined and treats that as "all features on" (registry
|
|
9
|
+
* Without a wired resolver this returns undefined, which means "all features on" (registry
|
|
14
10
|
* filter hooks accept undefined to skip filtering).
|
|
15
11
|
*
|
|
16
12
|
* This is the single path used by all four lifecycle-hook call sites
|
|
@@ -18,9 +14,7 @@ function resolveTracer(context) {
|
|
|
18
14
|
* consistent.
|
|
19
15
|
*/
|
|
20
16
|
function currentEffectiveFeatures(context) {
|
|
21
|
-
|
|
22
|
-
return undefined;
|
|
23
|
-
return context.effectiveFeatures?.(context._tenantId);
|
|
17
|
+
return context.services.effectiveFeatures?.(context.user.tenantId);
|
|
24
18
|
}
|
|
25
19
|
export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
|
|
26
20
|
const { eventDedup } = options;
|
|
@@ -46,14 +40,14 @@ export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
|
|
|
46
40
|
// best-effort side-effects like Search Index, SSE broadcast, Audit — a
|
|
47
41
|
// missed hook is preferable to a duplicate notification. Features that
|
|
48
42
|
// need at-least-once semantics must not rely on this path; use
|
|
49
|
-
// ctx.
|
|
43
|
+
// ctx.events.append + r.multiStreamProjection instead, which the
|
|
50
44
|
// event-dispatcher retries until the consumer advances.
|
|
51
45
|
if (eventDedup && opts.hookPhase === HookPhases.afterCommit) {
|
|
52
46
|
const eventId = buildEventId(opts.handlerName, opts.payload, opts.phaseLabel);
|
|
53
47
|
if (eventId) {
|
|
54
48
|
const acquired = await eventDedup.tryAcquire(eventId);
|
|
55
49
|
if (!acquired) {
|
|
56
|
-
opts.context.log
|
|
50
|
+
opts.context.obs.log.debug(`${opts.phaseLabel}: skipping ${opts.handlerName} — event ${eventId} already processed (dedup)`);
|
|
57
51
|
return;
|
|
58
52
|
}
|
|
59
53
|
}
|
|
@@ -62,7 +56,7 @@ export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
|
|
|
62
56
|
// always returns one. Log so we can spot framework/feature bugs where
|
|
63
57
|
// a handler emits a non-standard LifecycleResult and accidentally
|
|
64
58
|
// bypasses dedup.
|
|
65
|
-
opts.context.log
|
|
59
|
+
opts.context.obs.log.warn(`${opts.phaseLabel}: ${opts.handlerName} has no dedup id (payload missing \`id\`) — hook may run multiple times on retry`);
|
|
66
60
|
}
|
|
67
61
|
}
|
|
68
62
|
const errors = [];
|
|
@@ -128,7 +122,7 @@ export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
|
|
|
128
122
|
await runHooks(applicable, (h) => ({ "kumiko.hook_source": "system", "kumiko.hook_name": h.name }), (h) => h.name, (h) => h.fn(opts.payload, opts.context));
|
|
129
123
|
}
|
|
130
124
|
if (errors.length > 0) {
|
|
131
|
-
const logError = createFallbackLogger("lifecycle", opts.context.log);
|
|
125
|
+
const logError = createFallbackLogger("lifecycle", opts.context.obs.log);
|
|
132
126
|
const msg = `${opts.phaseLabel} errors for ${opts.handlerName}`;
|
|
133
127
|
logError.error(msg, { details: errors.map((e) => `${e.name}: ${e.error}`) });
|
|
134
128
|
}
|
|
@@ -235,7 +229,7 @@ export function createLifecycleHooks(registry, systemHooks = {}, options = {}) {
|
|
|
235
229
|
// skip: all batch hooks succeeded, nothing to log
|
|
236
230
|
if (failures.length === 0)
|
|
237
231
|
return;
|
|
238
|
-
const logError = createFallbackLogger("lifecycle", opts.context.log);
|
|
232
|
+
const logError = createFallbackLogger("lifecycle", opts.context.obs.log);
|
|
239
233
|
const msg = `${opts.phaseLabel} errors`;
|
|
240
234
|
logError.error(msg, { details: failures.map((f) => `${f.name}: ${f.outcome.reason}`) });
|
|
241
235
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { extractPgError } from "../db/pg-error.js";
|
|
2
2
|
import { asRawClient, runInSavepoint, transaction } from "../db/query.js";
|
|
3
|
-
import {
|
|
3
|
+
import { activeRowLevelSecurityScope, runInCapturedRowLevelSecurityScope, runInSystemRowLevelSecurityScope, } from "../db/row-level-security-scope.js";
|
|
4
|
+
import { MemberReadTimeoutError } from "../errors/classes.js";
|
|
5
|
+
import { AccessDeniedError, InternalError } from "../errors/index.js";
|
|
6
|
+
import { memberResolutionReadOnlyDenied } from "../errors/member-resolution.js";
|
|
4
7
|
import { resolveDbSource } from "./dispatch-shared.js";
|
|
5
8
|
const PG_READ_ONLY_SQLSTATE = "25006";
|
|
6
9
|
const PG_QUERY_CANCELED_SQLSTATE = "57014";
|
|
@@ -51,7 +54,12 @@ async function runInDiscardedReadOnlySavepoint(tx, timeoutMs, bindIdleTimeout, f
|
|
|
51
54
|
}
|
|
52
55
|
return settled.outcome.value;
|
|
53
56
|
}
|
|
54
|
-
export
|
|
57
|
+
export function runInMemberReadOnlyTransaction(ctx, tx, fn) {
|
|
58
|
+
// Only the transaction plumbing (savepoint, SET) runs system-scoped; the caller's fn keeps the dispatch scope it came in with.
|
|
59
|
+
const incoming = activeRowLevelSecurityScope();
|
|
60
|
+
return runInSystemRowLevelSecurityScope("member read-only transaction opens its connection under system scope, then restores the caller scope", () => runInMemberReadOnlyTransactionScoped(ctx, tx, (readOnlyTx) => runInCapturedRowLevelSecurityScope(incoming, () => fn(readOnlyTx))));
|
|
61
|
+
}
|
|
62
|
+
async function runInMemberReadOnlyTransactionScoped(ctx, tx, fn) {
|
|
55
63
|
const timeoutMs = ctx.memberReadTimeoutMs;
|
|
56
64
|
try {
|
|
57
65
|
if (tx)
|
|
@@ -59,7 +67,7 @@ export async function runInMemberReadOnlyTransaction(ctx, tx, fn) {
|
|
|
59
67
|
const pool = resolveDbSource(ctx, undefined);
|
|
60
68
|
if (!pool) {
|
|
61
69
|
throw new InternalError({
|
|
62
|
-
message: "ctx.queryAsMember requires a database connection — none is configured.",
|
|
70
|
+
message: "ctx.dispatch.queryAsMember requires a database connection — none is configured.",
|
|
63
71
|
});
|
|
64
72
|
}
|
|
65
73
|
// Savepoint even on the pool path: Postgres rejects a READ WRITE reset (SQLSTATE 25001) inside a subtransaction.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { MemberReader } from "@cosmicdrift/kumiko-types/handlers";
|
|
1
2
|
import type { DbTx } from "../db/connection.ts";
|
|
2
3
|
import type { TenantId } from "../engine/types/identifiers.ts";
|
|
3
|
-
import type { MemberReader } from "../engine/types/index.ts";
|
|
4
4
|
import { type ActiveMembershipPolicy } from "./active-membership.ts";
|
|
5
5
|
import { type DispatchContext } from "./dispatch-shared.ts";
|
|
6
6
|
export declare const BACKGROUND_READ_POLICY: ActiveMembershipPolicy;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ctx.queryAsMember — reads a query handler as a stored tenant member. The
|
|
1
|
+
// ctx.dispatch.queryAsMember — reads a query handler as a stored tenant member. The
|
|
2
2
|
// resolved SessionUser never leaves this module.
|
|
3
3
|
import { buildSessionRoles } from "../engine/membership-roles.js";
|
|
4
4
|
import { SYSTEM_TENANT_ID } from "../engine/types/index.js";
|
|
@@ -32,7 +32,7 @@ async function resolveMember(ctx, tenantId, userId) {
|
|
|
32
32
|
const dbSource = resolveDbSource(ctx, undefined);
|
|
33
33
|
if (!dbSource) {
|
|
34
34
|
throw new InternalError({
|
|
35
|
-
message: "ctx.queryAsMember requires a database connection — none is configured.",
|
|
35
|
+
message: "ctx.dispatch.queryAsMember requires a database connection — none is configured.",
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
// resolveDbSource(ctx, undefined) never returns a tx, only AppContext.db.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { markConsumerRebuildFailed, resetConsumerForMspRebuild, selectConsumerForUpdate, selectEventIdHorizonWithMissingRanges, selectSnapshotXmax, updateConsumerRebuildCursor, } from "../db/queries/event-consumer.js";
|
|
2
|
-
import {
|
|
2
|
+
import { assertRebuildableRowLevelSecurity } from "../db/queries/rebuild-rls-guard.js";
|
|
3
|
+
import { assertLiveColumnsMatchMeta, buildShadowTable, ensureRebuildSchema, rebuildMetaOrThrow, swapShadowIntoLive, } from "../db/queries/shadow-swap.js";
|
|
3
4
|
import { runInSavepoint, selectMany } from "../db/query.js";
|
|
5
|
+
import { runInSystemRowLevelSecurityScope } from "../db/row-level-security-scope.js";
|
|
4
6
|
import { withoutStatementTimeout } from "../db/statement-timeout.js";
|
|
5
7
|
import { withExecutorManagedWrites } from "../db/tenant-db.js";
|
|
6
8
|
import { InternalError } from "../errors/index.js";
|
|
@@ -31,7 +33,7 @@ function createRebuildCtx(registry, db, tenantId) {
|
|
|
31
33
|
};
|
|
32
34
|
}
|
|
33
35
|
export function rebuildMultiStreamProjection(mspName, deps) {
|
|
34
|
-
return withoutStatementTimeout(deps.db, (db) => replayMultiStreamProjectionIntoShadow(mspName, { ...deps, db }));
|
|
36
|
+
return withoutStatementTimeout(deps.db, (db) => runInSystemRowLevelSecurityScope("multi-stream projection rebuild replays events of all tenants", () => replayMultiStreamProjectionIntoShadow(mspName, { ...deps, db })));
|
|
35
37
|
}
|
|
36
38
|
async function replayMultiStreamProjectionIntoShadow(mspName, deps) {
|
|
37
39
|
const { db, registry } = deps;
|
|
@@ -62,11 +64,11 @@ async function replayMultiStreamProjectionIntoShadow(mspName, deps) {
|
|
|
62
64
|
await createRebuildDeadLetterTable(db);
|
|
63
65
|
const replayedIds = [];
|
|
64
66
|
await db.begin(async (tx) => {
|
|
67
|
+
await assertRebuildableRowLevelSecurity(tx, meta.tableName);
|
|
65
68
|
await resetConsumerForMspRebuild(tx, mspName, SHARED_INSTANCE_SENTINEL);
|
|
66
69
|
await selectConsumerForUpdate(tx, mspName, SHARED_INSTANCE_SENTINEL);
|
|
67
70
|
const { horizon, gaps: seededGaps } = await selectEventIdHorizonWithMissingRanges(tx);
|
|
68
71
|
await assertLiveColumnsMatchMeta(tx, meta, mspName);
|
|
69
|
-
await assertLiveTableHasNoRowLevelSecurity(tx, meta.tableName, mspName);
|
|
70
72
|
await buildShadowTable(tx, meta);
|
|
71
73
|
const subscribedTypes = Object.keys(msp.apply);
|
|
72
74
|
if (subscribedTypes.length > 0) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { loadAggregate, loadAggregateAsOf } from "../event-store/event-store.js";
|
|
2
2
|
import { upcastStoredEvents } from "../event-store/upcaster.js";
|
|
3
3
|
import { appendDomainEventCore } from "./append-event-core.js";
|
|
4
|
+
import { asTypedAppendEventFn } from "./typed-append-event.js";
|
|
4
5
|
export function createMultiStreamApplyContext(deps) {
|
|
5
6
|
return {
|
|
6
7
|
registry: deps.registry,
|
|
@@ -8,7 +9,7 @@ export function createMultiStreamApplyContext(deps) {
|
|
|
8
9
|
...(deps.derivatives ? { derivatives: deps.derivatives } : {}),
|
|
9
10
|
...(deps.secrets ? { secrets: deps.secrets } : {}),
|
|
10
11
|
...(deps.jobs ? { jobs: deps.jobs } : {}),
|
|
11
|
-
appendEvent: (async (args) => {
|
|
12
|
+
appendEvent: asTypedAppendEventFn(async (args) => {
|
|
12
13
|
await appendDomainEventCore({
|
|
13
14
|
registry: deps.registry,
|
|
14
15
|
db: deps.db,
|
|
@@ -17,7 +18,7 @@ export function createMultiStreamApplyContext(deps) {
|
|
|
17
18
|
callSiteLabel: "MSP-apply ctx.appendEvent",
|
|
18
19
|
...(deps.callerFeature && { callerFeature: deps.callerFeature }),
|
|
19
20
|
}, args);
|
|
20
|
-
}),
|
|
21
|
+
}),
|
|
21
22
|
unsafeAppendEvent: async (args) => {
|
|
22
23
|
await appendDomainEventCore({
|
|
23
24
|
registry: deps.registry,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { NotifyFn, NotifyOptions } from "@cosmicdrift/kumiko-types/handlers";
|
|
1
2
|
import type { TenantId } from "../engine/types/identifiers.ts";
|
|
2
|
-
import type {
|
|
3
|
+
import type { Registry } from "../engine/types/index.ts";
|
|
3
4
|
import type { AfterCommitHook } from "./dispatcher-utils.ts";
|
|
4
5
|
export declare function assertNotifyTargetsOwnTenant(options: NotifyOptions, tenantId: TenantId): void;
|
|
5
6
|
type DeferringNotifyDeps = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { WriteHandlerDef } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import type { SessionUser } from "../engine/types/index.ts";
|
|
2
3
|
import { type WriteFailure } from "../errors/index.ts";
|
|
3
4
|
import type { DispatchContext } from "./dispatch-shared.ts";
|
|
4
5
|
export type PreHandlerGateMode = "charge" | "recheck";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ReservationHandle } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
-
import type { SessionUser
|
|
3
|
-
import {
|
|
1
|
+
import type { ReservationHandle, WriteHandlerDef } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import type { SessionUser } from "../engine/types/index.ts";
|
|
3
|
+
import type { WriteErrorInfo } from "../errors/index.ts";
|
|
4
4
|
import type { BatchCommand, DispatchContext } from "./dispatch-shared.ts";
|
|
5
5
|
import type { WriteOrigin } from "./write-origin.ts";
|
|
6
6
|
type ReservationConfirm = ReservationHandle["confirmInTransaction"];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
-
import { toWriteErrorInfo } from "../errors/
|
|
2
|
+
import { toWriteErrorInfo } from "../errors/write-error-info.js";
|
|
3
3
|
import { createFallbackLogger } from "../logging/utils.js";
|
|
4
|
-
import {
|
|
4
|
+
import { buildHandlerContext, isMemberResolutionPrincipal } from "./dispatch-shared.js";
|
|
5
5
|
import { wrapToKumiko } from "./dispatcher-utils.js";
|
|
6
6
|
import { runPreHandlerGates } from "./pre-handler-gates.js";
|
|
7
7
|
import { effectiveWriteOrigin, rootWriteOrigin } from "./write-origin.js";
|
|
@@ -9,7 +9,7 @@ export function hasPreTransactionPhase(handler) {
|
|
|
9
9
|
return handler.reserveBeforeTransaction !== undefined || handler.beforeTransaction !== undefined;
|
|
10
10
|
}
|
|
11
11
|
// One-shot permission per top-level command: the handler that reserved before the transaction
|
|
12
|
-
// consumes it on entry. A capped handler reached any other way (nested ctx.write, writeAs, a
|
|
12
|
+
// consumes it on entry. A capped handler reached any other way (nested ctx.dispatch.write, writeAs, a
|
|
13
13
|
// second execution of the same type) finds it spent and is rejected instead of running unreserved.
|
|
14
14
|
const reservedForCommand = new AsyncLocalStorage();
|
|
15
15
|
export function runAsCommand(reserved, fn) {
|
|
@@ -65,8 +65,10 @@ export async function reserveBeforeTransaction(ctx, commands, user, inheritedOri
|
|
|
65
65
|
const event = { type: command.type, payload: gates.payload, user };
|
|
66
66
|
let confirmInTransaction;
|
|
67
67
|
if (handler.reserveBeforeTransaction) {
|
|
68
|
-
const
|
|
69
|
-
|
|
68
|
+
const reservationContext = await buildHandlerContext(ctx, command.type, user, origin, {
|
|
69
|
+
phase: "reservation",
|
|
70
|
+
});
|
|
71
|
+
const handle = toReservationHandle(await handler.reserveBeforeTransaction(event, reservationContext));
|
|
70
72
|
if (handle)
|
|
71
73
|
releases.push(handle.release);
|
|
72
74
|
confirmInTransaction = handle?.confirmInTransaction;
|
|
@@ -74,9 +76,9 @@ export async function reserveBeforeTransaction(ctx, commands, user, inheritedOri
|
|
|
74
76
|
let prepared;
|
|
75
77
|
if (handler.beforeTransaction) {
|
|
76
78
|
const phaseContext = await buildHandlerContext(ctx, command.type, user, origin, {
|
|
77
|
-
|
|
79
|
+
phase: "beforeTransaction",
|
|
78
80
|
});
|
|
79
|
-
const phase = await handler.beforeTransaction(event,
|
|
81
|
+
const phase = await handler.beforeTransaction(event, phaseContext);
|
|
80
82
|
if (!phase.isSuccess) {
|
|
81
83
|
await releaseAll(ctx, releases);
|
|
82
84
|
return { isSuccess: false, error: phase.error, failedIndex: index };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { countSubscribedEvents, finalizeProjectionRebuild, markProjectionRebuildFailed, markProjectionRebuilding, selectEventsForProjectionRebuildBatch, } from "../db/queries/projection-rebuild.js";
|
|
2
|
-
import {
|
|
2
|
+
import { assertRebuildableRowLevelSecurity } from "../db/queries/rebuild-rls-guard.js";
|
|
3
|
+
import { assertLiveColumnsMatchMeta, assertNoBlindIndexLoss, assertNoUnreachableLiveRows, buildShadowTable, countColumnDrift, ensureRebuildSchema, fenceLiveTable, rebuildMetaOrThrow, swapShadowIntoLive, } from "../db/queries/shadow-swap.js";
|
|
3
4
|
import { coerceRow, runInSavepoint, selectMany } from "../db/query.js";
|
|
5
|
+
import { runInSystemRowLevelSecurityScope } from "../db/row-level-security-scope.js";
|
|
4
6
|
import { withoutStatementTimeout } from "../db/statement-timeout.js";
|
|
5
7
|
import { extractTableInfo } from "../db/table-info.js";
|
|
6
8
|
import { withExecutorManagedWrites } from "../db/tenant-db.js";
|
|
@@ -35,6 +37,7 @@ function rowToStoredEvent(row) {
|
|
|
35
37
|
createdBy: row.createdBy,
|
|
36
38
|
};
|
|
37
39
|
}
|
|
40
|
+
const TENANT_COLUMN_SUFFIX = ".tenant_id";
|
|
38
41
|
// Ops-facing log line for countColumnDrift's result. No-op when clean.
|
|
39
42
|
function warnOnColumnDrift(projectionName, tableName, drift) {
|
|
40
43
|
// skip: no drift found — nothing to warn about
|
|
@@ -44,13 +47,17 @@ function warnOnColumnDrift(projectionName, tableName, drift) {
|
|
|
44
47
|
const countLabel = sampledIds.size < drift.rowCount
|
|
45
48
|
? `${drift.rowCount} (sample truncated)`
|
|
46
49
|
: String(drift.rowCount);
|
|
50
|
+
// A stream-tenant move (boot backfill) changes the stream's tenant, so the replayed row differs only in tenant_id.
|
|
51
|
+
const onlyTenantColumn = drift.sample.every((s) => s.endsWith(TENANT_COLUMN_SUFFIX));
|
|
52
|
+
const likelyCause = onlyTenantColumn
|
|
53
|
+
? "Expected cause: a stream-tenant move by the boot backfill (the replay carries the new stream tenant)."
|
|
54
|
+
: "Likely cause: a legacy direct-write predating the row's event history (#494), or a sensitive custom field pending #972. Investigate if unexpected.";
|
|
47
55
|
log.warn(`projection "${projectionName}": ${countLabel} live row(s) in "${tableName}" have ` +
|
|
48
56
|
`column values that differ from the freshly-replayed shadow (sample: ${drift.sample.join(", ")}). ` +
|
|
49
|
-
|
|
50
|
-
"event history (#494), or a sensitive custom field pending #972. Investigate if unexpected.");
|
|
57
|
+
`Not blocking — replay wins on swap. ${likelyCause}`);
|
|
51
58
|
}
|
|
52
59
|
export function rebuildProjection(projectionName, deps) {
|
|
53
|
-
return withoutStatementTimeout(deps.db, (db) => replayProjectionIntoShadow(projectionName, { ...deps, db }));
|
|
60
|
+
return withoutStatementTimeout(deps.db, (db) => runInSystemRowLevelSecurityScope("projection rebuild scans events of all tenants", () => replayProjectionIntoShadow(projectionName, { ...deps, db })));
|
|
54
61
|
}
|
|
55
62
|
async function replayProjectionIntoShadow(projectionName, deps) {
|
|
56
63
|
const { db, registry } = deps;
|
|
@@ -124,9 +131,9 @@ async function replayProjectionIntoShadow(projectionName, deps) {
|
|
|
124
131
|
if (skipApplyErrors)
|
|
125
132
|
await createRebuildDeadLetterTable(db);
|
|
126
133
|
await db.begin(async (tx) => {
|
|
134
|
+
await assertRebuildableRowLevelSecurity(tx, meta.tableName);
|
|
127
135
|
await markProjectionRebuilding(tx, projectionName);
|
|
128
136
|
await assertLiveColumnsMatchMeta(tx, meta, projectionName);
|
|
129
|
-
await assertLiveTableHasNoRowLevelSecurity(tx, meta.tableName, projectionName);
|
|
130
137
|
await buildShadowTable(tx, meta);
|
|
131
138
|
deps.__test_onBuildShadowTable?.();
|
|
132
139
|
// A projection that subscribes to nothing has no events to replay and no
|
|
@@ -1,9 +1,3 @@
|
|
|
1
1
|
import type { DbConnection } from "../db/connection.ts";
|
|
2
2
|
export declare const projectionStateTable: import("@cosmicdrift/kumiko-types/executor-brand").WritableSchemaTable;
|
|
3
|
-
export declare const ProjectionStatuses: {
|
|
4
|
-
readonly idle: "idle";
|
|
5
|
-
readonly rebuilding: "rebuilding";
|
|
6
|
-
readonly failed: "failed";
|
|
7
|
-
};
|
|
8
|
-
export type ProjectionStatus = (typeof ProjectionStatuses)[keyof typeof ProjectionStatuses];
|
|
9
3
|
export declare function createProjectionStateTable(db: DbConnection): Promise<void>;
|
|
@@ -34,11 +34,6 @@ export const projectionStateTable = pgTable("kumiko_projections", {
|
|
|
34
34
|
}, (t) => ({
|
|
35
35
|
statusIdx: index("kumiko_projections_status_idx").on(t.status),
|
|
36
36
|
}));
|
|
37
|
-
export const ProjectionStatuses = {
|
|
38
|
-
idle: "idle",
|
|
39
|
-
rebuilding: "rebuilding",
|
|
40
|
-
failed: "failed",
|
|
41
|
-
};
|
|
42
37
|
// Idempotent table bootstrap. Called by setupTestStack (and createApp once
|
|
43
38
|
// that wires it up) — same pattern as createEventsTable. If the table is
|
|
44
39
|
// already there (second stack in same test DB, production boot after
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { LifecycleResult } from "@cosmicdrift/kumiko-types/hooks";
|
|
1
2
|
import type { DbRunner } from "../db/index.ts";
|
|
2
|
-
import type {
|
|
3
|
+
import type { Registry } from "../engine/types/index.ts";
|
|
3
4
|
import type { StoredEvent } from "../event-store/index.ts";
|
|
4
5
|
export declare function runProjections(result: LifecycleResult, registry: Registry, runner: DbRunner | undefined): Promise<void>;
|
|
5
6
|
export declare function hasLiveProjectionsForEvent(event: StoredEvent, registry: Registry): boolean;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { withExecutorManagedWrites } from "../db/tenant-db.js";
|
|
2
2
|
import { InternalError } from "../errors/index.js";
|
|
3
|
+
import { inEventStreamScope } from "../event-store/stream-scope.js";
|
|
3
4
|
// Run custom projections for a save or delete result. Lives INSIDE the
|
|
4
5
|
// transaction that appended the event — a throw from apply() rolls the event
|
|
5
6
|
// back along with any auto-projection write.
|
|
@@ -33,7 +34,7 @@ export async function runProjections(result, registry, runner) {
|
|
|
33
34
|
}
|
|
34
35
|
// Fire every projection whose source matches the event's aggregate type AND
|
|
35
36
|
// that declares an apply-handler for the event's type. Used by both the
|
|
36
|
-
// CRUD path (via runProjections) and the ctx.
|
|
37
|
+
// CRUD path (via runProjections) and the ctx.events.append path (domain events
|
|
37
38
|
// emitted inside a write handler). Keeping one function means an auto-event
|
|
38
39
|
// and a r.defineEvent-event land in the same inline-projection pipeline.
|
|
39
40
|
// Events whose projections already ran. The EventStoreExecutor projects right
|
|
@@ -57,10 +58,13 @@ export async function runProjectionsForEvent(event, registry, tx) {
|
|
|
57
58
|
// skip: this event object was already projected in this write
|
|
58
59
|
if (projectedEvents.has(event))
|
|
59
60
|
return;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
// Inline projections write the event's own tenant, which differs from the caller's scope for system-actor events.
|
|
62
|
+
await inEventStreamScope(event.tenantId, async () => {
|
|
63
|
+
for (const proj of liveProjectionsForEvent(event, registry)) {
|
|
64
|
+
const applyFn = proj.apply[event.type];
|
|
65
|
+
if (applyFn)
|
|
66
|
+
await applyFn(event, withExecutorManagedWrites(tx), proj.table);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
65
69
|
projectedEvents.add(event);
|
|
66
70
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { JobRunnerRef } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import type { EntityId } from "@cosmicdrift/kumiko-types/identifiers";
|
|
1
3
|
import { type SseBroker } from "../api/sse-broker.ts";
|
|
2
|
-
import type {
|
|
4
|
+
import type { Registry, TenantId } from "../engine/types/index.ts";
|
|
3
5
|
import type { SearchAdapter, SearchDocument } from "../search/types.ts";
|
|
4
6
|
import type { EventConsumer } from "./event-dispatcher.ts";
|
|
5
7
|
export declare const SEARCH_CONSUMER_NAME = "system:consumer:search";
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
2
|
import { readNonEmptyStringArray, } from "../api/sse-broker.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { configuredPiiSubjectKms, decryptPiiFieldValues, isPiiCiphertext, PII_ERASED_SENTINEL, } from "../crypto/index.js";
|
|
4
|
+
import { collectSearchableSubjectFields } from "../crypto/subject-resolver.js";
|
|
5
|
+
import { rehydrateCompoundTypes } from "../db/compound-types.js";
|
|
6
|
+
import { createTenantDb, entityTableFromRegistry } from "../db/index.js";
|
|
5
7
|
import { tenantChannel } from "../engine/constants.js";
|
|
6
8
|
import { InternalError } from "../errors/index.js";
|
|
7
9
|
import { createFallbackLogger } from "../logging/utils.js";
|
|
@@ -422,7 +424,7 @@ export function createSseBroadcastEventConsumer(sseBroker) {
|
|
|
422
424
|
// r.job's `trigger.on` historically only fired via the synchronous
|
|
423
425
|
// write-handler dispatch path (dispatch-write.ts's afterCommitHooks calling
|
|
424
426
|
// jobRunner.handleEvent). Events appended any other way — an
|
|
425
|
-
// r.multiStreamProjection's ctx.
|
|
427
|
+
// r.multiStreamProjection's ctx.events.unsafeAppend, or a raw
|
|
426
428
|
// event-store-executor write (e.g. `files`' fileRef.created) — never
|
|
427
429
|
// reached it, so a job could never trigger on an r.defineEvent-registered
|
|
428
430
|
// event.
|
|
@@ -431,7 +433,7 @@ export function createSseBroadcastEventConsumer(sseBroker) {
|
|
|
431
433
|
// committed event off the shared cursor and re-check job triggers. It is
|
|
432
434
|
// scoped EXACTLY to the gap — the write/query-handler-QN skip below is
|
|
433
435
|
// defense-in-depth: no stored event's `type` is a handler QN today (entity
|
|
434
|
-
// events are "entity.verb"; ctx.
|
|
436
|
+
// events are "entity.verb"; ctx.events.append enforces defineEvent-only
|
|
435
437
|
// ownership), but if that ever changes, this consumer must not re-fire a
|
|
436
438
|
// trigger the synchronous dispatch-write.ts path already handled.
|
|
437
439
|
//
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import type { ActiveMembershipResult, EscapeHatchDeclaration, EscapeHatchReporter, MemberReader, WriteResult } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import type { LifecycleHookFn } from "@cosmicdrift/kumiko-types/hooks";
|
|
1
3
|
import type { TenantId } from "../engine/types/identifiers.ts";
|
|
2
|
-
import type {
|
|
4
|
+
import type { HandlerContext, SessionUser } from "../engine/types/index.ts";
|
|
3
5
|
import { AccessDeniedError } from "../errors/index.ts";
|
|
4
6
|
export type QueryAsFn = (user: SessionUser, qn: string, payload: unknown) => Promise<unknown>;
|
|
5
7
|
export type WriteAsFn = (user: SessionUser, qn: string, payload: unknown) => Promise<WriteResult>;
|
|
6
8
|
export type ResolveActiveMembershipFn = (userId: string, tenantId: TenantId) => Promise<ActiveMembershipResult>;
|
|
7
|
-
export type ProjectionReader = HandlerContext["queryProjection"];
|
|
9
|
+
export type ProjectionReader = HandlerContext["dispatch"]["queryProjection"];
|
|
8
10
|
export type IdentitySwitch = {
|
|
9
11
|
readonly queryAs: QueryAsFn;
|
|
10
12
|
readonly writeAs: WriteAsFn;
|