@segmentstream/ontology 0.0.0-stage → 0.92.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/LICENSE +201 -0
- package/NOTICE +2 -0
- package/README.md +1655 -2
- package/dist/action.d.ts +193 -0
- package/dist/action.js +41 -0
- package/dist/agent-chat.d.ts +44 -0
- package/dist/agent-chat.js +91 -0
- package/dist/agent-task-contract.d.ts +64 -0
- package/dist/agent-task-contract.js +15 -0
- package/dist/agent-task.d.ts +39 -0
- package/dist/agent-task.js +112 -0
- package/dist/analyze.d.ts +215 -0
- package/dist/analyze.js +2438 -0
- package/dist/app-feedback.d.ts +167 -0
- package/dist/app-feedback.js +176 -0
- package/dist/authoring-input.d.ts +3 -0
- package/dist/authoring-input.js +107 -0
- package/dist/authoring-names.d.ts +4 -0
- package/dist/authoring-names.js +13 -0
- package/dist/authoring-records.d.ts +35 -0
- package/dist/authoring-records.js +264 -0
- package/dist/authoring.d.ts +15 -0
- package/dist/authoring.js +331 -0
- package/dist/bin/check.d.ts +30 -0
- package/dist/bin/check.js +99 -0
- package/dist/bin/load.d.ts +48 -0
- package/dist/bin/load.js +139 -0
- package/dist/bin/main.d.ts +31 -0
- package/dist/bin/main.js +121 -0
- package/dist/bin/migrate.d.ts +57 -0
- package/dist/bin/migrate.js +170 -0
- package/dist/bin/output.d.ts +31 -0
- package/dist/bin/output.js +84 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +31 -0
- package/dist/blob.d.ts +52 -0
- package/dist/blob.js +87 -0
- package/dist/channel-session.d.ts +16 -0
- package/dist/channel-session.js +16 -0
- package/dist/chat.d.ts +43 -0
- package/dist/chat.js +34 -0
- package/dist/confirmation.d.ts +46 -0
- package/dist/confirmation.js +41 -0
- package/dist/connection.d.ts +213 -0
- package/dist/connection.js +289 -0
- package/dist/deployment.d.ts +35 -0
- package/dist/deployment.js +76 -0
- package/dist/diagnostics.d.ts +27 -0
- package/dist/diagnostics.js +106 -0
- package/dist/emails.d.ts +70 -0
- package/dist/emails.js +221 -0
- package/dist/entity.d.ts +331 -0
- package/dist/entity.js +153 -0
- package/dist/errors.d.ts +154 -0
- package/dist/errors.js +109 -0
- package/dist/feedback-config.d.ts +24 -0
- package/dist/feedback-config.js +126 -0
- package/dist/files.d.ts +39 -0
- package/dist/files.js +4 -0
- package/dist/groups.d.ts +95 -0
- package/dist/groups.js +280 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.js +70 -0
- package/dist/internal/diagnostics.js +594 -0
- package/dist/legacy.d.ts +160 -0
- package/dist/legacy.js +270 -0
- package/dist/manifest-compatibility.d.ts +8 -0
- package/dist/manifest-compatibility.js +87 -0
- package/dist/manifest.d.ts +3329 -0
- package/dist/manifest.js +757 -0
- package/dist/me.d.ts +46 -0
- package/dist/me.js +109 -0
- package/dist/metric-filters.d.ts +48 -0
- package/dist/metric-filters.js +252 -0
- package/dist/metric-routes.d.ts +132 -0
- package/dist/metric-routes.js +498 -0
- package/dist/metric.d.ts +172 -0
- package/dist/metric.js +132 -0
- package/dist/migrate/apply.d.ts +94 -0
- package/dist/migrate/apply.js +526 -0
- package/dist/migrate/errors.d.ts +46 -0
- package/dist/migrate/errors.js +38 -0
- package/dist/migrate/index.d.ts +10 -0
- package/dist/migrate/index.js +7 -0
- package/dist/migrate/model.d.ts +2311 -0
- package/dist/migrate/model.js +148 -0
- package/dist/migrate/plan.d.ts +51 -0
- package/dist/migrate/plan.js +1856 -0
- package/dist/migrate/preview.d.ts +13 -0
- package/dist/migrate/preview.js +65 -0
- package/dist/migrate/storage.d.ts +226 -0
- package/dist/migrate/storage.js +774 -0
- package/dist/model-metrics.d.ts +22 -0
- package/dist/model-metrics.js +545 -0
- package/dist/names.d.ts +49 -0
- package/dist/names.js +110 -0
- package/dist/navigation-artifact.d.ts +13 -0
- package/dist/navigation-artifact.js +11 -0
- package/dist/navigation-catalog.d.ts +55 -0
- package/dist/navigation-catalog.js +297 -0
- package/dist/nitro-navigation.d.ts +3 -0
- package/dist/nitro-navigation.js +64 -0
- package/dist/nitro-workflows.d.ts +108 -0
- package/dist/nitro-workflows.js +286 -0
- package/dist/nitro.d.ts +40 -0
- package/dist/nitro.js +50 -0
- package/dist/ontology.d.ts +41 -0
- package/dist/ontology.js +46 -0
- package/dist/permissions.d.ts +198 -0
- package/dist/permissions.js +272 -0
- package/dist/property.d.ts +188 -0
- package/dist/property.js +301 -0
- package/dist/query.d.ts +245 -0
- package/dist/query.js +615 -0
- package/dist/relationship.d.ts +99 -0
- package/dist/relationship.js +33 -0
- package/dist/render.d.ts +81 -0
- package/dist/render.js +512 -0
- package/dist/replication/baseline.d.ts +51 -0
- package/dist/replication/baseline.js +215 -0
- package/dist/replication/bigquery.d.ts +37 -0
- package/dist/replication/bigquery.js +211 -0
- package/dist/replication/coverage.d.ts +14 -0
- package/dist/replication/coverage.js +53 -0
- package/dist/replication/evolution.d.ts +25 -0
- package/dist/replication/evolution.js +184 -0
- package/dist/replication/identities.d.ts +6 -0
- package/dist/replication/identities.js +47 -0
- package/dist/replication/legacy-baseline.d.ts +27 -0
- package/dist/replication/legacy-baseline.js +109 -0
- package/dist/replication/legacy-store.d.ts +19 -0
- package/dist/replication/legacy-store.js +63 -0
- package/dist/replication/lineage.d.ts +36 -0
- package/dist/replication/lineage.js +72 -0
- package/dist/replication/migrate.d.ts +21 -0
- package/dist/replication/migrate.js +84 -0
- package/dist/replication/model.d.ts +52 -0
- package/dist/replication/model.js +99 -0
- package/dist/replication/scans.d.ts +34 -0
- package/dist/replication/scans.js +158 -0
- package/dist/replication/schema.d.ts +11 -0
- package/dist/replication/schema.js +226 -0
- package/dist/replication/shadow-schema.d.ts +4 -0
- package/dist/replication/shadow-schema.js +61 -0
- package/dist/replication/shadow.d.ts +127 -0
- package/dist/replication/shadow.js +614 -0
- package/dist/replication/source-replacement.d.ts +33 -0
- package/dist/replication/source-replacement.js +76 -0
- package/dist/replication/store.d.ts +36 -0
- package/dist/replication/store.js +382 -0
- package/dist/replication/transaction.d.ts +23 -0
- package/dist/replication/transaction.js +88 -0
- package/dist/role.d.ts +61 -0
- package/dist/role.js +76 -0
- package/dist/runtime/action-deadlocks.d.ts +21 -0
- package/dist/runtime/action-deadlocks.js +130 -0
- package/dist/runtime/action-transactions.d.ts +35 -0
- package/dist/runtime/action-transactions.js +54 -0
- package/dist/runtime/agent-counters.d.ts +26 -0
- package/dist/runtime/agent-counters.js +98 -0
- package/dist/runtime/agent-tasks.d.ts +63 -0
- package/dist/runtime/agent-tasks.js +120 -0
- package/dist/runtime/agents.d.ts +15 -0
- package/dist/runtime/agents.js +457 -0
- package/dist/runtime/batch-diagnostics.d.ts +22 -0
- package/dist/runtime/batch-diagnostics.js +89 -0
- package/dist/runtime/batch.d.ts +52 -0
- package/dist/runtime/batch.js +534 -0
- package/dist/runtime/channel-session-revocation.d.ts +3 -0
- package/dist/runtime/channel-session-revocation.js +5 -0
- package/dist/runtime/channel-sessions.d.ts +4 -0
- package/dist/runtime/channel-sessions.js +61 -0
- package/dist/runtime/confirmations.d.ts +29 -0
- package/dist/runtime/confirmations.js +57 -0
- package/dist/runtime/cursor.d.ts +23 -0
- package/dist/runtime/cursor.js +100 -0
- package/dist/runtime/deployment.d.ts +7 -0
- package/dist/runtime/deployment.js +4 -0
- package/dist/runtime/errors.d.ts +118 -0
- package/dist/runtime/errors.js +109 -0
- package/dist/runtime/federation-tables.d.ts +2 -0
- package/dist/runtime/federation-tables.js +20 -0
- package/dist/runtime/federation.d.ts +42 -0
- package/dist/runtime/federation.js +222 -0
- package/dist/runtime/files.d.ts +39 -0
- package/dist/runtime/files.js +44 -0
- package/dist/runtime/generated-actions.d.ts +37 -0
- package/dist/runtime/generated-actions.js +307 -0
- package/dist/runtime/history.d.ts +91 -0
- package/dist/runtime/history.js +77 -0
- package/dist/runtime/ids.d.ts +6 -0
- package/dist/runtime/ids.js +39 -0
- package/dist/runtime/member-tables.d.ts +8 -0
- package/dist/runtime/member-tables.js +33 -0
- package/dist/runtime/member-writes.d.ts +78 -0
- package/dist/runtime/member-writes.js +202 -0
- package/dist/runtime/metric-query.d.ts +19 -0
- package/dist/runtime/metric-query.js +411 -0
- package/dist/runtime/model.d.ts +67 -0
- package/dist/runtime/model.js +150 -0
- package/dist/runtime/new-user-hook.d.ts +6 -0
- package/dist/runtime/new-user-hook.js +37 -0
- package/dist/runtime/oauth.d.ts +9 -0
- package/dist/runtime/oauth.js +299 -0
- package/dist/runtime/pipeline.d.ts +155 -0
- package/dist/runtime/pipeline.js +597 -0
- package/dist/runtime/postgres-tls.d.ts +10 -0
- package/dist/runtime/postgres-tls.js +14 -0
- package/dist/runtime/principals.d.ts +302 -0
- package/dist/runtime/principals.js +1307 -0
- package/dist/runtime/reads.d.ts +55 -0
- package/dist/runtime/reads.js +313 -0
- package/dist/runtime/records.d.ts +42 -0
- package/dist/runtime/records.js +245 -0
- package/dist/runtime/resolve-agent-identity.d.ts +6 -0
- package/dist/runtime/resolve-agent-identity.js +181 -0
- package/dist/runtime/service-binding.d.ts +18 -0
- package/dist/runtime/service-binding.js +266 -0
- package/dist/runtime/sign-in-links.d.ts +68 -0
- package/dist/runtime/sign-in-links.js +147 -0
- package/dist/runtime/sql-runtime.d.ts +131 -0
- package/dist/runtime/sql-runtime.js +362 -0
- package/dist/runtime/statement.d.ts +18 -0
- package/dist/runtime/statement.js +31 -0
- package/dist/runtime/user-identities.d.ts +66 -0
- package/dist/runtime/user-identities.js +106 -0
- package/dist/runtime/user-identity-sql.d.ts +86 -0
- package/dist/runtime/user-identity-sql.js +297 -0
- package/dist/runtime/user-roles.d.ts +16 -0
- package/dist/runtime/user-roles.js +32 -0
- package/dist/runtime/validation.d.ts +16 -0
- package/dist/runtime/validation.js +26 -0
- package/dist/runtime/where.d.ts +57 -0
- package/dist/runtime/where.js +404 -0
- package/dist/runtime/workflow-admission.d.ts +49 -0
- package/dist/runtime/workflow-admission.js +92 -0
- package/dist/runtime/workflow-argument-codec.d.ts +10 -0
- package/dist/runtime/workflow-argument-codec.js +120 -0
- package/dist/runtime/workflow-arguments.d.ts +17 -0
- package/dist/runtime/workflow-arguments.js +99 -0
- package/dist/runtime/workflow-starts.d.ts +203 -0
- package/dist/runtime/workflow-starts.js +493 -0
- package/dist/runtime/workflow-users.d.ts +9 -0
- package/dist/runtime/workflow-users.js +17 -0
- package/dist/runtime/workload.d.ts +25 -0
- package/dist/runtime/workload.js +24 -0
- package/dist/runtime/writes.d.ts +108 -0
- package/dist/runtime/writes.js +491 -0
- package/dist/runtime-source.d.ts +22 -0
- package/dist/runtime-source.js +28 -0
- package/dist/runtime.d.ts +310 -0
- package/dist/runtime.js +31 -0
- package/dist/server.d.ts +23 -0
- package/dist/server.js +107 -0
- package/dist/service/agent/attachments.d.ts +33 -0
- package/dist/service/agent/attachments.js +228 -0
- package/dist/service/agent/authentication.d.ts +22 -0
- package/dist/service/agent/authentication.js +58 -0
- package/dist/service/agent/confirmations.d.ts +5 -0
- package/dist/service/agent/confirmations.js +73 -0
- package/dist/service/agent/conversation-routes.d.ts +14 -0
- package/dist/service/agent/conversation-routes.js +45 -0
- package/dist/service/agent/conversations.d.ts +40 -0
- package/dist/service/agent/conversations.js +69 -0
- package/dist/service/agent/files.d.ts +12 -0
- package/dist/service/agent/files.js +69 -0
- package/dist/service/agent/protocol.d.ts +90 -0
- package/dist/service/agent/protocol.js +114 -0
- package/dist/service/agent/server.d.ts +28 -0
- package/dist/service/agent/server.js +374 -0
- package/dist/service/agent/task-caller.d.ts +21 -0
- package/dist/service/agent/task-caller.js +35 -0
- package/dist/service/agent/task-start.d.ts +53 -0
- package/dist/service/agent/task-start.js +161 -0
- package/dist/service/agent/tasks.d.ts +40 -0
- package/dist/service/agent/tasks.js +155 -0
- package/dist/service/api.d.ts +50 -0
- package/dist/service/api.js +288 -0
- package/dist/service/authentication.d.ts +227 -0
- package/dist/service/authentication.js +767 -0
- package/dist/service/caller-context.d.ts +24 -0
- package/dist/service/caller-context.js +6 -0
- package/dist/service/catalog.d.ts +42 -0
- package/dist/service/catalog.js +66 -0
- package/dist/service/channel/provider.d.ts +10 -0
- package/dist/service/channel/provider.js +1 -0
- package/dist/service/channel/providers/telegram.d.ts +18 -0
- package/dist/service/channel/providers/telegram.js +108 -0
- package/dist/service/channel/sessions.d.ts +5 -0
- package/dist/service/channel/sessions.js +53 -0
- package/dist/service/channel/sign-in.d.ts +7 -0
- package/dist/service/channel/sign-in.js +78 -0
- package/dist/service/chat/archive.d.ts +64 -0
- package/dist/service/chat/archive.js +62 -0
- package/dist/service/chat/attribution.d.ts +26 -0
- package/dist/service/chat/attribution.js +28 -0
- package/dist/service/chat/delivery.d.ts +18 -0
- package/dist/service/chat/delivery.js +251 -0
- package/dist/service/chat/diagnostics.d.ts +2 -0
- package/dist/service/chat/diagnostics.js +35 -0
- package/dist/service/chat/envelope.d.ts +96 -0
- package/dist/service/chat/envelope.js +39 -0
- package/dist/service/chat/idempotency.d.ts +19 -0
- package/dist/service/chat/idempotency.js +37 -0
- package/dist/service/chat/providers/telegram.d.ts +36 -0
- package/dist/service/chat/providers/telegram.js +133 -0
- package/dist/service/chat/reads.d.ts +25 -0
- package/dist/service/chat/reads.js +75 -0
- package/dist/service/chat/resolve.d.ts +34 -0
- package/dist/service/chat/resolve.js +150 -0
- package/dist/service/chat/routes.d.ts +23 -0
- package/dist/service/chat/routes.js +75 -0
- package/dist/service/chat/schemas.d.ts +43 -0
- package/dist/service/chat/schemas.js +31 -0
- package/dist/service/config.d.ts +218 -0
- package/dist/service/config.js +265 -0
- package/dist/service/connection-stream.d.ts +10 -0
- package/dist/service/connection-stream.js +191 -0
- package/dist/service/connections.d.ts +60 -0
- package/dist/service/connections.js +271 -0
- package/dist/service/decisions.d.ts +35 -0
- package/dist/service/decisions.js +63 -0
- package/dist/service/descriptions.d.ts +8 -0
- package/dist/service/descriptions.js +20 -0
- package/dist/service/discovery-schemas.d.ts +92 -0
- package/dist/service/discovery-schemas.js +59 -0
- package/dist/service/discovery-search.d.ts +30 -0
- package/dist/service/discovery-search.js +95 -0
- package/dist/service/discovery.d.ts +37 -0
- package/dist/service/discovery.js +436 -0
- package/dist/service/docs.d.ts +9 -0
- package/dist/service/docs.js +197 -0
- package/dist/service/errors.d.ts +145 -0
- package/dist/service/errors.js +704 -0
- package/dist/service/federation-provider.d.ts +36 -0
- package/dist/service/federation-provider.js +110 -0
- package/dist/service/federation-server.d.ts +20 -0
- package/dist/service/federation-server.js +249 -0
- package/dist/service/federation-status.d.ts +40 -0
- package/dist/service/federation-status.js +151 -0
- package/dist/service/handlers.d.ts +18 -0
- package/dist/service/handlers.js +287 -0
- package/dist/service/mcp/confirmation.d.ts +68 -0
- package/dist/service/mcp/confirmation.js +178 -0
- package/dist/service/mcp/find-input.d.ts +12 -0
- package/dist/service/mcp/find-input.js +122 -0
- package/dist/service/mcp/input-schema.d.ts +6 -0
- package/dist/service/mcp/input-schema.js +126 -0
- package/dist/service/mcp/listing.d.ts +26 -0
- package/dist/service/mcp/listing.js +92 -0
- package/dist/service/mcp/metric-tools.d.ts +85 -0
- package/dist/service/mcp/metric-tools.js +258 -0
- package/dist/service/mcp/request-log.d.ts +5 -0
- package/dist/service/mcp/request-log.js +53 -0
- package/dist/service/mcp/runtime-policy.d.ts +27 -0
- package/dist/service/mcp/runtime-policy.js +62 -0
- package/dist/service/mcp/server.d.ts +52 -0
- package/dist/service/mcp/server.js +861 -0
- package/dist/service/mcp/tools.d.ts +99 -0
- package/dist/service/mcp/tools.js +938 -0
- package/dist/service/member-file-routes.d.ts +22 -0
- package/dist/service/member-file-routes.js +52 -0
- package/dist/service/member-files.d.ts +245 -0
- package/dist/service/member-files.js +258 -0
- package/dist/service/metric-query-platform.d.ts +77 -0
- package/dist/service/metric-query-platform.js +198 -0
- package/dist/service/metric-query-scopes.d.ts +43 -0
- package/dist/service/metric-query-scopes.js +147 -0
- package/dist/service/metric-query.d.ts +48 -0
- package/dist/service/metric-query.js +200 -0
- package/dist/service/name-suggestions.d.ts +3 -0
- package/dist/service/name-suggestions.js +38 -0
- package/dist/service/navigation-schemas.d.ts +80 -0
- package/dist/service/navigation-schemas.js +49 -0
- package/dist/service/navigation.d.ts +20 -0
- package/dist/service/navigation.js +165 -0
- package/dist/service/oauth/protocol.d.ts +70 -0
- package/dist/service/oauth/protocol.js +157 -0
- package/dist/service/oauth/refresh-replay.d.ts +2 -0
- package/dist/service/oauth/refresh-replay.js +20 -0
- package/dist/service/oauth/server.d.ts +28 -0
- package/dist/service/oauth/server.js +769 -0
- package/dist/service/operations.d.ts +170 -0
- package/dist/service/operations.js +392 -0
- package/dist/service/plan.d.ts +57 -0
- package/dist/service/plan.js +96 -0
- package/dist/service/rate-limit.d.ts +22 -0
- package/dist/service/rate-limit.js +52 -0
- package/dist/service/record-reads.d.ts +21 -0
- package/dist/service/record-reads.js +155 -0
- package/dist/service/replication.d.ts +5 -0
- package/dist/service/replication.js +39 -0
- package/dist/service/runtime-contract.d.ts +508 -0
- package/dist/service/runtime-contract.js +18 -0
- package/dist/service/runtime-identity.d.ts +71 -0
- package/dist/service/runtime-identity.js +122 -0
- package/dist/service/schemas.d.ts +961 -0
- package/dist/service/schemas.js +639 -0
- package/dist/service/service.d.ts +21 -0
- package/dist/service/service.js +526 -0
- package/dist/service/warehouse-platform.d.ts +17 -0
- package/dist/service/warehouse-platform.js +122 -0
- package/dist/service/warehouse-query.d.ts +24 -0
- package/dist/service/warehouse-query.js +280 -0
- package/dist/service/webhooks.d.ts +106 -0
- package/dist/service/webhooks.js +233 -0
- package/dist/service/workflow-admission-provider.d.ts +31 -0
- package/dist/service/workflow-admission-provider.js +205 -0
- package/dist/service/workflow-argument-serialization.d.ts +2 -0
- package/dist/service/workflow-argument-serialization.js +14 -0
- package/dist/service/workflow-callback.d.ts +22 -0
- package/dist/service/workflow-callback.js +75 -0
- package/dist/service/workflow-deployment.d.ts +8 -0
- package/dist/service/workflow-deployment.js +131 -0
- package/dist/service/workflow-diagnostics.d.ts +23 -0
- package/dist/service/workflow-diagnostics.js +263 -0
- package/dist/service/workflow-errors.d.ts +26 -0
- package/dist/service/workflow-errors.js +181 -0
- package/dist/service/workflow-logging.d.ts +2 -0
- package/dist/service/workflow-logging.js +50 -0
- package/dist/service/workflow-queue-fence.d.ts +6 -0
- package/dist/service/workflow-queue-fence.js +66 -0
- package/dist/service/workflows.d.ts +200 -0
- package/dist/service/workflows.js +1549 -0
- package/dist/sign-in.d.ts +58 -0
- package/dist/sign-in.js +57 -0
- package/dist/source.d.ts +30 -0
- package/dist/source.js +107 -0
- package/dist/start-recovery-contract.d.ts +49 -0
- package/dist/start-recovery-contract.js +26 -0
- package/dist/start-recovery.d.ts +27 -0
- package/dist/start-recovery.js +81 -0
- package/dist/storage/api.d.ts +4 -0
- package/dist/storage/api.js +40 -0
- package/dist/storage/attachments.d.ts +146 -0
- package/dist/storage/attachments.js +733 -0
- package/dist/storage/authorization.d.ts +38 -0
- package/dist/storage/authorization.js +83 -0
- package/dist/storage/file-access.d.ts +17 -0
- package/dist/storage/file-access.js +8 -0
- package/dist/storage/limits.d.ts +12 -0
- package/dist/storage/limits.js +17 -0
- package/dist/storage/maintenance-auth.d.ts +20 -0
- package/dist/storage/maintenance-auth.js +24 -0
- package/dist/storage/maintenance.d.ts +11 -0
- package/dist/storage/maintenance.js +67 -0
- package/dist/storage/neon.d.ts +4 -0
- package/dist/storage/neon.js +318 -0
- package/dist/storage/operator.d.ts +11 -0
- package/dist/storage/operator.js +30 -0
- package/dist/storage/provider.d.ts +93 -0
- package/dist/storage/provider.js +36 -0
- package/dist/storage/sessions.d.ts +184 -0
- package/dist/storage/sessions.js +688 -0
- package/dist/storage/tables.d.ts +54 -0
- package/dist/storage/tables.js +205 -0
- package/dist/storage/transfers.d.ts +16 -0
- package/dist/storage/transfers.js +153 -0
- package/dist/storage/writes.d.ts +7 -0
- package/dist/storage/writes.js +88 -0
- package/dist/telegram.d.ts +35 -0
- package/dist/telegram.js +173 -0
- package/dist/user-identity.d.ts +28 -0
- package/dist/user-identity.js +106 -0
- package/dist/user.d.ts +75 -0
- package/dist/user.js +111 -0
- package/dist/warehouse-backed.d.ts +6 -0
- package/dist/warehouse-backed.js +495 -0
- package/dist/webhook-token.d.ts +11 -0
- package/dist/webhook-token.js +18 -0
- package/dist/webhooks.d.ts +40 -0
- package/dist/webhooks.js +55 -0
- package/dist/wire.d.ts +10 -0
- package/dist/wire.js +35 -0
- package/dist/workflow-runtime.d.ts +116 -0
- package/dist/workflow-runtime.js +109 -0
- package/dist/workflow-topics.d.ts +28 -0
- package/dist/workflow-topics.js +28 -0
- package/dist/workflow.d.ts +284 -0
- package/dist/workflow.js +259 -0
- package/dist/workflows.d.ts +24 -0
- package/dist/workflows.js +18 -0
- package/package.json +127 -4
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { quoteIdentifier as qi, tableName } from "../migrate/storage.js";
|
|
3
|
+
import { renamedReplicationField } from "./lineage.js";
|
|
4
|
+
import { queryFields } from "../query.js";
|
|
5
|
+
import { snapshotExpression } from "./schema.js";
|
|
6
|
+
/** Persist exclusions across temporary removals, and follow a property's logical rename. */
|
|
7
|
+
export function migrationReplicationExclusions(current, target, exclusions) {
|
|
8
|
+
return exclusions.map((item) => ({
|
|
9
|
+
...item,
|
|
10
|
+
...(item.fields === undefined
|
|
11
|
+
? {}
|
|
12
|
+
: {
|
|
13
|
+
fields: item.fields.map((field) => {
|
|
14
|
+
const entity = target.entities.find((entity) => entity.id === item.entityId);
|
|
15
|
+
const renamed = entity?.properties.find((property) => renamedReplicationField(current, target, item.entityId, property.name) === field);
|
|
16
|
+
return renamed?.name ?? field;
|
|
17
|
+
}),
|
|
18
|
+
}),
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
/** Only current declarations participate; retained exclusions still protect a later restoration. */
|
|
22
|
+
export function effectiveReplicationExclusions(manifest, exclusions) {
|
|
23
|
+
return exclusions.flatMap((item) => {
|
|
24
|
+
const entity = manifest.entities.find((entity) => entity.id === item.entityId && !entity.builtIn && !entity.source);
|
|
25
|
+
if (!entity) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
const fields = new Set(queryFields(entity).map((field) => field.name));
|
|
29
|
+
const relationships = new Set(entity.relationships.map((relationship) => relationship.name));
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
...item,
|
|
33
|
+
...(item.fields === undefined
|
|
34
|
+
? {}
|
|
35
|
+
: { fields: item.fields.filter((field) => fields.has(field)) }),
|
|
36
|
+
...(item.relationships === undefined
|
|
37
|
+
? {}
|
|
38
|
+
: { relationships: item.relationships.filter((name) => relationships.has(name)) }),
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Fills of the migrated target, read inside the migration transaction after its steps. PostgreSQL gives
|
|
45
|
+
* a field added to an existing entity one value on every row, so any row shows it as capture would
|
|
46
|
+
* serialize it. A null value needs no fill: a missing key already reads as null.
|
|
47
|
+
*/
|
|
48
|
+
export const migratedReplicationFills = (sql, current, manifest, selection, retained) => Effect.gen(function* () {
|
|
49
|
+
const fills = {};
|
|
50
|
+
for (const next of selection) {
|
|
51
|
+
const entity = manifest.entities.find((item) => item.id === next.entityId);
|
|
52
|
+
const previousEntity = current.manifest.entities.find((item) => item.id === entity.id);
|
|
53
|
+
const values = {};
|
|
54
|
+
const previousFills = current.fills?.[entity.id] ?? {};
|
|
55
|
+
for (const field of next.fields) {
|
|
56
|
+
const old = renamedReplicationField(current.manifest, manifest, entity.id, field) ?? field;
|
|
57
|
+
if (Object.hasOwn(previousFills, old)) {
|
|
58
|
+
values[field] = previousFills[old];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (previousEntity) {
|
|
62
|
+
const previousFields = new Set(queryFields(previousEntity).map((field) => field.name));
|
|
63
|
+
const kept = retained?.entities.find((item) => item.id === entity.id);
|
|
64
|
+
const added = next.fields.filter((field) => !previousFields.has(field) &&
|
|
65
|
+
!renamedReplicationField(current.manifest, manifest, entity.id, field) &&
|
|
66
|
+
!kept?.fields.properties.some((property) => property.name === field) &&
|
|
67
|
+
!kept?.fields.relationships.some((relationship) => `${relationship.name}_id` === field));
|
|
68
|
+
if (added.length > 0) {
|
|
69
|
+
const [row] = yield* sql.unsafe(`SELECT ${snapshotExpression(entity, "record")} AS snapshot
|
|
70
|
+
FROM ${qi(tableName(entity.name))} AS record LIMIT 1`);
|
|
71
|
+
for (const field of added) {
|
|
72
|
+
const value = row?.snapshot[field];
|
|
73
|
+
if (value !== undefined && value !== null) {
|
|
74
|
+
values[field] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (Object.keys(values).length > 0) {
|
|
80
|
+
fills[entity.id] = values;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return fills;
|
|
84
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type OntologyManifest } from "../manifest.js";
|
|
2
|
+
/** The current projection of a continuous replication stream. `id` is always included. */
|
|
3
|
+
export interface ReplicationSelection {
|
|
4
|
+
readonly entityId: string;
|
|
5
|
+
readonly fields: ReadonlyArray<string>;
|
|
6
|
+
readonly relationships?: ReadonlyArray<string>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* By entity ID, the captured value of each field added to an already replicated entity. Events
|
|
10
|
+
* captured before the field existed lack its key, while every record they describe holds this value.
|
|
11
|
+
*/
|
|
12
|
+
export type ReplicationFills = Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
13
|
+
/** Everything is replicated unless explicitly excluded. Internal identity data is never exported. */
|
|
14
|
+
export interface ReplicationExclusion {
|
|
15
|
+
readonly entityId: string;
|
|
16
|
+
readonly disabled?: boolean;
|
|
17
|
+
readonly fields?: ReadonlyArray<string>;
|
|
18
|
+
readonly relationships?: ReadonlyArray<string>;
|
|
19
|
+
}
|
|
20
|
+
export declare function resolveReplicationSelection(manifest: OntologyManifest, exclusions?: ReadonlyArray<ReplicationExclusion>): ReadonlyArray<ReplicationSelection>;
|
|
21
|
+
export interface ReplicationEvent {
|
|
22
|
+
readonly event_id: string;
|
|
23
|
+
readonly source_id: string;
|
|
24
|
+
readonly generation: string;
|
|
25
|
+
readonly entity_id: string;
|
|
26
|
+
readonly record_key: string;
|
|
27
|
+
readonly record_kind: string;
|
|
28
|
+
/** Decimal strings preserve PostgreSQL bigint precision in JavaScript. */
|
|
29
|
+
readonly revision: string;
|
|
30
|
+
readonly deleted: boolean;
|
|
31
|
+
readonly schema_hash: string;
|
|
32
|
+
/** Pub/Sub's BigQuery table-schema mode expects a string for a JSON column. */
|
|
33
|
+
readonly payload: string;
|
|
34
|
+
}
|
|
35
|
+
export declare const REPLICATION_BATCH_SIZE = 100;
|
|
36
|
+
export declare const REPLICATION_BATCH_BYTES = 1000000;
|
|
37
|
+
export declare const REPLICATION_RECORD_BYTES = 200000;
|
|
38
|
+
export declare function validateReplicationSelection(manifest: OntologyManifest, selection: ReadonlyArray<ReplicationSelection>): void;
|
|
39
|
+
export declare function replicationEventId(source: string, history: string, generation: string): string;
|
|
40
|
+
/** Includes base64 and JSON overhead, not just the original payload bytes. */
|
|
41
|
+
export declare function publishMessage(event: ReplicationEvent): {
|
|
42
|
+
data: string;
|
|
43
|
+
};
|
|
44
|
+
/** Immutable warehouse provenance. Current workspace admission is independently required. */
|
|
45
|
+
export interface SourcePublicationProof {
|
|
46
|
+
readonly published: string;
|
|
47
|
+
readonly sourceId: string;
|
|
48
|
+
readonly selectorIncarnation: string;
|
|
49
|
+
readonly registryIncarnation: string;
|
|
50
|
+
readonly projectId: string;
|
|
51
|
+
readonly workspaceId: string;
|
|
52
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { isValueMatched } from "../manifest.js";
|
|
3
|
+
import { queryFields } from "../query.js";
|
|
4
|
+
export function resolveReplicationSelection(manifest, exclusions = []) {
|
|
5
|
+
const entities = manifest.entities.filter((entity) => !entity.builtIn && !entity.source);
|
|
6
|
+
if (new Set(exclusions.map((item) => item.entityId)).size !== exclusions.length) {
|
|
7
|
+
throw new Error("Replication exclusions must name distinct entities.");
|
|
8
|
+
}
|
|
9
|
+
for (const item of exclusions) {
|
|
10
|
+
const entity = entities.find((candidate) => candidate.id === item.entityId);
|
|
11
|
+
if (!entity) {
|
|
12
|
+
throw new Error(`Unknown stored business entity in replication exclusions: ${item.entityId}.`);
|
|
13
|
+
}
|
|
14
|
+
const fields = new Set(queryFields(entity).map((field) => field.name));
|
|
15
|
+
const relationships = new Set(entity.relationships.map((relationship) => relationship.name));
|
|
16
|
+
if (item.fields?.some((field) => field === "id" || !fields.has(field))) {
|
|
17
|
+
throw new Error(`Unknown or required replication field on ${entity.name}.`);
|
|
18
|
+
}
|
|
19
|
+
if (item.relationships?.some((relationship) => !relationships.has(relationship))) {
|
|
20
|
+
throw new Error(`Unknown replication relationship on ${entity.name}.`);
|
|
21
|
+
}
|
|
22
|
+
// A value-matched relationship has no `<name>_id`: its reference is the property `on` names.
|
|
23
|
+
const matched = entity.relationships.find((relationship) => item.relationships?.includes(relationship.name) && isValueMatched(relationship));
|
|
24
|
+
if (matched !== undefined) {
|
|
25
|
+
throw new Error(`${entity.name}.${matched.name} is matched by value; exclude its property ` +
|
|
26
|
+
`${matched.on?.property ?? ""} instead.`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const included = entities.filter((entity) => !exclusions.some((item) => item.entityId === entity.id && item.disabled));
|
|
30
|
+
const selection = included.map((entity) => {
|
|
31
|
+
const excluded = exclusions.find((item) => item.entityId === entity.id);
|
|
32
|
+
const keyed = entity.relationships.filter((relationship) => relationship.cardinality === "one" && !isValueMatched(relationship));
|
|
33
|
+
const excludedFields = new Set([
|
|
34
|
+
...(excluded?.fields ?? []),
|
|
35
|
+
...keyed
|
|
36
|
+
.filter((relationship) => excluded?.relationships?.includes(relationship.name))
|
|
37
|
+
.map((relationship) => `${relationship.name}_id`),
|
|
38
|
+
]);
|
|
39
|
+
return {
|
|
40
|
+
entityId: entity.id,
|
|
41
|
+
fields: queryFields(entity)
|
|
42
|
+
.filter((field) => !excludedFields.has(field.name))
|
|
43
|
+
.map((field) => field.name),
|
|
44
|
+
relationships: entity.relationships
|
|
45
|
+
.filter((relationship) => relationship.cardinality === "many" &&
|
|
46
|
+
!excluded?.relationships?.includes(relationship.name) &&
|
|
47
|
+
included.some((target) => target.name === relationship.to))
|
|
48
|
+
.map((relationship) => relationship.name),
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
validateReplicationSelection(manifest, selection);
|
|
52
|
+
return selection;
|
|
53
|
+
}
|
|
54
|
+
export const REPLICATION_BATCH_SIZE = 100;
|
|
55
|
+
export const REPLICATION_BATCH_BYTES = 1_000_000;
|
|
56
|
+
// Leaves room for JSON escaping, the envelope and base64 inside a 1 MB publish request.
|
|
57
|
+
export const REPLICATION_RECORD_BYTES = 200_000;
|
|
58
|
+
export function validateReplicationSelection(manifest, selection) {
|
|
59
|
+
if (new Set(selection.map((s) => s.entityId)).size !== selection.length) {
|
|
60
|
+
throw new Error("Replicated entities must be distinct.");
|
|
61
|
+
}
|
|
62
|
+
const viewNames = new Set();
|
|
63
|
+
const addView = (name) => {
|
|
64
|
+
const key = name.toLowerCase();
|
|
65
|
+
if (viewNames.has(key)) {
|
|
66
|
+
throw new Error("Replicated entity and relationship view names collide.");
|
|
67
|
+
}
|
|
68
|
+
viewNames.add(key);
|
|
69
|
+
};
|
|
70
|
+
for (const item of selection) {
|
|
71
|
+
const entity = manifest.entities.find((e) => e.id === item.entityId);
|
|
72
|
+
if (!entity || entity.builtIn || entity.source !== undefined) {
|
|
73
|
+
throw new Error(`Only stored business entities can be replicated: ${item.entityId}.`);
|
|
74
|
+
}
|
|
75
|
+
addView(entity.name);
|
|
76
|
+
const fields = new Set(queryFields(entity).map((f) => f.name));
|
|
77
|
+
if (item.fields.some((field) => !fields.has(field))) {
|
|
78
|
+
throw new Error(`Unknown replication field on ${entity.name}.`);
|
|
79
|
+
}
|
|
80
|
+
for (const name of item.relationships ?? []) {
|
|
81
|
+
const relationship = entity.relationships.find((r) => r.name === name);
|
|
82
|
+
const target = manifest.entities.find((e) => e.name === relationship?.to);
|
|
83
|
+
if (relationship?.cardinality !== "many" ||
|
|
84
|
+
!target ||
|
|
85
|
+
target.builtIn ||
|
|
86
|
+
!selection.some((s) => s.entityId === target.id)) {
|
|
87
|
+
throw new Error(`Replication of ${entity.name}.${name} requires both business entities.`);
|
|
88
|
+
}
|
|
89
|
+
addView(`${entity.name}_${name}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function replicationEventId(source, history, generation) {
|
|
94
|
+
return createHash("sha256").update(`${source}:${history}:${generation}`).digest("hex");
|
|
95
|
+
}
|
|
96
|
+
/** Includes base64 and JSON overhead, not just the original payload bytes. */
|
|
97
|
+
export function publishMessage(event) {
|
|
98
|
+
return { data: Buffer.from(JSON.stringify(event)).toString("base64") };
|
|
99
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { SqlClient } from "effect/unstable/sql";
|
|
3
|
+
import type { ReplicationTarget } from "./baseline.js";
|
|
4
|
+
import { ReplicationBaselineFailed } from "./baseline.js";
|
|
5
|
+
export interface ReplicationScanScope {
|
|
6
|
+
readonly entityId: string;
|
|
7
|
+
readonly kind: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function replicationScanScopes(target: Pick<ReplicationTarget, "selection">): ReplicationScanScope[];
|
|
10
|
+
/** Installed in a lifecycle transaction. Existing cursors survive unrelated schema changes. */
|
|
11
|
+
export declare const scheduleReplicationScans: (sql: SqlClient.SqlClient, generation: string, scopes: readonly ReplicationScanScope[], options?: {
|
|
12
|
+
readonly initial?: boolean;
|
|
13
|
+
readonly reset?: boolean;
|
|
14
|
+
}) => Effect.Effect<void, import("effect/unstable/sql/SqlError").SqlError, never>;
|
|
15
|
+
/** Convert an old positional baseline once, before its manifest can change. */
|
|
16
|
+
export declare const upgradeReplicationScans: (sql: SqlClient.SqlClient, target: ReplicationTarget & {
|
|
17
|
+
readonly baseline_cursor?: {
|
|
18
|
+
readonly index?: number;
|
|
19
|
+
readonly key?: string;
|
|
20
|
+
};
|
|
21
|
+
}) => Effect.Effect<void, import("effect/unstable/sql/SqlError").SqlError, never>;
|
|
22
|
+
/** Drop obsolete scopes without making an unrelated pending scan start over. */
|
|
23
|
+
export declare const reconcileReplicationScans: (sql: SqlClient.SqlClient, target: ReplicationTarget) => import("effect/unstable/sql/Statement").Statement<object>;
|
|
24
|
+
/**
|
|
25
|
+
* Full snapshots of one affected entity/edge scope. Share lifecycle admission first, then lock
|
|
26
|
+
* source rows in key order before allocating revisions. Concurrent mutations therefore supersede
|
|
27
|
+
* these snapshots, including deletes, without holding a business lock for the whole copy.
|
|
28
|
+
*/
|
|
29
|
+
export declare const advanceReplicationScan: (sql: SqlClient.SqlClient, generation: string) => Effect.Effect<{
|
|
30
|
+
complete: boolean;
|
|
31
|
+
progressed: boolean;
|
|
32
|
+
}, import("effect/unstable/sql/SqlError").SqlError | ReplicationBaselineFailed, never>;
|
|
33
|
+
/** A published schema may add coverage only after its finite scan output is accepted by Pub/Sub. */
|
|
34
|
+
export declare const replicationScansReady: (sql: SqlClient.SqlClient, generation: string) => Effect.Effect<boolean, import("effect/unstable/sql/SqlError").SqlError, never>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ReplicationBaselineFailed } from "./baseline.js";
|
|
3
|
+
import { joinColumnNames, joinTableName, quoteIdentifier as qi, quoteLiteral as ql, tableName, } from "../migrate/storage.js";
|
|
4
|
+
import { REPLICATION_RECORD_BYTES } from "./model.js";
|
|
5
|
+
import { snapshotExpression } from "./schema.js";
|
|
6
|
+
import { lockReplicationLifecycle, shareReplicationLifecycle } from "./transaction.js";
|
|
7
|
+
export function replicationScanScopes(target) {
|
|
8
|
+
return target.selection.flatMap((item) => [
|
|
9
|
+
{ entityId: item.entityId, kind: "entity" },
|
|
10
|
+
...(item.relationships ?? []).map((name) => ({
|
|
11
|
+
entityId: item.entityId,
|
|
12
|
+
kind: `edge:${name}`,
|
|
13
|
+
})),
|
|
14
|
+
]);
|
|
15
|
+
}
|
|
16
|
+
/** Installed in a lifecycle transaction. Existing cursors survive unrelated schema changes. */
|
|
17
|
+
export const scheduleReplicationScans = (sql, generation, scopes, options = {}) => Effect.gen(function* () {
|
|
18
|
+
for (const scope of scopes) {
|
|
19
|
+
yield* sql.unsafe(`INSERT INTO _ontology_replication_scans (generation, entity_id, record_kind, initial)
|
|
20
|
+
VALUES ($1::uuid,$2,$3,$4)
|
|
21
|
+
ON CONFLICT (generation,entity_id,record_kind) WHERE NOT complete DO UPDATE
|
|
22
|
+
SET cursor = CASE WHEN $5::boolean THEN '' ELSE _ontology_replication_scans.cursor END,
|
|
23
|
+
required = true, initial = _ontology_replication_scans.initial OR excluded.initial`, [generation, scope.entityId, scope.kind, options.initial ?? false, options.reset ?? false]);
|
|
24
|
+
}
|
|
25
|
+
if (scopes.length > 0) {
|
|
26
|
+
yield* sql.unsafe("UPDATE _ontology_replication_targets SET scans_complete = false WHERE generation = $1::uuid", [generation]);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
/** Convert an old positional baseline once, before its manifest can change. */
|
|
30
|
+
export const upgradeReplicationScans = (sql, target) => Effect.gen(function* () {
|
|
31
|
+
const [existing] = yield* sql.unsafe("SELECT EXISTS (SELECT 1 FROM _ontology_replication_scans WHERE generation = $1::uuid) AS present", [target.generation]);
|
|
32
|
+
if (target.baseline_complete !== false || existing?.present) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const position = target.baseline_cursor?.index ?? 0;
|
|
36
|
+
const scopes = replicationScanScopes(target).slice(position);
|
|
37
|
+
// An empty remaining scope list still needs to finalize the fixed initialization fence.
|
|
38
|
+
yield* sql.unsafe("UPDATE _ontology_replication_targets SET scans_complete = false WHERE generation = $1::uuid", [target.generation]);
|
|
39
|
+
yield* scheduleReplicationScans(sql, target.generation, scopes, { initial: true });
|
|
40
|
+
if (scopes[0] && target.baseline_cursor?.key) {
|
|
41
|
+
yield* sql.unsafe(`UPDATE _ontology_replication_scans SET cursor = $4
|
|
42
|
+
WHERE generation = $1::uuid AND entity_id = $2 AND record_kind = $3 AND NOT complete`, [target.generation, scopes[0].entityId, scopes[0].kind, target.baseline_cursor.key]);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
/** Drop obsolete scopes without making an unrelated pending scan start over. */
|
|
46
|
+
export const reconcileReplicationScans = (sql, target) => sql.unsafe(`UPDATE _ontology_replication_scans SET complete = true, required = false
|
|
47
|
+
WHERE generation = $1::uuid AND NOT EXISTS (
|
|
48
|
+
SELECT 1 FROM jsonb_to_recordset($2::jsonb) AS s("entityId" text, kind text)
|
|
49
|
+
WHERE s."entityId" = entity_id AND s.kind = record_kind)`, [target.generation, JSON.stringify(replicationScanScopes(target))]);
|
|
50
|
+
const PAGE_SIZE = 250;
|
|
51
|
+
/**
|
|
52
|
+
* Full snapshots of one affected entity/edge scope. Share lifecycle admission first, then lock
|
|
53
|
+
* source rows in key order before allocating revisions. Concurrent mutations therefore supersede
|
|
54
|
+
* these snapshots, including deletes, without holding a business lock for the whole copy.
|
|
55
|
+
*/
|
|
56
|
+
export const advanceReplicationScan = (sql, generation) => Effect.gen(function* () {
|
|
57
|
+
const scanned = yield* sql.withTransaction(Effect.gen(function* () {
|
|
58
|
+
yield* sql.unsafe("SET LOCAL statement_timeout = '30s'");
|
|
59
|
+
yield* sql.unsafe("SET LOCAL lock_timeout = '5s'");
|
|
60
|
+
yield* shareReplicationLifecycle(sql);
|
|
61
|
+
const [target] = yield* sql.unsafe(`SELECT * FROM _ontology_replication_targets WHERE generation = $1::uuid FOR NO KEY UPDATE`, [generation]);
|
|
62
|
+
const [state] = yield* sql.unsafe("SELECT enabled, active_generation::text, version FROM _ontology_replication WHERE id");
|
|
63
|
+
if (!target || !state?.enabled || state.active_generation !== generation) {
|
|
64
|
+
return { finish: false, progressed: false };
|
|
65
|
+
}
|
|
66
|
+
const [scan] = yield* sql.unsafe(`SELECT id::text, entity_id, record_kind, cursor FROM _ontology_replication_scans
|
|
67
|
+
WHERE generation = $1::uuid AND NOT complete ORDER BY initial DESC, id LIMIT 1 FOR UPDATE`, [generation]);
|
|
68
|
+
if (!scan) {
|
|
69
|
+
return { finish: true, progressed: false };
|
|
70
|
+
}
|
|
71
|
+
const entity = target.manifest.entities.find((entity) => entity.id === scan.entity_id);
|
|
72
|
+
const selection = target.selection.find((item) => item.entityId === scan.entity_id);
|
|
73
|
+
let records;
|
|
74
|
+
if (scan.record_kind === "entity") {
|
|
75
|
+
const fields = selection.fields.includes("id")
|
|
76
|
+
? selection.fields
|
|
77
|
+
: ["id", ...selection.fields];
|
|
78
|
+
records = `SELECT r.id::text AS record_key,
|
|
79
|
+
(SELECT jsonb_object_agg(key,value) FROM jsonb_each(${snapshotExpression(entity, "r")})
|
|
80
|
+
WHERE ${ql(JSON.stringify(fields))}::jsonb ? key) AS payload
|
|
81
|
+
FROM ${qi(tableName(entity.name))} r
|
|
82
|
+
WHERE ($2::text = '' OR r.id > NULLIF($2::text,'')::uuid)
|
|
83
|
+
ORDER BY r.id LIMIT ${PAGE_SIZE} FOR SHARE OF r`;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const name = scan.record_kind.slice(5);
|
|
87
|
+
const relationship = entity.relationships.find((relationship) => relationship.name === name);
|
|
88
|
+
const columns = joinColumnNames({
|
|
89
|
+
entity: entity.name,
|
|
90
|
+
relationship: name,
|
|
91
|
+
target: relationship.to,
|
|
92
|
+
});
|
|
93
|
+
const source = qi(columns.source);
|
|
94
|
+
const destination = qi(columns.target);
|
|
95
|
+
records = `SELECT ${source}::text || ':' || ${destination}::text AS record_key,
|
|
96
|
+
jsonb_build_object('source_id',${source}::text,'target_id',${destination}::text) AS payload
|
|
97
|
+
FROM ${qi(joinTableName(entity.name, name))}
|
|
98
|
+
WHERE ($2::text = '' OR (${source},${destination}) >
|
|
99
|
+
(NULLIF(split_part($2::text,':',1),'')::uuid,NULLIF(split_part($2::text,':',2),'')::uuid))
|
|
100
|
+
ORDER BY ${source},${destination} LIMIT ${PAGE_SIZE} FOR SHARE`;
|
|
101
|
+
}
|
|
102
|
+
const [page] = yield* sql.unsafe(`WITH page AS MATERIALIZED (${records}), valid AS (
|
|
103
|
+
SELECT NOT EXISTS(SELECT 1 FROM page WHERE octet_length(payload::text) > ${REPLICATION_RECORD_BYTES}) AS ok
|
|
104
|
+
), inserted AS (
|
|
105
|
+
INSERT INTO _ontology_replication_baselines (generation,event)
|
|
106
|
+
SELECT $1::uuid,jsonb_build_object('source_id',$3::text,'entity_id',$4::text,
|
|
107
|
+
'record_key',record_key,'record_kind',$5::text,'revision',nextval('_ontology_replication_revision')::text,
|
|
108
|
+
'deleted',false,'schema_hash',$6::text,'payload',payload::text)
|
|
109
|
+
FROM page WHERE (SELECT ok FROM valid) RETURNING id,event
|
|
110
|
+
), queued AS (
|
|
111
|
+
INSERT INTO _ontology_replication_delivery
|
|
112
|
+
(generation,event_id,revision,is_baseline,scan_id${state.version >= 6 ? ",payload_bytes" : ""})
|
|
113
|
+
SELECT $1::uuid,id,(event->>'revision')::bigint,true,$7::uuid
|
|
114
|
+
${state.version >= 6 ? ",octet_length(event::text)" : ""} FROM inserted RETURNING event_id
|
|
115
|
+
) SELECT (SELECT count(*)::integer FROM queued) AS count,
|
|
116
|
+
(SELECT max(record_key) FROM page) AS key, NOT (SELECT ok FROM valid) AS oversized`, [
|
|
117
|
+
generation,
|
|
118
|
+
scan.cursor,
|
|
119
|
+
target.source_id,
|
|
120
|
+
entity.id,
|
|
121
|
+
scan.record_kind,
|
|
122
|
+
target.manifest.hash,
|
|
123
|
+
scan.id,
|
|
124
|
+
]);
|
|
125
|
+
if (page.oversized) {
|
|
126
|
+
return yield* new ReplicationBaselineFailed({
|
|
127
|
+
message: `A projected record exceeds ${REPLICATION_RECORD_BYTES} bytes; ` +
|
|
128
|
+
"change the record or its declared projection.",
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
yield* sql.unsafe(`UPDATE _ontology_replication_scans SET cursor = COALESCE($2,cursor), complete = $3 WHERE id = $1::uuid`, [scan.id, page.key, page.count < PAGE_SIZE]);
|
|
132
|
+
return { finish: false, progressed: true };
|
|
133
|
+
}));
|
|
134
|
+
if (!scanned.finish) {
|
|
135
|
+
return { complete: false, progressed: scanned.progressed };
|
|
136
|
+
}
|
|
137
|
+
// Finalization must drain admitted writers; never upgrade a shared lifecycle lock in place.
|
|
138
|
+
return yield* sql.withTransaction(Effect.gen(function* () {
|
|
139
|
+
yield* sql.unsafe("SET LOCAL statement_timeout = '30s'");
|
|
140
|
+
yield* sql.unsafe("SET LOCAL lock_timeout = '5s'");
|
|
141
|
+
yield* lockReplicationLifecycle(sql);
|
|
142
|
+
const [target] = yield* sql.unsafe(`UPDATE _ontology_replication_targets SET scans_complete = true, baseline_complete = true,
|
|
143
|
+
initial_revision = COALESCE(initial_revision,
|
|
144
|
+
(SELECT CASE WHEN is_called THEN last_value ELSE 0 END FROM _ontology_replication_revision))
|
|
145
|
+
WHERE generation = $1::uuid AND NOT EXISTS (
|
|
146
|
+
SELECT 1 FROM _ontology_replication_scans WHERE generation = $1::uuid AND NOT complete)
|
|
147
|
+
AND generation = (SELECT active_generation FROM _ontology_replication WHERE id AND enabled)
|
|
148
|
+
RETURNING scans_complete AS complete`, [generation]);
|
|
149
|
+
return { complete: target?.complete ?? false, progressed: target?.complete ?? false };
|
|
150
|
+
}));
|
|
151
|
+
});
|
|
152
|
+
/** A published schema may add coverage only after its finite scan output is accepted by Pub/Sub. */
|
|
153
|
+
export const replicationScansReady = (sql, generation) => sql
|
|
154
|
+
.unsafe(`SELECT scans_complete AND NOT EXISTS (
|
|
155
|
+
SELECT 1 FROM _ontology_replication_delivery d JOIN _ontology_replication_scans s ON s.id = d.scan_id
|
|
156
|
+
WHERE d.generation = $1::uuid AND s.required AND d.accepted_at IS NULL
|
|
157
|
+
) AS ready FROM _ontology_replication_targets WHERE generation = $1::uuid`, [generation])
|
|
158
|
+
.pipe(Effect.map((rows) => rows[0]?.ready ?? false));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EntityManifest, OntologyManifest } from "../manifest.js";
|
|
2
|
+
export declare const REPLICATION_SCHEMA_VERSION = 6;
|
|
3
|
+
/** Targets of sources not migrated since fills were introduced have no `fills` column. */
|
|
4
|
+
export declare const REPLICATION_TARGET_FILLS = "COALESCE(to_jsonb(_ontology_replication_targets) -> 'fills',\n '{}'::jsonb) AS fills";
|
|
5
|
+
/** Optional metadata keeps the platform reader compatible with sources not upgraded yet. */
|
|
6
|
+
export declare const REPLICATION_TARGET_METADATA = "\n to_jsonb(_ontology_replication_targets)->'identities' AS identities,\n COALESCE(to_jsonb(_ontology_replication_targets)->'lineage', 'null'::jsonb) AS lineage,\n COALESCE((to_jsonb(_ontology_replication_targets)->>'scans_complete')::boolean, true) AS scans_complete,\n to_jsonb(_ontology_replication_targets)->'backfill_sources' AS backfill_sources,\n (SELECT version FROM _ontology_replication WHERE id) AS schema_version";
|
|
7
|
+
/** Installed only by the SDK migration runner, never at service startup. */
|
|
8
|
+
export declare const REPLICATION_DDL: string[];
|
|
9
|
+
export declare function snapshotExpression(entity: EntityManifest, alias: string): string;
|
|
10
|
+
/** History is the durable source. Triggers also reject old writers while capture is enabled. */
|
|
11
|
+
export declare function replicationEntityDdl(manifest: OntologyManifest, previous?: OntologyManifest): ReadonlyArray<string>;
|