@spine-event-engine/server 2.0.0-snapshot.24 → 2.0.0-snapshot.26
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/README.md +86 -19
- package/REFERENCE.md +538 -150
- package/dist/agent/agent-acceptance-receipts.d.ts +69 -0
- package/dist/agent/agent-acceptance-receipts.d.ts.map +1 -0
- package/dist/agent/agent-acceptance-receipts.js +198 -0
- package/dist/agent/agent-acceptance-receipts.js.map +1 -0
- package/dist/agent/agent-execution-capacity.d.ts +37 -9
- package/dist/agent/agent-execution-capacity.d.ts.map +1 -1
- package/dist/agent/agent-execution-capacity.js +73 -15
- package/dist/agent/agent-execution-capacity.js.map +1 -1
- package/dist/agent/agent-history.d.ts +33 -12
- package/dist/agent/agent-history.d.ts.map +1 -1
- package/dist/agent/agent-history.js +61 -18
- package/dist/agent/agent-history.js.map +1 -1
- package/dist/agent/agent-live-ai-audit.d.ts +95 -0
- package/dist/agent/agent-live-ai-audit.d.ts.map +1 -0
- package/dist/agent/agent-live-ai-audit.js +290 -0
- package/dist/agent/agent-live-ai-audit.js.map +1 -0
- package/dist/agent/agent-live-ai-runtime.d.ts +300 -0
- package/dist/agent/agent-live-ai-runtime.d.ts.map +1 -0
- package/dist/agent/agent-live-ai-runtime.js +611 -0
- package/dist/agent/agent-live-ai-runtime.js.map +1 -0
- package/dist/agent/agent-live-audit.d.ts +67 -0
- package/dist/agent/agent-live-audit.d.ts.map +1 -0
- package/dist/agent/agent-live-audit.js +121 -0
- package/dist/agent/agent-live-audit.js.map +1 -0
- package/dist/agent/agent-live-budget.d.ts +84 -0
- package/dist/agent/agent-live-budget.d.ts.map +1 -0
- package/dist/agent/agent-live-budget.js +161 -0
- package/dist/agent/agent-live-budget.js.map +1 -0
- package/dist/agent/agent-live-fault.d.ts +18 -0
- package/dist/agent/agent-live-fault.d.ts.map +1 -0
- package/dist/agent/{agent-execution-fault.js → agent-live-fault.js} +7 -7
- package/dist/agent/agent-live-fault.js.map +1 -0
- package/dist/agent/agent-live-inputs.d.ts +74 -0
- package/dist/agent/agent-live-inputs.d.ts.map +1 -0
- package/dist/agent/agent-live-inputs.js +15 -0
- package/dist/agent/agent-live-inputs.js.map +1 -0
- package/dist/agent/agent-live-interaction-events.d.ts +46 -0
- package/dist/agent/agent-live-interaction-events.d.ts.map +1 -0
- package/dist/agent/agent-live-interaction-events.js +104 -0
- package/dist/agent/agent-live-interaction-events.js.map +1 -0
- package/dist/agent/agent-live-mcp-controls.d.ts +129 -0
- package/dist/agent/agent-live-mcp-controls.d.ts.map +1 -0
- package/dist/agent/agent-live-mcp-controls.js +228 -0
- package/dist/agent/agent-live-mcp-controls.js.map +1 -0
- package/dist/agent/agent-live-mcp-host.d.ts +88 -0
- package/dist/agent/agent-live-mcp-host.d.ts.map +1 -0
- package/dist/agent/{agent-mcp-host.js → agent-live-mcp-host.js} +1 -1
- package/dist/agent/agent-live-mcp-host.js.map +1 -0
- package/dist/agent/{agent-mcp-runtime.d.ts → agent-live-mcp-runtime.d.ts} +6 -6
- package/dist/agent/agent-live-mcp-runtime.d.ts.map +1 -0
- package/dist/agent/{agent-mcp-runtime.js → agent-live-mcp-runtime.js} +13 -42
- package/dist/agent/agent-live-mcp-runtime.js.map +1 -0
- package/dist/agent/agent-live-read-runtime.d.ts +72 -0
- package/dist/agent/agent-live-read-runtime.d.ts.map +1 -0
- package/dist/agent/agent-live-read-runtime.js +122 -0
- package/dist/agent/agent-live-read-runtime.js.map +1 -0
- package/dist/agent/agent-model-selection.d.ts +21 -34
- package/dist/agent/agent-model-selection.d.ts.map +1 -1
- package/dist/agent/agent-model-selection.js +61 -78
- package/dist/agent/agent-model-selection.js.map +1 -1
- package/dist/browser/browser-server.d.ts +163 -0
- package/dist/browser/browser-server.d.ts.map +1 -1
- package/dist/browser/browser-server.js +579 -188
- package/dist/browser/browser-server.js.map +1 -1
- package/dist/browser/durable-subscription-bindings.d.ts +5 -0
- package/dist/browser/durable-subscription-bindings.d.ts.map +1 -1
- package/dist/browser/durable-subscription-bindings.js +226 -38
- package/dist/browser/durable-subscription-bindings.js.map +1 -1
- package/dist/browser/options.d.ts +5 -0
- package/dist/browser/options.d.ts.map +1 -1
- package/dist/bus/command-bus.d.ts +17 -18
- package/dist/bus/command-bus.d.ts.map +1 -1
- package/dist/bus/command-bus.js +97 -54
- package/dist/bus/command-bus.js.map +1 -1
- package/dist/bus/command-errors.d.ts +20 -4
- package/dist/bus/command-errors.d.ts.map +1 -1
- package/dist/bus/command-errors.js +47 -7
- package/dist/bus/command-errors.js.map +1 -1
- package/dist/bus/event-bus.d.ts +20 -4
- package/dist/bus/event-bus.d.ts.map +1 -1
- package/dist/bus/event-bus.js +166 -14
- package/dist/bus/event-bus.js.map +1 -1
- package/dist/context/bounded-context.d.ts +169 -98
- package/dist/context/bounded-context.d.ts.map +1 -1
- package/dist/context/bounded-context.js +837 -503
- package/dist/context/bounded-context.js.map +1 -1
- package/dist/context/entity-inbox.d.ts +7 -2
- package/dist/context/entity-inbox.d.ts.map +1 -1
- package/dist/context/entity-inbox.js +22 -13
- package/dist/context/entity-inbox.js.map +1 -1
- package/dist/context/local-inbox-handoff.d.ts +34 -34
- package/dist/context/local-inbox-handoff.d.ts.map +1 -1
- package/dist/context/local-inbox-handoff.js +108 -150
- package/dist/context/local-inbox-handoff.js.map +1 -1
- package/dist/context/projection-handoff.d.ts +2 -2
- package/dist/context/projection-handoff.d.ts.map +1 -1
- package/dist/context/projection-handoff.js +10 -8
- package/dist/context/projection-handoff.js.map +1 -1
- package/dist/context/tenant-index.d.ts +36 -31
- package/dist/context/tenant-index.d.ts.map +1 -1
- package/dist/context/tenant-index.js +123 -125
- package/dist/context/tenant-index.js.map +1 -1
- package/dist/context/tenant-unknown-error.d.ts +33 -0
- package/dist/context/tenant-unknown-error.d.ts.map +1 -0
- package/dist/context/tenant-unknown-error.js +75 -0
- package/dist/context/tenant-unknown-error.js.map +1 -0
- package/dist/delivery/agent-delivery-scope.d.ts +66 -0
- package/dist/delivery/agent-delivery-scope.d.ts.map +1 -0
- package/dist/delivery/agent-delivery-scope.js +44 -0
- package/dist/delivery/agent-delivery-scope.js.map +1 -0
- package/dist/delivery/delivery-builder.d.ts +25 -1
- package/dist/delivery/delivery-builder.d.ts.map +1 -1
- package/dist/delivery/delivery-builder.js +89 -0
- package/dist/delivery/delivery-builder.js.map +1 -1
- package/dist/delivery/delivery-monitor.d.ts +1 -1
- package/dist/delivery/delivery-monitor.js +1 -1
- package/dist/delivery/delivery-run-control.d.ts +6 -0
- package/dist/delivery/delivery-run-control.d.ts.map +1 -1
- package/dist/delivery/delivery-run-control.js +10 -0
- package/dist/delivery/delivery-run-control.js.map +1 -1
- package/dist/delivery/delivery-supervisor.d.ts.map +1 -1
- package/dist/delivery/delivery-supervisor.js +28 -4
- package/dist/delivery/delivery-supervisor.js.map +1 -1
- package/dist/delivery/delivery-tenant.d.ts +17 -0
- package/dist/delivery/delivery-tenant.d.ts.map +1 -0
- package/dist/delivery/delivery-tenant.js +50 -0
- package/dist/delivery/delivery-tenant.js.map +1 -0
- package/dist/delivery/delivery.d.ts +96 -2
- package/dist/delivery/delivery.d.ts.map +1 -1
- package/dist/delivery/delivery.js +693 -53
- package/dist/delivery/delivery.js.map +1 -1
- package/dist/delivery/inbox-records.d.ts.map +1 -1
- package/dist/delivery/inbox-records.js +9 -16
- package/dist/delivery/inbox-records.js.map +1 -1
- package/dist/delivery/inbox-storage.d.ts +6 -0
- package/dist/delivery/inbox-storage.d.ts.map +1 -1
- package/dist/delivery/inbox-storage.js +43 -6
- package/dist/delivery/inbox-storage.js.map +1 -1
- package/dist/delivery/inbox.d.ts.map +1 -1
- package/dist/delivery/inbox.js +3 -2
- package/dist/delivery/inbox.js.map +1 -1
- package/dist/delivery/reception-observation.d.ts +12 -4
- package/dist/delivery/reception-observation.d.ts.map +1 -1
- package/dist/delivery/reception-observation.js +14 -3
- package/dist/delivery/reception-observation.js.map +1 -1
- package/dist/delivery/sharded-work-registry.d.ts +6 -0
- package/dist/delivery/sharded-work-registry.d.ts.map +1 -1
- package/dist/delivery/sharded-work-registry.js +41 -4
- package/dist/delivery/sharded-work-registry.js.map +1 -1
- package/dist/entity/entity-storage-descriptor.d.ts.map +1 -1
- package/dist/entity/entity-storage-descriptor.js +7 -4
- package/dist/entity/entity-storage-descriptor.js.map +1 -1
- package/dist/entity/entity.d.ts +59 -0
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +60 -0
- package/dist/entity/entity.js.map +1 -1
- package/dist/handler/app-query-handler.d.ts +60 -0
- package/dist/handler/app-query-handler.d.ts.map +1 -0
- package/dist/{bus/saved-dispatcher-binding.js → handler/app-query-handler.js} +8 -12
- package/dist/handler/app-query-handler.js.map +1 -0
- package/dist/handler/generated-registry-discovery.d.ts +6 -0
- package/dist/handler/generated-registry-discovery.d.ts.map +1 -1
- package/dist/handler/generated-registry-discovery.js +71 -2
- package/dist/handler/generated-registry-discovery.js.map +1 -1
- package/dist/handler/handler-decorators.d.ts +8 -29
- package/dist/handler/handler-decorators.d.ts.map +1 -1
- package/dist/handler/handler-decorators.js +33 -210
- package/dist/handler/handler-decorators.js.map +1 -1
- package/dist/handler/spine-metadata-inventory.d.ts +99 -0
- package/dist/handler/spine-metadata-inventory.d.ts.map +1 -0
- package/dist/handler/spine-metadata-inventory.js +162 -0
- package/dist/handler/spine-metadata-inventory.js.map +1 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/integration/external-messages.d.ts.map +1 -1
- package/dist/integration/external-messages.js +9 -15
- package/dist/integration/external-messages.js.map +1 -1
- package/dist/integration/integration-broker.d.ts.map +1 -1
- package/dist/integration/integration-broker.js +112 -6
- package/dist/integration/integration-broker.js.map +1 -1
- package/dist/integration/third-party-context.d.ts.map +1 -1
- package/dist/integration/third-party-context.js +7 -10
- package/dist/integration/third-party-context.js.map +1 -1
- package/dist/repository/primitive-id.js +26 -11
- package/dist/repository/primitive-id.js.map +1 -1
- package/dist/repository/repository.d.ts +75 -60
- package/dist/repository/repository.d.ts.map +1 -1
- package/dist/repository/repository.js +1757 -1818
- package/dist/repository/repository.js.map +1 -1
- package/dist/runtime/runtime.d.ts +13 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +18 -0
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/signal-metadata.d.ts.map +1 -1
- package/dist/runtime/signal-metadata.js +6 -6
- package/dist/runtime/signal-metadata.js.map +1 -1
- package/dist/runtime/signal-publisher.d.ts +0 -6
- package/dist/runtime/signal-publisher.d.ts.map +1 -1
- package/dist/runtime/signal-publisher.js +1 -9
- package/dist/runtime/signal-publisher.js.map +1 -1
- package/dist/runtime/standalone-handler-runtime.d.ts +0 -7
- package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -1
- package/dist/runtime/standalone-handler-runtime.js +13 -99
- package/dist/runtime/standalone-handler-runtime.js.map +1 -1
- package/dist/server/managed-delivery-gate.d.ts +34 -0
- package/dist/server/managed-delivery-gate.d.ts.map +1 -0
- package/dist/server/managed-delivery-gate.js +70 -0
- package/dist/server/managed-delivery-gate.js.map +1 -0
- package/dist/server/managed-server-application.d.ts +12 -11
- package/dist/server/managed-server-application.d.ts.map +1 -1
- package/dist/server/managed-server-application.js +48 -29
- package/dist/server/managed-server-application.js.map +1 -1
- package/dist/server/node-coordinator.d.ts +18 -5
- package/dist/server/node-coordinator.d.ts.map +1 -1
- package/dist/server/node-coordinator.js +554 -84
- package/dist/server/node-coordinator.js.map +1 -1
- package/dist/server/reserved-spine-rpc-paths.json +1 -0
- package/dist/server/server-environment.d.ts +220 -25
- package/dist/server/server-environment.d.ts.map +1 -1
- package/dist/server/server-environment.js +734 -145
- package/dist/server/server-environment.js.map +1 -1
- package/dist/server/server-log.d.ts +7 -0
- package/dist/server/server-log.d.ts.map +1 -1
- package/dist/server/server-log.js +14 -1
- package/dist/server/server-log.js.map +1 -1
- package/dist/server/server.d.ts +60 -29
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +155 -201
- package/dist/server/server.js.map +1 -1
- package/dist/services/app-query-execution.d.ts +53 -0
- package/dist/services/app-query-execution.d.ts.map +1 -0
- package/dist/services/app-query-execution.js +408 -0
- package/dist/services/app-query-execution.js.map +1 -0
- package/dist/services/query-reader.d.ts +32 -7
- package/dist/services/query-reader.d.ts.map +1 -1
- package/dist/services/query-reader.js +22 -2
- package/dist/services/query-reader.js.map +1 -1
- package/dist/services/read-request-status.d.ts +65 -0
- package/dist/services/read-request-status.d.ts.map +1 -0
- package/dist/services/read-request-status.js +151 -0
- package/dist/services/read-request-status.js.map +1 -0
- package/dist/services/spine-services.d.ts +37 -8
- package/dist/services/spine-services.d.ts.map +1 -1
- package/dist/services/spine-services.js +1103 -470
- package/dist/services/spine-services.js.map +1 -1
- package/dist/services/trusted-reader-ingress.d.ts +92 -0
- package/dist/services/trusted-reader-ingress.d.ts.map +1 -0
- package/dist/services/trusted-reader-ingress.js +89 -0
- package/dist/services/trusted-reader-ingress.js.map +1 -0
- package/dist/spi/handler-registry.d.ts +2 -0
- package/dist/spi/handler-registry.d.ts.map +1 -1
- package/dist/spi/handler-registry.js +1 -1
- package/dist/spi/handler-registry.js.map +1 -1
- package/dist/stand/event-origin-filter.js +3 -3
- package/dist/stand/event-origin-filter.js.map +1 -1
- package/dist/stand/read-side-filter-engine.d.ts +46 -0
- package/dist/stand/read-side-filter-engine.d.ts.map +1 -0
- package/dist/stand/read-side-filter-engine.js +356 -0
- package/dist/stand/read-side-filter-engine.js.map +1 -0
- package/dist/stand/read-side-filter.d.ts +247 -0
- package/dist/stand/read-side-filter.d.ts.map +1 -0
- package/dist/stand/read-side-filter.js +39 -0
- package/dist/stand/read-side-filter.js.map +1 -0
- package/dist/stand/read-side-message.d.ts +66 -0
- package/dist/stand/read-side-message.d.ts.map +1 -0
- package/dist/stand/read-side-message.js +167 -0
- package/dist/stand/read-side-message.js.map +1 -0
- package/dist/stand/stand-direct-delivery.d.ts +161 -0
- package/dist/stand/stand-direct-delivery.d.ts.map +1 -0
- package/dist/stand/stand-direct-delivery.js +210 -0
- package/dist/stand/stand-direct-delivery.js.map +1 -0
- package/dist/stand/stand.d.ts +94 -42
- package/dist/stand/stand.d.ts.map +1 -1
- package/dist/stand/stand.js +460 -60
- package/dist/stand/stand.js.map +1 -1
- package/dist/stand/subscription-observer.d.ts.map +1 -1
- package/dist/stand/subscription-observer.js +157 -40
- package/dist/stand/subscription-observer.js.map +1 -1
- package/dist/stand/subscription-read-filters.d.ts +40 -0
- package/dist/stand/subscription-read-filters.d.ts.map +1 -0
- package/dist/stand/subscription-read-filters.js +91 -0
- package/dist/stand/subscription-read-filters.js.map +1 -0
- package/dist/stand/subscription-reader-binding.d.ts +20 -0
- package/dist/stand/subscription-reader-binding.d.ts.map +1 -0
- package/dist/stand/subscription-reader-binding.js +56 -0
- package/dist/stand/subscription-reader-binding.js.map +1 -0
- package/dist/stand/subscription-records.d.ts +30 -3
- package/dist/stand/subscription-records.d.ts.map +1 -1
- package/dist/stand/subscription-records.js +61 -16
- package/dist/stand/subscription-records.js.map +1 -1
- package/dist/stand/subscription-registry.d.ts +54 -15
- package/dist/stand/subscription-registry.d.ts.map +1 -1
- package/dist/stand/subscription-registry.js +164 -41
- package/dist/stand/subscription-registry.js.map +1 -1
- package/dist/stand/subscription-runtime.d.ts +12 -5
- package/dist/stand/subscription-runtime.d.ts.map +1 -1
- package/dist/stand/subscription-runtime.js +183 -34
- package/dist/stand/subscription-runtime.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +4 -3
- package/dist/testing/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -14
- package/dist/agent/agent-admission.d.ts +0 -80
- package/dist/agent/agent-admission.d.ts.map +0 -1
- package/dist/agent/agent-admission.js +0 -127
- package/dist/agent/agent-admission.js.map +0 -1
- package/dist/agent/agent-ai-runtime.d.ts +0 -76
- package/dist/agent/agent-ai-runtime.d.ts.map +0 -1
- package/dist/agent/agent-ai-runtime.js +0 -1269
- package/dist/agent/agent-ai-runtime.js.map +0 -1
- package/dist/agent/agent-execution-fault.d.ts +0 -18
- package/dist/agent/agent-execution-fault.d.ts.map +0 -1
- package/dist/agent/agent-execution-fault.js.map +0 -1
- package/dist/agent/agent-execution-session.d.ts +0 -103
- package/dist/agent/agent-execution-session.d.ts.map +0 -1
- package/dist/agent/agent-execution-session.js +0 -238
- package/dist/agent/agent-execution-session.js.map +0 -1
- package/dist/agent/agent-interaction-audit.d.ts +0 -58
- package/dist/agent/agent-interaction-audit.d.ts.map +0 -1
- package/dist/agent/agent-interaction-audit.js +0 -114
- package/dist/agent/agent-interaction-audit.js.map +0 -1
- package/dist/agent/agent-interaction-events.d.ts +0 -40
- package/dist/agent/agent-interaction-events.d.ts.map +0 -1
- package/dist/agent/agent-interaction-events.js +0 -129
- package/dist/agent/agent-interaction-events.js.map +0 -1
- package/dist/agent/agent-mcp-budget.d.ts +0 -125
- package/dist/agent/agent-mcp-budget.d.ts.map +0 -1
- package/dist/agent/agent-mcp-budget.js +0 -566
- package/dist/agent/agent-mcp-budget.js.map +0 -1
- package/dist/agent/agent-mcp-host.d.ts +0 -125
- package/dist/agent/agent-mcp-host.d.ts.map +0 -1
- package/dist/agent/agent-mcp-host.js.map +0 -1
- package/dist/agent/agent-mcp-runtime.d.ts.map +0 -1
- package/dist/agent/agent-mcp-runtime.js.map +0 -1
- package/dist/agent/agent-read-runtime.d.ts +0 -70
- package/dist/agent/agent-read-runtime.d.ts.map +0 -1
- package/dist/agent/agent-read-runtime.js +0 -320
- package/dist/agent/agent-read-runtime.js.map +0 -1
- package/dist/agent/agent-revisions.d.ts +0 -35
- package/dist/agent/agent-revisions.d.ts.map +0 -1
- package/dist/agent/agent-revisions.js +0 -133
- package/dist/agent/agent-revisions.js.map +0 -1
- package/dist/agent/agent-scheduler.d.ts +0 -99
- package/dist/agent/agent-scheduler.d.ts.map +0 -1
- package/dist/agent/agent-scheduler.js +0 -398
- package/dist/agent/agent-scheduler.js.map +0 -1
- package/dist/bus/saved-dispatcher-binding.d.ts +0 -53
- package/dist/bus/saved-dispatcher-binding.d.ts.map +0 -1
- package/dist/bus/saved-dispatcher-binding.js.map +0 -1
- package/dist/delivery/delivery-run-coordinator.d.ts +0 -218
- package/dist/delivery/delivery-run-coordinator.d.ts.map +0 -1
- package/dist/delivery/delivery-run-coordinator.js +0 -609
- package/dist/delivery/delivery-run-coordinator.js.map +0 -1
- package/dist/delivery/parked-delivery-obligations.d.ts +0 -182
- package/dist/delivery/parked-delivery-obligations.d.ts.map +0 -1
- package/dist/delivery/parked-delivery-obligations.js +0 -390
- package/dist/delivery/parked-delivery-obligations.js.map +0 -1
- package/dist/server/environment-attachment.d.ts +0 -356
- package/dist/server/environment-attachment.d.ts.map +0 -1
- package/dist/server/environment-attachment.js +0 -2062
- package/dist/server/environment-attachment.js.map +0 -1
- package/dist/server/environment-delivery-records.d.ts +0 -77
- package/dist/server/environment-delivery-records.d.ts.map +0 -1
- package/dist/server/environment-delivery-records.js +0 -282
- package/dist/server/environment-delivery-records.js.map +0 -1
- package/dist/server/environment-delivery-worker.d.ts +0 -161
- package/dist/server/environment-delivery-worker.d.ts.map +0 -1
- package/dist/server/environment-delivery-worker.js +0 -973
- package/dist/server/environment-delivery-worker.js.map +0 -1
package/dist/stand/stand.js
CHANGED
|
@@ -12,14 +12,23 @@
|
|
|
12
12
|
* the License.
|
|
13
13
|
*/
|
|
14
14
|
var _a;
|
|
15
|
-
import { clone } from "@bufbuild/protobuf";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
15
|
+
import { clone, create, toBinary } from "@bufbuild/protobuf";
|
|
16
|
+
import { AnySchema } from "@bufbuild/protobuf/wkt";
|
|
17
|
+
import { TypeRegistry, TypeUrls } from "@spine-event-engine/core";
|
|
18
|
+
import { registeredProtoModules } from "@spine-event-engine/proto/codegen";
|
|
19
|
+
import { ActorContextSchema, EventSchema, TenantIdSchema, VersionSchema, } from "@spine-event-engine/proto";
|
|
18
20
|
import { ColumnTypes, RecordColumn, RecordQuery, } from "@spine-event-engine/storage";
|
|
19
21
|
import { TenantBoundary } from "@spine-event-engine/storage/provider";
|
|
20
|
-
import { EntityRecords, standEntityStorageDescriptor, } from "../entity/entity-storage-descriptor.js";
|
|
22
|
+
import { EntityIds, EntityRecords, standEntityStorageDescriptor, } from "../entity/entity-storage-descriptor.js";
|
|
21
23
|
import { SubscriptionObservers } from "./subscription-observer.js";
|
|
24
|
+
import { ReadSideFilterEngine } from "./read-side-filter-engine.js";
|
|
25
|
+
import { SubscriptionReadFilters } from "./subscription-read-filters.js";
|
|
26
|
+
import { ReadSideMessages } from "./read-side-message.js";
|
|
27
|
+
import { StandDirectDelivery, } from "./stand-direct-delivery.js";
|
|
28
|
+
import { ServerEnvironment } from "../server/server-environment.js";
|
|
29
|
+
import { snapshotTrustedReader, } from "@spine-event-engine/core/spi/trusted-reader";
|
|
22
30
|
const HANDLE_CLOSE_ERROR_LIMIT = 16;
|
|
31
|
+
export { StandSubscriptionCapacityError } from "./stand-direct-delivery.js";
|
|
23
32
|
/**
|
|
24
33
|
* Error thrown when direct Stand access targets an unregistered state type.
|
|
25
34
|
*/
|
|
@@ -54,12 +63,14 @@ export class StandStateTypeError extends Error {
|
|
|
54
63
|
*/
|
|
55
64
|
export class Stand {
|
|
56
65
|
#context;
|
|
66
|
+
#subscriptionQueueCapacity;
|
|
57
67
|
#storageFactory;
|
|
58
68
|
#registrations = new Map();
|
|
59
69
|
#entityHandles = new Map();
|
|
60
70
|
#handleCloseErrors = [];
|
|
61
71
|
#omittedHandleCloseErrors = 0;
|
|
62
72
|
#inFlight = new Set();
|
|
73
|
+
#pendingUpdates = new Map();
|
|
63
74
|
#closing = false;
|
|
64
75
|
#closed = false;
|
|
65
76
|
#closedPromise;
|
|
@@ -69,10 +80,12 @@ export class Stand {
|
|
|
69
80
|
* @param options The storage context and factory used for state records.
|
|
70
81
|
*/
|
|
71
82
|
constructor(options) {
|
|
83
|
+
this.#subscriptionQueueCapacity = ServerEnvironment.instance().subscriptionQueueCapacity;
|
|
72
84
|
this.#context = _a.#cloneContext(options.context);
|
|
73
85
|
this.#storageFactory = options.storageFactory;
|
|
74
86
|
deferredUpdates.set(this, (schema, state, updateOptions, metadata) => this.#deferUpdate(schema, state, updateOptions, metadata));
|
|
75
87
|
currentReads.set(this, (schema, id, readOptions) => this.#readCurrent(schema, id, readOptions));
|
|
88
|
+
routedQueryPlans.set(this, (schema, plan, readOptions, readSide) => this.#queryPlanVersioned(schema, plan, readOptions, readSide));
|
|
76
89
|
}
|
|
77
90
|
/**
|
|
78
91
|
* Registers one entity state schema. Re-registering the same schema is idempotent.
|
|
@@ -144,26 +157,46 @@ export class Stand {
|
|
|
144
157
|
* @returns The current state and version, or undefined when no live record exists.
|
|
145
158
|
*/
|
|
146
159
|
async readVersioned(schema, id, options = {}) {
|
|
147
|
-
const finish = this.#
|
|
160
|
+
const finish = this.#beginPublicOperation();
|
|
148
161
|
try {
|
|
162
|
+
const captured = _a.#snapshotRead(options);
|
|
163
|
+
const copiedId = ReadSideMessages.copy(id);
|
|
149
164
|
const registration = this.#registration(schema, "read");
|
|
150
|
-
const tenantId = this.#
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
finally {
|
|
160
|
-
storage.release();
|
|
161
|
-
}
|
|
165
|
+
const tenantId = await this.#checkedTenantId(captured.tenantId);
|
|
166
|
+
const result = await this.#readStored(registration, copiedId, tenantId);
|
|
167
|
+
return await this.#filteredResult(registration.schema, result, {
|
|
168
|
+
...captured,
|
|
169
|
+
...(tenantId === undefined ? {} : { tenantId }),
|
|
170
|
+
}, {
|
|
171
|
+
kind: "direct",
|
|
172
|
+
read: { typeUrl: registration.typeUrl, id: copiedId },
|
|
173
|
+
});
|
|
162
174
|
}
|
|
163
175
|
finally {
|
|
164
176
|
finish();
|
|
165
177
|
}
|
|
166
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Captures a current record and releases its provider lease before policy awaits.
|
|
181
|
+
*
|
|
182
|
+
* @typeParam Schema Registered state schema.
|
|
183
|
+
* @param registration State metadata and storage descriptor.
|
|
184
|
+
* @param id Detached Entity identifier.
|
|
185
|
+
* @param tenantId Admitted tenant, if multitenant.
|
|
186
|
+
* @returns Detached live state and version, or undefined.
|
|
187
|
+
*/
|
|
188
|
+
async #readStored(registration, id, tenantId) {
|
|
189
|
+
const storage = this.#leaseCurrent(registration, tenantId);
|
|
190
|
+
try {
|
|
191
|
+
const stored = await storage.current.read(id);
|
|
192
|
+
if (stored === undefined || EntityRecords.unpack(registration.schema, stored).deleted)
|
|
193
|
+
return undefined;
|
|
194
|
+
return this.#currentResult(registration, stored);
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
storage.release();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
167
200
|
/**
|
|
168
201
|
* Reads all latest states and version metadata in storage query order.
|
|
169
202
|
*
|
|
@@ -185,19 +218,27 @@ export class Stand {
|
|
|
185
218
|
* @returns The matching current states and versions.
|
|
186
219
|
*/
|
|
187
220
|
async queryVersioned(schema, query = {}, options = {}) {
|
|
188
|
-
const finish = this.#
|
|
221
|
+
const finish = this.#beginPublicOperation();
|
|
189
222
|
try {
|
|
223
|
+
const captured = _a.#snapshotRead(options);
|
|
224
|
+
const copiedQuery = ReadSideMessages.copy(query);
|
|
190
225
|
const registration = this.#registration(schema, "read");
|
|
191
|
-
const tenantId = this.#
|
|
226
|
+
const tenantId = await this.#checkedTenantId(captured.tenantId);
|
|
192
227
|
const storage = this.#leaseCurrent(registration, tenantId);
|
|
228
|
+
let results;
|
|
193
229
|
try {
|
|
194
|
-
const stored = await storage.current.query(_a.#legacyPlan(
|
|
195
|
-
|
|
196
|
-
|
|
230
|
+
const stored = await storage.current.query(_a.#legacyPlan(copiedQuery));
|
|
231
|
+
results = stored
|
|
232
|
+
.map((entry) => this.#entryResult(registration, entry.record))
|
|
233
|
+
.filter((result) => result !== undefined);
|
|
197
234
|
}
|
|
198
235
|
finally {
|
|
199
236
|
storage.release();
|
|
200
237
|
}
|
|
238
|
+
return await this.#filteredResults(registration.schema, results, {
|
|
239
|
+
...captured,
|
|
240
|
+
...(tenantId === undefined ? {} : { tenantId }),
|
|
241
|
+
}, { kind: "direct", query: copiedQuery });
|
|
201
242
|
}
|
|
202
243
|
finally {
|
|
203
244
|
finish();
|
|
@@ -213,24 +254,117 @@ export class Stand {
|
|
|
213
254
|
* @returns The matching current states and versions.
|
|
214
255
|
*/
|
|
215
256
|
async queryPlanVersioned(schema, plan, options = {}) {
|
|
216
|
-
|
|
257
|
+
return this.#queryPlanVersioned(schema, plan, options);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Reads stored rows and applies the context's outward policy in one operation lifetime.
|
|
261
|
+
* @typeParam Schema Registered state schema.
|
|
262
|
+
* @param schema Registered Entity state schema.
|
|
263
|
+
* @param plan Normalized storage query plan.
|
|
264
|
+
* @param options Trusted read facts and tenant.
|
|
265
|
+
* @param readSide Actual routed Query context, if supplied internally.
|
|
266
|
+
* @returns Surviving versioned state records.
|
|
267
|
+
*/
|
|
268
|
+
async #queryPlanVersioned(schema, plan, options, readSide) {
|
|
269
|
+
const finish = this.#beginPublicOperation();
|
|
217
270
|
try {
|
|
271
|
+
const captured = _a.#snapshotRead(options, readSide);
|
|
272
|
+
const copiedPlan = ReadSideMessages.copy(plan);
|
|
218
273
|
const registration = this.#registration(schema, "read");
|
|
219
|
-
const tenantId = this.#
|
|
274
|
+
const tenantId = await this.#checkedTenantId(captured.tenantId);
|
|
220
275
|
const storage = this.#leaseCurrent(registration, tenantId);
|
|
276
|
+
let results;
|
|
221
277
|
try {
|
|
222
|
-
const stored = await storage.current.query(
|
|
223
|
-
|
|
224
|
-
|
|
278
|
+
const stored = await storage.current.query(copiedPlan);
|
|
279
|
+
results = stored
|
|
280
|
+
.map((entry) => this.#entryResult(registration, entry.record))
|
|
281
|
+
.filter((result) => result !== undefined);
|
|
225
282
|
}
|
|
226
283
|
finally {
|
|
227
284
|
storage.release();
|
|
228
285
|
}
|
|
286
|
+
return await this.#filteredResults(registration.schema, results, {
|
|
287
|
+
...captured,
|
|
288
|
+
...(tenantId === undefined ? {} : { tenantId }),
|
|
289
|
+
}, { kind: "direct", plan: copiedPlan });
|
|
229
290
|
}
|
|
230
291
|
finally {
|
|
231
292
|
finish();
|
|
232
293
|
}
|
|
233
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Detaches mutable caller facts before storage admission can await.
|
|
297
|
+
*
|
|
298
|
+
* @param options Direct or service read options.
|
|
299
|
+
* @returns Stable tenant and invocation facts, retaining the live cancellation signal.
|
|
300
|
+
*/
|
|
301
|
+
static #snapshotRead(options, side) {
|
|
302
|
+
const { signal, producingContext, effectiveTenant, parent, field, ...facts } = side ?? {};
|
|
303
|
+
void producingContext;
|
|
304
|
+
void effectiveTenant;
|
|
305
|
+
void parent;
|
|
306
|
+
void field;
|
|
307
|
+
return {
|
|
308
|
+
...(options.tenantId === undefined
|
|
309
|
+
? {}
|
|
310
|
+
: { tenantId: clone(TenantIdSchema, options.tenantId) }),
|
|
311
|
+
readSide: {
|
|
312
|
+
...(side === undefined ? {} : ReadSideMessages.copy(facts)),
|
|
313
|
+
...(options.actorContext === undefined
|
|
314
|
+
? {}
|
|
315
|
+
: { actorContext: clone(ActorContextSchema, options.actorContext) }),
|
|
316
|
+
...(options.reader === undefined ? {} : snapshotTrustedReader(options.reader)),
|
|
317
|
+
...((signal ?? options.signal) === undefined ? {} : { signal: signal ?? options.signal }),
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Applies this context's outward read policy after storage has been released.
|
|
323
|
+
*
|
|
324
|
+
* @typeParam Schema Registered state schema.
|
|
325
|
+
* @param schema State schema selected by the read.
|
|
326
|
+
* @param result Captured state and durable version.
|
|
327
|
+
* @param options Tenant and service read facts.
|
|
328
|
+
* @param operation Actual direct operation when no service request is present.
|
|
329
|
+
* @returns Detached visible state with its unchanged version, or no state.
|
|
330
|
+
*/
|
|
331
|
+
async #filteredResult(schema, result, options, operation) {
|
|
332
|
+
if (result === undefined)
|
|
333
|
+
return undefined;
|
|
334
|
+
const filters = standReadFilters.get(this);
|
|
335
|
+
if (filters === undefined)
|
|
336
|
+
return result;
|
|
337
|
+
const producer = standProducingContexts.get(this);
|
|
338
|
+
const context = {
|
|
339
|
+
...(options.readSide ?? {}),
|
|
340
|
+
operation: options.readSide?.operation ?? operation,
|
|
341
|
+
...(producer === undefined ? {} : { producingContext: producer }),
|
|
342
|
+
...(options.tenantId === undefined ? {} : { effectiveTenant: options.tenantId }),
|
|
343
|
+
};
|
|
344
|
+
const state = await filters.apply(schema, result.state, context);
|
|
345
|
+
return state === null ? undefined : { ...result, state };
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Applies outward policy in stored query order without replenishing removed records.
|
|
349
|
+
*
|
|
350
|
+
* @typeParam Schema Registered state schema.
|
|
351
|
+
* @param schema State schema selected by the read.
|
|
352
|
+
* @param results Captured stored states and durable versions.
|
|
353
|
+
* @param options Tenant and service read facts.
|
|
354
|
+
* @param operation Actual direct query when no service request is present.
|
|
355
|
+
* @returns Surviving visible records in their original order.
|
|
356
|
+
*/
|
|
357
|
+
async #filteredResults(schema, results, options, operation) {
|
|
358
|
+
if (!standReadFilters.has(this))
|
|
359
|
+
return results;
|
|
360
|
+
const visible = [];
|
|
361
|
+
for (const result of results) {
|
|
362
|
+
const next = await this.#filteredResult(schema, result, options, operation);
|
|
363
|
+
if (next !== undefined)
|
|
364
|
+
visible.push(next);
|
|
365
|
+
}
|
|
366
|
+
return visible;
|
|
367
|
+
}
|
|
234
368
|
/**
|
|
235
369
|
* Clears all stored states and durable version metadata for one known state schema.
|
|
236
370
|
*
|
|
@@ -246,7 +380,7 @@ export class Stand {
|
|
|
246
380
|
const finish = this.#beginOperation();
|
|
247
381
|
try {
|
|
248
382
|
const registration = this.#registration(schema, "clear");
|
|
249
|
-
const tenantId = this.#
|
|
383
|
+
const tenantId = await this.#checkedTenantId(options.tenantId);
|
|
250
384
|
const storage = this.#leaseCurrent(registration, tenantId);
|
|
251
385
|
try {
|
|
252
386
|
const entries = await storage.current.query({
|
|
@@ -317,26 +451,77 @@ export class Stand {
|
|
|
317
451
|
* @returns Prepared write with cleanup actions.
|
|
318
452
|
*/
|
|
319
453
|
async #prepareUpdate(schema, state, options, metadata) {
|
|
320
|
-
const
|
|
454
|
+
const onFinish = this.#beginOperation();
|
|
321
455
|
let storage;
|
|
456
|
+
let releaseUpdate;
|
|
322
457
|
try {
|
|
323
458
|
const registration = this.#registration(schema, "update");
|
|
324
|
-
|
|
325
|
-
throw new Error("Repository metadata does not match the Entity state schema.");
|
|
326
|
-
const tenantId = this.#tenantId(options.tenantId);
|
|
459
|
+
_a.#requireUpdateMetadata(registration, metadata);
|
|
327
460
|
const snapshot = _a.#snapshotUpdateOptions(options);
|
|
328
461
|
const stateCopy = clone(schema, state);
|
|
462
|
+
const tenantId = await this.#checkedTenantId(options.tenantId);
|
|
329
463
|
const id = _a.#readStateId(stateCopy, registration);
|
|
464
|
+
releaseUpdate = await this.#reserveUpdate(registration, tenantId, id, metadata);
|
|
330
465
|
storage = this.#leaseCurrent(registration, tenantId);
|
|
331
466
|
const previousState = await this.#previousUpdateState(registration, tenantId, id, storage);
|
|
332
|
-
return this.#preparedUpdate(registration, { id, previousState, state: stateCopy, tenantId, version: snapshot.version }, snapshot, metadata, storage,
|
|
467
|
+
return this.#preparedUpdate(registration, { id, previousState, state: stateCopy, tenantId, version: snapshot.version }, snapshot, metadata, storage, () => {
|
|
468
|
+
_a.#finishUpdate(releaseUpdate, onFinish);
|
|
469
|
+
});
|
|
333
470
|
}
|
|
334
471
|
catch (error) {
|
|
335
472
|
storage?.release();
|
|
336
|
-
|
|
473
|
+
_a.#finishUpdate(releaseUpdate, onFinish);
|
|
337
474
|
throw error;
|
|
338
475
|
}
|
|
339
476
|
}
|
|
477
|
+
/**
|
|
478
|
+
* Checks repository metadata before preparing the state update.
|
|
479
|
+
*
|
|
480
|
+
* @param registration Registered state metadata.
|
|
481
|
+
* @param metadata Repository metadata, when supplied.
|
|
482
|
+
*/
|
|
483
|
+
static #requireUpdateMetadata(registration, metadata) {
|
|
484
|
+
if (metadata !== undefined && metadata.schema !== registration.schema)
|
|
485
|
+
throw new Error("Repository metadata does not match the Entity state schema.");
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Releases the update reservation and completes its tracked Stand operation.
|
|
489
|
+
*
|
|
490
|
+
* @param onReleaseUpdate Per-Entity reservation release, when acquired.
|
|
491
|
+
* @param onFinish Completes the tracked Stand operation.
|
|
492
|
+
*/
|
|
493
|
+
static #finishUpdate(onReleaseUpdate, onFinish) {
|
|
494
|
+
onReleaseUpdate?.();
|
|
495
|
+
onFinish();
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Keeps one Entity's previous-state read and commit in notification order.
|
|
499
|
+
*
|
|
500
|
+
* @param registration State metadata.
|
|
501
|
+
* @param tenantId Tenant for the state.
|
|
502
|
+
* @param id Entity identifier.
|
|
503
|
+
* @param metadata Repository-validated identifier metadata, when available.
|
|
504
|
+
* @returns A release action for notification or cancellation.
|
|
505
|
+
*/
|
|
506
|
+
async #reserveUpdate(registration, tenantId, id, metadata) {
|
|
507
|
+
const packed = metadata === undefined
|
|
508
|
+
? EntityIds.pack(registration.schema, id)
|
|
509
|
+
: EntityIds.packField(metadata.idField.descriptor, id);
|
|
510
|
+
const key = JSON.stringify([
|
|
511
|
+
registration.typeUrl,
|
|
512
|
+
this.#tenantKey(tenantId),
|
|
513
|
+
Buffer.from(toBinary(AnySchema, packed)).toString("base64"),
|
|
514
|
+
]);
|
|
515
|
+
const previous = this.#pendingUpdates.get(key);
|
|
516
|
+
const settled = Promise.withResolvers();
|
|
517
|
+
this.#pendingUpdates.set(key, settled.promise);
|
|
518
|
+
await previous;
|
|
519
|
+
return () => {
|
|
520
|
+
if (this.#pendingUpdates.get(key) === settled.promise)
|
|
521
|
+
this.#pendingUpdates.delete(key);
|
|
522
|
+
settled.resolve(undefined);
|
|
523
|
+
};
|
|
524
|
+
}
|
|
340
525
|
/**
|
|
341
526
|
* Copies mutable Version and lifecycle input before update preparation awaits.
|
|
342
527
|
* @param options Update metadata supplied by the caller.
|
|
@@ -425,7 +610,7 @@ export class Stand {
|
|
|
425
610
|
const finish = this.#beginOperation();
|
|
426
611
|
try {
|
|
427
612
|
const registration = this.#registration(schema, "read");
|
|
428
|
-
const tenantId = this.#
|
|
613
|
+
const tenantId = await this.#checkedTenantId(options.tenantId);
|
|
429
614
|
const storage = this.#leaseCurrent(registration, tenantId);
|
|
430
615
|
try {
|
|
431
616
|
const stored = await storage.current.read(id);
|
|
@@ -453,29 +638,74 @@ export class Stand {
|
|
|
453
638
|
*
|
|
454
639
|
* @typeParam Schema The registered state schema.
|
|
455
640
|
* @param schema The registered entity state schema.
|
|
456
|
-
* @param
|
|
457
|
-
* @param options
|
|
458
|
-
* @returns A handle that
|
|
641
|
+
* @param observer Receives serial visible updates and one terminal local fault.
|
|
642
|
+
* @param options Tenant, trusted facts, and cancellation.
|
|
643
|
+
* @returns A handle that invalidates pending and active delivery.
|
|
459
644
|
*/
|
|
460
|
-
subscribe(schema,
|
|
645
|
+
subscribe(schema, observer, options = {}) {
|
|
461
646
|
this.#requireOpen();
|
|
647
|
+
_a.#requireObserver(observer);
|
|
462
648
|
const registration = this.#registration(schema, "subscribe");
|
|
463
649
|
const tenantKey = this.#tenantKey(options.tenantId);
|
|
464
|
-
const
|
|
465
|
-
let closed = false;
|
|
466
|
-
registration.subscribers.add(subscriber);
|
|
650
|
+
const delivery = this.#subscribeDelivery(schema, observer, options, registration, tenantKey);
|
|
467
651
|
return Object.freeze({
|
|
652
|
+
/**
|
|
653
|
+
* Reports whether this subscription handle has stopped delivering.
|
|
654
|
+
*/
|
|
468
655
|
get closed() {
|
|
469
|
-
return closed;
|
|
656
|
+
return delivery.closed;
|
|
470
657
|
},
|
|
658
|
+
/**
|
|
659
|
+
* Detaches the subscriber and stops future local deliveries.
|
|
660
|
+
*/
|
|
471
661
|
unsubscribe() {
|
|
472
|
-
|
|
473
|
-
closed = true;
|
|
474
|
-
registration.subscribers.delete(subscriber);
|
|
475
|
-
}
|
|
662
|
+
delivery.close();
|
|
476
663
|
},
|
|
477
664
|
});
|
|
478
665
|
}
|
|
666
|
+
/**
|
|
667
|
+
* Rejects a raw callback or malformed JavaScript observer before registration.
|
|
668
|
+
*
|
|
669
|
+
* @param observer The runtime value supplied for direct delivery.
|
|
670
|
+
*/
|
|
671
|
+
static #requireObserver(observer) {
|
|
672
|
+
if (typeof observer !== "object" ||
|
|
673
|
+
observer === null ||
|
|
674
|
+
!("next" in observer) ||
|
|
675
|
+
typeof observer.next !== "function" ||
|
|
676
|
+
!("error" in observer) ||
|
|
677
|
+
typeof observer.error !== "function")
|
|
678
|
+
throw new TypeError("Stand.subscribe requires an observer with next and error callbacks.");
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Captures the subscriber's read facts and attaches its independent delivery queue.
|
|
682
|
+
*
|
|
683
|
+
* @typeParam Schema The registered state schema.
|
|
684
|
+
* @param schema The state schema selected by the caller.
|
|
685
|
+
* @param observer Receives visible updates or one terminal local fault.
|
|
686
|
+
* @param options Trusted reader, tenant, and cancellation at subscribe time.
|
|
687
|
+
* @param registration The Stand registration for this state schema.
|
|
688
|
+
* @param tenantKey The normalized tenant slice for delivery.
|
|
689
|
+
* @returns The subscriber's serial delivery queue.
|
|
690
|
+
*/
|
|
691
|
+
#subscribeDelivery(schema, observer, options, registration, tenantKey) {
|
|
692
|
+
const captured = _a.#snapshotRead(options);
|
|
693
|
+
const producingContext = standProducingContexts.get(this);
|
|
694
|
+
const attachment = {};
|
|
695
|
+
const delivery = new StandDirectDelivery(schema, observer, standReadFilters.get(this), {
|
|
696
|
+
...captured.readSide,
|
|
697
|
+
operation: { kind: "direct", subscription: { typeUrl: registration.typeUrl } },
|
|
698
|
+
...(captured.tenantId === undefined ? {} : { effectiveTenant: captured.tenantId }),
|
|
699
|
+
...(producingContext === undefined ? {} : { producingContext }),
|
|
700
|
+
}, this.#subscriptionQueueCapacity, () => {
|
|
701
|
+
if (attachment.subscriber !== undefined)
|
|
702
|
+
registration.subscribers.delete(attachment.subscriber);
|
|
703
|
+
}, options.signal);
|
|
704
|
+
attachment.subscriber = Object.freeze({ tenantKey, delivery });
|
|
705
|
+
if (!delivery.closed)
|
|
706
|
+
registration.subscribers.add(attachment.subscriber);
|
|
707
|
+
return delivery;
|
|
708
|
+
}
|
|
479
709
|
/**
|
|
480
710
|
* Closes direct subscriptions and rejects later Stand operations.
|
|
481
711
|
*
|
|
@@ -490,10 +720,15 @@ export class Stand {
|
|
|
490
720
|
this.#closedPromise ??= this.#closeOnce();
|
|
491
721
|
return this.#closedPromise;
|
|
492
722
|
}
|
|
723
|
+
/**
|
|
724
|
+
* Drains accepted Stand work, closes subscriptions, and releases Entity handles.
|
|
725
|
+
*/
|
|
493
726
|
async #closeOnce() {
|
|
494
727
|
this.#closing = true;
|
|
495
728
|
await Promise.all([...this.#inFlight]);
|
|
496
729
|
for (const registration of this.#registrations.values()) {
|
|
730
|
+
for (const subscriber of registration.subscribers)
|
|
731
|
+
subscriber.delivery.close();
|
|
497
732
|
registration.subscribers.clear();
|
|
498
733
|
}
|
|
499
734
|
const errors = this.#handleCloseErrors.splice(0);
|
|
@@ -535,6 +770,9 @@ export class Stand {
|
|
|
535
770
|
}
|
|
536
771
|
return registration;
|
|
537
772
|
}
|
|
773
|
+
/**
|
|
774
|
+
* Reuses single-tenant storage or opens a temporary multitenant Entity handle.
|
|
775
|
+
*/
|
|
538
776
|
#leaseCurrent(registration, tenantId) {
|
|
539
777
|
if (this.#context.multitenant) {
|
|
540
778
|
return this.#lease(_a.#openStorage(this.#storageFactory, standEntityStorageDescriptor(this.#storageContext(tenantId), registration.schema, registration.columns)), true);
|
|
@@ -547,6 +785,9 @@ export class Stand {
|
|
|
547
785
|
this.#entityHandles.set(key, handle);
|
|
548
786
|
return this.#lease(handle, false);
|
|
549
787
|
}
|
|
788
|
+
/**
|
|
789
|
+
* Returns a release callback for a current-state storage handle.
|
|
790
|
+
*/
|
|
550
791
|
#lease(handle, releaseAfterOperation) {
|
|
551
792
|
let released = false;
|
|
552
793
|
return {
|
|
@@ -611,28 +852,22 @@ export class Stand {
|
|
|
611
852
|
* @param captured Subscribers captured before persistence, if available.
|
|
612
853
|
*/
|
|
613
854
|
#notify(registration, input, captured) {
|
|
614
|
-
const errors = [];
|
|
615
855
|
const tenantKey = this.#tenantKey(input.tenantId);
|
|
616
856
|
const subscribers = captured ?? this.#tenantSubscribers(registration, tenantKey);
|
|
617
857
|
for (const subscriber of subscribers) {
|
|
618
|
-
|
|
619
|
-
subscriber.callback(_a.#createUpdate(registration, input));
|
|
620
|
-
}
|
|
621
|
-
catch (error) {
|
|
622
|
-
errors.push(error);
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
if (errors.length === 1) {
|
|
626
|
-
throw errors[0];
|
|
627
|
-
}
|
|
628
|
-
if (errors.length > 1) {
|
|
629
|
-
throw new AggregateError(errors, "Stand subscriber delivery failed.");
|
|
858
|
+
subscriber.delivery.admit(_a.#createUpdate(registration, input));
|
|
630
859
|
}
|
|
631
860
|
}
|
|
861
|
+
/**
|
|
862
|
+
* Creates the subscription partition key for the selected tenant.
|
|
863
|
+
*/
|
|
632
864
|
#tenantKey(tenantId) {
|
|
633
865
|
const selected = this.#tenantId(tenantId);
|
|
634
866
|
return selected === undefined ? "__single__" : String(TenantBoundary.from(selected).key);
|
|
635
867
|
}
|
|
868
|
+
/**
|
|
869
|
+
* Checks whether a registered Entity state has subscribers in this tenant slice.
|
|
870
|
+
*/
|
|
636
871
|
#hasTenantSubscribers(registration, tenantId) {
|
|
637
872
|
const tenantKey = this.#tenantKey(tenantId);
|
|
638
873
|
for (const subscriber of registration.subscribers) {
|
|
@@ -653,6 +888,9 @@ export class Stand {
|
|
|
653
888
|
#tenantSubscribers(registration, tenantKey) {
|
|
654
889
|
return [...registration.subscribers].filter((subscriber) => subscriber.tenantKey === tenantKey);
|
|
655
890
|
}
|
|
891
|
+
/**
|
|
892
|
+
* Validates and detaches the tenant ID required by this Stand's tenancy mode.
|
|
893
|
+
*/
|
|
656
894
|
#tenantId(tenantId) {
|
|
657
895
|
if (!this.#context.multitenant) {
|
|
658
896
|
if (tenantId !== undefined) {
|
|
@@ -665,6 +903,20 @@ export class Stand {
|
|
|
665
903
|
}
|
|
666
904
|
return TenantBoundary.from(tenantId).tenantId;
|
|
667
905
|
}
|
|
906
|
+
/**
|
|
907
|
+
* Validates shape and awaits live membership before leasing a storage handle.
|
|
908
|
+
*
|
|
909
|
+
* @param tenantId Selected tenant identity.
|
|
910
|
+
* @returns Detached selected tenant identity, when applicable.
|
|
911
|
+
*/
|
|
912
|
+
async #checkedTenantId(tenantId) {
|
|
913
|
+
const selected = this.#tenantId(tenantId);
|
|
914
|
+
await standAdmissions.get(this)?.(selected);
|
|
915
|
+
return selected;
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Builds the provider storage scope for a validated tenant selection.
|
|
919
|
+
*/
|
|
668
920
|
#storageContext(tenantId) {
|
|
669
921
|
if (!this.#context.multitenant) {
|
|
670
922
|
this.#tenantId(tenantId);
|
|
@@ -679,11 +931,17 @@ export class Stand {
|
|
|
679
931
|
tenantId: TenantBoundary.from(tenantId).tenantId,
|
|
680
932
|
});
|
|
681
933
|
}
|
|
934
|
+
/**
|
|
935
|
+
* Rejects a new operation once Stand closing has begun.
|
|
936
|
+
*/
|
|
682
937
|
#requireOpen() {
|
|
683
938
|
if (this.#closing || this.#closed) {
|
|
684
939
|
throw new Error("Stand is closed.");
|
|
685
940
|
}
|
|
686
941
|
}
|
|
942
|
+
/**
|
|
943
|
+
* Tracks an accepted operation and returns its completion callback.
|
|
944
|
+
*/
|
|
687
945
|
#beginOperation() {
|
|
688
946
|
this.#requireOpen();
|
|
689
947
|
let finish;
|
|
@@ -696,6 +954,15 @@ export class Stand {
|
|
|
696
954
|
finish?.();
|
|
697
955
|
};
|
|
698
956
|
}
|
|
957
|
+
/**
|
|
958
|
+
* Admits an external read before repository operations can continue internally.
|
|
959
|
+
* @returns Completion callback for the tracked read.
|
|
960
|
+
*/
|
|
961
|
+
#beginPublicOperation() {
|
|
962
|
+
this.#requireOpen();
|
|
963
|
+
standPublicAdmissions.get(this)?.();
|
|
964
|
+
return this.#beginOperation();
|
|
965
|
+
}
|
|
699
966
|
/**
|
|
700
967
|
* Clones a state update before delivering it to subscribers.
|
|
701
968
|
*
|
|
@@ -717,6 +984,9 @@ export class Stand {
|
|
|
717
984
|
...(input.tenantId === undefined ? {} : { tenantId: clone(TenantIdSchema, input.tenantId) }),
|
|
718
985
|
});
|
|
719
986
|
}
|
|
987
|
+
/**
|
|
988
|
+
* Extracts the registered Entity ID field from a state update.
|
|
989
|
+
*/
|
|
720
990
|
static #readStateId(state, registration) {
|
|
721
991
|
const id = state[registration.idField];
|
|
722
992
|
if (id === undefined || id === null) {
|
|
@@ -724,9 +994,15 @@ export class Stand {
|
|
|
724
994
|
}
|
|
725
995
|
return id;
|
|
726
996
|
}
|
|
997
|
+
/**
|
|
998
|
+
* Detaches a structured storage value before returning it to a caller.
|
|
999
|
+
*/
|
|
727
1000
|
static #cloneValue(value) {
|
|
728
1001
|
return typeof value === "object" && value !== null ? globalThis.structuredClone(value) : value;
|
|
729
1002
|
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Translates a supported RecordQuery into the normalized storage query plan.
|
|
1005
|
+
*/
|
|
730
1006
|
static #legacyPlan(query) {
|
|
731
1007
|
RecordQuery.validate(query);
|
|
732
1008
|
if (query.after !== undefined) {
|
|
@@ -774,6 +1050,9 @@ export class Stand {
|
|
|
774
1050
|
}
|
|
775
1051
|
return candidate.createEntityStorage(input);
|
|
776
1052
|
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Freezes a detached name and tenancy mode for storage configuration.
|
|
1055
|
+
*/
|
|
777
1056
|
static #cloneContext(context) {
|
|
778
1057
|
return Object.freeze({ name: context.name, multitenant: context.multitenant });
|
|
779
1058
|
}
|
|
@@ -785,6 +1064,122 @@ _a = Stand;
|
|
|
785
1064
|
* @internal
|
|
786
1065
|
*/
|
|
787
1066
|
export const standAccess = Object.freeze({
|
|
1067
|
+
/**
|
|
1068
|
+
* Forwards trusted routed Query context to the private Stand read path.
|
|
1069
|
+
* @typeParam Schema Registered state schema.
|
|
1070
|
+
* @param stand Producing context's Stand.
|
|
1071
|
+
* @param schema Registered state schema.
|
|
1072
|
+
* @param plan Normalized routed query plan.
|
|
1073
|
+
* @param options Admitted tenant and trusted facts.
|
|
1074
|
+
* @param readSide Actual service or handler Query context.
|
|
1075
|
+
* @returns Surviving versioned states.
|
|
1076
|
+
*/
|
|
1077
|
+
queryPlanVersioned(stand, schema, plan, options, readSide) {
|
|
1078
|
+
const read = routedQueryPlans.get(stand);
|
|
1079
|
+
if (read === undefined)
|
|
1080
|
+
throw new Error("Stand routed read is unavailable.");
|
|
1081
|
+
return read(schema, plan, options, readSide);
|
|
1082
|
+
},
|
|
1083
|
+
/**
|
|
1084
|
+
* Associates actual context identity with direct and historical outward reads.
|
|
1085
|
+
*
|
|
1086
|
+
* @param stand Context Stand.
|
|
1087
|
+
* @param context Built Bounded Context.
|
|
1088
|
+
*/
|
|
1089
|
+
bindProducingContext(stand, context) {
|
|
1090
|
+
standProducingContexts.set(stand, context);
|
|
1091
|
+
},
|
|
1092
|
+
/**
|
|
1093
|
+
* Applies a history state policy after the physical history read.
|
|
1094
|
+
*
|
|
1095
|
+
* @typeParam Schema Registered domain schema.
|
|
1096
|
+
* @param stand Context read facade.
|
|
1097
|
+
* @param schema Historical state schema.
|
|
1098
|
+
* @param state Captured state.
|
|
1099
|
+
* @param context Actual history call.
|
|
1100
|
+
* @returns Filtered state or null.
|
|
1101
|
+
*/
|
|
1102
|
+
filterState(stand, schema, state, context) {
|
|
1103
|
+
const filters = standReadFilters.get(stand);
|
|
1104
|
+
const producer = standProducingContexts.get(stand);
|
|
1105
|
+
return filters === undefined
|
|
1106
|
+
? Promise.resolve(state)
|
|
1107
|
+
: filters.apply(schema, state, {
|
|
1108
|
+
...context,
|
|
1109
|
+
...(producer === undefined ? {} : { producingContext: producer }),
|
|
1110
|
+
});
|
|
1111
|
+
},
|
|
1112
|
+
/**
|
|
1113
|
+
* Filters a retained Event payload while retaining envelope identity and metadata.
|
|
1114
|
+
*
|
|
1115
|
+
* @param stand Context read facade.
|
|
1116
|
+
* @param event Retained Event envelope.
|
|
1117
|
+
* @param context Actual history call.
|
|
1118
|
+
* @returns Event with filtered payload, or null when removed.
|
|
1119
|
+
*/
|
|
1120
|
+
async filterEvent(stand, event, context) {
|
|
1121
|
+
const filters = standReadFilters.get(stand);
|
|
1122
|
+
if (filters === undefined)
|
|
1123
|
+
return event;
|
|
1124
|
+
if (event.message === undefined)
|
|
1125
|
+
throw new TypeError("Retained Event payload is missing.");
|
|
1126
|
+
const producer = standProducingContexts.get(stand);
|
|
1127
|
+
const message = await filters.applyPacked(event.message, {
|
|
1128
|
+
...context,
|
|
1129
|
+
...(producer === undefined ? {} : { producingContext: producer }),
|
|
1130
|
+
});
|
|
1131
|
+
return message === null ? null : create(EventSchema, { ...clone(EventSchema, event), message });
|
|
1132
|
+
},
|
|
1133
|
+
/**
|
|
1134
|
+
* Applies Bounded Context policy to one subscription update before delivery.
|
|
1135
|
+
*
|
|
1136
|
+
* @param stand Context read facade.
|
|
1137
|
+
* @param update Subscription update awaiting delivery.
|
|
1138
|
+
* @param context Actual subscription read facts.
|
|
1139
|
+
* @returns Visible update, or null when policy removes it.
|
|
1140
|
+
*/
|
|
1141
|
+
filterSubscription(stand, update, context) {
|
|
1142
|
+
const producer = standProducingContexts.get(stand);
|
|
1143
|
+
return SubscriptionReadFilters.apply(update, standReadFilters.get(stand), {
|
|
1144
|
+
...context,
|
|
1145
|
+
...(producer === undefined ? {} : { producingContext: producer }),
|
|
1146
|
+
});
|
|
1147
|
+
},
|
|
1148
|
+
/**
|
|
1149
|
+
* Attaches registered policies to this Stand without changing persistence reads.
|
|
1150
|
+
*
|
|
1151
|
+
* @param stand Context read facade.
|
|
1152
|
+
* @param filters Policies in registration order.
|
|
1153
|
+
*/
|
|
1154
|
+
installReadFilters(stand, filters) {
|
|
1155
|
+
if (!(stand instanceof Stand))
|
|
1156
|
+
throw new TypeError("Read filters require a Stand instance.");
|
|
1157
|
+
if (standReadFilters.has(stand))
|
|
1158
|
+
throw new TypeError("Stand read filters are already installed.");
|
|
1159
|
+
standReadFilters.set(stand, new ReadSideFilterEngine(filters, TypeRegistry.from(...registeredProtoModules())));
|
|
1160
|
+
},
|
|
1161
|
+
/**
|
|
1162
|
+
* Sets the immediate external read admission check.
|
|
1163
|
+
*
|
|
1164
|
+
* @param stand Context Stand.
|
|
1165
|
+
* @param onAdmit Synchronous external admission check.
|
|
1166
|
+
*/
|
|
1167
|
+
setPublicAdmission(stand, onAdmit) {
|
|
1168
|
+
if (!(stand instanceof Stand))
|
|
1169
|
+
throw new TypeError("Stand admission requires a Stand instance.");
|
|
1170
|
+
standPublicAdmissions.set(stand, onAdmit);
|
|
1171
|
+
},
|
|
1172
|
+
/**
|
|
1173
|
+
* Installs an internal receiving-context membership check.
|
|
1174
|
+
*
|
|
1175
|
+
* @param stand Context Stand.
|
|
1176
|
+
* @param onAdmit Checks current membership.
|
|
1177
|
+
*/
|
|
1178
|
+
setAdmission(stand, onAdmit) {
|
|
1179
|
+
if (!(stand instanceof Stand))
|
|
1180
|
+
throw new TypeError("Stand admission requires a Stand instance.");
|
|
1181
|
+
standAdmissions.set(stand, onAdmit);
|
|
1182
|
+
},
|
|
788
1183
|
/**
|
|
789
1184
|
* Finds observer metadata on the supplied Stand.
|
|
790
1185
|
*
|
|
@@ -849,5 +1244,10 @@ export const standAccess = Object.freeze({
|
|
|
849
1244
|
},
|
|
850
1245
|
});
|
|
851
1246
|
const deferredUpdates = new WeakMap();
|
|
1247
|
+
const standAdmissions = new WeakMap();
|
|
1248
|
+
const standPublicAdmissions = new WeakMap();
|
|
1249
|
+
const standReadFilters = new WeakMap();
|
|
1250
|
+
const standProducingContexts = new WeakMap();
|
|
852
1251
|
const currentReads = new WeakMap();
|
|
1252
|
+
const routedQueryPlans = new WeakMap();
|
|
853
1253
|
//# sourceMappingURL=stand.js.map
|