@spine-event-engine/server 2.0.0-snapshot.11
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/README.md +209 -0
- package/REFERENCE.md +760 -0
- package/dist/browser/browser-server.d.ts +95 -0
- package/dist/browser/browser-server.d.ts.map +1 -0
- package/dist/browser/browser-server.js +719 -0
- package/dist/browser/browser-server.js.map +1 -0
- package/dist/browser/durable-subscription-bindings.d.ts +122 -0
- package/dist/browser/durable-subscription-bindings.d.ts.map +1 -0
- package/dist/browser/durable-subscription-bindings.js +524 -0
- package/dist/browser/durable-subscription-bindings.js.map +1 -0
- package/dist/browser/index.d.ts +12 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +24 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/options.d.ts +183 -0
- package/dist/browser/options.d.ts.map +1 -0
- package/dist/browser/options.js +15 -0
- package/dist/browser/options.js.map +1 -0
- package/dist/bus/command-bus.d.ts +63 -0
- package/dist/bus/command-bus.d.ts.map +1 -0
- package/dist/bus/command-bus.js +236 -0
- package/dist/bus/command-bus.js.map +1 -0
- package/dist/bus/command-dispatcher-registry.d.ts +33 -0
- package/dist/bus/command-dispatcher-registry.d.ts.map +1 -0
- package/dist/bus/command-dispatcher-registry.js +75 -0
- package/dist/bus/command-dispatcher-registry.js.map +1 -0
- package/dist/bus/command-dispatcher.d.ts +25 -0
- package/dist/bus/command-dispatcher.d.ts.map +1 -0
- package/dist/bus/command-dispatcher.js +15 -0
- package/dist/bus/command-dispatcher.js.map +1 -0
- package/dist/bus/command-errors.d.ts +23 -0
- package/dist/bus/command-errors.d.ts.map +1 -0
- package/dist/bus/command-errors.js +52 -0
- package/dist/bus/command-errors.js.map +1 -0
- package/dist/bus/event-bus.d.ts +113 -0
- package/dist/bus/event-bus.d.ts.map +1 -0
- package/dist/bus/event-bus.js +518 -0
- package/dist/bus/event-bus.js.map +1 -0
- package/dist/bus/event-dispatcher-origin-schemas.d.ts +17 -0
- package/dist/bus/event-dispatcher-origin-schemas.d.ts.map +1 -0
- package/dist/bus/event-dispatcher-origin-schemas.js +32 -0
- package/dist/bus/event-dispatcher-origin-schemas.js.map +1 -0
- package/dist/bus/event-dispatcher-registry.d.ts +48 -0
- package/dist/bus/event-dispatcher-registry.d.ts.map +1 -0
- package/dist/bus/event-dispatcher-registry.js +176 -0
- package/dist/bus/event-dispatcher-registry.js.map +1 -0
- package/dist/bus/event-dispatcher.d.ts +48 -0
- package/dist/bus/event-dispatcher.d.ts.map +1 -0
- package/dist/bus/event-dispatcher.js +15 -0
- package/dist/bus/event-dispatcher.js.map +1 -0
- package/dist/context/bounded-context.d.ts +592 -0
- package/dist/context/bounded-context.d.ts.map +1 -0
- package/dist/context/bounded-context.js +1897 -0
- package/dist/context/bounded-context.js.map +1 -0
- package/dist/context/entity-inbox.d.ts +63 -0
- package/dist/context/entity-inbox.d.ts.map +1 -0
- package/dist/context/entity-inbox.js +387 -0
- package/dist/context/entity-inbox.js.map +1 -0
- package/dist/context/local-inbox-handoff.d.ts +248 -0
- package/dist/context/local-inbox-handoff.d.ts.map +1 -0
- package/dist/context/local-inbox-handoff.js +340 -0
- package/dist/context/local-inbox-handoff.js.map +1 -0
- package/dist/context/projection-handoff.d.ts +46 -0
- package/dist/context/projection-handoff.d.ts.map +1 -0
- package/dist/context/projection-handoff.js +177 -0
- package/dist/context/projection-handoff.js.map +1 -0
- package/dist/context/tenant-index.d.ts +41 -0
- package/dist/context/tenant-index.d.ts.map +1 -0
- package/dist/context/tenant-index.js +93 -0
- package/dist/context/tenant-index.js.map +1 -0
- package/dist/delivery/conditional-pickup.d.ts +25 -0
- package/dist/delivery/conditional-pickup.d.ts.map +1 -0
- package/dist/delivery/conditional-pickup.js +26 -0
- package/dist/delivery/conditional-pickup.js.map +1 -0
- package/dist/delivery/delivery-builder.d.ts +216 -0
- package/dist/delivery/delivery-builder.d.ts.map +1 -0
- package/dist/delivery/delivery-builder.js +323 -0
- package/dist/delivery/delivery-builder.js.map +1 -0
- package/dist/delivery/delivery-lease.d.ts +15 -0
- package/dist/delivery/delivery-lease.d.ts.map +1 -0
- package/dist/delivery/delivery-lease.js +44 -0
- package/dist/delivery/delivery-lease.js.map +1 -0
- package/dist/delivery/delivery-loop.d.ts +113 -0
- package/dist/delivery/delivery-loop.d.ts.map +1 -0
- package/dist/delivery/delivery-loop.js +119 -0
- package/dist/delivery/delivery-loop.js.map +1 -0
- package/dist/delivery/delivery-monitor.d.ts +165 -0
- package/dist/delivery/delivery-monitor.d.ts.map +1 -0
- package/dist/delivery/delivery-monitor.js +168 -0
- package/dist/delivery/delivery-monitor.js.map +1 -0
- package/dist/delivery/delivery-ports.d.ts +151 -0
- package/dist/delivery/delivery-ports.d.ts.map +1 -0
- package/dist/delivery/delivery-ports.js +15 -0
- package/dist/delivery/delivery-ports.js.map +1 -0
- package/dist/delivery/delivery-run-control.d.ts +50 -0
- package/dist/delivery/delivery-run-control.d.ts.map +1 -0
- package/dist/delivery/delivery-run-control.js +66 -0
- package/dist/delivery/delivery-run-control.js.map +1 -0
- package/dist/delivery/delivery-run-coordinator.d.ts +218 -0
- package/dist/delivery/delivery-run-coordinator.d.ts.map +1 -0
- package/dist/delivery/delivery-run-coordinator.js +609 -0
- package/dist/delivery/delivery-run-coordinator.js.map +1 -0
- package/dist/delivery/delivery-storage-error.d.ts +13 -0
- package/dist/delivery/delivery-storage-error.d.ts.map +1 -0
- package/dist/delivery/delivery-storage-error.js +30 -0
- package/dist/delivery/delivery-storage-error.js.map +1 -0
- package/dist/delivery/delivery-supervisor.d.ts +175 -0
- package/dist/delivery/delivery-supervisor.d.ts.map +1 -0
- package/dist/delivery/delivery-supervisor.js +469 -0
- package/dist/delivery/delivery-supervisor.js.map +1 -0
- package/dist/delivery/delivery-worker.d.ts +180 -0
- package/dist/delivery/delivery-worker.d.ts.map +1 -0
- package/dist/delivery/delivery-worker.js +232 -0
- package/dist/delivery/delivery-worker.js.map +1 -0
- package/dist/delivery/delivery.d.ts +236 -0
- package/dist/delivery/delivery.d.ts.map +1 -0
- package/dist/delivery/delivery.js +539 -0
- package/dist/delivery/delivery.js.map +1 -0
- package/dist/delivery/inbox-records.d.ts +19 -0
- package/dist/delivery/inbox-records.d.ts.map +1 -0
- package/dist/delivery/inbox-records.js +291 -0
- package/dist/delivery/inbox-records.js.map +1 -0
- package/dist/delivery/inbox-storage.d.ts +83 -0
- package/dist/delivery/inbox-storage.d.ts.map +1 -0
- package/dist/delivery/inbox-storage.js +336 -0
- package/dist/delivery/inbox-storage.js.map +1 -0
- package/dist/delivery/inbox.d.ts +272 -0
- package/dist/delivery/inbox.d.ts.map +1 -0
- package/dist/delivery/inbox.js +183 -0
- package/dist/delivery/inbox.js.map +1 -0
- package/dist/delivery/parked-delivery-obligations.d.ts +182 -0
- package/dist/delivery/parked-delivery-obligations.d.ts.map +1 -0
- package/dist/delivery/parked-delivery-obligations.js +390 -0
- package/dist/delivery/parked-delivery-obligations.js.map +1 -0
- package/dist/delivery/shard-index.d.ts +41 -0
- package/dist/delivery/shard-index.d.ts.map +1 -0
- package/dist/delivery/shard-index.js +67 -0
- package/dist/delivery/shard-index.js.map +1 -0
- package/dist/delivery/sharded-work-registry.d.ts +114 -0
- package/dist/delivery/sharded-work-registry.d.ts.map +1 -0
- package/dist/delivery/sharded-work-registry.js +361 -0
- package/dist/delivery/sharded-work-registry.js.map +1 -0
- package/dist/entity/entity-metadata.d.ts +173 -0
- package/dist/entity/entity-metadata.d.ts.map +1 -0
- package/dist/entity/entity-metadata.js +187 -0
- package/dist/entity/entity-metadata.js.map +1 -0
- package/dist/entity/entity-storage-descriptor.d.ts +64 -0
- package/dist/entity/entity-storage-descriptor.d.ts.map +1 -0
- package/dist/entity/entity-storage-descriptor.js +227 -0
- package/dist/entity/entity-storage-descriptor.js.map +1 -0
- package/dist/entity/entity-transaction.d.ts +372 -0
- package/dist/entity/entity-transaction.d.ts.map +1 -0
- package/dist/entity/entity-transaction.js +413 -0
- package/dist/entity/entity-transaction.js.map +1 -0
- package/dist/entity/entity-transition-validation.d.ts +47 -0
- package/dist/entity/entity-transition-validation.d.ts.map +1 -0
- package/dist/entity/entity-transition-validation.js +327 -0
- package/dist/entity/entity-transition-validation.js.map +1 -0
- package/dist/entity/entity.d.ts +605 -0
- package/dist/entity/entity.d.ts.map +1 -0
- package/dist/entity/entity.js +981 -0
- package/dist/entity/entity.js.map +1 -0
- package/dist/entity/implicit-required-id.d.ts +15 -0
- package/dist/entity/implicit-required-id.d.ts.map +1 -0
- package/dist/entity/implicit-required-id.js +123 -0
- package/dist/entity/implicit-required-id.js.map +1 -0
- package/dist/entity/spec-scanner.d.ts +14 -0
- package/dist/entity/spec-scanner.d.ts.map +1 -0
- package/dist/entity/spec-scanner.js +37 -0
- package/dist/entity/spec-scanner.js.map +1 -0
- package/dist/handler/command-registration-readiness.d.ts +99 -0
- package/dist/handler/command-registration-readiness.d.ts.map +1 -0
- package/dist/handler/command-registration-readiness.js +120 -0
- package/dist/handler/command-registration-readiness.js.map +1 -0
- package/dist/handler/declared-rejections.d.ts +11 -0
- package/dist/handler/declared-rejections.d.ts.map +1 -0
- package/dist/handler/declared-rejections.js +34 -0
- package/dist/handler/declared-rejections.js.map +1 -0
- package/dist/handler/event-handler-filter.d.ts +43 -0
- package/dist/handler/event-handler-filter.d.ts.map +1 -0
- package/dist/handler/event-handler-filter.js +128 -0
- package/dist/handler/event-handler-filter.js.map +1 -0
- package/dist/handler/event-registration-readiness.d.ts +196 -0
- package/dist/handler/event-registration-readiness.d.ts.map +1 -0
- package/dist/handler/event-registration-readiness.js +187 -0
- package/dist/handler/event-registration-readiness.js.map +1 -0
- package/dist/handler/external.d.ts +10 -0
- package/dist/handler/external.d.ts.map +1 -0
- package/dist/handler/external.js +15 -0
- package/dist/handler/external.js.map +1 -0
- package/dist/handler/generated-handler-registry.d.ts +185 -0
- package/dist/handler/generated-handler-registry.d.ts.map +1 -0
- package/dist/handler/generated-handler-registry.js +439 -0
- package/dist/handler/generated-handler-registry.js.map +1 -0
- package/dist/handler/generated-registry-discovery.d.ts +94 -0
- package/dist/handler/generated-registry-discovery.d.ts.map +1 -0
- package/dist/handler/generated-registry-discovery.js +226 -0
- package/dist/handler/generated-registry-discovery.js.map +1 -0
- package/dist/handler/handler-decorators.d.ts +151 -0
- package/dist/handler/handler-decorators.d.ts.map +1 -0
- package/dist/handler/handler-decorators.js +275 -0
- package/dist/handler/handler-decorators.js.map +1 -0
- package/dist/handler/handler-metadata.d.ts +553 -0
- package/dist/handler/handler-metadata.d.ts.map +1 -0
- package/dist/handler/handler-metadata.js +437 -0
- package/dist/handler/handler-metadata.js.map +1 -0
- package/dist/handler/registration-readiness-metadata.d.ts +68 -0
- package/dist/handler/registration-readiness-metadata.d.ts.map +1 -0
- package/dist/handler/registration-readiness-metadata.js +171 -0
- package/dist/handler/registration-readiness-metadata.js.map +1 -0
- package/dist/handler/rejection-source.d.ts +11 -0
- package/dist/handler/rejection-source.d.ts.map +1 -0
- package/dist/handler/rejection-source.js +25 -0
- package/dist/handler/rejection-source.js.map +1 -0
- package/dist/handler/standalone.d.ts +25 -0
- package/dist/handler/standalone.d.ts.map +1 -0
- package/dist/handler/standalone.js +38 -0
- package/dist/handler/standalone.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/integration/external-messages.d.ts +49 -0
- package/dist/integration/external-messages.d.ts.map +1 -0
- package/dist/integration/external-messages.js +112 -0
- package/dist/integration/external-messages.js.map +1 -0
- package/dist/integration/integration-broker.d.ts +74 -0
- package/dist/integration/integration-broker.d.ts.map +1 -0
- package/dist/integration/integration-broker.js +444 -0
- package/dist/integration/integration-broker.js.map +1 -0
- package/dist/integration/third-party-context.d.ts +56 -0
- package/dist/integration/third-party-context.d.ts.map +1 -0
- package/dist/integration/third-party-context.js +130 -0
- package/dist/integration/third-party-context.js.map +1 -0
- package/dist/repository/command-errors.d.ts +25 -0
- package/dist/repository/command-errors.d.ts.map +1 -0
- package/dist/repository/command-errors.js +43 -0
- package/dist/repository/command-errors.js.map +1 -0
- package/dist/repository/command-routing.d.ts +72 -0
- package/dist/repository/command-routing.d.ts.map +1 -0
- package/dist/repository/command-routing.js +98 -0
- package/dist/repository/command-routing.js.map +1 -0
- package/dist/repository/commit-fence.d.ts +22 -0
- package/dist/repository/commit-fence.d.ts.map +1 -0
- package/dist/repository/commit-fence.js +37 -0
- package/dist/repository/commit-fence.js.map +1 -0
- package/dist/repository/event-routing.d.ts +71 -0
- package/dist/repository/event-routing.d.ts.map +1 -0
- package/dist/repository/event-routing.js +96 -0
- package/dist/repository/event-routing.js.map +1 -0
- package/dist/repository/primitive-id.d.ts +75 -0
- package/dist/repository/primitive-id.d.ts.map +1 -0
- package/dist/repository/primitive-id.js +85 -0
- package/dist/repository/primitive-id.js.map +1 -0
- package/dist/repository/repository.d.ts +667 -0
- package/dist/repository/repository.d.ts.map +1 -0
- package/dist/repository/repository.js +3510 -0
- package/dist/repository/repository.js.map +1 -0
- package/dist/repository/routing-declarations.d.ts +75 -0
- package/dist/repository/routing-declarations.d.ts.map +1 -0
- package/dist/repository/routing-declarations.js +101 -0
- package/dist/repository/routing-declarations.js.map +1 -0
- package/dist/repository/state-update-routing.d.ts +66 -0
- package/dist/repository/state-update-routing.d.ts.map +1 -0
- package/dist/repository/state-update-routing.js +91 -0
- package/dist/repository/state-update-routing.js.map +1 -0
- package/dist/runtime/runtime.d.ts +156 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +215 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/runtime/signal-intake.d.ts +84 -0
- package/dist/runtime/signal-intake.d.ts.map +1 -0
- package/dist/runtime/signal-intake.js +94 -0
- package/dist/runtime/signal-intake.js.map +1 -0
- package/dist/runtime/signal-metadata.d.ts +217 -0
- package/dist/runtime/signal-metadata.d.ts.map +1 -0
- package/dist/runtime/signal-metadata.js +333 -0
- package/dist/runtime/signal-metadata.js.map +1 -0
- package/dist/runtime/signal-publisher.d.ts +144 -0
- package/dist/runtime/signal-publisher.d.ts.map +1 -0
- package/dist/runtime/signal-publisher.js +248 -0
- package/dist/runtime/signal-publisher.js.map +1 -0
- package/dist/runtime/standalone-handler-runtime.d.ts +114 -0
- package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -0
- package/dist/runtime/standalone-handler-runtime.js +307 -0
- package/dist/runtime/standalone-handler-runtime.js.map +1 -0
- package/dist/server/environment-attachment.d.ts +356 -0
- package/dist/server/environment-attachment.d.ts.map +1 -0
- package/dist/server/environment-attachment.js +2062 -0
- package/dist/server/environment-attachment.js.map +1 -0
- package/dist/server/environment-delivery-records.d.ts +77 -0
- package/dist/server/environment-delivery-records.d.ts.map +1 -0
- package/dist/server/environment-delivery-records.js +282 -0
- package/dist/server/environment-delivery-records.js.map +1 -0
- package/dist/server/environment-delivery-worker.d.ts +161 -0
- package/dist/server/environment-delivery-worker.d.ts.map +1 -0
- package/dist/server/environment-delivery-worker.js +673 -0
- package/dist/server/environment-delivery-worker.js.map +1 -0
- package/dist/server/environment.d.ts +43 -0
- package/dist/server/environment.d.ts.map +1 -0
- package/dist/server/environment.js +90 -0
- package/dist/server/environment.js.map +1 -0
- package/dist/server/managed-child-subscription.d.ts +11 -0
- package/dist/server/managed-child-subscription.d.ts.map +1 -0
- package/dist/server/managed-child-subscription.js +44 -0
- package/dist/server/managed-child-subscription.js.map +1 -0
- package/dist/server/managed-server-application.d.ts +327 -0
- package/dist/server/managed-server-application.d.ts.map +1 -0
- package/dist/server/managed-server-application.js +937 -0
- package/dist/server/managed-server-application.js.map +1 -0
- package/dist/server/node-coordinator.d.ts +191 -0
- package/dist/server/node-coordinator.d.ts.map +1 -0
- package/dist/server/node-coordinator.js +552 -0
- package/dist/server/node-coordinator.js.map +1 -0
- package/dist/server/process-server-coordinator.d.ts +15 -0
- package/dist/server/process-server-coordinator.d.ts.map +1 -0
- package/dist/server/process-server-coordinator.js +112 -0
- package/dist/server/process-server-coordinator.js.map +1 -0
- package/dist/server/reserved-spine-rpc-paths.json +8 -0
- package/dist/server/retryable-close.d.ts +28 -0
- package/dist/server/retryable-close.d.ts.map +1 -0
- package/dist/server/retryable-close.js +129 -0
- package/dist/server/retryable-close.js.map +1 -0
- package/dist/server/server-environment.d.ts +180 -0
- package/dist/server/server-environment.d.ts.map +1 -0
- package/dist/server/server-environment.js +418 -0
- package/dist/server/server-environment.js.map +1 -0
- package/dist/server/server-log.d.ts +18 -0
- package/dist/server/server-log.d.ts.map +1 -0
- package/dist/server/server-log.js +100 -0
- package/dist/server/server-log.js.map +1 -0
- package/dist/server/server.d.ts +221 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +704 -0
- package/dist/server/server.js.map +1 -0
- package/dist/services/query-reader.d.ts +19 -0
- package/dist/services/query-reader.d.ts.map +1 -0
- package/dist/services/query-reader.js +43 -0
- package/dist/services/query-reader.js.map +1 -0
- package/dist/services/spine-services.d.ts +88 -0
- package/dist/services/spine-services.d.ts.map +1 -0
- package/dist/services/spine-services.js +1582 -0
- package/dist/services/spine-services.js.map +1 -0
- package/dist/spi/delivery.d.ts +5 -0
- package/dist/spi/delivery.d.ts.map +1 -0
- package/dist/spi/delivery.js +18 -0
- package/dist/spi/delivery.js.map +1 -0
- package/dist/spi/handler-registry.d.ts +8 -0
- package/dist/spi/handler-registry.d.ts.map +1 -0
- package/dist/spi/handler-registry.js +15 -0
- package/dist/spi/handler-registry.js.map +1 -0
- package/dist/stand/stand.d.ts +294 -0
- package/dist/stand/stand.d.ts.map +1 -0
- package/dist/stand/stand.js +681 -0
- package/dist/stand/stand.js.map +1 -0
- package/dist/stand/subscription-observer.d.ts +53 -0
- package/dist/stand/subscription-observer.d.ts.map +1 -0
- package/dist/stand/subscription-observer.js +444 -0
- package/dist/stand/subscription-observer.js.map +1 -0
- package/dist/stand/subscription-records.d.ts +12 -0
- package/dist/stand/subscription-records.d.ts.map +1 -0
- package/dist/stand/subscription-records.js +99 -0
- package/dist/stand/subscription-records.js.map +1 -0
- package/dist/stand/subscription-registry.d.ts +285 -0
- package/dist/stand/subscription-registry.d.ts.map +1 -0
- package/dist/stand/subscription-registry.js +403 -0
- package/dist/stand/subscription-registry.js.map +1 -0
- package/dist/stand/subscription-runtime.d.ts +102 -0
- package/dist/stand/subscription-runtime.d.ts.map +1 -0
- package/dist/stand/subscription-runtime.js +380 -0
- package/dist/stand/subscription-runtime.js.map +1 -0
- package/dist/testing/index.d.ts +36 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +54 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,981 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, CodeMatters. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
5
|
+
* in compliance with the License. You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
10
|
+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
11
|
+
* or implied. See the License for the specific language governing permissions and limitations under
|
|
12
|
+
* the License.
|
|
13
|
+
*/
|
|
14
|
+
import { clone, fromBinary, toBinary } from "@bufbuild/protobuf";
|
|
15
|
+
import { EntityQuery, } from "@spine-event-engine/core";
|
|
16
|
+
import { ActorContextSchema, ValidationErrorSchema, } from "@spine-event-engine/proto";
|
|
17
|
+
import { describeEntityMetadata, } from "./entity-metadata.js";
|
|
18
|
+
import { EntityTransaction, } from "./entity-transaction.js";
|
|
19
|
+
const processManagerQueries = new WeakMap();
|
|
20
|
+
/**
|
|
21
|
+
* Binds the repository-scoped query capability for one Process Manager invocation.
|
|
22
|
+
*
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export const processManagerQueryAccess = Object.freeze({
|
|
26
|
+
bind(entity, execute, actorContext) {
|
|
27
|
+
const capability = {
|
|
28
|
+
execute,
|
|
29
|
+
actorContext: clone(ActorContextSchema, actorContext),
|
|
30
|
+
active: true,
|
|
31
|
+
};
|
|
32
|
+
processManagerQueries.set(entity, capability);
|
|
33
|
+
return () => {
|
|
34
|
+
capability.active = false;
|
|
35
|
+
processManagerQueries.delete(entity);
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
require(entity) {
|
|
39
|
+
const capability = processManagerQueries.get(entity);
|
|
40
|
+
if (capability?.active !== true) {
|
|
41
|
+
throw new Error("Process Manager queries are available only during repository handler execution.");
|
|
42
|
+
}
|
|
43
|
+
return capability;
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* A repository-scoped, read-only Entity query issued by a Process Manager.
|
|
48
|
+
*
|
|
49
|
+
* @typeParam Schema State schema read by the query.
|
|
50
|
+
* @typeParam Columns Registered descriptor-backed columns for `Schema`.
|
|
51
|
+
*/
|
|
52
|
+
export class ProcessManagerQuery {
|
|
53
|
+
#entity;
|
|
54
|
+
#schema;
|
|
55
|
+
#builder;
|
|
56
|
+
/**
|
|
57
|
+
* Creates the repository-scoped query facade.
|
|
58
|
+
*
|
|
59
|
+
* @internal
|
|
60
|
+
* @param entity Process Manager that owns this query capability.
|
|
61
|
+
* @param schema State schema read by this query.
|
|
62
|
+
* @param builder Typed query builder used to create the wire query.
|
|
63
|
+
*/
|
|
64
|
+
constructor(entity, schema, builder) {
|
|
65
|
+
this.#entity = entity;
|
|
66
|
+
this.#schema = schema;
|
|
67
|
+
this.#builder = builder;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Adds the supplied Entity IDs to the query target.
|
|
71
|
+
*
|
|
72
|
+
* @param ids Entity IDs to include.
|
|
73
|
+
* @returns This query for fluent configuration.
|
|
74
|
+
*/
|
|
75
|
+
byId(...ids) {
|
|
76
|
+
this.#builder.byId(...ids);
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Adds a typed state predicate to the query.
|
|
81
|
+
*
|
|
82
|
+
* @param predicate Predicate evaluated against registered state columns.
|
|
83
|
+
* @returns This query for fluent configuration.
|
|
84
|
+
*/
|
|
85
|
+
where(predicate) {
|
|
86
|
+
this.#builder.where(predicate);
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Sets the state fields returned by the server.
|
|
91
|
+
*
|
|
92
|
+
* @param paths Generated state-field property names to include.
|
|
93
|
+
* @returns This query for fluent configuration.
|
|
94
|
+
*/
|
|
95
|
+
mask(...paths) {
|
|
96
|
+
this.#builder.mask(...paths);
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Sets the ordering for matching states by one registered column.
|
|
101
|
+
*
|
|
102
|
+
* @param column Registered orderable column used for sorting.
|
|
103
|
+
* @param direction Optional sort direction, ascending by default.
|
|
104
|
+
* @returns This query for fluent configuration.
|
|
105
|
+
*/
|
|
106
|
+
orderBy(column, direction = "asc") {
|
|
107
|
+
this.#builder.orderBy(column, direction);
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Sets the returned-state limit to at most 1,000 entries.
|
|
112
|
+
*
|
|
113
|
+
* @param value Maximum number of states to return.
|
|
114
|
+
* @returns This query for fluent configuration.
|
|
115
|
+
*/
|
|
116
|
+
limit(value) {
|
|
117
|
+
if (value > 1_000) {
|
|
118
|
+
throw new TypeError("Process Manager query limit may be at most 1000.");
|
|
119
|
+
}
|
|
120
|
+
this.#builder.limit(value);
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Reads matching state snapshots from the eventually consistent query projection.
|
|
125
|
+
*
|
|
126
|
+
* @returns Readonly state snapshots, subject to the configured result limit.
|
|
127
|
+
*/
|
|
128
|
+
async read() {
|
|
129
|
+
const capability = processManagerQueryAccess.require(this.#entity);
|
|
130
|
+
const states = await capability.execute(this.#builder.buildPlan(), this.#schema, this.#builder.build());
|
|
131
|
+
return Object.freeze(states.slice(0, 1_000));
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Reads the first state snapshot for one Entity ID.
|
|
135
|
+
*
|
|
136
|
+
* @param id Entity ID to read.
|
|
137
|
+
* @returns The eventually consistent state snapshot, or `undefined` when it is absent.
|
|
138
|
+
*/
|
|
139
|
+
async findById(id) {
|
|
140
|
+
const states = await this.byId(id).read();
|
|
141
|
+
return states[0];
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Reads every matching state snapshot within the configured result limit.
|
|
145
|
+
*
|
|
146
|
+
* This can be more expensive than an ID-targeted read because the projection must evaluate all
|
|
147
|
+
* matching states.
|
|
148
|
+
*
|
|
149
|
+
* @returns Readonly eventually consistent state snapshots.
|
|
150
|
+
*/
|
|
151
|
+
async all() {
|
|
152
|
+
return await this.read();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const rejectedCommits = new WeakMap();
|
|
156
|
+
/**
|
|
157
|
+
* Error thrown when a transactional entity draft helper is used outside its scope.
|
|
158
|
+
*/
|
|
159
|
+
export class TransactionalEntityScopeError extends Error {
|
|
160
|
+
// prettier-ignore
|
|
161
|
+
/**
|
|
162
|
+
* Scope failure reason.
|
|
163
|
+
*/
|
|
164
|
+
reason;
|
|
165
|
+
/**
|
|
166
|
+
* Operation rejected by the current transaction scope.
|
|
167
|
+
*/
|
|
168
|
+
operation;
|
|
169
|
+
/**
|
|
170
|
+
* Creates a deterministic transaction-scope error.
|
|
171
|
+
*
|
|
172
|
+
* @param reason Scope failure reason.
|
|
173
|
+
* @param operation Operation rejected by the scope.
|
|
174
|
+
*/
|
|
175
|
+
constructor(reason, operation) {
|
|
176
|
+
super(reason === "duplicate"
|
|
177
|
+
? `Cannot ${operation}: transactional entity already has an active transaction.`
|
|
178
|
+
: `Cannot ${operation}: transactional entity requires an active transaction.`);
|
|
179
|
+
this.name = "TransactionalEntityScopeError";
|
|
180
|
+
this.reason = reason;
|
|
181
|
+
this.operation = operation;
|
|
182
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const isProxy = process.getBuiltinModule("node:util").types.isProxy;
|
|
186
|
+
/**
|
|
187
|
+
* Common in-memory OOP shell for one server-side entity state.
|
|
188
|
+
*
|
|
189
|
+
* The shell exposes identity, descriptor-derived metadata, cloned state
|
|
190
|
+
* snapshots, caller-owned plain version metadata snapshots, and lifecycle flags. It does not
|
|
191
|
+
* invoke handlers, create transactions, write repositories or storage, dispatch
|
|
192
|
+
* messages, increment versions, route IDs, query read models, start buses, or
|
|
193
|
+
* mutate process-wide runtime state.
|
|
194
|
+
*/
|
|
195
|
+
export class Entity {
|
|
196
|
+
#id;
|
|
197
|
+
#schema;
|
|
198
|
+
#metadata;
|
|
199
|
+
#state;
|
|
200
|
+
#version;
|
|
201
|
+
#lifecycle;
|
|
202
|
+
#lifecycleFlagsChanged = false;
|
|
203
|
+
/**
|
|
204
|
+
* Creates an entity shell from caller-provided state and metadata inputs.
|
|
205
|
+
*
|
|
206
|
+
* @param options Identity, schema, state, version, and lifecycle inputs.
|
|
207
|
+
*/
|
|
208
|
+
constructor(options) {
|
|
209
|
+
this.#id = options.id;
|
|
210
|
+
this.#schema = options.schema;
|
|
211
|
+
this.#metadata = describeEntityMetadata(options.schema);
|
|
212
|
+
this.#state = EntitySnapshots.clone(options.schema, options.state);
|
|
213
|
+
this.#version = EntityVersions.clone(options.version);
|
|
214
|
+
this.#lifecycle = {
|
|
215
|
+
archived: options.lifecycle?.archived ?? false,
|
|
216
|
+
deleted: options.lifecycle?.deleted ?? false,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Gets the stable entity identifier.
|
|
221
|
+
*
|
|
222
|
+
* @returns The caller-owned entity identifier.
|
|
223
|
+
*/
|
|
224
|
+
get id() {
|
|
225
|
+
return this.#id;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Gets the generated Protobuf-ES schema describing this entity's state.
|
|
229
|
+
*
|
|
230
|
+
* @returns The generated state schema.
|
|
231
|
+
*/
|
|
232
|
+
get schema() {
|
|
233
|
+
return this.#schema;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Gets descriptor-derived metadata for this entity's state schema.
|
|
237
|
+
*
|
|
238
|
+
* @returns The frozen descriptor metadata.
|
|
239
|
+
*/
|
|
240
|
+
get metadata() {
|
|
241
|
+
return this.#metadata;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Gets the current entity state snapshot.
|
|
245
|
+
*
|
|
246
|
+
* @returns A cloned state snapshot.
|
|
247
|
+
*/
|
|
248
|
+
get state() {
|
|
249
|
+
return EntitySnapshots.clone(this.#schema, this.#state);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Gets the caller-owned plain version metadata snapshot.
|
|
253
|
+
*
|
|
254
|
+
* @returns A validated clone of the version metadata.
|
|
255
|
+
*/
|
|
256
|
+
get version() {
|
|
257
|
+
return EntityVersions.clone(this.#version);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Gets the current lifecycle flag snapshot.
|
|
261
|
+
*
|
|
262
|
+
* @returns The archived and deleted flags.
|
|
263
|
+
*/
|
|
264
|
+
get lifecycle() {
|
|
265
|
+
return {
|
|
266
|
+
archived: this.#lifecycle.archived,
|
|
267
|
+
deleted: this.#lifecycle.deleted,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Determines whether the entity is archived.
|
|
272
|
+
*
|
|
273
|
+
* @returns `true` when the entity is archived.
|
|
274
|
+
*/
|
|
275
|
+
get isArchived() {
|
|
276
|
+
return this.#lifecycle.archived;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Determines whether the entity is deleted.
|
|
280
|
+
*
|
|
281
|
+
* @returns `true` when the entity is deleted.
|
|
282
|
+
*/
|
|
283
|
+
get isDeleted() {
|
|
284
|
+
return this.#lifecycle.deleted;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Determines whether neither lifecycle flag marks the entity inactive.
|
|
288
|
+
*
|
|
289
|
+
* @returns `true` when the entity is active.
|
|
290
|
+
*/
|
|
291
|
+
get isActive() {
|
|
292
|
+
return !this.isArchived && !this.isDeleted;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Determines whether lifecycle flags changed after construction.
|
|
296
|
+
*
|
|
297
|
+
* @returns `true` when lifecycle flags changed.
|
|
298
|
+
*/
|
|
299
|
+
get lifecycleFlagsChanged() {
|
|
300
|
+
return this.#lifecycleFlagsChanged;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Replaces stored state from framework-owned subclass or runtime code.
|
|
304
|
+
*
|
|
305
|
+
* @param state Next entity state snapshot.
|
|
306
|
+
*/
|
|
307
|
+
replaceState(state) {
|
|
308
|
+
this.#state = EntitySnapshots.clone(this.#schema, state);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Replaces caller-owned version metadata from framework-owned subclass or runtime code.
|
|
312
|
+
*
|
|
313
|
+
* @param version Next caller-owned version metadata.
|
|
314
|
+
*/
|
|
315
|
+
replaceVersionMetadata(version) {
|
|
316
|
+
this.#version = EntityVersions.clone(version);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Replaces lifecycle flags from framework-owned subclass or runtime code.
|
|
320
|
+
*
|
|
321
|
+
* @param lifecycle Lifecycle flag changes to apply.
|
|
322
|
+
*/
|
|
323
|
+
replaceLifecycleFlags(lifecycle) {
|
|
324
|
+
const next = {
|
|
325
|
+
archived: lifecycle.archived ?? this.#lifecycle.archived,
|
|
326
|
+
deleted: lifecycle.deleted ?? this.#lifecycle.deleted,
|
|
327
|
+
};
|
|
328
|
+
if (next.archived !== this.#lifecycle.archived || next.deleted !== this.#lifecycle.deleted) {
|
|
329
|
+
this.#lifecycle = next;
|
|
330
|
+
this.#lifecycleFlagsChanged = true;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Reads the newest retained state at or before `time`.
|
|
335
|
+
*
|
|
336
|
+
* This diagnostic facility is repository-bound and is not a remote API.
|
|
337
|
+
*
|
|
338
|
+
* @param time Timestamp of the requested state snapshot.
|
|
339
|
+
* @returns The retained state snapshot, if one exists.
|
|
340
|
+
*/
|
|
341
|
+
stateAt(time) {
|
|
342
|
+
return entityHistoryAccess.stateAt(this, time);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Reads retained states in descending version order.
|
|
346
|
+
*
|
|
347
|
+
* @param depth Maximum number of retained states to read.
|
|
348
|
+
* @returns Retained state snapshots in descending version order.
|
|
349
|
+
*/
|
|
350
|
+
stateHistoryBackward(depth) {
|
|
351
|
+
return entityHistoryAccess.states(this, depth);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Gets application-managed state-history retention.
|
|
355
|
+
*
|
|
356
|
+
* @returns State-history storage for this entity.
|
|
357
|
+
*/
|
|
358
|
+
stateHistoryStorage() {
|
|
359
|
+
return entityHistoryAccess.stateMaintenance(this);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
const boundEntityHistories = new WeakMap();
|
|
363
|
+
/**
|
|
364
|
+
* Provides repository-only history binding.
|
|
365
|
+
*
|
|
366
|
+
* @internal
|
|
367
|
+
*/
|
|
368
|
+
export const entityHistoryAccess = Object.freeze({
|
|
369
|
+
bind(entity, binding) {
|
|
370
|
+
boundEntityHistories.set(entity, binding);
|
|
371
|
+
},
|
|
372
|
+
stateAt(entity, time) {
|
|
373
|
+
return EntityHistory.require(entity).stateAt(time);
|
|
374
|
+
},
|
|
375
|
+
states(entity, depth) {
|
|
376
|
+
return EntityHistory.require(entity).states(EntityHistory.depth(depth));
|
|
377
|
+
},
|
|
378
|
+
events(entity, depth) {
|
|
379
|
+
return EntityHistory.require(entity).events(EntityHistory.depth(depth));
|
|
380
|
+
},
|
|
381
|
+
stateMaintenance(entity) {
|
|
382
|
+
return EntityHistory.require(entity).stateMaintenance;
|
|
383
|
+
},
|
|
384
|
+
eventMaintenance(entity) {
|
|
385
|
+
return EntityHistory.require(entity).eventMaintenance;
|
|
386
|
+
},
|
|
387
|
+
});
|
|
388
|
+
/**
|
|
389
|
+
* Validates repository-bound history lookups.
|
|
390
|
+
*/
|
|
391
|
+
const EntityHistory = Object.freeze({
|
|
392
|
+
require(entity) {
|
|
393
|
+
const binding = boundEntityHistories.get(entity);
|
|
394
|
+
if (binding === undefined) {
|
|
395
|
+
throw new Error("Entity history is available only from repository execution.");
|
|
396
|
+
}
|
|
397
|
+
return binding;
|
|
398
|
+
},
|
|
399
|
+
depth(depth) {
|
|
400
|
+
if (!Number.isSafeInteger(depth) || depth <= 0) {
|
|
401
|
+
throw new RangeError("Entity history depth must be a positive safe integer.");
|
|
402
|
+
}
|
|
403
|
+
return depth;
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
/**
|
|
407
|
+
* Common in-memory entity shell with a protected scoped transaction draft.
|
|
408
|
+
*
|
|
409
|
+
* The transaction scope is backed by {@link EntityTransaction}. Subclasses can
|
|
410
|
+
* start one active draft, mutate draft state/version/lifecycle through protected
|
|
411
|
+
* helpers, and then commit or roll back the scope. Accepted commits replace this
|
|
412
|
+
* entity's in-memory state, explicit version metadata, and lifecycle flags.
|
|
413
|
+
* Rejected commits leave the transaction active so subclass code can correct the
|
|
414
|
+
* draft or roll it back explicitly. This base does not write repositories,
|
|
415
|
+
* emit events, dispatch handlers, increment versions, or manage global
|
|
416
|
+
* transaction state.
|
|
417
|
+
*/
|
|
418
|
+
export class TransactionalEntity extends Entity {
|
|
419
|
+
#transaction;
|
|
420
|
+
#stateChanged = false;
|
|
421
|
+
/**
|
|
422
|
+
* Determines whether accepted transaction state or lifecycle changes are visible.
|
|
423
|
+
*
|
|
424
|
+
* @returns `true` when the entity differs from its initial state.
|
|
425
|
+
*/
|
|
426
|
+
get changed() {
|
|
427
|
+
return this.#stateChanged || this.lifecycleFlagsChanged;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Determines whether a protected transaction scope is currently active.
|
|
431
|
+
*
|
|
432
|
+
* @returns `true` when an active transaction scope exists.
|
|
433
|
+
*/
|
|
434
|
+
isTransactionInProgress() {
|
|
435
|
+
return this.#transaction?.status === "active";
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Starts a protected draft transaction from the entity's current snapshots.
|
|
439
|
+
*
|
|
440
|
+
* @throws {@link TransactionalEntityScopeError} when another transaction is active.
|
|
441
|
+
*/
|
|
442
|
+
startTransaction() {
|
|
443
|
+
if (this.isTransactionInProgress()) {
|
|
444
|
+
throw new TransactionalEntityScopeError("duplicate", "startTransaction");
|
|
445
|
+
}
|
|
446
|
+
const previousVersion = this.version;
|
|
447
|
+
this.#transaction = new EntityTransaction({
|
|
448
|
+
schema: this.schema,
|
|
449
|
+
previous: this.state,
|
|
450
|
+
version: {
|
|
451
|
+
previous: previousVersion,
|
|
452
|
+
draft: EntityVersions.clone(previousVersion),
|
|
453
|
+
},
|
|
454
|
+
lifecycle: this.lifecycle,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Gets the current draft state snapshot.
|
|
459
|
+
*
|
|
460
|
+
* @returns A cloned current draft state snapshot.
|
|
461
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
462
|
+
*/
|
|
463
|
+
currentDraft() {
|
|
464
|
+
return this.#requireTransaction("currentDraft").currentDraft;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Gets the current draft version metadata snapshot.
|
|
468
|
+
*
|
|
469
|
+
* @returns Cloned previous and draft version metadata.
|
|
470
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
471
|
+
*/
|
|
472
|
+
draftVersionMetadata() {
|
|
473
|
+
const version = this.#requireTransaction("draftVersionMetadata").version;
|
|
474
|
+
return {
|
|
475
|
+
previous: EntityVersions.clone(version.previous),
|
|
476
|
+
draft: EntityVersions.clone(version.draft),
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Gets the current draft lifecycle flag snapshot.
|
|
481
|
+
*
|
|
482
|
+
* @returns Current archived and deleted draft flags.
|
|
483
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
484
|
+
*/
|
|
485
|
+
draftLifecycleFlags() {
|
|
486
|
+
return this.#requireTransaction("draftLifecycleFlags").lifecycle;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Updates the buffered draft state in place.
|
|
490
|
+
*
|
|
491
|
+
* @param mutator Changes the active draft state.
|
|
492
|
+
* @returns A cloned snapshot of the updated draft state.
|
|
493
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
494
|
+
*/
|
|
495
|
+
update(mutator) {
|
|
496
|
+
return this.#requireTransaction("update").update(mutator);
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Tries to update and validate a scratch draft, applying it only when valid.
|
|
500
|
+
*
|
|
501
|
+
* Validation failures return immutable constraint violations. Other errors
|
|
502
|
+
* propagate and leave the active draft unchanged.
|
|
503
|
+
*
|
|
504
|
+
* @param mutator Changes the scratch draft state.
|
|
505
|
+
* @returns Immutable constraint violations, or an empty array when the update applies.
|
|
506
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
507
|
+
*/
|
|
508
|
+
tryUpdate(mutator) {
|
|
509
|
+
return this.#requireTransaction("tryUpdate").tryUpdate(mutator);
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Updates the buffered draft version metadata without computing version increments.
|
|
513
|
+
*
|
|
514
|
+
* @param draft Caller-owned version metadata for the active draft.
|
|
515
|
+
* @returns Cloned previous and draft version metadata.
|
|
516
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
517
|
+
*/
|
|
518
|
+
updateDraftVersionMetadata(draft) {
|
|
519
|
+
this.#requireTransaction("updateDraftVersionMetadata").updateVersionMetadata(EntityVersions.clone(draft));
|
|
520
|
+
return this.draftVersionMetadata();
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Marks the buffered draft lifecycle as archived.
|
|
524
|
+
*
|
|
525
|
+
* @returns The archived and deleted draft flags.
|
|
526
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
527
|
+
*/
|
|
528
|
+
archiveDraft() {
|
|
529
|
+
return this.#requireTransaction("archiveDraft").archive();
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Marks the buffered draft lifecycle as not archived.
|
|
533
|
+
*
|
|
534
|
+
* @returns The archived and deleted draft flags.
|
|
535
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
536
|
+
*/
|
|
537
|
+
unarchiveDraft() {
|
|
538
|
+
return this.#requireTransaction("unarchiveDraft").unarchive();
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Marks the buffered draft lifecycle as deleted.
|
|
542
|
+
*
|
|
543
|
+
* @returns The archived and deleted draft flags.
|
|
544
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
545
|
+
*/
|
|
546
|
+
markDraftDeleted() {
|
|
547
|
+
return this.#requireTransaction("markDraftDeleted").markDeleted();
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Marks the buffered draft lifecycle as not deleted.
|
|
551
|
+
*
|
|
552
|
+
* @returns The archived and deleted draft flags.
|
|
553
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
554
|
+
*/
|
|
555
|
+
restoreDraft() {
|
|
556
|
+
return this.#requireTransaction("restoreDraft").restore();
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Commits the active draft transaction.
|
|
560
|
+
*
|
|
561
|
+
* Accepted commits apply state, version metadata, and lifecycle flags to this
|
|
562
|
+
* entity and close the transaction. Rejected commits do not apply anything and
|
|
563
|
+
* keep the transaction active for correction or explicit rollback.
|
|
564
|
+
*
|
|
565
|
+
* @returns A cloned accepted or rejected transaction result.
|
|
566
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
567
|
+
*/
|
|
568
|
+
commitTransaction() {
|
|
569
|
+
const transaction = this.#requireTransaction("commitTransaction");
|
|
570
|
+
const result = transaction.commit();
|
|
571
|
+
if (result.status === "accepted") {
|
|
572
|
+
if (result.previous === undefined ||
|
|
573
|
+
!EntitySnapshots.equal(this.schema, result.previous, result.next)) {
|
|
574
|
+
this.#stateChanged = true;
|
|
575
|
+
}
|
|
576
|
+
this.replaceState(result.next);
|
|
577
|
+
this.replaceVersionMetadata(result.version.committed);
|
|
578
|
+
this.replaceLifecycleFlags(result.lifecycle);
|
|
579
|
+
this.#transaction = undefined;
|
|
580
|
+
rejectedCommits.delete(this);
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
rejectedCommits.set(this, EntityCommits.clone(result));
|
|
584
|
+
}
|
|
585
|
+
return EntityCommits.clone(result);
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Rolls back the active draft without applying state, version, or lifecycle changes.
|
|
589
|
+
*
|
|
590
|
+
* @returns A cloned rollback result containing the discarded draft snapshots.
|
|
591
|
+
* @throws {@link TransactionalEntityScopeError} when no transaction is active.
|
|
592
|
+
*/
|
|
593
|
+
rollbackTransaction() {
|
|
594
|
+
const result = this.#requireTransaction("rollbackTransaction").rollback();
|
|
595
|
+
this.#transaction = undefined;
|
|
596
|
+
return result;
|
|
597
|
+
}
|
|
598
|
+
#requireTransaction(operation) {
|
|
599
|
+
const transaction = this.#transaction;
|
|
600
|
+
if (transaction?.status !== "active") {
|
|
601
|
+
throw new TransactionalEntityScopeError("missing", operation);
|
|
602
|
+
}
|
|
603
|
+
return transaction;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Exposes framework-only transaction operations for repository execution.
|
|
608
|
+
*
|
|
609
|
+
* @internal
|
|
610
|
+
*/
|
|
611
|
+
export const transactionalEntityAccess = Object.freeze({
|
|
612
|
+
start(entity) {
|
|
613
|
+
TransactionAccess.call(entity, "startTransaction");
|
|
614
|
+
},
|
|
615
|
+
commit(entity) {
|
|
616
|
+
return TransactionAccess.call(entity, "commitTransaction");
|
|
617
|
+
},
|
|
618
|
+
rollback(entity) {
|
|
619
|
+
try {
|
|
620
|
+
TransactionAccess.call(entity, "rollbackTransaction");
|
|
621
|
+
}
|
|
622
|
+
catch (error) {
|
|
623
|
+
if (!TransactionAccess.isMissing(error)) {
|
|
624
|
+
throw error;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
rejectedCommit(entity) {
|
|
629
|
+
const rejected = rejectedCommits.get(entity);
|
|
630
|
+
return rejected === undefined
|
|
631
|
+
? undefined
|
|
632
|
+
: EntityCommits.clone(rejected);
|
|
633
|
+
},
|
|
634
|
+
});
|
|
635
|
+
/**
|
|
636
|
+
* Bridges repository code to protected transactional entity methods.
|
|
637
|
+
*/
|
|
638
|
+
const TransactionAccess = Object.freeze({
|
|
639
|
+
call(entity, methodName) {
|
|
640
|
+
const method = entity[methodName];
|
|
641
|
+
if (typeof method !== "function") {
|
|
642
|
+
throw new TypeError(`Transactional entity access requires "${methodName}".`);
|
|
643
|
+
}
|
|
644
|
+
return Reflect.apply(method, entity, []);
|
|
645
|
+
},
|
|
646
|
+
isMissing(error) {
|
|
647
|
+
return error instanceof TransactionalEntityScopeError && error.reason === "missing";
|
|
648
|
+
},
|
|
649
|
+
});
|
|
650
|
+
/**
|
|
651
|
+
* Abstract aggregate family marker over the common transactional entity shell.
|
|
652
|
+
*
|
|
653
|
+
* This class intentionally adds only stable family identity. It does not add
|
|
654
|
+
* command dispatch, snapshots, repositories, idempotency guards, or handler
|
|
655
|
+
* invocation. Repository-bound diagnostic event-history reads are declared
|
|
656
|
+
* below for the Aggregate family.
|
|
657
|
+
*/
|
|
658
|
+
export class Aggregate extends TransactionalEntity {
|
|
659
|
+
/**
|
|
660
|
+
* Creates an aggregate family shell from caller-provided state and metadata inputs.
|
|
661
|
+
*
|
|
662
|
+
* @param options Identity, schema, state, version, and lifecycle inputs.
|
|
663
|
+
*/
|
|
664
|
+
constructor(options) {
|
|
665
|
+
super(options);
|
|
666
|
+
EntityFamilies.mark(this, "aggregate");
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Reads retained diagnostic events in descending producer-version order.
|
|
670
|
+
*
|
|
671
|
+
* @param depth Maximum number of retained events to read.
|
|
672
|
+
* @returns Retained events in descending producer-version order.
|
|
673
|
+
*/
|
|
674
|
+
eventHistoryBackward(depth) {
|
|
675
|
+
return entityHistoryAccess.events(this, depth);
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Tests retained diagnostic events in descending producer-version order.
|
|
679
|
+
*
|
|
680
|
+
* @param depth Maximum number of retained events to inspect.
|
|
681
|
+
* @param predicate Tests each retained event.
|
|
682
|
+
* @returns `true` when a retained event matches the predicate.
|
|
683
|
+
*/
|
|
684
|
+
async eventHistoryContains(depth, predicate) {
|
|
685
|
+
return (await this.eventHistoryBackward(depth)).some(predicate);
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Gets application-managed diagnostic event-history retention.
|
|
689
|
+
*
|
|
690
|
+
* @returns Event-history storage for this entity.
|
|
691
|
+
*/
|
|
692
|
+
eventStorage() {
|
|
693
|
+
return entityHistoryAccess.eventMaintenance(this);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Abstract projection family marker over the common transactional entity shell.
|
|
698
|
+
*
|
|
699
|
+
* This class intentionally adds only stable family identity. It does not add
|
|
700
|
+
* event subscriptions, event playing, repositories, version columns, query
|
|
701
|
+
* clients, or handler invocation.
|
|
702
|
+
*/
|
|
703
|
+
export class Projection extends TransactionalEntity {
|
|
704
|
+
/**
|
|
705
|
+
* Creates a projection family shell from caller-provided state and metadata inputs.
|
|
706
|
+
*
|
|
707
|
+
* @param options Identity, schema, state, version, and lifecycle inputs.
|
|
708
|
+
*/
|
|
709
|
+
constructor(options) {
|
|
710
|
+
super(options);
|
|
711
|
+
EntityFamilies.mark(this, "projection");
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Abstract process manager family marker over the common transactional entity shell.
|
|
716
|
+
*
|
|
717
|
+
* This class adds a protected, handler-scoped, read-only Projection query
|
|
718
|
+
* capability. It does not add command posting, repositories, bounded-context
|
|
719
|
+
* injection, or handler invocation.
|
|
720
|
+
*/
|
|
721
|
+
export class ProcessManager extends TransactionalEntity {
|
|
722
|
+
/**
|
|
723
|
+
* Creates a process manager family shell from caller-provided state and metadata inputs.
|
|
724
|
+
*
|
|
725
|
+
* @param options Identity, schema, state, version, and lifecycle inputs.
|
|
726
|
+
*/
|
|
727
|
+
constructor(options) {
|
|
728
|
+
super(options);
|
|
729
|
+
EntityFamilies.mark(this, "process-manager");
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Reads retained diagnostic events when this repository enabled Process Manager event history.
|
|
733
|
+
*
|
|
734
|
+
* @param depth Maximum number of retained events to read.
|
|
735
|
+
* @returns Retained events in descending producer-version order.
|
|
736
|
+
*/
|
|
737
|
+
eventHistoryBackward(depth) {
|
|
738
|
+
return entityHistoryAccess.events(this, depth);
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Tests retained diagnostic events when this repository enabled Process Manager event history.
|
|
742
|
+
*
|
|
743
|
+
* @param depth Maximum number of retained events to inspect.
|
|
744
|
+
* @param predicate Tests each retained event.
|
|
745
|
+
* @returns `true` when a retained event matches the predicate.
|
|
746
|
+
*/
|
|
747
|
+
async eventHistoryContains(depth, predicate) {
|
|
748
|
+
return (await this.eventHistoryBackward(depth)).some(predicate);
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Gets application-managed Process Manager diagnostic event-history retention.
|
|
752
|
+
*
|
|
753
|
+
* @returns Event-history storage for this Process Manager.
|
|
754
|
+
*/
|
|
755
|
+
eventStorage() {
|
|
756
|
+
return entityHistoryAccess.eventMaintenance(this);
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Starts a typed, eventually consistent read-side query during handler execution.
|
|
760
|
+
*
|
|
761
|
+
* The repository binds this capability only while it invokes a Process Manager
|
|
762
|
+
* handler. Reads use that signal's actor and tenant; they cannot mutate state
|
|
763
|
+
* or select a different tenant.
|
|
764
|
+
*
|
|
765
|
+
* @param schema Projection state schema to query.
|
|
766
|
+
* @param columns Generated descriptor-backed columns for `schema`.
|
|
767
|
+
* @returns A read-only Entity query.
|
|
768
|
+
*/
|
|
769
|
+
select(schema, columns) {
|
|
770
|
+
const capability = processManagerQueryAccess.require(this);
|
|
771
|
+
return new ProcessManagerQuery(this, schema, EntityQuery.select({ schema, columns, context: capability.actorContext }));
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Marks immutable entity families.
|
|
776
|
+
*/
|
|
777
|
+
const EntityFamilies = Object.freeze({
|
|
778
|
+
mark(entity, family) {
|
|
779
|
+
Object.defineProperty(entity, "entityFamily", {
|
|
780
|
+
configurable: false,
|
|
781
|
+
enumerable: false,
|
|
782
|
+
value: family,
|
|
783
|
+
writable: false,
|
|
784
|
+
});
|
|
785
|
+
},
|
|
786
|
+
});
|
|
787
|
+
/**
|
|
788
|
+
* Creates entity-state snapshots and compares state bytes.
|
|
789
|
+
*/
|
|
790
|
+
const EntitySnapshots = Object.freeze({
|
|
791
|
+
clone(schema, state) {
|
|
792
|
+
return fromBinary(schema, toBinary(schema, state, { writeUnknownFields: false }));
|
|
793
|
+
},
|
|
794
|
+
equal(schema, previous, next) {
|
|
795
|
+
const previousBinary = toBinary(schema, previous, { writeUnknownFields: false });
|
|
796
|
+
const nextBinary = toBinary(schema, next, { writeUnknownFields: false });
|
|
797
|
+
return (previousBinary.byteLength === nextBinary.byteLength &&
|
|
798
|
+
previousBinary.every((byte, index) => byte === nextBinary[index]));
|
|
799
|
+
},
|
|
800
|
+
});
|
|
801
|
+
/**
|
|
802
|
+
* Creates immutable transaction-result snapshots.
|
|
803
|
+
*/
|
|
804
|
+
const EntityCommits = Object.freeze({
|
|
805
|
+
clone(result) {
|
|
806
|
+
if (result.status === "accepted") {
|
|
807
|
+
return {
|
|
808
|
+
...result,
|
|
809
|
+
version: {
|
|
810
|
+
previous: EntityVersions.clone(result.version.previous),
|
|
811
|
+
committed: EntityVersions.clone(result.version.committed),
|
|
812
|
+
},
|
|
813
|
+
lifecycle: { archived: result.lifecycle.archived, deleted: result.lifecycle.deleted },
|
|
814
|
+
validation: this.validation(result.validation),
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
return {
|
|
818
|
+
...result,
|
|
819
|
+
version: {
|
|
820
|
+
previous: EntityVersions.clone(result.version.previous),
|
|
821
|
+
draft: EntityVersions.clone(result.version.draft),
|
|
822
|
+
},
|
|
823
|
+
lifecycle: { archived: result.lifecycle.archived, deleted: result.lifecycle.deleted },
|
|
824
|
+
validation: this.validation(result.validation),
|
|
825
|
+
};
|
|
826
|
+
},
|
|
827
|
+
validation(validation) {
|
|
828
|
+
if (validation.valid) {
|
|
829
|
+
return { valid: true, violations: [], error: undefined };
|
|
830
|
+
}
|
|
831
|
+
const error = clone(ValidationErrorSchema, validation.error);
|
|
832
|
+
return {
|
|
833
|
+
valid: false,
|
|
834
|
+
violations: error.constraintViolation,
|
|
835
|
+
error,
|
|
836
|
+
};
|
|
837
|
+
},
|
|
838
|
+
});
|
|
839
|
+
const maxVersionMetadataDepth = 1_000;
|
|
840
|
+
/**
|
|
841
|
+
* Validates and clones caller-provided plain version metadata.
|
|
842
|
+
*/
|
|
843
|
+
const EntityVersions = Object.freeze({
|
|
844
|
+
clone(version) {
|
|
845
|
+
return this.value(version, "$", new WeakSet(), 0);
|
|
846
|
+
},
|
|
847
|
+
value(value, path, stack, depth) {
|
|
848
|
+
if (depth > maxVersionMetadataDepth) {
|
|
849
|
+
throw this.error(path, "excessive nesting depth");
|
|
850
|
+
}
|
|
851
|
+
if (value === null) {
|
|
852
|
+
return value;
|
|
853
|
+
}
|
|
854
|
+
switch (typeof value) {
|
|
855
|
+
case "string":
|
|
856
|
+
case "number":
|
|
857
|
+
case "boolean":
|
|
858
|
+
case "bigint":
|
|
859
|
+
case "symbol":
|
|
860
|
+
case "undefined":
|
|
861
|
+
return value;
|
|
862
|
+
case "function":
|
|
863
|
+
throw this.error(path, "function");
|
|
864
|
+
case "object":
|
|
865
|
+
return this.object(value, path, stack, depth);
|
|
866
|
+
}
|
|
867
|
+
},
|
|
868
|
+
object(value, path, stack, depth) {
|
|
869
|
+
if (isProxy(value))
|
|
870
|
+
throw this.error(path, "Proxy");
|
|
871
|
+
if (ArrayBuffer.isView(value))
|
|
872
|
+
throw this.error(path, this.kind(value));
|
|
873
|
+
if (value instanceof ArrayBuffer || this.isSharedBuffer(value)) {
|
|
874
|
+
throw this.error(path, this.kind(value));
|
|
875
|
+
}
|
|
876
|
+
if (stack.has(value))
|
|
877
|
+
throw this.error(path, "cyclic object");
|
|
878
|
+
stack.add(value);
|
|
879
|
+
try {
|
|
880
|
+
if (Array.isArray(value))
|
|
881
|
+
return this.array(value, path, stack, depth);
|
|
882
|
+
if (!this.isPlainObject(value))
|
|
883
|
+
throw this.error(path, this.kind(value));
|
|
884
|
+
const clone = Object.create(this.prototype(value));
|
|
885
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
886
|
+
const [symbolKey] = Object.getOwnPropertySymbols(descriptors);
|
|
887
|
+
if (symbolKey !== undefined) {
|
|
888
|
+
throw this.error(`${path}[${String(symbolKey)}]`, "symbol-keyed property");
|
|
889
|
+
}
|
|
890
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
891
|
+
const childPath = `${path}.${key}`;
|
|
892
|
+
if (!descriptor.enumerable)
|
|
893
|
+
throw this.error(childPath, "non-enumerable property");
|
|
894
|
+
if (!("value" in descriptor))
|
|
895
|
+
throw this.error(childPath, "accessor property");
|
|
896
|
+
Object.defineProperty(clone, key, {
|
|
897
|
+
configurable: true,
|
|
898
|
+
enumerable: true,
|
|
899
|
+
value: this.value(descriptor.value, childPath, stack, depth + 1),
|
|
900
|
+
writable: true,
|
|
901
|
+
});
|
|
902
|
+
}
|
|
903
|
+
return clone;
|
|
904
|
+
}
|
|
905
|
+
finally {
|
|
906
|
+
stack.delete(value);
|
|
907
|
+
}
|
|
908
|
+
},
|
|
909
|
+
array(value, path, stack, depth) {
|
|
910
|
+
if (this.prototype(value) !== Array.prototype)
|
|
911
|
+
throw this.error(path, "Array");
|
|
912
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
913
|
+
const [symbolKey] = Object.getOwnPropertySymbols(descriptors);
|
|
914
|
+
if (symbolKey !== undefined) {
|
|
915
|
+
throw this.error(`${path}[${String(symbolKey)}]`, "symbol-keyed property");
|
|
916
|
+
}
|
|
917
|
+
const lengthDescriptor = descriptors.length;
|
|
918
|
+
if (lengthDescriptor === undefined || !("value" in lengthDescriptor)) {
|
|
919
|
+
throw this.error(path, "array without data length");
|
|
920
|
+
}
|
|
921
|
+
const length = lengthDescriptor.value;
|
|
922
|
+
const clone = new Array(length);
|
|
923
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
924
|
+
if (key === "length")
|
|
925
|
+
continue;
|
|
926
|
+
if (!this.isArrayKey(key, length))
|
|
927
|
+
throw this.error(`${path}.${key}`, "custom array property");
|
|
928
|
+
if (!descriptor.enumerable)
|
|
929
|
+
throw this.error(`${path}[${key}]`, "non-enumerable property");
|
|
930
|
+
if (!("value" in descriptor))
|
|
931
|
+
throw this.error(`${path}[${key}]`, "accessor property");
|
|
932
|
+
}
|
|
933
|
+
for (let index = 0; index < length; index += 1) {
|
|
934
|
+
const key = String(index);
|
|
935
|
+
const descriptor = descriptors[key];
|
|
936
|
+
if (descriptor === undefined || !("value" in descriptor)) {
|
|
937
|
+
throw this.error(`${path}[${key}]`, "sparse array element");
|
|
938
|
+
}
|
|
939
|
+
Object.defineProperty(clone, index, {
|
|
940
|
+
configurable: true,
|
|
941
|
+
enumerable: true,
|
|
942
|
+
value: this.value(descriptor.value, `${path}[${key}]`, stack, depth + 1),
|
|
943
|
+
writable: true,
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
return clone;
|
|
947
|
+
},
|
|
948
|
+
isArrayKey(key, length) {
|
|
949
|
+
const index = Number(key);
|
|
950
|
+
return Number.isInteger(index) && index >= 0 && index < length && String(index) === key;
|
|
951
|
+
},
|
|
952
|
+
isPlainObject(value) {
|
|
953
|
+
const prototype = this.prototype(value);
|
|
954
|
+
return prototype === Object.prototype || prototype === null;
|
|
955
|
+
},
|
|
956
|
+
prototype(value) {
|
|
957
|
+
return Object.getPrototypeOf(value);
|
|
958
|
+
},
|
|
959
|
+
kind(value) {
|
|
960
|
+
if (value instanceof Date)
|
|
961
|
+
return "Date";
|
|
962
|
+
if (value instanceof Map)
|
|
963
|
+
return "Map";
|
|
964
|
+
if (value instanceof Set)
|
|
965
|
+
return "Set";
|
|
966
|
+
if (ArrayBuffer.isView(value))
|
|
967
|
+
return "typed array";
|
|
968
|
+
if (value instanceof ArrayBuffer)
|
|
969
|
+
return "ArrayBuffer";
|
|
970
|
+
if (this.isSharedBuffer(value))
|
|
971
|
+
return "SharedArrayBuffer";
|
|
972
|
+
return "object";
|
|
973
|
+
},
|
|
974
|
+
isSharedBuffer(value) {
|
|
975
|
+
return typeof SharedArrayBuffer !== "undefined" && value instanceof SharedArrayBuffer;
|
|
976
|
+
},
|
|
977
|
+
error(path, kind) {
|
|
978
|
+
return new TypeError(`Entity version metadata must be plain snapshot data; ${path} contains ${kind}.`);
|
|
979
|
+
},
|
|
980
|
+
});
|
|
981
|
+
//# sourceMappingURL=entity.js.map
|