@zlink-systems/framework 0.30.1 → 0.30.2
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/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
- package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
- package/dist/contracts/Common/encoded-payload-storage.js +5 -2
- package/dist/contracts/Configuration/Builders.d.ts +1 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
- package/dist/contracts/Locations/Rows.d.ts +2 -0
- package/dist/contracts/Spots/Contracts.d.ts +4 -0
- package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
- package/dist/runtime/abort.d.ts +5 -0
- package/dist/runtime/abort.js +10 -0
- package/dist/runtime/actors/actor-authority-publication.js +3 -2
- package/dist/runtime/actors/actor-client.d.ts +0 -1
- package/dist/runtime/actors/actor-client.js +38 -45
- package/dist/runtime/actors/actor-context.d.ts +2 -0
- package/dist/runtime/actors/actor-context.js +46 -9
- package/dist/runtime/actors/actor-handoff.d.ts +7 -3
- package/dist/runtime/actors/actor-handoff.js +212 -88
- package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
- package/dist/runtime/actors/actor-local-native-join.js +4 -0
- package/dist/runtime/actors/actor-mailbox.js +27 -1
- package/dist/runtime/actors/actor-remote-joiner.js +3 -1
- package/dist/runtime/actors/actor-reply.d.ts +4 -0
- package/dist/runtime/actors/actor-reply.js +29 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-state.js +2 -20
- package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
- package/dist/runtime/actors/index.d.ts +6 -2
- package/dist/runtime/actors/index.js +37 -21
- package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
- package/dist/runtime/actors/session-disconnected-wire.js +48 -0
- package/dist/runtime/admission.d.ts +9 -1
- package/dist/runtime/admission.js +55 -32
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
- package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
- package/dist/runtime/application-jobs/contracts.d.ts +2 -0
- package/dist/runtime/backend/contracts/index.d.ts +19 -3
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
- package/dist/runtime/backend/mesh-completion-table.js +5 -0
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
- package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
- package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
- package/dist/runtime/channels/channel-clients.d.ts +1 -0
- package/dist/runtime/channels/channel-clients.js +20 -5
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
- package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
- package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
- package/dist/runtime/channels/channel-dispatchers.js +44 -37
- package/dist/runtime/channels/channel-envelope.d.ts +1 -0
- package/dist/runtime/channels/channel-envelope.js +74 -31
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
- package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
- package/dist/runtime/channels/channel-runtime-manager.js +4 -4
- package/dist/runtime/channels/channel-transports.d.ts +0 -1
- package/dist/runtime/channels/channel-transports.js +35 -33
- package/dist/runtime/channels/client-server-location-runtime.js +5 -4
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/fanout-location-runtime.js +3 -3
- package/dist/runtime/diagnostics/flow-context.js +19 -7
- package/dist/runtime/diagnostics/index.js +4 -9
- package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
- package/dist/runtime/diagnostics/message-flow.js +35 -5
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
- package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
- package/dist/runtime/execution/index.d.ts +4 -2
- package/dist/runtime/execution/index.js +33 -10
- package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
- package/dist/runtime/execution/serial-execution-queue.js +21 -2
- package/dist/runtime/execution/state-lane.d.ts +2 -0
- package/dist/runtime/execution/state-lane.js +5 -0
- package/dist/runtime/foundation/operation-registry.d.ts +25 -1
- package/dist/runtime/foundation/operation-registry.js +86 -18
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
- package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
- package/dist/runtime/foundation/service-liveness-registry.js +38 -0
- package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
- package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
- package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
- package/dist/runtime/foundation/service-stateful-registry.js +24 -26
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
- package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
- package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
- package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
- package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
- package/dist/runtime/host/actor-packet-relay.js +59 -72
- package/dist/runtime/host/actor-placement-coordinator.js +25 -8
- package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
- package/dist/runtime/host/actor-transfer-runtime.js +85 -331
- package/dist/runtime/host/application-job-queue.d.ts +24 -3
- package/dist/runtime/host/application-job-queue.js +28 -41
- package/dist/runtime/host/index.d.ts +5 -1
- package/dist/runtime/host/index.js +171 -97
- package/dist/runtime/host/location-runtime-owner.js +2 -6
- package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
- package/dist/runtime/host/mesh-router-resolver.js +14 -6
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
- package/dist/runtime/host/remote-bound-session-relay.js +71 -190
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
- package/dist/runtime/host/route-mesh-runtime.js +5 -3
- package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
- package/dist/runtime/host/runtime-shutdown.js +3 -2
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
- package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
- package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
- package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
- package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
- package/dist/runtime/locations/auto-connect-loop.js +22 -14
- package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
- package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
- package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
- package/dist/runtime/locations/descriptor-publication.js +11 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
- package/dist/runtime/locations/in-memory-authority-store.js +56 -19
- package/dist/runtime/locations/in-memory-location-store.js +1 -10
- package/dist/runtime/locations/index.d.ts +1 -0
- package/dist/runtime/locations/index.js +1 -0
- package/dist/runtime/locations/lease-tracker.js +1 -6
- package/dist/runtime/locations/location-store-repository.d.ts +51 -1
- package/dist/runtime/locations/location-store-repository.js +363 -139
- package/dist/runtime/locations/relocation-blob.d.ts +18 -1
- package/dist/runtime/locations/relocation-blob.js +52 -1
- package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
- package/dist/runtime/locations/request-source-resolver.js +80 -0
- package/dist/runtime/locations/resolvers.js +1 -1
- package/dist/runtime/locations/runtime.d.ts +6 -2
- package/dist/runtime/locations/runtime.js +37 -30
- package/dist/runtime/messaging/payload-codec.d.ts +7 -1
- package/dist/runtime/messaging/payload-codec.js +7 -6
- package/dist/runtime/messaging/request-result.js +29 -26
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
- package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
- package/dist/runtime/spots/index.d.ts +18 -11
- package/dist/runtime/spots/index.js +234 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +21 -11
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +7 -7
- package/dist/runtime/spots/spot-activation.d.ts +6 -3
- package/dist/runtime/spots/spot-activation.js +123 -44
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
- package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-membership.js +0 -8
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
- package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
- package/dist/runtime/spots/spot-entry-activation.js +14 -9
- package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
- package/dist/runtime/spots/spot-handler-registry.js +6 -2
- package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
- package/dist/runtime/spots/spot-manager-public.js +2 -2
- package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
- package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
- package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
- package/dist/runtime/spots/spot-outbound.js +3 -3
- package/dist/runtime/spots/spot-remote-codec.js +5 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
- package/dist/runtime/spots/spot-serial-executor.js +61 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
- package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
- package/dist/runtime/spots/spot-timer.d.ts +57 -5
- package/dist/runtime/spots/spot-timer.js +287 -103
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
- package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
- package/dist/runtime/streams/bound-session-service.d.ts +1 -1
- package/dist/runtime/streams/bound-session-service.js +6 -11
- package/dist/runtime/streams/index.d.ts +3 -2
- package/dist/runtime/streams/index.js +6 -4
- package/dist/runtime/streams/managed-stream.js +3 -2
- package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
- package/dist/runtime/streams/session-actor-coordinator.js +15 -32
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
- package/dist/runtime/streams/stream-session-runtime.js +1 -4
- package/dist/runtime/workers/index.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
- package/src/contracts/Common/encoded-payload-storage.ts +6 -3
- package/src/contracts/Configuration/Builders.ts +4 -1
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
- package/src/contracts/Locations/Rows.ts +2 -0
- package/src/contracts/Spots/Contracts.ts +8 -0
- package/src/contracts/Spots/ZLinkSpot.ts +3 -3
- package/src/runtime/abort.ts +12 -0
- package/src/runtime/actors/actor-authority-publication.ts +3 -2
- package/src/runtime/actors/actor-client.ts +61 -70
- package/src/runtime/actors/actor-context.ts +49 -9
- package/src/runtime/actors/actor-handoff.ts +282 -106
- package/src/runtime/actors/actor-join-relocation.ts +2 -0
- package/src/runtime/actors/actor-local-native-join.ts +4 -0
- package/src/runtime/actors/actor-mailbox.ts +40 -2
- package/src/runtime/actors/actor-remote-joiner.ts +6 -1
- package/src/runtime/actors/actor-reply.ts +42 -0
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
- package/src/runtime/actors/actor-runtime-state.ts +2 -20
- package/src/runtime/actors/actor-source-transfer.ts +1 -34
- package/src/runtime/actors/index.ts +41 -27
- package/src/runtime/actors/session-disconnected-wire.ts +66 -0
- package/src/runtime/admission.ts +69 -34
- package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
- package/src/runtime/application-jobs/contracts.ts +2 -0
- package/src/runtime/backend/contracts/index.ts +39 -4
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
- package/src/runtime/backend/mesh-completion-table.ts +4 -0
- package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
- package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
- package/src/runtime/channels/channel-clients.ts +49 -24
- package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
- package/src/runtime/channels/channel-dispatchers.ts +116 -72
- package/src/runtime/channels/channel-envelope.ts +105 -36
- package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
- package/src/runtime/channels/channel-runtime-manager.ts +12 -5
- package/src/runtime/channels/channel-transports.ts +49 -58
- package/src/runtime/channels/client-server-location-runtime.ts +11 -10
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
- package/src/runtime/channels/fanout-location-runtime.ts +17 -9
- package/src/runtime/diagnostics/flow-context.ts +20 -7
- package/src/runtime/diagnostics/index.ts +1 -7
- package/src/runtime/diagnostics/message-flow.ts +47 -9
- package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
- package/src/runtime/execution/index.ts +40 -14
- package/src/runtime/execution/serial-execution-queue.ts +31 -4
- package/src/runtime/execution/state-lane.ts +7 -0
- package/src/runtime/foundation/operation-registry.ts +98 -20
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
- package/src/runtime/foundation/service-liveness-registry.ts +39 -0
- package/src/runtime/foundation/service-mailbox.ts +8 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
- package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
- package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
- package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
- package/src/runtime/foundation/service-stateful-registry.ts +38 -35
- package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
- package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
- package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
- package/src/runtime/host/actor-packet-relay.ts +113 -94
- package/src/runtime/host/actor-placement-coordinator.ts +31 -8
- package/src/runtime/host/actor-transfer-runtime.ts +104 -430
- package/src/runtime/host/application-job-queue.ts +29 -44
- package/src/runtime/host/index.ts +286 -129
- package/src/runtime/host/location-runtime-owner.ts +2 -6
- package/src/runtime/host/mesh-router-resolver.ts +13 -5
- package/src/runtime/host/remote-bound-session-relay.ts +86 -248
- package/src/runtime/host/route-mesh-runtime.ts +11 -5
- package/src/runtime/host/runtime-shutdown.ts +15 -4
- package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
- package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
- package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
- package/src/runtime/locations/auto-connect-loop.ts +22 -14
- package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
- package/src/runtime/locations/auto-connect-types.ts +0 -1
- package/src/runtime/locations/descriptor-publication.ts +7 -0
- package/src/runtime/locations/domain-store-contract.ts +5 -0
- package/src/runtime/locations/in-memory-authority-store.ts +85 -23
- package/src/runtime/locations/in-memory-location-store.ts +1 -12
- package/src/runtime/locations/index.ts +1 -0
- package/src/runtime/locations/lease-tracker.ts +2 -9
- package/src/runtime/locations/location-store-repository.ts +628 -152
- package/src/runtime/locations/relocation-blob.ts +75 -1
- package/src/runtime/locations/request-source-resolver.ts +138 -0
- package/src/runtime/locations/resolvers.ts +2 -2
- package/src/runtime/locations/runtime.ts +70 -40
- package/src/runtime/messaging/payload-codec.ts +8 -11
- package/src/runtime/messaging/request-result.ts +33 -29
- package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
- package/src/runtime/spots/index.ts +375 -281
- package/src/runtime/spots/spot-activation-registry.ts +25 -13
- package/src/runtime/spots/spot-activation-state.ts +12 -19
- package/src/runtime/spots/spot-activation.ts +170 -86
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
- package/src/runtime/spots/spot-actor-membership.ts +0 -15
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
- package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
- package/src/runtime/spots/spot-entry-activation.ts +24 -19
- package/src/runtime/spots/spot-handler-registry.ts +15 -4
- package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
- package/src/runtime/spots/spot-manager-public.ts +2 -2
- package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
- package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
- package/src/runtime/spots/spot-outbound.ts +3 -3
- package/src/runtime/spots/spot-remote-codec.ts +9 -2
- package/src/runtime/spots/spot-runtime-ports.ts +0 -1
- package/src/runtime/spots/spot-serial-executor.ts +97 -25
- package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
- package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
- package/src/runtime/spots/spot-timer.ts +413 -157
- package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
- package/src/runtime/streams/bound-session-service.ts +7 -10
- package/src/runtime/streams/index.ts +12 -6
- package/src/runtime/streams/managed-stream.ts +4 -2
- package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
- package/src/runtime/streams/session-actor-coordinator.ts +39 -88
- package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
- package/src/runtime/streams/stream-session-runtime.ts +1 -5
- package/src/runtime/workers/index.ts +1 -1
|
@@ -14,6 +14,9 @@ exports.encodeApplicationPayload = encodeApplicationPayload;
|
|
|
14
14
|
exports.encodeMultipartApplicationPayload = encodeMultipartApplicationPayload;
|
|
15
15
|
exports.decodeApplicationPayload = decodeApplicationPayload;
|
|
16
16
|
exports.decodeApplicationPayloadView = decodeApplicationPayloadView;
|
|
17
|
+
exports.decodeMultipartApplicationPayloadView = decodeMultipartApplicationPayloadView;
|
|
18
|
+
exports.decodeMultipartApplicationParts = decodeMultipartApplicationParts;
|
|
19
|
+
exports.decodeMultipartParts = decodeMultipartParts;
|
|
17
20
|
exports.validateApplicationPayloadFrame = validateApplicationPayloadFrame;
|
|
18
21
|
exports.encodeRouteMeshAdmission = encodeRouteMeshAdmission;
|
|
19
22
|
exports.decodeRouteMeshAdmission = decodeRouteMeshAdmission;
|
|
@@ -37,6 +40,10 @@ exports.APPLICATION_PAYLOAD_MINIMUM_FIELD_BYTES = 1 +
|
|
|
37
40
|
APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES;
|
|
38
41
|
const MAX_U32 = stream_wire_1.UINT32_MAX;
|
|
39
42
|
const MAX_U64 = stream_wire_1.UINT64_MAX;
|
|
43
|
+
// The framework multipart frame always carries these two schema constants;
|
|
44
|
+
// decoding compares their bytes in place instead of decoding text.
|
|
45
|
+
const MULTIPART_PACKET_NAME_BYTES = Buffer.from(service_wire_constants_generated_1.SERVICE_FRAMEWORK_MULTIPART_PACKET_NAME);
|
|
46
|
+
const MULTIPART_CONTENT_TYPE_BYTES = Buffer.from(service_wire_constants_generated_1.SERVICE_FRAMEWORK_MULTIPART_CONTENT_TYPE);
|
|
40
47
|
exports.M6A_SERVICE_WIRE_MAGIC = service_wire_constants_generated_1.SERVICE_WIRE_MAGIC;
|
|
41
48
|
exports.M6A_SERVICE_WIRE_MAJOR = service_wire_constants_generated_1.SERVICE_WIRE_MAJOR;
|
|
42
49
|
exports.M6A_SERVICE_WIRE_REQUIRED_CAPABILITY = service_wire_constants_generated_1.SERVICE_WIRE_REQUIRED_CAPABILITY;
|
|
@@ -52,7 +59,7 @@ function encodeNodeSendHeader() {
|
|
|
52
59
|
return prefix(exports.M6aServiceWireCommand.nodeSend);
|
|
53
60
|
}
|
|
54
61
|
function encodeNodeRequestHeader(correlation) {
|
|
55
|
-
return withU64(
|
|
62
|
+
return withU64(exports.M6aServiceWireCommand.nodeRequest, correlation, 0);
|
|
56
63
|
}
|
|
57
64
|
function decodeNodeRequestHeader(frame, header = decodeHeader(frame)) {
|
|
58
65
|
if (header.command !== exports.M6aServiceWireCommand.nodeRequest ||
|
|
@@ -63,7 +70,10 @@ function decodeNodeRequestHeader(frame, header = decodeHeader(frame)) {
|
|
|
63
70
|
return readNonZeroU64(asBuffer(frame), PREFIX_SIZE, 'correlation');
|
|
64
71
|
}
|
|
65
72
|
function encodeChannelSendHeader(channelName) {
|
|
66
|
-
|
|
73
|
+
const length = channelNameLength(channelName);
|
|
74
|
+
const result = frame(exports.M6aServiceWireCommand.channelSend, 1 + length);
|
|
75
|
+
writeText8(result, PREFIX_SIZE, channelName, length);
|
|
76
|
+
return result;
|
|
67
77
|
}
|
|
68
78
|
function decodeChannelSendHeader(frame, header = decodeHeader(frame)) {
|
|
69
79
|
if (header.command !== exports.M6aServiceWireCommand.channelSend || header.flags !== 0) {
|
|
@@ -75,7 +85,13 @@ function decodeChannelSendHeader(frame, header = decodeHeader(frame)) {
|
|
|
75
85
|
return channelName;
|
|
76
86
|
}
|
|
77
87
|
function encodeChannelRequestHeader(correlation, channelName) {
|
|
78
|
-
|
|
88
|
+
const length = channelNameLength(channelName);
|
|
89
|
+
const result = withU64(exports.M6aServiceWireCommand.channelRequest, correlation, 1 + length);
|
|
90
|
+
writeText8(result, PREFIX_SIZE + 8, channelName, length);
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
function channelNameLength(channelName) {
|
|
94
|
+
return (0, service_wire_binary_primitives_1.canonicalServiceWireTextLength)(channelName, 'channelName', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
|
|
79
95
|
}
|
|
80
96
|
function decodeChannelRequestHeader(frame, header = decodeHeader(frame)) {
|
|
81
97
|
if (header.command !== exports.M6aServiceWireCommand.channelRequest || header.flags !== 0) {
|
|
@@ -87,7 +103,7 @@ function decodeChannelRequestHeader(frame, header = decodeHeader(frame)) {
|
|
|
87
103
|
reader.end();
|
|
88
104
|
return { correlation, channelName };
|
|
89
105
|
}
|
|
90
|
-
function encodeReplyHeader(correlation, terminalResult = 0, failureCode = 0, tail
|
|
106
|
+
function encodeReplyHeader(correlation, terminalResult = 0, failureCode = 0, tail) {
|
|
91
107
|
validateReplyFields(correlation, terminalResult, failureCode);
|
|
92
108
|
// service-wire-v1.schema.json: reply(20).tail -> `request-specific-tail`,
|
|
93
109
|
// a conditional-union with NO `bodyLengthType`, so the selected case's
|
|
@@ -95,12 +111,12 @@ function encodeReplyHeader(correlation, terminalResult = 0, failureCode = 0, tai
|
|
|
95
111
|
// length on the wire; an empty tail yields exactly 21 bytes. (Contrast
|
|
96
112
|
// `actor-join-reply-tail`, which does declare `bodyLengthType: u16` and
|
|
97
113
|
// therefore carries its own inner length prefix.)
|
|
98
|
-
const result =
|
|
99
|
-
prefix(exports.M6aServiceWireCommand.reply).copy(result);
|
|
114
|
+
const result = frame(exports.M6aServiceWireCommand.reply, 16 + (tail?.byteLength ?? 0));
|
|
100
115
|
result.writeBigUInt64BE(correlation, PREFIX_SIZE);
|
|
101
116
|
result.writeUInt32BE(terminalResult, PREFIX_SIZE + 8);
|
|
102
117
|
result.writeUInt32BE(failureCode, PREFIX_SIZE + 12);
|
|
103
|
-
|
|
118
|
+
if (tail !== undefined)
|
|
119
|
+
result.set(tail, PREFIX_SIZE + 16);
|
|
104
120
|
return result;
|
|
105
121
|
}
|
|
106
122
|
function decodeReplyHeader(frame) {
|
|
@@ -118,7 +134,8 @@ function decodeReplyHeader(frame) {
|
|
|
118
134
|
correlation: bytes.readBigUInt64BE(PREFIX_SIZE),
|
|
119
135
|
terminalResult: bytes.readUInt32BE(PREFIX_SIZE + 8),
|
|
120
136
|
failureCode: bytes.readUInt32BE(PREFIX_SIZE + 12),
|
|
121
|
-
|
|
137
|
+
// A view of the frame: the caller validates the tail before the frame is released.
|
|
138
|
+
tail: bytes.subarray(PREFIX_SIZE + 16)
|
|
122
139
|
};
|
|
123
140
|
validateReplyFields(result.correlation, result.terminalResult, result.failureCode);
|
|
124
141
|
return result;
|
|
@@ -159,14 +176,11 @@ function encodeMultipartApplicationPayload(parts, packetName, contentType) {
|
|
|
159
176
|
return result;
|
|
160
177
|
}
|
|
161
178
|
function allocateApplicationPayload(packetName, contentType, payloadLength) {
|
|
162
|
-
const
|
|
163
|
-
const
|
|
179
|
+
const packetNameLength = (0, service_wire_binary_primitives_1.canonicalServiceWireTextLength)(packetName, 'packetName', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
|
|
180
|
+
const contentTypeLength = (0, service_wire_binary_primitives_1.canonicalServiceWireTextLength)(contentType, 'contentType', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
|
|
164
181
|
if (payloadLength > MAX_U32)
|
|
165
182
|
fail('Application payload exceeds u32.');
|
|
166
|
-
const frameLength = exports.APPLICATION_PAYLOAD_MINIMUM_FIELD_BYTES +
|
|
167
|
-
packetNameBytes.byteLength +
|
|
168
|
-
contentTypeBytes.byteLength +
|
|
169
|
-
payloadLength;
|
|
183
|
+
const frameLength = exports.APPLICATION_PAYLOAD_MINIMUM_FIELD_BYTES + packetNameLength + contentTypeLength + payloadLength;
|
|
170
184
|
const prefixLength = 1 + APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES;
|
|
171
185
|
const bodyLength = frameLength - prefixLength;
|
|
172
186
|
if (bodyLength > MAX_U32)
|
|
@@ -174,13 +188,8 @@ function allocateApplicationPayload(packetName, contentType, payloadLength) {
|
|
|
174
188
|
const result = Buffer.alloc(frameLength);
|
|
175
189
|
result[0] = exports.APPLICATION_PAYLOAD_VERSION;
|
|
176
190
|
result.writeUInt32BE(bodyLength, 1);
|
|
177
|
-
let offset = prefixLength;
|
|
178
|
-
|
|
179
|
-
result.set(packetNameBytes, offset);
|
|
180
|
-
offset += packetNameBytes.byteLength;
|
|
181
|
-
result[offset++] = contentTypeBytes.byteLength;
|
|
182
|
-
result.set(contentTypeBytes, offset);
|
|
183
|
-
offset += contentTypeBytes.byteLength;
|
|
191
|
+
let offset = writeText8(result, prefixLength, packetName, packetNameLength);
|
|
192
|
+
offset = writeText8(result, offset, contentType, contentTypeLength);
|
|
184
193
|
result.writeUInt32BE(payloadLength, offset);
|
|
185
194
|
return result;
|
|
186
195
|
}
|
|
@@ -197,20 +206,111 @@ function decodeApplicationPayload(frame) {
|
|
|
197
206
|
* they must hand the multipart bytes to another runtime-owned queue.
|
|
198
207
|
*/
|
|
199
208
|
function decodeApplicationPayloadView(frame) {
|
|
200
|
-
const reader =
|
|
201
|
-
if (reader.u8('version') !== exports.APPLICATION_PAYLOAD_VERSION)
|
|
202
|
-
fail('Invalid application payload version.');
|
|
203
|
-
const bodyLength = reader.u32('bodyLength');
|
|
204
|
-
if (bodyLength !== reader.remaining)
|
|
205
|
-
fail('Application payload body length mismatch.');
|
|
209
|
+
const reader = applicationPayloadReader(frame);
|
|
206
210
|
const packetName = reader.text8('packetName');
|
|
207
211
|
const contentType = reader.text8('contentType');
|
|
208
|
-
|
|
209
|
-
|
|
212
|
+
return { packetName, contentType, payload: applicationPayloadView(reader) };
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Decodes the framework multipart application frame, whose packet name and
|
|
216
|
+
* content type are the schema's multipart constants, and returns a view of its
|
|
217
|
+
* multipart payload without decoding either text field.
|
|
218
|
+
*/
|
|
219
|
+
function decodeMultipartApplicationPayloadView(frame) {
|
|
220
|
+
const bytes = asBuffer(frame);
|
|
221
|
+
const offset = multipartApplicationPayloadOffset(bytes);
|
|
222
|
+
return {
|
|
223
|
+
packetName: service_wire_constants_generated_1.SERVICE_FRAMEWORK_MULTIPART_PACKET_NAME,
|
|
224
|
+
contentType: service_wire_constants_generated_1.SERVICE_FRAMEWORK_MULTIPART_CONTENT_TYPE,
|
|
225
|
+
payload: bytes.subarray(offset)
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/** Materializes final message parts directly over the retained application frame. */
|
|
229
|
+
function decodeMultipartApplicationParts(frame, materialize, release) {
|
|
230
|
+
const bytes = asBuffer(frame);
|
|
231
|
+
return decodeMultipartParts(bytes, materialize, release, multipartApplicationPayloadOffset(bytes));
|
|
232
|
+
}
|
|
233
|
+
function multipartApplicationPayloadOffset(bytes) {
|
|
234
|
+
let offset = applicationPayloadBodyOffset(bytes);
|
|
235
|
+
offset = expectText8At(bytes, offset, MULTIPART_PACKET_NAME_BYTES, 'packetName');
|
|
236
|
+
offset = expectText8At(bytes, offset, MULTIPART_CONTENT_TYPE_BYTES, 'contentType');
|
|
237
|
+
return applicationPayloadDataOffset(bytes, offset);
|
|
238
|
+
}
|
|
239
|
+
function expectText8At(bytes, offset, expected, field) {
|
|
240
|
+
if (bytes.length <= offset)
|
|
241
|
+
fail(`Truncated ${field}.length.`);
|
|
242
|
+
const length = bytes[offset++];
|
|
243
|
+
if (bytes.length - offset < length)
|
|
244
|
+
fail(`Truncated ${field}.`);
|
|
245
|
+
if (length !== expected.length || expected.compare(bytes, offset, offset + length) !== 0) {
|
|
246
|
+
fail(`Unexpected ${field}.`);
|
|
247
|
+
}
|
|
248
|
+
return offset + length;
|
|
249
|
+
}
|
|
250
|
+
function applicationPayloadBodyOffset(bytes) {
|
|
251
|
+
if (bytes.length === 0)
|
|
252
|
+
fail('Truncated version.');
|
|
253
|
+
if (bytes[0] !== exports.APPLICATION_PAYLOAD_VERSION)
|
|
254
|
+
fail('Invalid application payload version.');
|
|
255
|
+
const offset = 1 + APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES;
|
|
256
|
+
if (bytes.length < offset)
|
|
257
|
+
fail('Truncated bodyLength.');
|
|
258
|
+
if (bytes.readUInt32BE(1) !== bytes.length - offset)
|
|
259
|
+
fail('Application payload body length mismatch.');
|
|
260
|
+
return offset;
|
|
261
|
+
}
|
|
262
|
+
function applicationPayloadDataOffset(bytes, offset) {
|
|
263
|
+
if (bytes.length - offset < APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES)
|
|
264
|
+
fail('Truncated payloadLength.');
|
|
265
|
+
const length = bytes.readUInt32BE(offset);
|
|
266
|
+
offset += APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES;
|
|
267
|
+
if (length !== bytes.length - offset)
|
|
210
268
|
fail('Application payload length mismatch.');
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
269
|
+
return offset;
|
|
270
|
+
}
|
|
271
|
+
function applicationPayloadReader(frame) {
|
|
272
|
+
const bytes = asBuffer(frame);
|
|
273
|
+
return new Reader(bytes, applicationPayloadBodyOffset(bytes));
|
|
274
|
+
}
|
|
275
|
+
function applicationPayloadView(reader) {
|
|
276
|
+
return reader.buffer.subarray(applicationPayloadDataOffset(reader.buffer, reader.offset));
|
|
277
|
+
}
|
|
278
|
+
function decodeMultipartParts(payload, materialize, release, offset = 0) {
|
|
279
|
+
const bytes = asBuffer(payload);
|
|
280
|
+
if (bytes.length - offset < 4)
|
|
281
|
+
throw new ServiceWireProtocolError('Truncated multipart payload.');
|
|
282
|
+
const count = bytes.readUInt32BE(offset);
|
|
283
|
+
if (count === 0 || count > Math.floor((bytes.length - offset - 4) / 4)) {
|
|
284
|
+
throw new ServiceWireProtocolError('Invalid multipart part count.');
|
|
285
|
+
}
|
|
286
|
+
const result = new Array(count);
|
|
287
|
+
offset += 4;
|
|
288
|
+
let index = 0;
|
|
289
|
+
try {
|
|
290
|
+
for (; index < count; index++) {
|
|
291
|
+
if (bytes.length - offset < 4) {
|
|
292
|
+
throw new ServiceWireProtocolError('Truncated multipart part length.');
|
|
293
|
+
}
|
|
294
|
+
const length = bytes.readUInt32BE(offset);
|
|
295
|
+
offset += 4;
|
|
296
|
+
if (bytes.length - offset < length) {
|
|
297
|
+
throw new ServiceWireProtocolError('Truncated multipart part.');
|
|
298
|
+
}
|
|
299
|
+
result[index] = materialize(bytes.subarray(offset, offset + length));
|
|
300
|
+
offset += length;
|
|
301
|
+
}
|
|
302
|
+
if (offset !== bytes.length) {
|
|
303
|
+
throw new ServiceWireProtocolError('Multipart payload has trailing bytes.');
|
|
304
|
+
}
|
|
305
|
+
return result;
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
if (release !== undefined) {
|
|
309
|
+
for (let retained = 0; retained < index; retained++)
|
|
310
|
+
release(result[retained]);
|
|
311
|
+
}
|
|
312
|
+
throw error;
|
|
313
|
+
}
|
|
214
314
|
}
|
|
215
315
|
/**
|
|
216
316
|
* Validates the M6A envelope without retaining a second payload buffer. The
|
|
@@ -219,12 +319,7 @@ function decodeApplicationPayloadView(frame) {
|
|
|
219
319
|
* message is admitted to an execution queue.
|
|
220
320
|
*/
|
|
221
321
|
function validateApplicationPayloadFrame(frame) {
|
|
222
|
-
const reader =
|
|
223
|
-
if (reader.u8('version') !== exports.APPLICATION_PAYLOAD_VERSION)
|
|
224
|
-
fail('Invalid application payload version.');
|
|
225
|
-
const bodyLength = reader.u32('bodyLength');
|
|
226
|
-
if (bodyLength !== reader.remaining)
|
|
227
|
-
fail('Application payload body length mismatch.');
|
|
322
|
+
const reader = applicationPayloadReader(frame);
|
|
228
323
|
reader.text8('packetName');
|
|
229
324
|
reader.text8('contentType');
|
|
230
325
|
const payloadLength = reader.u32('payloadLength');
|
|
@@ -381,19 +476,35 @@ function decodeHeader(frame) {
|
|
|
381
476
|
fail('Unsupported service wire major.');
|
|
382
477
|
return { command: frame[3], flags: frame[4] };
|
|
383
478
|
}
|
|
479
|
+
/** Allocates a whole service wire record once and writes its prefix; the caller fills the body. */
|
|
480
|
+
function frame(command, bodyLength) {
|
|
481
|
+
const result = Buffer.allocUnsafe(PREFIX_SIZE + bodyLength);
|
|
482
|
+
result[0] = exports.M6A_SERVICE_WIRE_MAGIC[0];
|
|
483
|
+
result[1] = exports.M6A_SERVICE_WIRE_MAGIC[1];
|
|
484
|
+
result[2] = exports.M6A_SERVICE_WIRE_MAJOR;
|
|
485
|
+
result[3] = command;
|
|
486
|
+
result[4] = 0;
|
|
487
|
+
return result;
|
|
488
|
+
}
|
|
384
489
|
function prefix(command) {
|
|
385
|
-
return
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
490
|
+
return frame(command, 0);
|
|
491
|
+
}
|
|
492
|
+
/** A record whose body starts with the non-zero u64 correlation, followed by `restLength` bytes. */
|
|
493
|
+
function withU64(command, correlation, restLength) {
|
|
494
|
+
if (correlation <= 0n || correlation > MAX_U64)
|
|
495
|
+
fail('correlation must be a non-zero u64.');
|
|
496
|
+
const result = frame(command, 8 + restLength);
|
|
497
|
+
result.writeBigUInt64BE(correlation, PREFIX_SIZE);
|
|
498
|
+
return result;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Writes a validated text8 field — the byte length from
|
|
502
|
+
* canonicalServiceWireTextLength, then the UTF-8 text — and returns the next offset.
|
|
503
|
+
*/
|
|
504
|
+
function writeText8(target, offset, value, length) {
|
|
505
|
+
target[offset] = length;
|
|
506
|
+
target.write(value, offset + 1, length, 'utf8');
|
|
507
|
+
return offset + 1 + length;
|
|
397
508
|
}
|
|
398
509
|
function encodeU16(value) {
|
|
399
510
|
if (!Number.isInteger(value) || value < 0 || value > 0xffff)
|
|
@@ -437,7 +548,9 @@ function readNonZeroU64(bytes, offset, field) {
|
|
|
437
548
|
return result;
|
|
438
549
|
}
|
|
439
550
|
function asBuffer(value) {
|
|
440
|
-
return Buffer.
|
|
551
|
+
return Buffer.isBuffer(value)
|
|
552
|
+
? value
|
|
553
|
+
: Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
441
554
|
}
|
|
442
555
|
function validateAdmissionCommand(command) {
|
|
443
556
|
if (command !== exports.M6aServiceWireCommand.hello &&
|
|
@@ -543,13 +656,13 @@ class Reader {
|
|
|
543
656
|
const length = this.u8(`${field}.length`);
|
|
544
657
|
if (length === 0)
|
|
545
658
|
fail(`${field} must be non-empty.`);
|
|
546
|
-
return decodeText(this.
|
|
659
|
+
return decodeText(this.view(length, field), field);
|
|
547
660
|
}
|
|
548
661
|
text16(field) {
|
|
549
662
|
const length = this.u16(`${field}.length`);
|
|
550
663
|
if (length === 0 || length > SERVICE_ROUTE_TEXT_MAX_BYTES)
|
|
551
664
|
fail(`${field} has invalid length.`);
|
|
552
|
-
return decodeText(this.
|
|
665
|
+
return decodeText(this.view(length, field), field);
|
|
553
666
|
}
|
|
554
667
|
bytes(length, field) {
|
|
555
668
|
this.require(length, field);
|
|
@@ -6,6 +6,7 @@ import type { DefaultZLinkActorManager } from '../actors';
|
|
|
6
6
|
import type { DefaultZLinkSpotManager, ZLinkSpotNodeRuntimeManager } from '../spots';
|
|
7
7
|
import type { ZLinkDetachedTaskRunner } from '../spots/spot-actor-join-dispatch';
|
|
8
8
|
import type { ZLinkBoundSessionResponsePort, ZLinkSessionBindingConfirmationOptions, ZLinkStreamActorLookupPort } from '../streams/stream-binding-runtime-ports';
|
|
9
|
+
import type { ServiceStreamSessionBinding } from '../foundation/service-runtime-contracts';
|
|
9
10
|
import { type ZLinkStreamFrameHeader } from '../streams/protocol';
|
|
10
11
|
import type { MeshRouterResolver } from './mesh-router-resolver';
|
|
11
12
|
import type { ZLinkStoreLocationResolvers } from '../locations';
|
|
@@ -29,12 +30,11 @@ export declare class ZLinkActorPacketRelay {
|
|
|
29
30
|
private readonly options;
|
|
30
31
|
private readonly targets;
|
|
31
32
|
constructor(options: ZLinkActorPacketRelayOptions);
|
|
32
|
-
notifyBoundActorDisconnected(actor: ZLinkSessionActor, signal?: AbortSignal): Promise<void>;
|
|
33
|
+
notifyBoundActorDisconnected(actor: ZLinkSessionActor, signal?: AbortSignal, binding?: ServiceStreamSessionBinding): Promise<void>;
|
|
33
34
|
clearRemoteActorPacketTarget(actorId: string): void;
|
|
34
35
|
updateRemoteActorPacketTarget(actorId: string, value: unknown): Promise<void>;
|
|
35
36
|
actorPacketTargetForState(actorId: string): ZLinkRemoteActorPacketTarget | undefined;
|
|
36
|
-
|
|
37
|
-
notifyLocalActorDisconnectedById(actorId: string, signal?: AbortSignal): Promise<void>;
|
|
37
|
+
notifyLocalActorDisconnectedById(actorId: string, signal?: AbortSignal, binding?: ServiceStreamSessionBinding, bindingActorRef?: ActorRef): Promise<void>;
|
|
38
38
|
receiveRemoteActorPacketRelay(payload: unknown, _routeContext: ZLinkRouteMessageContext): Promise<{
|
|
39
39
|
readonly ok: boolean;
|
|
40
40
|
readonly error?: unknown;
|
|
@@ -52,8 +52,10 @@ export declare class ZLinkActorPacketRelay {
|
|
|
52
52
|
*/
|
|
53
53
|
private installSameNodeSessionBinding;
|
|
54
54
|
relayRemoteActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message): Promise<boolean>;
|
|
55
|
-
notifyRemoteActorDisconnected(actorId: string, remoteTarget: ZLinkRemoteBoundSessionTarget | ZLinkRemoteActorPacketTarget, signal?: AbortSignal, bindingActorRef?: ActorRef): Promise<void>;
|
|
55
|
+
notifyRemoteActorDisconnected(actorId: string, remoteTarget: ZLinkRemoteBoundSessionTarget | ZLinkRemoteActorPacketTarget, signal?: AbortSignal, bindingActorRef?: ActorRef, binding?: ServiceStreamSessionBinding): Promise<void>;
|
|
56
|
+
private disconnectedFrame;
|
|
56
57
|
private requireCurrentRemoteBinding;
|
|
58
|
+
private matchesCurrentRemoteBinding;
|
|
57
59
|
private requestRemoteTarget;
|
|
58
60
|
private relayLocalActorPacket;
|
|
59
61
|
private sendCapturedOrCurrentBoundSessionResponse;
|
|
@@ -5,12 +5,14 @@ const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
|
5
5
|
const runtime_message_1 = require("../backend/runtime-message");
|
|
6
6
|
const contracts_1 = require("../../contracts");
|
|
7
7
|
const ConfigurationException_1 = require("../../contracts/Configuration/ConfigurationException");
|
|
8
|
+
const abort_1 = require("../abort");
|
|
8
9
|
const actors_1 = require("../actors");
|
|
9
10
|
const actor_packet_relay_wire_1 = require("../actors/actor-packet-relay-wire");
|
|
10
11
|
const actor_routed_json_request_1 = require("../actors/actor-routed-json-request");
|
|
11
12
|
const actor_message_follow_context_1 = require("../actors/actor-message-follow-context");
|
|
12
13
|
const bound_session_wire_1 = require("../actors/bound-session-wire");
|
|
13
14
|
const routing_id_1 = require("../routing-id");
|
|
15
|
+
const session_disconnected_wire_1 = require("../actors/session-disconnected-wire");
|
|
14
16
|
const submission_result_1 = require("../messaging/submission-result");
|
|
15
17
|
const actor_session_binding_runtime_owner_1 = require("../streams/actor-session-binding-runtime-owner");
|
|
16
18
|
const protocol_1 = require("../streams/protocol");
|
|
@@ -32,29 +34,14 @@ class ZLinkActorPacketRelay {
|
|
|
32
34
|
spotRouterChannelIdForMesh: spotRouterChannelIdByMesh?.call(options.meshRouters) ?? ((meshName) => meshName)
|
|
33
35
|
});
|
|
34
36
|
}
|
|
35
|
-
async notifyBoundActorDisconnected(actor, signal) {
|
|
36
|
-
|
|
37
|
-
const currentRemoteBoundSessionTarget = state?.spotId === undefined ? undefined : state.remoteBoundSessionTarget;
|
|
38
|
-
const currentRemoteActorPacketTarget = state?.spotId === undefined ? undefined : state.remoteActorPacketTarget;
|
|
39
|
-
const remoteTarget = currentRemoteBoundSessionTarget ??
|
|
40
|
-
currentRemoteActorPacketTarget ??
|
|
41
|
-
(state?.spotId === undefined ? undefined : this.targets.cachedTargetForActor(actor));
|
|
42
|
-
if (remoteTarget !== undefined) {
|
|
43
|
-
await this.notifyRemoteActorDisconnected(actor.actorId, remoteTarget, signal, actor.ref);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
37
|
+
async notifyBoundActorDisconnected(actor, signal, binding) {
|
|
38
|
+
// The Session binding owns this route, including after relocation and detach (§5, §7).
|
|
46
39
|
const actorRefTarget = this.targets.targetForActorRef(actor.ref);
|
|
47
40
|
if (actorRefTarget !== undefined) {
|
|
48
|
-
await this.notifyRemoteActorDisconnected(actor.actorId, actorRefTarget, signal, actor.ref);
|
|
41
|
+
await this.notifyRemoteActorDisconnected(actor.actorId, actorRefTarget, signal, actor.ref, binding);
|
|
49
42
|
return;
|
|
50
43
|
}
|
|
51
|
-
|
|
52
|
-
const handled = await this.requireSpotManager().notifyJoinedSpotActorDisconnected(state.spotId, state.actor, signal);
|
|
53
|
-
if (handled) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
await this.notifyActorDisconnectedById(actor.actorId, signal);
|
|
44
|
+
await this.notifyLocalActorDisconnectedById(actor.actorId, signal, binding, actor.ref);
|
|
58
45
|
}
|
|
59
46
|
clearRemoteActorPacketTarget(actorId) {
|
|
60
47
|
this.targets.clear(actorId);
|
|
@@ -65,34 +52,22 @@ class ZLinkActorPacketRelay {
|
|
|
65
52
|
actorPacketTargetForState(actorId) {
|
|
66
53
|
return this.targets.targetForState(actorId);
|
|
67
54
|
}
|
|
68
|
-
async
|
|
55
|
+
async notifyLocalActorDisconnectedById(actorId, signal, binding, bindingActorRef) {
|
|
56
|
+
(0, abort_1.throwIfAborted)(signal);
|
|
69
57
|
const state = this.options.actorManager()?.getState(actorId);
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
async notifyLocalActorDisconnectedById(actorId, signal) {
|
|
80
|
-
const state = this.options.actorManager()?.getState(actorId);
|
|
81
|
-
if (state?.spotId !== undefined && state.actor !== undefined) {
|
|
82
|
-
const handled = await this.requireSpotManager().notifyJoinedSpotActorDisconnected(state.spotId, state.actor, signal);
|
|
83
|
-
if (handled) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const localActor = state?.actor;
|
|
88
|
-
if (localActor === undefined) {
|
|
89
|
-
throw new Error(`Actor '${actorId}' does not have a local actor instance.`);
|
|
58
|
+
const frame = this.disconnectedFrame(actorId, binding);
|
|
59
|
+
const header = runtime_message_1.ZLinkBufferMessage.fromOwned(Buffer.from(frame.header));
|
|
60
|
+
const body = runtime_message_1.ZLinkBufferMessage.fromOwned(frame.payload);
|
|
61
|
+
try {
|
|
62
|
+
if (state?.spotId === undefined)
|
|
63
|
+
await this.requireSpotNodeRuntime().dispatchEntryActorPacket('local', actorId, [header, body], false, undefined, bindingActorRef);
|
|
64
|
+
else
|
|
65
|
+
await this.requireSpotManager().dispatchRoutedActorPacket('local', state.spotId, actorId, [header, body], false, undefined, bindingActorRef);
|
|
90
66
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
67
|
+
finally {
|
|
68
|
+
header.close();
|
|
69
|
+
body.close();
|
|
94
70
|
}
|
|
95
|
-
await this.requireSpotNodeRuntime().notifyEntrySpotActorDisconnected(meshName, localActor, signal);
|
|
96
71
|
}
|
|
97
72
|
async receiveRemoteActorPacketRelay(payload, _routeContext) {
|
|
98
73
|
const relay = (0, actor_packet_relay_wire_1.decodeRemoteActorPacketRelayPayload)(payload);
|
|
@@ -159,22 +134,23 @@ class ZLinkActorPacketRelay {
|
|
|
159
134
|
}
|
|
160
135
|
return { ok: true, response: { acknowledged: true } };
|
|
161
136
|
}
|
|
162
|
-
if (
|
|
163
|
-
|
|
164
|
-
await this.notifyLocalActorDisconnectedById(relay.actorId);
|
|
165
|
-
return {
|
|
166
|
-
ok: true,
|
|
167
|
-
actorPacketTarget: (0, actor_packet_relay_wire_1.encodeRemoteActorPacketTarget)(this.actorPacketTargetForState(relay.actorId))
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
if (remoteBoundSessionTarget !== undefined) {
|
|
137
|
+
if (remoteBoundSessionTarget !== undefined &&
|
|
138
|
+
frameHeader.name !== actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET) {
|
|
171
139
|
this.requireCurrentRemoteBinding(relay, _routeContext);
|
|
172
140
|
}
|
|
173
141
|
const state = this.options.actorManager()?.getState(relay.actorId);
|
|
174
|
-
if (frameHeader.kind === protocol_1.ZLinkStreamMessageKind.Send
|
|
142
|
+
if (frameHeader.kind === protocol_1.ZLinkStreamMessageKind.Send ||
|
|
143
|
+
frameHeader.name === actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET) {
|
|
175
144
|
const dispatch = state?.spotId === undefined
|
|
176
145
|
? this.requireSpotNodeRuntime().dispatchEntryActorPacket('remote', relay.actorId, [header, body], false, remoteBoundSessionTarget, fallbackActorRef)
|
|
177
146
|
: this.requireSpotManager().dispatchRoutedActorPacket('remote', state.spotId, relay.actorId, [header, body], false, remoteBoundSessionTarget, fallbackActorRef);
|
|
147
|
+
if (frameHeader.name === actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET) {
|
|
148
|
+
await dispatch;
|
|
149
|
+
return {
|
|
150
|
+
ok: true,
|
|
151
|
+
actorPacketTarget: (0, actor_packet_relay_wire_1.encodeRemoteActorPacketTarget)(this.actorPacketTargetForState(relay.actorId))
|
|
152
|
+
};
|
|
153
|
+
}
|
|
178
154
|
// Spec 05 §1.3: a one-way Session Actor relay completes at relay
|
|
179
155
|
// queue admission, not after the remote application turn. In
|
|
180
156
|
// particular, a handler may register a deferred Join whose relocation
|
|
@@ -469,21 +445,14 @@ class ZLinkActorPacketRelay {
|
|
|
469
445
|
}
|
|
470
446
|
return true;
|
|
471
447
|
}
|
|
472
|
-
async notifyRemoteActorDisconnected(actorId, remoteTarget, signal, bindingActorRef) {
|
|
448
|
+
async notifyRemoteActorDisconnected(actorId, remoteTarget, signal, bindingActorRef, binding) {
|
|
473
449
|
const spotKind = 'spotKind' in remoteTarget ? remoteTarget.spotKind : undefined;
|
|
474
|
-
const
|
|
475
|
-
kind: protocol_1.ZLinkStreamMessageKind.Send,
|
|
476
|
-
codec: protocol_1.ZLinkStreamCodec.Raw,
|
|
477
|
-
flags: protocol_1.ZLinkStreamHeaderFlags.None,
|
|
478
|
-
name: actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET,
|
|
479
|
-
metadata: new Map()
|
|
480
|
-
};
|
|
450
|
+
const frame = this.disconnectedFrame(actorId, binding, 'sessionNodeRid' in remoteTarget ? remoteTarget : undefined);
|
|
481
451
|
const payload = (0, actor_packet_relay_wire_1.encodeRemoteActorPacketRelayPayload)({
|
|
482
452
|
actorId,
|
|
483
453
|
routerChannelId: remoteTarget.routerChannelId,
|
|
484
454
|
bindingActorRef,
|
|
485
|
-
|
|
486
|
-
payload: Buffer.alloc(0)
|
|
455
|
+
...frame
|
|
487
456
|
});
|
|
488
457
|
if ((spotKind ?? contracts_1.ZLinkSpotKind.Entry) === contracts_1.ZLinkSpotKind.Entry) {
|
|
489
458
|
await this.options.routeTransport.request(remoteTarget.routerChannelId, String(remoteTarget.targetNodeRid), actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET, payload, this.options.requestTimeoutMs, signal);
|
|
@@ -500,18 +469,36 @@ class ZLinkActorPacketRelay {
|
|
|
500
469
|
signal
|
|
501
470
|
});
|
|
502
471
|
}
|
|
472
|
+
disconnectedFrame(actorId, binding, target) {
|
|
473
|
+
const current = binding === undefined
|
|
474
|
+
? (this.options.actorManager()?.getState(actorId)?.boundSession ?? target)
|
|
475
|
+
: undefined;
|
|
476
|
+
const header = {
|
|
477
|
+
kind: protocol_1.ZLinkStreamMessageKind.Send,
|
|
478
|
+
codec: protocol_1.ZLinkStreamCodec.Raw,
|
|
479
|
+
flags: protocol_1.ZLinkStreamHeaderFlags.None,
|
|
480
|
+
name: actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET,
|
|
481
|
+
metadata: new Map()
|
|
482
|
+
};
|
|
483
|
+
return {
|
|
484
|
+
header: (0, protocol_1.encodeStreamHeader)(header),
|
|
485
|
+
payload: (0, session_disconnected_wire_1.encodeSessionDisconnected)(binding?.sessionOwnerNodeRid ?? current?.sessionNodeRid, binding?.sessionOwnerNodeGeneration ?? current?.sessionOwnerNodeGeneration, binding?.bindingGeneration ?? current?.bindingGeneration)
|
|
486
|
+
};
|
|
487
|
+
}
|
|
503
488
|
requireCurrentRemoteBinding(relay, routeContext) {
|
|
504
|
-
|
|
505
|
-
const current = state?.boundSession;
|
|
506
|
-
if (current === undefined ||
|
|
507
|
-
current.sessionNodeRid === undefined ||
|
|
508
|
-
!(0, routing_id_1.routingIdsEqual)(current.sessionNodeRid, routeContext.sourceNodeRid) ||
|
|
509
|
-
current.bindingGeneration === undefined ||
|
|
510
|
-
relay.bindingGeneration === undefined ||
|
|
511
|
-
current.bindingGeneration !== BigInt(relay.bindingGeneration)) {
|
|
489
|
+
if (!this.matchesCurrentRemoteBinding(relay, routeContext)) {
|
|
512
490
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorSessionNotBound, `Actor '${relay.actorId}' bound session identity is stale.`, true);
|
|
513
491
|
}
|
|
514
492
|
}
|
|
493
|
+
matchesCurrentRemoteBinding(relay, routeContext) {
|
|
494
|
+
const current = this.options.actorManager()?.getState(relay.actorId)?.boundSession;
|
|
495
|
+
return (current !== undefined &&
|
|
496
|
+
current.sessionNodeRid !== undefined &&
|
|
497
|
+
(0, routing_id_1.routingIdsEqual)(current.sessionNodeRid, routeContext.sourceNodeRid) &&
|
|
498
|
+
current.bindingGeneration !== undefined &&
|
|
499
|
+
relay.bindingGeneration !== undefined &&
|
|
500
|
+
current.bindingGeneration === BigInt(relay.bindingGeneration));
|
|
501
|
+
}
|
|
515
502
|
async requestRemoteTarget(target, request, unavailableMessage, decodeReply, signal) {
|
|
516
503
|
if (target.spotKind === contracts_1.ZLinkSpotKind.Entry) {
|
|
517
504
|
try {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZLinkActorPlacementCoordinator = void 0;
|
|
4
|
+
const routing_id_1 = require("../routing-id");
|
|
4
5
|
const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
5
6
|
const node_crypto_1 = require("node:crypto");
|
|
6
7
|
const runtime_values_1 = require("../backend/runtime-values");
|
|
@@ -33,6 +34,13 @@ class ZLinkActorPlacementCoordinator {
|
|
|
33
34
|
for (;;) {
|
|
34
35
|
const target = await this.options.target(meshName, stableType, deadline.signal, excluded);
|
|
35
36
|
if (target === undefined) {
|
|
37
|
+
// Entry eligibility limits new creation, not lookup of a Ready Actor (Actor model §6.3, §6.5).
|
|
38
|
+
if (!createOnly) {
|
|
39
|
+
const current = await this.options.store.readAuthority((0, authority_key_codec_1.encodeAuthorityKey)('actor', actorId), deadline.signal);
|
|
40
|
+
const existing = existingActor(current, actorId, stableType);
|
|
41
|
+
if (existing !== undefined)
|
|
42
|
+
return { status: 'existing', actor: existing };
|
|
43
|
+
}
|
|
36
44
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.PlacementCapacityExhausted, `No eligible Actor placement target is ready for '${stableType}'.`, true);
|
|
37
45
|
}
|
|
38
46
|
const creatingPayload = (0, actor_authority_publication_1.encodeActorAuthorityIdentity)({
|
|
@@ -75,7 +83,7 @@ class ZLinkActorPlacementCoordinator {
|
|
|
75
83
|
throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorTypeMismatch, `Actor '${actorId}' is registered with another stable type.`);
|
|
76
84
|
}
|
|
77
85
|
if (reserved.kind === 'placementCapacityExhausted') {
|
|
78
|
-
excluded.add(
|
|
86
|
+
excluded.add((0, routing_id_1.encodeRoutingIdStorageHex)(target.nodeRid));
|
|
79
87
|
continue;
|
|
80
88
|
}
|
|
81
89
|
if (reserved.kind === 'alreadyExists' || reserved.kind === 'conflict') {
|
|
@@ -106,6 +114,13 @@ class ZLinkActorPlacementCoordinator {
|
|
|
106
114
|
}
|
|
107
115
|
if (remote === undefined)
|
|
108
116
|
throw transportFailure;
|
|
117
|
+
if ((0, framework_errors_internal_1.internalFrameworkErrorKindFromWireReply)(remote.terminalResult, remote.failureCode) ===
|
|
118
|
+
framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RouteNotConnected) {
|
|
119
|
+
// The target refused before the callback and cancelled its reservation
|
|
120
|
+
// (Actor model §6.3); exclude this host run like a Reserve failure.
|
|
121
|
+
excluded.add((0, routing_id_1.encodeRoutingIdStorageHex)(target.nodeRid));
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
109
124
|
if (remote.terminalResult !== runtime_values_1.RequestResult.Ok || remote.failureCode !== 0) {
|
|
110
125
|
// Classify the (terminal, fine failure code) pair via the shared
|
|
111
126
|
// ownership-aware translator instead of collapsing every non-OK
|
|
@@ -274,12 +289,14 @@ function creationTarget(snapshot) {
|
|
|
274
289
|
}
|
|
275
290
|
};
|
|
276
291
|
}
|
|
277
|
-
function existingActor(
|
|
278
|
-
const snapshot =
|
|
279
|
-
?
|
|
280
|
-
:
|
|
281
|
-
?
|
|
282
|
-
:
|
|
292
|
+
function existingActor(current, actorId, stableType) {
|
|
293
|
+
const snapshot = current.kind === 'snapshot'
|
|
294
|
+
? current
|
|
295
|
+
: current.kind === 'alreadyExists'
|
|
296
|
+
? current.current
|
|
297
|
+
: current.kind === 'conflict' && current.current.kind === 'snapshot'
|
|
298
|
+
? current.current
|
|
299
|
+
: undefined;
|
|
283
300
|
if (snapshot === undefined ||
|
|
284
301
|
snapshot.allocation.state !== 'active' ||
|
|
285
302
|
snapshot.allocation.objectKind !== 'actor' ||
|
|
@@ -348,7 +365,7 @@ function requireExactReservation(current, record) {
|
|
|
348
365
|
current.allocation.stableType !== record.stableType ||
|
|
349
366
|
current.objectGeneration !== record.reservation.objectGeneration ||
|
|
350
367
|
current.authorityOwnerGeneration !== record.reservation.authorityOwnerGeneration ||
|
|
351
|
-
|
|
368
|
+
!(0, routing_id_1.routingIdsEqual)(current.allocation.descriptor.rid, record.reservation.targetNodeRid) ||
|
|
352
369
|
current.allocation.descriptorLifecycleGeneration !== record.reservation.targetNodeGeneration ||
|
|
353
370
|
current.ownerId !== record.reservation.targetOwnerId ||
|
|
354
371
|
current.ownerLeaseGeneration !== record.reservation.targetOwnerLeaseGeneration ||
|