@zlink-systems/framework 0.21.0 → 0.23.0

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.
Files changed (516) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Common/ZLinkMessage.js +5 -5
  3. package/dist/contracts/Configuration/CodecContentType.js +5 -7
  4. package/dist/contracts/Configuration/DiagnosticsValidation.js +1 -6
  5. package/dist/contracts/Configuration/EndpointNotation.js +4 -8
  6. package/dist/contracts/Configuration/Registration.js +14 -11
  7. package/dist/contracts/Configuration/RegistrationBuilders.js +32 -25
  8. package/dist/contracts/Configuration/RegistrationNormalizers.js +25 -26
  9. package/dist/contracts/Configuration/RegistrationValidators.js +36 -38
  10. package/dist/contracts/Configuration/SendTimeoutValidation.js +4 -4
  11. package/dist/contracts/Configuration/TimerRegistrationValidator.js +7 -7
  12. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -0
  13. package/dist/contracts/Handlers/JsonContract.js +23 -11
  14. package/dist/contracts/Spots/SpotKind.js +16 -8
  15. package/dist/contracts/Streams/IZLinkSession.d.ts +2 -1
  16. package/dist/location-store-integration.js +16 -16
  17. package/dist/nest-integration.js +17 -11
  18. package/dist/runtime/abort.js +9 -5
  19. package/dist/runtime/actors/actor-authority-payload-codec.js +12 -16
  20. package/dist/runtime/actors/actor-authority-publication.js +18 -17
  21. package/dist/runtime/actors/actor-client.js +83 -63
  22. package/dist/runtime/actors/actor-context.js +28 -22
  23. package/dist/runtime/actors/actor-creation.js +4 -3
  24. package/dist/runtime/actors/actor-handoff.js +89 -92
  25. package/dist/runtime/actors/actor-join-deferred-scope.d.ts +0 -1
  26. package/dist/runtime/actors/actor-join-deferred-scope.js +0 -18
  27. package/dist/runtime/actors/actor-local-native-join.js +18 -19
  28. package/dist/runtime/actors/actor-mailbox.js +1 -1
  29. package/dist/runtime/actors/actor-message-follow-context.js +24 -21
  30. package/dist/runtime/actors/actor-packet-relay-wire.js +1 -3
  31. package/dist/runtime/actors/actor-remote-joiner.js +20 -17
  32. package/dist/runtime/actors/actor-remote-wire.js +6 -7
  33. package/dist/runtime/actors/actor-runtime-state.js +87 -81
  34. package/dist/runtime/actors/actor-transfer-registry.js +3 -5
  35. package/dist/runtime/actors/bound-session-wire.js +14 -9
  36. package/dist/runtime/actors/deferred-join-accepted-journal.js +160 -130
  37. package/dist/runtime/actors/index.js +2 -5
  38. package/dist/runtime/actors/post-commit-actor-binder.js +3 -6
  39. package/dist/runtime/actors/post-commit-actor-location.js +1 -1
  40. package/dist/runtime/actors/spot-actor-dispatch.js +5 -5
  41. package/dist/runtime/actors/transferred-actor-rollback.js +4 -4
  42. package/dist/runtime/admission.js +2 -6
  43. package/dist/runtime/application-jobs/application-ingress-record-owner.js +2 -6
  44. package/dist/runtime/application-jobs/receive-flow-controller.js +11 -12
  45. package/dist/runtime/backend/contracts/index.d.ts +1 -0
  46. package/dist/runtime/backend/mesh-completion-table.js +1 -3
  47. package/dist/runtime/backend/mesh-dispatch-pump.js +12 -16
  48. package/dist/runtime/backend/node/node-backend-adapter-factory.js +1 -3
  49. package/dist/runtime/backend/node/node-backend-adapter-support.js +26 -17
  50. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +4 -3
  51. package/dist/runtime/backend/node/node-raw-binding-port.js +7 -6
  52. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +3 -0
  53. package/dist/runtime/backend/node/node-raw-mesh-backend.js +134 -118
  54. package/dist/runtime/backend/node/node-socket-backend-adapter.js +12 -13
  55. package/dist/runtime/backend/runtime-message.js +3 -3
  56. package/dist/runtime/backend/runtime-values.d.ts +2 -2
  57. package/dist/runtime/backend/runtime-values.js +4 -5
  58. package/dist/runtime/channels/channel-clients.js +27 -24
  59. package/dist/runtime/channels/channel-dispatch-pipeline.js +12 -20
  60. package/dist/runtime/channels/channel-dispatch-services.js +7 -4
  61. package/dist/runtime/channels/channel-dispatchers.js +9 -9
  62. package/dist/runtime/channels/channel-envelope-inspection.js +16 -13
  63. package/dist/runtime/channels/channel-envelope.js +83 -47
  64. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  65. package/dist/runtime/channels/channel-receive-loops.js +20 -22
  66. package/dist/runtime/channels/channel-receive-task-tracker.js +1 -1
  67. package/dist/runtime/channels/channel-runtime-lifecycle.js +61 -56
  68. package/dist/runtime/channels/channel-runtime-manager.js +18 -9
  69. package/dist/runtime/channels/channel-socket-registry.js +126 -123
  70. package/dist/runtime/channels/channel-transports.js +46 -42
  71. package/dist/runtime/channels/client-server-location-runtime.js +32 -40
  72. package/dist/runtime/channels/client-server-service-wire.js +29 -22
  73. package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -0
  74. package/dist/runtime/channels/dispatch-error-reporter.js +9 -39
  75. package/dist/runtime/channels/fanout-location-runtime.js +34 -47
  76. package/dist/runtime/channels/fanout-service-wire.js +3 -5
  77. package/dist/runtime/channels/local-spot-route-transport.js +7 -1
  78. package/dist/runtime/channels/route-member-snapshot.js +3 -3
  79. package/dist/runtime/channels/source-spot-router.js +6 -2
  80. package/dist/runtime/channels/spot-route-bridge-transport.js +5 -2
  81. package/dist/runtime/channels/spot-route-dispatch-strategy.js +2 -2
  82. package/dist/runtime/channels/spot-route-target-resolver.js +6 -6
  83. package/dist/runtime/diagnostics/dispatch-error-details.d.ts +6 -0
  84. package/dist/runtime/diagnostics/dispatch-error-details.js +55 -0
  85. package/dist/runtime/diagnostics/flow-context.d.ts +2 -1
  86. package/dist/runtime/diagnostics/flow-context.js +2 -2
  87. package/dist/runtime/diagnostics/index.js +38 -10
  88. package/dist/runtime/diagnostics/message-flow.js +58 -42
  89. package/dist/runtime/diagnostics/runtime-metrics.js +18 -9
  90. package/dist/runtime/diagnostics/runtime-observation-queue.js +8 -10
  91. package/dist/runtime/diagnostics/topology-runtime-projections.js +17 -10
  92. package/dist/runtime/execution/index.js +7 -6
  93. package/dist/runtime/execution/serial-execution-queue.js +12 -18
  94. package/dist/runtime/execution/state-lane.js +2 -2
  95. package/dist/runtime/foundation/actor-join-recovery-codec.js +31 -27
  96. package/dist/runtime/foundation/event-loop-resources.js +4 -4
  97. package/dist/runtime/foundation/message-follow-suppression-registry.js +4 -4
  98. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +4 -2
  99. package/dist/runtime/foundation/raw-service-mesh-runtime.js +169 -144
  100. package/dist/runtime/foundation/route-mesh-connection-policy.js +4 -4
  101. package/dist/runtime/foundation/runtime-state-projections.js +22 -11
  102. package/dist/runtime/foundation/service-authority-payload-codec.js +13 -15
  103. package/dist/runtime/foundation/service-discovery-registry.js +35 -33
  104. package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +20 -22
  105. package/dist/runtime/foundation/service-liveness-registry.js +16 -12
  106. package/dist/runtime/foundation/service-maintenance-runtime.js +2 -4
  107. package/dist/runtime/foundation/service-relocation-aggregate-committer.js +24 -24
  108. package/dist/runtime/foundation/service-relocation-object-owner.js +6 -6
  109. package/dist/runtime/foundation/service-relocation-runtime.js +137 -94
  110. package/dist/runtime/foundation/service-runtime-contracts.js +5 -5
  111. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +1 -0
  112. package/dist/runtime/foundation/service-stateful-registry.js +24 -23
  113. package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -0
  114. package/dist/runtime/foundation/service-stateful-runtime.js +461 -439
  115. package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
  116. package/dist/runtime/foundation/service-topology-registry.d.ts +1 -0
  117. package/dist/runtime/foundation/service-topology-registry.js +105 -96
  118. package/dist/runtime/foundation/service-weighted-selection.js +6 -11
  119. package/dist/runtime/foundation/service-wire-binary-primitives.js +5 -6
  120. package/dist/runtime/foundation/service-wire-m6a-codec.js +46 -35
  121. package/dist/runtime/framework-errors-internal.js +7 -10
  122. package/dist/runtime/handlers/handler-instance-scope.js +4 -5
  123. package/dist/runtime/handlers/index.js +3 -1
  124. package/dist/runtime/host/actor-packet-relay.js +74 -70
  125. package/dist/runtime/host/actor-placement-coordinator.js +29 -31
  126. package/dist/runtime/host/actor-runtime-options-factory.js +12 -14
  127. package/dist/runtime/host/actor-transfer-authority-runtime.js +7 -9
  128. package/dist/runtime/host/actor-transfer-runtime.js +176 -153
  129. package/dist/runtime/host/application-job-queue.js +18 -22
  130. package/dist/runtime/host/bound-session-relay.js +3 -1
  131. package/dist/runtime/host/channel-runtime-options-factory.js +31 -14
  132. package/dist/runtime/host/host-capacity-status.js +8 -4
  133. package/dist/runtime/host/index.js +245 -228
  134. package/dist/runtime/host/instance-activation-authority.js +93 -96
  135. package/dist/runtime/host/location-runtime-owner.js +16 -14
  136. package/dist/runtime/host/mesh-router-resolver.js +11 -13
  137. package/dist/runtime/host/relocation-direct-transfer.js +10 -9
  138. package/dist/runtime/host/remote-actor-join-receiver.js +20 -15
  139. package/dist/runtime/host/remote-actor-packet-target-store.js +18 -22
  140. package/dist/runtime/host/remote-bound-session-relay.js +97 -73
  141. package/dist/runtime/host/route-mesh-runtime.js +64 -69
  142. package/dist/runtime/host/runtime-shutdown.js +1 -2
  143. package/dist/runtime/host/service-relocation-host-runtime.js +586 -511
  144. package/dist/runtime/host/spot-address-transport.js +69 -71
  145. package/dist/runtime/host/spot-runtime-options-factory.js +30 -29
  146. package/dist/runtime/host/stateful-authority-route-runtime.js +65 -68
  147. package/dist/runtime/host/user-spot-creation-coordinator.js +61 -67
  148. package/dist/runtime/locations/actor-location-claims.js +26 -20
  149. package/dist/runtime/locations/aggregate-inventory-store.js +72 -75
  150. package/dist/runtime/locations/authority-key-codec.js +7 -7
  151. package/dist/runtime/locations/auto-connect-loop.js +3 -3
  152. package/dist/runtime/locations/auto-connect-planner.js +25 -19
  153. package/dist/runtime/locations/auto-connect-reconciler.js +51 -31
  154. package/dist/runtime/locations/in-memory-authority-store.js +128 -118
  155. package/dist/runtime/locations/in-memory-location-store.js +195 -168
  156. package/dist/runtime/locations/in-memory-provider-location-store.js +8 -10
  157. package/dist/runtime/locations/key-codec.js +1 -1
  158. package/dist/runtime/locations/lease-tracker.js +23 -21
  159. package/dist/runtime/locations/lifecycle.js +4 -5
  160. package/dist/runtime/locations/location-store-repository.js +368 -324
  161. package/dist/runtime/locations/opaque-record-key.js +2 -2
  162. package/dist/runtime/locations/resolvers.js +73 -82
  163. package/dist/runtime/locations/runtime.js +68 -63
  164. package/dist/runtime/locations/spot-location-claims.js +39 -35
  165. package/dist/runtime/messaging/framework-json-v1.js +7 -7
  166. package/dist/runtime/messaging/packet-name.js +7 -6
  167. package/dist/runtime/messaging/payload-codec.js +21 -18
  168. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +30 -2
  169. package/dist/runtime/protocol/service_wire_codec.generated.js +1671 -234
  170. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +20 -18
  171. package/dist/runtime/routing-id.js +3 -5
  172. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +35 -31
  173. package/dist/runtime/spots/formal-remote-actor-transfer-registry.js +1 -2
  174. package/dist/runtime/spots/index.js +209 -220
  175. package/dist/runtime/spots/spot-activation-registry.js +15 -14
  176. package/dist/runtime/spots/spot-activation-state.js +17 -15
  177. package/dist/runtime/spots/spot-activation.js +33 -16
  178. package/dist/runtime/spots/spot-actor-admission-coordinator.js +18 -15
  179. package/dist/runtime/spots/spot-actor-membership.js +1 -3
  180. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +2 -1
  181. package/dist/runtime/spots/spot-actor-packet-dispatch.js +29 -21
  182. package/dist/runtime/spots/spot-actor-packet-drain.js +14 -10
  183. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +10 -6
  184. package/dist/runtime/spots/spot-closing.js +3 -7
  185. package/dist/runtime/spots/spot-context.js +2 -2
  186. package/dist/runtime/spots/spot-entry-activation.js +13 -14
  187. package/dist/runtime/spots/spot-handle.js +6 -3
  188. package/dist/runtime/spots/spot-handler-registry.js +12 -12
  189. package/dist/runtime/spots/spot-manager-public.js +5 -6
  190. package/dist/runtime/spots/spot-native-actor-join-admission.js +4 -3
  191. package/dist/runtime/spots/spot-node-autoconnect.js +15 -18
  192. package/dist/runtime/spots/spot-node-runtime-manager.js +79 -86
  193. package/dist/runtime/spots/spot-outbound.js +10 -14
  194. package/dist/runtime/spots/spot-remote-codec.js +22 -26
  195. package/dist/runtime/spots/spot-remote-route-codec.js +5 -7
  196. package/dist/runtime/spots/spot-route-packet-dispatch.js +17 -15
  197. package/dist/runtime/spots/spot-route-replies.js +4 -6
  198. package/dist/runtime/spots/spot-routed-actor-admission.js +9 -7
  199. package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +2 -3
  200. package/dist/runtime/spots/spot-routed-frame-dispatch.js +5 -5
  201. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +14 -10
  202. package/dist/runtime/spots/spot-serial-executor.js +5 -8
  203. package/dist/runtime/spots/spot-serial-turn-executor.js +4 -6
  204. package/dist/runtime/spots/spot-subscription-dispatch.js +6 -6
  205. package/dist/runtime/spots/spot-timer.js +26 -30
  206. package/dist/runtime/streams/actor-session-binding-registry.d.ts +21 -8
  207. package/dist/runtime/streams/actor-session-binding-registry.js +168 -148
  208. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -0
  209. package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
  210. package/dist/runtime/streams/bound-actor-relay-sender.js +20 -17
  211. package/dist/runtime/streams/bound-session-response-target.js +8 -1
  212. package/dist/runtime/streams/bound-session-service.d.ts +1 -0
  213. package/dist/runtime/streams/bound-session-service.js +14 -12
  214. package/dist/runtime/streams/index.js +28 -20
  215. package/dist/runtime/streams/managed-stream.d.ts +3 -0
  216. package/dist/runtime/streams/managed-stream.js +52 -31
  217. package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
  218. package/dist/runtime/streams/protocol.d.ts +5 -1
  219. package/dist/runtime/streams/protocol.js +68 -20
  220. package/dist/runtime/streams/session-actor-coordinator.js +37 -41
  221. package/dist/runtime/streams/session-context.d.ts +9 -2
  222. package/dist/runtime/streams/session-context.js +50 -32
  223. package/dist/runtime/streams/session-local-actors.d.ts +3 -1
  224. package/dist/runtime/streams/session-local-actors.js +17 -2
  225. package/dist/runtime/streams/session-provider.js +2 -2
  226. package/dist/runtime/streams/session-serial-executor.js +1 -2
  227. package/dist/runtime/streams/stream-frame-factory.d.ts +1 -1
  228. package/dist/runtime/streams/stream-frame-factory.js +14 -7
  229. package/dist/runtime/streams/stream-session-runtime.js +112 -78
  230. package/dist/runtime/workers/index.js +15 -4
  231. package/package.json +3 -3
  232. package/src/contracts/Channels/RouteCalls.ts +6 -1
  233. package/src/contracts/Common/ZLinkMessage.ts +5 -5
  234. package/src/contracts/Common/ZLinkMessageMetadata.ts +4 -3
  235. package/src/contracts/Configuration/Builders.ts +14 -14
  236. package/src/contracts/Configuration/CodecContentType.ts +8 -10
  237. package/src/contracts/Configuration/DiagnosticsValidation.ts +1 -6
  238. package/src/contracts/Configuration/EndpointNotation.ts +11 -11
  239. package/src/contracts/Configuration/ObjectRoles.ts +1 -3
  240. package/src/contracts/Configuration/Registration.ts +46 -17
  241. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +10 -8
  242. package/src/contracts/Configuration/RegistrationBuilders.ts +107 -96
  243. package/src/contracts/Configuration/RegistrationCodecRegistry.ts +9 -3
  244. package/src/contracts/Configuration/RegistrationNormalizers.ts +116 -84
  245. package/src/contracts/Configuration/RegistrationTypes.ts +21 -25
  246. package/src/contracts/Configuration/RegistrationValidators.ts +122 -73
  247. package/src/contracts/Configuration/RouteChannelInternalState.ts +1 -4
  248. package/src/contracts/Configuration/RuntimeEndpointConnections.ts +4 -1
  249. package/src/contracts/Configuration/SendTimeoutValidation.ts +6 -4
  250. package/src/contracts/Configuration/TimerRegistrationValidator.ts +8 -13
  251. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -6
  252. package/src/contracts/Errors/index.ts +1 -4
  253. package/src/contracts/Handlers/Attributes.ts +15 -9
  254. package/src/contracts/Handlers/IZLinkChannelHandlers.ts +24 -4
  255. package/src/contracts/Handlers/JsonContract.ts +53 -19
  256. package/src/contracts/Locations/ActorTransfer.ts +1 -5
  257. package/src/contracts/Locations/Authority.ts +4 -11
  258. package/src/contracts/Locations/Keys.ts +6 -1
  259. package/src/contracts/Locations/Options.ts +3 -2
  260. package/src/contracts/Locations/RelocationStore.ts +1 -4
  261. package/src/contracts/Locations/Resolvers.ts +5 -5
  262. package/src/contracts/Locations/RuntimeQuery.ts +6 -2
  263. package/src/contracts/Locations/Stores.ts +1 -2
  264. package/src/contracts/Locations/index.ts +2 -8
  265. package/src/contracts/RouteMesh/Contracts.ts +1 -7
  266. package/src/contracts/RouteMesh/RuntimeTopology.ts +1 -4
  267. package/src/contracts/Spots/Contracts.ts +2 -8
  268. package/src/contracts/Spots/SpotKind.ts +16 -8
  269. package/src/contracts/Spots/ZLinkSpot.ts +8 -11
  270. package/src/contracts/Streams/IZLinkSession.ts +2 -2
  271. package/src/contracts/Streams/IZLinkSessionActor.ts +5 -1
  272. package/src/contracts/Streams/IZLinkSessionPacketHandler.ts +5 -1
  273. package/src/internal.ts +5 -4
  274. package/src/location-store-integration.ts +24 -16
  275. package/src/nest-integration.ts +40 -25
  276. package/src/runtime/abort.ts +10 -4
  277. package/src/runtime/actors/actor-authority-payload-codec.ts +20 -29
  278. package/src/runtime/actors/actor-authority-publication.ts +92 -77
  279. package/src/runtime/actors/actor-client.ts +162 -133
  280. package/src/runtime/actors/actor-context.ts +142 -134
  281. package/src/runtime/actors/actor-creation.ts +47 -44
  282. package/src/runtime/actors/actor-execution-context.ts +6 -4
  283. package/src/runtime/actors/actor-handoff.ts +269 -293
  284. package/src/runtime/actors/actor-join-deferred-scope.ts +1 -32
  285. package/src/runtime/actors/actor-lifecycle-snapshot.ts +5 -8
  286. package/src/runtime/actors/actor-local-native-join.ts +131 -159
  287. package/src/runtime/actors/actor-mailbox.ts +16 -19
  288. package/src/runtime/actors/actor-message-follow-context.ts +46 -36
  289. package/src/runtime/actors/actor-packet-relay-wire.ts +32 -21
  290. package/src/runtime/actors/actor-remote-joiner.ts +50 -54
  291. package/src/runtime/actors/actor-remote-wire.ts +9 -13
  292. package/src/runtime/actors/actor-routed-join-transport.ts +10 -2
  293. package/src/runtime/actors/actor-runtime-contracts.ts +2 -5
  294. package/src/runtime/actors/actor-runtime-state.ts +127 -124
  295. package/src/runtime/actors/actor-transfer-registry.ts +9 -14
  296. package/src/runtime/actors/actor-transport-delivery-gate.ts +4 -6
  297. package/src/runtime/actors/bound-session-wire.ts +37 -17
  298. package/src/runtime/actors/deferred-join-accepted-journal.ts +353 -326
  299. package/src/runtime/actors/index.ts +43 -86
  300. package/src/runtime/actors/post-commit-actor-binder.ts +10 -10
  301. package/src/runtime/actors/post-commit-actor-location.ts +30 -23
  302. package/src/runtime/actors/spot-actor-dispatch.ts +78 -53
  303. package/src/runtime/actors/transferred-actor-rollback.ts +18 -13
  304. package/src/runtime/admission.ts +9 -9
  305. package/src/runtime/application-jobs/application-ingress-record-owner.ts +5 -15
  306. package/src/runtime/application-jobs/application-job-queue-handler-start-gate.ts +3 -2
  307. package/src/runtime/application-jobs/receive-flow-controller.ts +17 -14
  308. package/src/runtime/backend/contracts/index.ts +77 -52
  309. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -14
  310. package/src/runtime/backend/mesh-completion-table.ts +6 -9
  311. package/src/runtime/backend/mesh-dispatch-pump.ts +38 -30
  312. package/src/runtime/backend/node/node-backend-adapter-factory.ts +23 -21
  313. package/src/runtime/backend/node/node-backend-adapter-support.ts +36 -22
  314. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +59 -58
  315. package/src/runtime/backend/node/node-event-loop-poller.ts +2 -10
  316. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +12 -5
  317. package/src/runtime/backend/node/node-monitor-backend-adapter.ts +4 -3
  318. package/src/runtime/backend/node/node-raw-binding-port.ts +29 -29
  319. package/src/runtime/backend/node/node-raw-mesh-backend.ts +370 -390
  320. package/src/runtime/backend/node/node-socket-backend-adapter.ts +101 -54
  321. package/src/runtime/backend/runtime-message.ts +5 -3
  322. package/src/runtime/backend/runtime-values.ts +10 -7
  323. package/src/runtime/channels/channel-autoconnect.ts +1 -4
  324. package/src/runtime/channels/channel-clients.ts +93 -73
  325. package/src/runtime/channels/channel-dispatch-pipeline.ts +44 -44
  326. package/src/runtime/channels/channel-dispatch-services.ts +51 -49
  327. package/src/runtime/channels/channel-dispatchers.ts +152 -96
  328. package/src/runtime/channels/channel-envelope-inspection.ts +20 -16
  329. package/src/runtime/channels/channel-envelope.ts +256 -150
  330. package/src/runtime/channels/channel-multipart.ts +13 -5
  331. package/src/runtime/channels/channel-outbound-operations.ts +37 -41
  332. package/src/runtime/channels/channel-receive-loops.ts +102 -98
  333. package/src/runtime/channels/channel-receive-task-tracker.ts +1 -1
  334. package/src/runtime/channels/channel-runtime-lifecycle.ts +248 -190
  335. package/src/runtime/channels/channel-runtime-manager.ts +63 -37
  336. package/src/runtime/channels/channel-socket-options.ts +3 -10
  337. package/src/runtime/channels/channel-socket-registry.ts +331 -273
  338. package/src/runtime/channels/channel-transports.ts +218 -206
  339. package/src/runtime/channels/client-server-location-runtime.ts +116 -100
  340. package/src/runtime/channels/client-server-service-wire.ts +37 -36
  341. package/src/runtime/channels/dispatch-error-reporter.ts +12 -47
  342. package/src/runtime/channels/fanout-location-runtime.ts +91 -94
  343. package/src/runtime/channels/fanout-service-wire.ts +5 -12
  344. package/src/runtime/channels/handler-filter-scope.ts +1 -4
  345. package/src/runtime/channels/index.ts +1 -4
  346. package/src/runtime/channels/local-spot-route-transport.ts +20 -5
  347. package/src/runtime/channels/route-member-snapshot.ts +11 -5
  348. package/src/runtime/channels/router-socket-spot-route-transport.ts +1 -7
  349. package/src/runtime/channels/source-spot-router.ts +26 -22
  350. package/src/runtime/channels/spot-direct-envelope.ts +10 -8
  351. package/src/runtime/channels/spot-node-route-transport.ts +13 -16
  352. package/src/runtime/channels/spot-route-bridge-transport.ts +26 -9
  353. package/src/runtime/channels/spot-route-dispatch-strategy.ts +40 -13
  354. package/src/runtime/channels/spot-route-target-resolver.ts +18 -9
  355. package/src/runtime/codecs/index.ts +3 -2
  356. package/src/runtime/diagnostics/dispatch-error-details.ts +62 -0
  357. package/src/runtime/diagnostics/flow-context.ts +18 -7
  358. package/src/runtime/diagnostics/index.ts +96 -61
  359. package/src/runtime/diagnostics/internal-event-contracts.ts +87 -33
  360. package/src/runtime/diagnostics/message-flow.ts +107 -79
  361. package/src/runtime/diagnostics/runtime-metrics.ts +46 -24
  362. package/src/runtime/diagnostics/runtime-observation-queue.ts +17 -28
  363. package/src/runtime/diagnostics/topology-runtime-projections.ts +62 -43
  364. package/src/runtime/execution/index.ts +18 -26
  365. package/src/runtime/execution/serial-execution-queue.ts +31 -40
  366. package/src/runtime/execution/state-lane.ts +2 -2
  367. package/src/runtime/foundation/actor-join-recovery-codec.ts +69 -55
  368. package/src/runtime/foundation/event-loop-resources.ts +8 -4
  369. package/src/runtime/foundation/message-follow-suppression-registry.ts +7 -14
  370. package/src/runtime/foundation/operation-identity.ts +1 -2
  371. package/src/runtime/foundation/operation-registry.ts +8 -2
  372. package/src/runtime/foundation/raw-service-mesh-runtime.ts +364 -396
  373. package/src/runtime/foundation/route-mesh-connection-policy.ts +7 -8
  374. package/src/runtime/foundation/runtime-state-projections.ts +24 -23
  375. package/src/runtime/foundation/service-authority-payload-codec.ts +54 -57
  376. package/src/runtime/foundation/service-discovery-registry.ts +67 -59
  377. package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +28 -29
  378. package/src/runtime/foundation/service-liveness-registry.ts +18 -13
  379. package/src/runtime/foundation/service-mailbox.ts +14 -14
  380. package/src/runtime/foundation/service-maintenance-runtime.ts +22 -21
  381. package/src/runtime/foundation/service-metadata-codec.ts +2 -9
  382. package/src/runtime/foundation/service-relocation-aggregate-committer.ts +39 -36
  383. package/src/runtime/foundation/service-relocation-coordinator.ts +1 -4
  384. package/src/runtime/foundation/service-relocation-object-owner.ts +40 -58
  385. package/src/runtime/foundation/service-relocation-runtime.ts +292 -216
  386. package/src/runtime/foundation/service-runtime-contracts.ts +8 -8
  387. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -4
  388. package/src/runtime/foundation/service-stateful-registry.ts +69 -59
  389. package/src/runtime/foundation/service-stateful-runtime.ts +1233 -1112
  390. package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
  391. package/src/runtime/foundation/service-topology-registry.ts +170 -159
  392. package/src/runtime/foundation/service-weighted-selection.ts +9 -15
  393. package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -12
  394. package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -47
  395. package/src/runtime/framework-errors-internal.ts +31 -30
  396. package/src/runtime/handlers/handler-instance-scope.ts +18 -29
  397. package/src/runtime/handlers/index.ts +18 -8
  398. package/src/runtime/host/actor-packet-relay.ts +290 -261
  399. package/src/runtime/host/actor-placement-coordinator.ts +165 -150
  400. package/src/runtime/host/actor-runtime-options-factory.ts +89 -87
  401. package/src/runtime/host/actor-transfer-authority-runtime.ts +46 -38
  402. package/src/runtime/host/actor-transfer-runtime.ts +391 -395
  403. package/src/runtime/host/application-job-queue.ts +32 -48
  404. package/src/runtime/host/bound-session-relay.ts +7 -9
  405. package/src/runtime/host/channel-runtime-options-factory.ts +75 -35
  406. package/src/runtime/host/host-capacity-status.ts +10 -9
  407. package/src/runtime/host/index.ts +861 -789
  408. package/src/runtime/host/instance-activation-authority.ts +125 -143
  409. package/src/runtime/host/location-runtime-owner.ts +38 -26
  410. package/src/runtime/host/mesh-router-resolver.ts +30 -23
  411. package/src/runtime/host/relocation-direct-transfer.ts +15 -15
  412. package/src/runtime/host/relocation-integrity-fault-gate.ts +3 -2
  413. package/src/runtime/host/remote-actor-join-receiver.ts +43 -34
  414. package/src/runtime/host/remote-actor-packet-target-store.ts +54 -52
  415. package/src/runtime/host/remote-bound-session-relay.ts +274 -247
  416. package/src/runtime/host/route-mesh-runtime-options.ts +1 -3
  417. package/src/runtime/host/route-mesh-runtime.ts +227 -181
  418. package/src/runtime/host/runtime-shutdown.ts +4 -3
  419. package/src/runtime/host/service-relocation-control.ts +14 -5
  420. package/src/runtime/host/service-relocation-host-runtime.ts +1388 -1165
  421. package/src/runtime/host/spot-address-transport.ts +284 -237
  422. package/src/runtime/host/spot-node-runtime-options-factory.ts +14 -8
  423. package/src/runtime/host/spot-runtime-options-factory.ts +71 -62
  424. package/src/runtime/host/stateful-authority-route-runtime.ts +117 -116
  425. package/src/runtime/host/user-spot-creation-coordinator.ts +225 -220
  426. package/src/runtime/locations/actor-location-claims.ts +61 -49
  427. package/src/runtime/locations/actor-session-route-claims.ts +1 -4
  428. package/src/runtime/locations/aggregate-inventory-store.ts +105 -134
  429. package/src/runtime/locations/authority-key-codec.ts +13 -10
  430. package/src/runtime/locations/auto-connect-loop.ts +14 -11
  431. package/src/runtime/locations/auto-connect-planner.ts +42 -31
  432. package/src/runtime/locations/auto-connect-reconciler.ts +106 -63
  433. package/src/runtime/locations/canonical-codec.ts +3 -1
  434. package/src/runtime/locations/creation-operation-id.ts +4 -3
  435. package/src/runtime/locations/domain-store-contract.ts +13 -7
  436. package/src/runtime/locations/in-memory-authority-store.ts +232 -199
  437. package/src/runtime/locations/in-memory-location-store.ts +432 -250
  438. package/src/runtime/locations/in-memory-provider-location-store.ts +16 -17
  439. package/src/runtime/locations/internal-store-contracts.ts +95 -38
  440. package/src/runtime/locations/key-codec.ts +3 -4
  441. package/src/runtime/locations/lease-tracker.ts +36 -27
  442. package/src/runtime/locations/lifecycle-runtime.ts +15 -3
  443. package/src/runtime/locations/lifecycle.ts +33 -28
  444. package/src/runtime/locations/location-store-repository.ts +1329 -1185
  445. package/src/runtime/locations/opaque-record-key.ts +4 -9
  446. package/src/runtime/locations/resolvers.ts +201 -178
  447. package/src/runtime/locations/runtime.ts +251 -159
  448. package/src/runtime/locations/spot-location-claims.ts +110 -112
  449. package/src/runtime/messaging/creation-payload-codec.ts +4 -1
  450. package/src/runtime/messaging/framework-json-v1.ts +34 -15
  451. package/src/runtime/messaging/packet-name.ts +8 -6
  452. package/src/runtime/messaging/payload-codec.ts +70 -50
  453. package/src/runtime/messaging/submission-result.ts +6 -9
  454. package/src/runtime/protocol/service_wire_codec.generated.ts +1376 -159
  455. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +19 -18
  456. package/src/runtime/routing-id.ts +10 -7
  457. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +56 -62
  458. package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +23 -20
  459. package/src/runtime/spots/index.ts +595 -564
  460. package/src/runtime/spots/spot-activation-registry.ts +38 -34
  461. package/src/runtime/spots/spot-activation-state.ts +43 -51
  462. package/src/runtime/spots/spot-activation.ts +179 -116
  463. package/src/runtime/spots/spot-actor-admission-coordinator.ts +110 -78
  464. package/src/runtime/spots/spot-actor-join-dispatch.ts +57 -41
  465. package/src/runtime/spots/spot-actor-lifecycle-drain.ts +5 -7
  466. package/src/runtime/spots/spot-actor-membership.ts +25 -27
  467. package/src/runtime/spots/spot-actor-packet-dispatch.ts +196 -148
  468. package/src/runtime/spots/spot-actor-packet-drain.ts +56 -42
  469. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +37 -39
  470. package/src/runtime/spots/spot-closing.ts +11 -12
  471. package/src/runtime/spots/spot-context.ts +46 -26
  472. package/src/runtime/spots/spot-entry-activation.ts +84 -65
  473. package/src/runtime/spots/spot-handle.ts +17 -15
  474. package/src/runtime/spots/spot-handler-registry.ts +44 -31
  475. package/src/runtime/spots/spot-location-claim.ts +5 -4
  476. package/src/runtime/spots/spot-manager-public.ts +62 -82
  477. package/src/runtime/spots/spot-native-actor-join-admission.ts +20 -16
  478. package/src/runtime/spots/spot-node-autoconnect.ts +54 -61
  479. package/src/runtime/spots/spot-node-runtime-manager.ts +235 -222
  480. package/src/runtime/spots/spot-outbound.ts +47 -59
  481. package/src/runtime/spots/spot-publisher-transport.ts +5 -4
  482. package/src/runtime/spots/spot-remote-codec.ts +66 -65
  483. package/src/runtime/spots/spot-remote-route-codec.ts +61 -41
  484. package/src/runtime/spots/spot-route-packet-dispatch.ts +129 -95
  485. package/src/runtime/spots/spot-route-replies.ts +23 -24
  486. package/src/runtime/spots/spot-route-reply-wire.ts +3 -2
  487. package/src/runtime/spots/spot-routed-actor-admission.ts +37 -27
  488. package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +13 -18
  489. package/src/runtime/spots/spot-routed-frame-dispatch.ts +18 -15
  490. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +35 -26
  491. package/src/runtime/spots/spot-routing-internal.ts +1 -4
  492. package/src/runtime/spots/spot-runtime-ports.ts +5 -5
  493. package/src/runtime/spots/spot-serial-executor.ts +5 -9
  494. package/src/runtime/spots/spot-serial-turn-executor.ts +19 -26
  495. package/src/runtime/spots/spot-subscription-dispatch.ts +58 -47
  496. package/src/runtime/spots/spot-timer.ts +103 -91
  497. package/src/runtime/streams/actor-session-binding-registry.ts +421 -292
  498. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +8 -4
  499. package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
  500. package/src/runtime/streams/bound-actor-relay-sender.ts +60 -50
  501. package/src/runtime/streams/bound-session-response-target.ts +39 -9
  502. package/src/runtime/streams/bound-session-service.ts +52 -42
  503. package/src/runtime/streams/index.ts +183 -100
  504. package/src/runtime/streams/managed-stream.ts +123 -90
  505. package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
  506. package/src/runtime/streams/protocol.ts +115 -46
  507. package/src/runtime/streams/session-actor-coordinator.ts +109 -93
  508. package/src/runtime/streams/session-calls.ts +2 -8
  509. package/src/runtime/streams/session-context.ts +96 -51
  510. package/src/runtime/streams/session-local-actors.ts +19 -3
  511. package/src/runtime/streams/session-provider.ts +5 -7
  512. package/src/runtime/streams/session-serial-executor.ts +7 -6
  513. package/src/runtime/streams/stream-binding-runtime-ports.ts +79 -29
  514. package/src/runtime/streams/stream-frame-factory.ts +59 -40
  515. package/src/runtime/streams/stream-session-runtime.ts +317 -214
  516. package/src/runtime/workers/index.ts +68 -29
@@ -1,4 +1,7 @@
1
- import { ZLinkFrameworkInternalErrorKind, createInternalFrameworkException } from '../framework-errors-internal';
1
+ import {
2
+ ZLinkFrameworkInternalErrorKind,
3
+ createInternalFrameworkException
4
+ } from '../framework-errors-internal';
2
5
  import { createAbortError, throwIfAborted } from '../abort';
3
6
  import { AsyncResource } from 'node:async_hooks';
4
7
  import { ZLinkStateLane } from '../execution/state-lane';
@@ -15,7 +18,11 @@ export interface ZLinkActorSessionBindingActor {
15
18
 
16
19
  export interface ZLinkActorSessionBindingContext<TActor extends ZLinkActorSessionBindingActor> {
17
20
  readonly routingId?: unknown;
18
- bindLocal(actor: TActor, bindingToken: string): void;
21
+ readonly actorSlotControls?: {
22
+ enqueueBound(actorSlot: number, actorId: string): Promise<void>;
23
+ enqueueUnbound(actorSlot: number): Promise<void>;
24
+ };
25
+ bindLocal(actor: TActor, bindingToken: string, actorSlot?: number): void;
19
26
  unbindLocal(actorId: string, bindingToken: string): void;
20
27
  }
21
28
 
@@ -26,6 +33,7 @@ export interface ZLinkActorSessionRoute<
26
33
  readonly context: TContext;
27
34
  readonly actor: TActor;
28
35
  readonly bindingToken: string;
36
+ readonly actorSlot?: number;
29
37
  readonly sessionIdentity?: string;
30
38
  readonly activeFrames: ZLinkActorSessionActiveFrames;
31
39
  sealId?: string;
@@ -134,17 +142,26 @@ export interface ZLinkActorSessionAuthorityFence {
134
142
  readonly actorType?: string;
135
143
  }
136
144
 
145
+ export enum ZLinkActorSessionBindingTermination {
146
+ BindingEnd,
147
+ PhysicalDisconnect
148
+ }
149
+
137
150
  export class ZLinkActorSessionBindingRegistry<
138
151
  TContext extends ZLinkActorSessionBindingContext<TActor>,
139
152
  TActor extends ZLinkActorSessionBindingActor
140
153
  > {
141
154
  private readonly lane = new ZLinkStateLane();
142
155
  private readonly routes = new Map<string, ZLinkActorSessionRoute<TContext, TActor>>();
143
- private readonly sealWaiters = new Map<string, Set<{
144
- readonly bindingToken: string;
145
- readonly resolve: () => void;
146
- readonly reject: (error: unknown) => void;
147
- }>>();
156
+ private readonly nextActorSlots = new WeakMap<TContext, number>();
157
+ private readonly sealWaiters = new Map<
158
+ string,
159
+ Set<{
160
+ readonly bindingToken: string;
161
+ readonly resolve: () => void;
162
+ readonly reject: (error: unknown) => void;
163
+ }>
164
+ >();
148
165
  private readonly activeFrameWaiters = new Map<string, Set<ZLinkActorSessionActiveFrameWaiter>>();
149
166
  private readonly relocations = new Map<string, ZLinkActorSessionRelocationQueue>();
150
167
  private readonly terminalRelocations = new Map<ZLinkActorSessionRelocationState, true>();
@@ -158,7 +175,9 @@ export class ZLinkActorSessionBindingRegistry<
158
175
  // (the sealing side) must observe that bound; an unbounded wait here
159
176
  // turns a lost control or a lifecycle interlock into a silent stall
160
177
  // (spec 48:205 — transport/deadline limits apply during relocation).
161
- private readonly sealWaitTimeoutMs = 3_000
178
+ private readonly sealWaitTimeoutMs = 3_000,
179
+ private readonly errorSink?: () =>
180
+ { reportRuntimeTaskException(taskName: string, error: unknown): void } | undefined
162
181
  ) {
163
182
  if (!Number.isSafeInteger(terminalRelocationCapacity) || terminalRelocationCapacity <= 0) {
164
183
  throw new RangeError('Session relocation terminal capacity must be a positive safe integer.');
@@ -176,82 +195,120 @@ export class ZLinkActorSessionBindingRegistry<
176
195
  actor: TActor,
177
196
  bindingToken: string,
178
197
  authorityFence?: ZLinkActorSessionAuthorityFence,
179
- sessionIdentity?: string
198
+ sessionIdentity?: string,
199
+ commitActor?: () => void
180
200
  ): Promise<void> {
181
- await this.lane.run(() => this.bindCore(context, actor, bindingToken, authorityFence, sessionIdentity));
182
- }
183
-
184
- private bindCore(
185
- context: TContext,
186
- actor: TActor,
187
- bindingToken: string,
188
- authorityFence?: ZLinkActorSessionAuthorityFence,
189
- sessionIdentity?: string
190
- ): void {
191
- this.routes.set(actor.actorId, {
192
- context,
193
- actor,
194
- bindingToken,
195
- sessionIdentity: sessionIdentity ?? sessionIdentityFromContext(context),
196
- activeFrames: { count: 0, requests: new Set() },
197
- authorityFence
198
- });
199
- context.bindLocal(actor, bindingToken);
201
+ await this.lane.run(() =>
202
+ this.commitCore(
203
+ undefined,
204
+ context,
205
+ actor,
206
+ bindingToken,
207
+ authorityFence,
208
+ sessionIdentity,
209
+ commitActor
210
+ )
211
+ );
200
212
  }
201
213
 
202
- async replace(
203
- previous: ZLinkActorSessionRoute<TContext, TActor>,
214
+ private async commitCore(
215
+ previous: ZLinkActorSessionRoute<TContext, TActor> | undefined,
204
216
  context: TContext,
205
217
  actor: TActor,
206
218
  bindingToken: string,
207
219
  authorityFence?: ZLinkActorSessionAuthorityFence,
208
- sessionIdentity?: string
220
+ sessionIdentity?: string,
221
+ commitActor?: () => void
209
222
  ): Promise<void> {
210
- await this.lane.run(() => this.replaceCore(
211
- previous, context, actor, bindingToken, authorityFence, sessionIdentity
212
- ));
213
- }
214
-
215
- private replaceCore(
216
- previous: ZLinkActorSessionRoute<TContext, TActor>,
217
- context: TContext,
218
- actor: TActor,
219
- bindingToken: string,
220
- authorityFence?: ZLinkActorSessionAuthorityFence,
221
- sessionIdentity?: string
222
- ): void {
223
223
  const current = this.routes.get(actor.actorId);
224
224
  if (current !== previous) {
225
225
  throw createInternalFrameworkException(
226
226
  ZLinkFrameworkInternalErrorKind.ActorSessionNotBound,
227
- `Actor '${actor.actorId}' session binding changed before route replacement.`,
227
+ `Actor '${actor.actorId}' session binding changed before route commit.`,
228
228
  true
229
229
  );
230
230
  }
231
231
 
232
- context.bindLocal(actor, bindingToken);
233
- const sameLocalBinding = previous.context === context
234
- && previous.bindingToken === bindingToken;
235
- if (!sameLocalBinding) {
236
- try {
232
+ const sameBinding =
233
+ previous !== undefined &&
234
+ previous.context === context &&
235
+ previous.bindingToken === bindingToken;
236
+ const actorSlot = sameBinding ? previous.actorSlot : this.issueActorSlot(context);
237
+ commitActor?.();
238
+ context.bindLocal(actor, bindingToken, actorSlot);
239
+
240
+ try {
241
+ if (previous !== undefined && !sameBinding) {
242
+ this.routes.delete(actor.actorId);
237
243
  previous.context.unbindLocal(actor.actorId, previous.bindingToken);
238
- } catch (error) {
239
- context.unbindLocal(actor.actorId, bindingToken);
240
- previous.context.bindLocal(previous.actor, previous.bindingToken);
241
- throw error;
244
+ if (previous.actorSlot !== undefined) {
245
+ let unbound: Promise<void> | undefined;
246
+ try {
247
+ unbound = previous.context.actorSlotControls?.enqueueUnbound(previous.actorSlot);
248
+ } catch (error) {
249
+ unbound = Promise.reject(error);
250
+ }
251
+ void unbound?.catch((error) =>
252
+ this.errorSink?.()?.reportRuntimeTaskException('retired session actor unbound', error)
253
+ );
254
+ }
255
+ }
256
+
257
+ if (!sameBinding && actorSlot !== undefined) {
258
+ await context.actorSlotControls!.enqueueBound(actorSlot, actor.actorId);
242
259
  }
260
+ } catch (error) {
261
+ context.unbindLocal(actor.actorId, bindingToken);
262
+ throw error;
243
263
  }
264
+
244
265
  this.routes.set(actor.actorId, {
245
266
  context,
246
267
  actor,
247
268
  bindingToken,
269
+ actorSlot,
248
270
  sessionIdentity: sessionIdentity ?? sessionIdentityFromContext(context),
249
- activeFrames: previous.activeFrames,
250
- sealId: previous.sealId,
251
- authorityFence: authorityFence ?? previous.authorityFence
271
+ activeFrames: previous?.activeFrames ?? { count: 0, requests: new Set() },
272
+ sealId: previous?.sealId,
273
+ authorityFence: authorityFence ?? previous?.authorityFence
252
274
  });
253
275
  }
254
276
 
277
+ private issueActorSlot(context: TContext): number | undefined {
278
+ if (context.actorSlotControls === undefined) return undefined;
279
+ const actorSlot = this.nextActorSlots.get(context) ?? 1;
280
+ if (actorSlot > 0xffff) {
281
+ throw createInternalFrameworkException(
282
+ ZLinkFrameworkInternalErrorKind.InvalidOperation,
283
+ `Stream session '${String(context.routingId)}' exhausted its Actor slots.`
284
+ );
285
+ }
286
+ this.nextActorSlots.set(context, actorSlot + 1);
287
+ return actorSlot;
288
+ }
289
+
290
+ async replace(
291
+ previous: ZLinkActorSessionRoute<TContext, TActor>,
292
+ context: TContext,
293
+ actor: TActor,
294
+ bindingToken: string,
295
+ authorityFence?: ZLinkActorSessionAuthorityFence,
296
+ sessionIdentity?: string,
297
+ commitActor?: () => void
298
+ ): Promise<void> {
299
+ await this.lane.run(() =>
300
+ this.commitCore(
301
+ previous,
302
+ context,
303
+ actor,
304
+ bindingToken,
305
+ authorityFence,
306
+ sessionIdentity,
307
+ commitActor
308
+ )
309
+ );
310
+ }
311
+
255
312
  async replaceAndReleaseSeal(
256
313
  previous: ZLinkActorSessionRoute<TContext, TActor>,
257
314
  context: TContext,
@@ -259,22 +316,33 @@ export class ZLinkActorSessionBindingRegistry<
259
316
  bindingToken: string,
260
317
  sealId: string,
261
318
  authorityFence?: ZLinkActorSessionAuthorityFence,
262
- sessionIdentity?: string
319
+ sessionIdentity?: string,
320
+ commitActor?: () => void
263
321
  ): Promise<void> {
264
- await this.lane.run(() => this.replaceAndReleaseSealCore(
265
- previous, context, actor, bindingToken, sealId, authorityFence, sessionIdentity
266
- ));
322
+ await this.lane.run(() =>
323
+ this.replaceAndReleaseSealCore(
324
+ previous,
325
+ context,
326
+ actor,
327
+ bindingToken,
328
+ sealId,
329
+ authorityFence,
330
+ sessionIdentity,
331
+ commitActor
332
+ )
333
+ );
267
334
  }
268
335
 
269
- private replaceAndReleaseSealCore(
336
+ private async replaceAndReleaseSealCore(
270
337
  previous: ZLinkActorSessionRoute<TContext, TActor>,
271
338
  context: TContext,
272
339
  actor: TActor,
273
340
  bindingToken: string,
274
341
  sealId: string,
275
342
  authorityFence?: ZLinkActorSessionAuthorityFence,
276
- sessionIdentity?: string
277
- ): void {
343
+ sessionIdentity?: string,
344
+ commitActor?: () => void
345
+ ): Promise<void> {
278
346
  if (previous.sealId !== sealId) {
279
347
  throw createInternalFrameworkException(
280
348
  ZLinkFrameworkInternalErrorKind.ActorLocationStale,
@@ -285,7 +353,15 @@ export class ZLinkActorSessionBindingRegistry<
285
353
  // JavaScript cannot interleave another ingress turn between these two
286
354
  // synchronous mutations. The replacement preserves the seal, then the
287
355
  // exact release publishes the route to held ingress as one owner turn.
288
- this.replaceCore(previous, context, actor, bindingToken, authorityFence, sessionIdentity);
356
+ await this.commitCore(
357
+ previous,
358
+ context,
359
+ actor,
360
+ bindingToken,
361
+ authorityFence,
362
+ sessionIdentity,
363
+ commitActor
364
+ );
289
365
  if (!this.abortSealCore(actor.actorId, sealId)) {
290
366
  throw createInternalFrameworkException(
291
367
  ZLinkFrameworkInternalErrorKind.ActorLocationStale,
@@ -316,7 +392,9 @@ export class ZLinkActorSessionBindingRegistry<
316
392
  actor: ZLinkActorSessionBindingActor,
317
393
  bindingToken: string
318
394
  ): Promise<{ readonly context: TContext } | undefined> {
319
- return await this.lane.run(() => this.capturePendingReplyClaimCore(actorId, actor, bindingToken));
395
+ return await this.lane.run(() =>
396
+ this.capturePendingReplyClaimCore(actorId, actor, bindingToken)
397
+ );
320
398
  }
321
399
 
322
400
  private capturePendingReplyClaimCore(
@@ -331,11 +409,21 @@ export class ZLinkActorSessionBindingRegistry<
331
409
  return Object.freeze({ context: route.context });
332
410
  }
333
411
 
334
- async unbind(actorId: string, context: TContext, bindingToken: string): Promise<void> {
335
- await this.lane.run(() => this.unbindCore(actorId, context, bindingToken));
412
+ async unbind(
413
+ actorId: string,
414
+ context: TContext,
415
+ bindingToken: string,
416
+ termination = ZLinkActorSessionBindingTermination.BindingEnd
417
+ ): Promise<void> {
418
+ await this.lane.run(() => this.unbindCore(actorId, context, bindingToken, termination));
336
419
  }
337
420
 
338
- private unbindCore(actorId: string, context: TContext, bindingToken: string): void {
421
+ private async unbindCore(
422
+ actorId: string,
423
+ context: TContext,
424
+ bindingToken: string,
425
+ termination: ZLinkActorSessionBindingTermination
426
+ ): Promise<void> {
339
427
  const route = this.routes.get(actorId);
340
428
  if (route === undefined || route.context !== context || route.bindingToken !== bindingToken) {
341
429
  return;
@@ -355,28 +443,44 @@ export class ZLinkActorSessionBindingRegistry<
355
443
  route,
356
444
  new Error(`Actor '${actorId}' session binding was removed.`)
357
445
  );
446
+ if (
447
+ termination === ZLinkActorSessionBindingTermination.BindingEnd &&
448
+ route.actorSlot !== undefined
449
+ ) {
450
+ await context.actorSlotControls?.enqueueUnbound(route.actorSlot);
451
+ }
358
452
  }
359
453
 
360
454
  async unbindActor(actorId: string): Promise<void> {
361
455
  await this.lane.run(() => this.unbindActorCore(actorId));
362
456
  }
363
457
 
364
- private unbindActorCore(actorId: string): void {
458
+ private async unbindActorCore(actorId: string): Promise<void> {
365
459
  const route = this.routes.get(actorId);
366
460
  if (route === undefined) {
367
461
  return;
368
462
  }
369
- this.unbindCore(actorId, route.context, route.bindingToken);
463
+ await this.unbindCore(
464
+ actorId,
465
+ route.context,
466
+ route.bindingToken,
467
+ ZLinkActorSessionBindingTermination.BindingEnd
468
+ );
370
469
  }
371
470
 
372
471
  async cleanup(context: TContext): Promise<void> {
373
472
  await this.lane.run(() => this.cleanupCore(context));
374
473
  }
375
474
 
376
- private cleanupCore(context: TContext): void {
475
+ private async cleanupCore(context: TContext): Promise<void> {
377
476
  for (const route of [...this.routes.values()]) {
378
477
  if (route.context === context) {
379
- this.unbindCore(route.actor.actorId, context, route.bindingToken);
478
+ await this.unbindCore(
479
+ route.actor.actorId,
480
+ context,
481
+ route.bindingToken,
482
+ ZLinkActorSessionBindingTermination.PhysicalDisconnect
483
+ );
380
484
  }
381
485
  }
382
486
  }
@@ -476,7 +580,9 @@ export class ZLinkActorSessionBindingRegistry<
476
580
  ): Promise<ZLinkActorSessionFrameAdmission> {
477
581
  for (;;) {
478
582
  throwIfAborted(signal);
479
- const admission = await this.lane.run(() => this.beginAcceptedFrameCore(actorId, bindingToken));
583
+ const admission = await this.lane.run(() =>
584
+ this.beginAcceptedFrameCore(actorId, bindingToken)
585
+ );
480
586
  if (admission !== undefined) return admission;
481
587
  await this.waitForSealRelease(actorId, bindingToken, signal);
482
588
  }
@@ -496,8 +602,8 @@ export class ZLinkActorSessionBindingRegistry<
496
602
  completed = true;
497
603
  route.activeFrames.count--;
498
604
  if (
499
- route.activeFrames.count === 0
500
- && this.routes.get(actorId)?.activeFrames === route.activeFrames
605
+ route.activeFrames.count === 0 &&
606
+ this.routes.get(actorId)?.activeFrames === route.activeFrames
501
607
  ) {
502
608
  this.resolveActiveFrameWaiters(actorId);
503
609
  }
@@ -516,7 +622,9 @@ export class ZLinkActorSessionBindingRegistry<
516
622
  signal?: AbortSignal
517
623
  ): Promise<ZLinkActorSessionRequestFrameAdmission> {
518
624
  const frame = await this.beginAcceptedFrameWhenReady(actorId, bindingToken, signal);
519
- return await this.lane.run(() => this.beginAcceptedRequestFrameCore(actorId, bindingToken, frame));
625
+ return await this.lane.run(() =>
626
+ this.beginAcceptedRequestFrameCore(actorId, bindingToken, frame)
627
+ );
520
628
  }
521
629
 
522
630
  private beginAcceptedRequestFrameCore(
@@ -570,11 +678,7 @@ export class ZLinkActorSessionBindingRegistry<
570
678
  operation: () => Promise<TResult>,
571
679
  signal?: AbortSignal
572
680
  ): Promise<TResult> {
573
- const admission = await this.beginAcceptedFrameWhenReady(
574
- actorId,
575
- bindingToken,
576
- signal
577
- );
681
+ const admission = await this.beginAcceptedFrameWhenReady(actorId, bindingToken, signal);
578
682
  try {
579
683
  return await operation();
580
684
  } finally {
@@ -582,7 +686,11 @@ export class ZLinkActorSessionBindingRegistry<
582
686
  }
583
687
  }
584
688
 
585
- async seal(actorId: string, sealId: string, expected: ZLinkActorSessionRouteFence): Promise<void> {
689
+ async seal(
690
+ actorId: string,
691
+ sealId: string,
692
+ expected: ZLinkActorSessionRouteFence
693
+ ): Promise<void> {
586
694
  await this.lane.run(() => this.sealCore(actorId, sealId, expected));
587
695
  }
588
696
 
@@ -658,9 +766,8 @@ export class ZLinkActorSessionBindingRegistry<
658
766
  assertRelocationClaim(existing, claim);
659
767
  return { kind: 'existing', wait: existing.ready };
660
768
  }
661
- const predecessor = queue?.activeSealId === undefined
662
- ? undefined
663
- : queue.seals.get(queue.activeSealId);
769
+ const predecessor =
770
+ queue?.activeSealId === undefined ? undefined : queue.seals.get(queue.activeSealId);
664
771
  if (predecessor !== undefined && predecessor.phase !== 'terminal') {
665
772
  if (predecessor.sessionIdentity === undefined || claim.sessionIdentity === undefined) {
666
773
  throw createInternalFrameworkException(
@@ -675,7 +782,9 @@ export class ZLinkActorSessionBindingRegistry<
675
782
 
676
783
  this.sealCore(claim.actorId, claim.sealId, expected);
677
784
  let resolveTerminal!: () => void;
678
- const terminal = new Promise<void>((resolve) => { resolveTerminal = resolve; });
785
+ const terminal = new Promise<void>((resolve) => {
786
+ resolveTerminal = resolve;
787
+ });
679
788
  const ready = this.waitForActiveFramesCore(claim.actorId, signal);
680
789
  const actorQueue: ZLinkActorSessionRelocationQueue = queue ?? {
681
790
  actorId: claim.actorId,
@@ -716,7 +825,9 @@ export class ZLinkActorSessionBindingRegistry<
716
825
  operation: ZLinkActorSessionRetainedOutbound,
717
826
  sealId?: string
718
827
  ): Promise<ServiceSessionBindingAdmissionResult> {
719
- return await this.lane.run(() => this.retainRelocationOutboundCorePublic(actorId, operation, sealId));
828
+ return await this.lane.run(() =>
829
+ this.retainRelocationOutboundCorePublic(actorId, operation, sealId)
830
+ );
720
831
  }
721
832
 
722
833
  private retainRelocationOutboundCorePublic(
@@ -728,10 +839,10 @@ export class ZLinkActorSessionBindingRegistry<
728
839
  const queue = this.relocations.get(actorId);
729
840
  const state = queue?.seals.get(sealId);
730
841
  if (
731
- queue === undefined
732
- || state === undefined
733
- || (queue.activeSealId !== sealId
734
- && !(queue.activeSealId === undefined && state.phase === 'terminal'))
842
+ queue === undefined ||
843
+ state === undefined ||
844
+ (queue.activeSealId !== sealId &&
845
+ !(queue.activeSealId === undefined && state.phase === 'terminal'))
735
846
  ) {
736
847
  failRetainedOutbound(
737
848
  operation,
@@ -755,9 +866,8 @@ export class ZLinkActorSessionBindingRegistry<
755
866
  operation: ZLinkActorSessionRetainedOutbound
756
867
  ): ServiceSessionBindingAdmissionResult {
757
868
  const queue = this.relocations.get(claim.actorId);
758
- const state = queue?.activeSealId === undefined
759
- ? undefined
760
- : queue.seals.get(queue.activeSealId);
869
+ const state =
870
+ queue?.activeSealId === undefined ? undefined : queue.seals.get(queue.activeSealId);
761
871
  const error = this.outboundAdmissionError(claim);
762
872
  if (error !== undefined) {
763
873
  failRetainedOutbound(operation, error);
@@ -767,48 +877,32 @@ export class ZLinkActorSessionBindingRegistry<
767
877
  if (!this.matchesCurrentProducerNode(claim)) {
768
878
  failRetainedOutbound(
769
879
  operation,
770
- new Error(`Actor '${claim.actorId}' Session outbound admission was fenced by its current binding.`)
880
+ new Error(
881
+ `Actor '${claim.actorId}' Session outbound admission was fenced by its current binding.`
882
+ )
771
883
  );
772
884
  return 'rejected';
773
885
  }
774
886
  if (queue === undefined) return 'passThrough';
775
- return this.retainRelocationOutboundCore(
776
- claim.actorId,
777
- operation,
778
- 'source',
779
- claim
780
- );
887
+ return this.retainRelocationOutboundCore(claim.actorId, operation, 'source', claim);
781
888
  }
782
889
  if (state.phase === 'sealed' || state.phase === 'applying') {
783
890
  const matchesSource = matchesRelocationSourceProof(state, claim);
784
891
  const matchesCurrent = this.matchesCurrentProducerNode(claim);
785
- const authorization = matchesSource || matchesCurrent
786
- ? 'source'
787
- : 'pendingTarget';
788
- return this.retainRelocationOutboundCore(
789
- claim.actorId,
790
- operation,
791
- authorization,
792
- claim
793
- );
892
+ const authorization = matchesSource || matchesCurrent ? 'source' : 'pendingTarget';
893
+ return this.retainRelocationOutboundCore(claim.actorId, operation, authorization, claim);
794
894
  }
795
895
  const acceptedProof = state.acceptedProducerProof;
796
- if (
797
- acceptedProof === undefined
798
- || !matchesAcceptedProducerProof(acceptedProof, claim)
799
- ) {
896
+ if (acceptedProof === undefined || !matchesAcceptedProducerProof(acceptedProof, claim)) {
800
897
  failRetainedOutbound(
801
898
  operation,
802
- new Error(`Actor '${claim.actorId}' Session outbound admission did not match its accepted producer proof.`)
899
+ new Error(
900
+ `Actor '${claim.actorId}' Session outbound admission did not match its accepted producer proof.`
901
+ )
803
902
  );
804
903
  return 'rejected';
805
904
  }
806
- return this.retainRelocationOutboundCore(
807
- claim.actorId,
808
- operation,
809
- 'source',
810
- claim
811
- );
905
+ return this.retainRelocationOutboundCore(claim.actorId, operation, 'source', claim);
812
906
  }
813
907
 
814
908
  private retainRelocationOutboundCore(
@@ -818,9 +912,8 @@ export class ZLinkActorSessionBindingRegistry<
818
912
  claim?: ServiceSessionBindingAdmissionClaim
819
913
  ): ServiceSessionBindingAdmissionResult {
820
914
  const queue = this.relocations.get(actorId);
821
- const state = queue?.activeSealId === undefined
822
- ? undefined
823
- : queue.seals.get(queue.activeSealId);
915
+ const state =
916
+ queue?.activeSealId === undefined ? undefined : queue.seals.get(queue.activeSealId);
824
917
  if (queue === undefined) return 'passThrough';
825
918
  if (state === undefined || state.phase === 'applied' || state.phase === 'terminal') {
826
919
  if (queue.drainPromise === undefined && queue.outbound.length === 0) return 'passThrough';
@@ -873,13 +966,9 @@ export class ZLinkActorSessionBindingRegistry<
873
966
  commitOwnerTransition: () => Promise<void>,
874
967
  acceptedProducerProof?: ZLinkActorSessionAcceptedProducerProof
875
968
  ): Promise<void> {
876
- const prepared = await this.lane.run(() => this.prepareRelocationApply(
877
- actorId,
878
- sealId,
879
- applyFingerprint,
880
- action,
881
- acceptedProducerProof
882
- ));
969
+ const prepared = await this.lane.run(() =>
970
+ this.prepareRelocationApply(actorId, sealId, applyFingerprint, action, acceptedProducerProof)
971
+ );
883
972
  if (prepared.applyPromise !== undefined) {
884
973
  await prepared.applyPromise;
885
974
  return;
@@ -937,9 +1026,9 @@ export class ZLinkActorSessionBindingRegistry<
937
1026
  return { queue, state, applyPromise: state.applyPromise };
938
1027
  }
939
1028
  if (
940
- action === 'commit'
941
- && acceptedProducerProof !== undefined
942
- && !validAcceptedTargetProof(state, acceptedProducerProof)
1029
+ action === 'commit' &&
1030
+ acceptedProducerProof !== undefined &&
1031
+ !validAcceptedTargetProof(state, acceptedProducerProof)
943
1032
  ) {
944
1033
  throw createInternalFrameworkException(
945
1034
  ZLinkFrameworkInternalErrorKind.ActorLocationStale,
@@ -986,9 +1075,10 @@ export class ZLinkActorSessionBindingRegistry<
986
1075
  readonly sealId?: string;
987
1076
  }): void {
988
1077
  const { queue, state, action, acceptedProducerProof, actorId, sealId } = prepared;
989
- const proof = action === 'commit'
990
- ? acceptedProducerProof ?? this.currentProducerProof(actorId!)
991
- : relocationSourceProof(state);
1078
+ const proof =
1079
+ action === 'commit'
1080
+ ? (acceptedProducerProof ?? this.currentProducerProof(actorId!))
1081
+ : relocationSourceProof(state);
992
1082
  state.acceptedProducerProof = proof;
993
1083
  for (let index = queue.outbound.length - 1; index >= 0; index--) {
994
1084
  const entry = queue.outbound[index]!;
@@ -998,10 +1088,10 @@ export class ZLinkActorSessionBindingRegistry<
998
1088
  continue;
999
1089
  }
1000
1090
  if (
1001
- action === 'commit'
1002
- && proof !== undefined
1003
- && entry.claim !== undefined
1004
- && matchesAcceptedProducerProof(proof, entry.claim)
1091
+ action === 'commit' &&
1092
+ proof !== undefined &&
1093
+ entry.claim !== undefined &&
1094
+ matchesAcceptedProducerProof(proof, entry.claim)
1005
1095
  ) {
1006
1096
  entry.released = true;
1007
1097
  continue;
@@ -1030,27 +1120,32 @@ export class ZLinkActorSessionBindingRegistry<
1030
1120
  actorId: string
1031
1121
  ): ZLinkActorSessionAcceptedProducerProof | undefined {
1032
1122
  const route = this.routes.get(actorId);
1033
- const actorRef = (route?.actor as TActor & { readonly ref?: {
1034
- readonly actorId?: unknown;
1035
- readonly objectGeneration?: unknown;
1036
- readonly generation?: unknown;
1037
- readonly nodeRid?: unknown;
1038
- readonly ownerNodeGeneration?: unknown;
1039
- readonly bindingGeneration?: unknown;
1040
- } }).ref;
1123
+ const actorRef = (
1124
+ route?.actor as TActor & {
1125
+ readonly ref?: {
1126
+ readonly actorId?: unknown;
1127
+ readonly objectGeneration?: unknown;
1128
+ readonly generation?: unknown;
1129
+ readonly nodeRid?: unknown;
1130
+ readonly ownerNodeGeneration?: unknown;
1131
+ readonly bindingGeneration?: unknown;
1132
+ };
1133
+ }
1134
+ ).ref;
1041
1135
  const sessionIdentity = route?.sessionIdentity;
1042
1136
  if (
1043
- route === undefined
1044
- || actorRef === undefined
1045
- || sessionIdentity === undefined
1046
- || actorRef.ownerNodeGeneration === undefined
1047
- ) return undefined;
1137
+ route === undefined ||
1138
+ actorRef === undefined ||
1139
+ sessionIdentity === undefined ||
1140
+ actorRef.ownerNodeGeneration === undefined
1141
+ )
1142
+ return undefined;
1048
1143
  return {
1049
1144
  actorId,
1050
1145
  objectGeneration: BigInt(
1051
- actorRef.objectGeneration as bigint | number | string | boolean | undefined
1052
- ?? actorRef.generation as bigint | number | string | boolean | undefined
1053
- ?? -1
1146
+ (actorRef.objectGeneration as bigint | number | string | boolean | undefined) ??
1147
+ (actorRef.generation as bigint | number | string | boolean | undefined) ??
1148
+ -1
1054
1149
  ),
1055
1150
  actorNodeRid: String(actorRef.nodeRid ?? ''),
1056
1151
  actorNodeGeneration: BigInt(
@@ -1058,7 +1153,7 @@ export class ZLinkActorSessionBindingRegistry<
1058
1153
  ),
1059
1154
  sessionIdentity: String(sessionIdentity),
1060
1155
  bindingGeneration: BigInt(
1061
- actorRef.bindingGeneration as bigint | number | string | boolean | undefined ?? -1
1156
+ (actorRef.bindingGeneration as bigint | number | string | boolean | undefined) ?? -1
1062
1157
  )
1063
1158
  };
1064
1159
  }
@@ -1068,7 +1163,9 @@ export class ZLinkActorSessionBindingRegistry<
1068
1163
  sealId: string,
1069
1164
  applyFingerprint: string
1070
1165
  ): Promise<void> {
1071
- await this.lane.run(() => this.observeRelocationTerminalCore(actorId, sealId, applyFingerprint));
1166
+ await this.lane.run(() =>
1167
+ this.observeRelocationTerminalCore(actorId, sealId, applyFingerprint)
1168
+ );
1072
1169
  }
1073
1170
 
1074
1171
  private observeRelocationTerminalCore(
@@ -1079,10 +1176,10 @@ export class ZLinkActorSessionBindingRegistry<
1079
1176
  const queue = this.relocations.get(actorId);
1080
1177
  const state = queue?.seals.get(sealId);
1081
1178
  if (
1082
- queue === undefined
1083
- || state === undefined
1084
- || state.applyFingerprint !== applyFingerprint
1085
- || (state.phase !== 'applied' && state.phase !== 'terminal')
1179
+ queue === undefined ||
1180
+ state === undefined ||
1181
+ state.applyFingerprint !== applyFingerprint ||
1182
+ (state.phase !== 'applied' && state.phase !== 'terminal')
1086
1183
  ) {
1087
1184
  throw createInternalFrameworkException(
1088
1185
  ZLinkFrameworkInternalErrorKind.ActorLocationStale,
@@ -1143,9 +1240,10 @@ export class ZLinkActorSessionBindingRegistry<
1143
1240
  if (queue === undefined) return;
1144
1241
  const activeSealId = queue.activeSealId;
1145
1242
  const activeState = activeSealId === undefined ? undefined : queue.seals.get(activeSealId);
1146
- const ownsActiveSeal = activeState !== undefined
1147
- && activeState.phase !== 'terminal'
1148
- && activeState.sessionIdentity === route.sessionIdentity;
1243
+ const ownsActiveSeal =
1244
+ activeState !== undefined &&
1245
+ activeState.phase !== 'terminal' &&
1246
+ activeState.sessionIdentity === route.sessionIdentity;
1149
1247
  if (!ownsActiveSeal) {
1150
1248
  // Nothing this exact route still holds open — leave terminal
1151
1249
  // retention and any other Session's active seal untouched.
@@ -1184,7 +1282,10 @@ export class ZLinkActorSessionBindingRegistry<
1184
1282
  await this.lane.run(() => this.updateAuthorityFenceCore(actorId, authorityFence));
1185
1283
  }
1186
1284
 
1187
- private updateAuthorityFenceCore(actorId: string, authorityFence: ZLinkActorSessionAuthorityFence): void {
1285
+ private updateAuthorityFenceCore(
1286
+ actorId: string,
1287
+ authorityFence: ZLinkActorSessionAuthorityFence
1288
+ ): void {
1188
1289
  const route = this.requireRouteCore(actorId);
1189
1290
  route.authorityFence = authorityFence;
1190
1291
  }
@@ -1195,8 +1296,7 @@ export class ZLinkActorSessionBindingRegistry<
1195
1296
 
1196
1297
  private validateSealCore(actorId: string, sealId: string): boolean {
1197
1298
  const route = this.routes.get(actorId);
1198
- return route !== undefined
1199
- && route.sealId === sealId;
1299
+ return route !== undefined && route.sealId === sealId;
1200
1300
  }
1201
1301
 
1202
1302
  /** True while a relocation seal currently holds this actor's ingress. */
@@ -1254,16 +1354,20 @@ export class ZLinkActorSessionBindingRegistry<
1254
1354
  waiters.delete(waiter);
1255
1355
  if (waiters.size === 0) this.sealWaiters.delete(actorId);
1256
1356
  };
1257
- timer = startOutsideStateLane(() => setTimeout(() => {
1258
- this.lane.tryPost(() => {
1259
- removeWaiter();
1260
- rejectWaiter(createInternalFrameworkException(
1261
- ZLinkFrameworkInternalErrorKind.DeadlineExceeded,
1262
- `Actor '${actorId}' session seal was not released within the relocation seal timeout.`,
1263
- true
1264
- ));
1265
- });
1266
- }, this.sealWaitTimeoutMs));
1357
+ timer = startOutsideStateLane(() =>
1358
+ setTimeout(() => {
1359
+ this.lane.tryPost(() => {
1360
+ removeWaiter();
1361
+ rejectWaiter(
1362
+ createInternalFrameworkException(
1363
+ ZLinkFrameworkInternalErrorKind.DeadlineExceeded,
1364
+ `Actor '${actorId}' session seal was not released within the relocation seal timeout.`,
1365
+ true
1366
+ )
1367
+ );
1368
+ });
1369
+ }, this.sealWaitTimeoutMs)
1370
+ );
1267
1371
  timer.unref();
1268
1372
  const onAbort = () => {
1269
1373
  this.lane.tryPost(() => {
@@ -1324,17 +1428,21 @@ export class ZLinkActorSessionBindingRegistry<
1324
1428
  // Spec 48:205 — transport/deadline limits keep applying during
1325
1429
  // relocation: the sealing side must not wait forever for active
1326
1430
  // frames that themselves may be waiting on this relocation.
1327
- timer = startOutsideStateLane(() => setTimeout(() => {
1328
- this.lane.tryPost(() => {
1329
- waiters.delete(waiter);
1330
- if (waiters.size === 0) this.activeFrameWaiters.delete(actorId);
1331
- waiter.reject(createInternalFrameworkException(
1332
- ZLinkFrameworkInternalErrorKind.DeadlineExceeded,
1333
- `Actor '${actorId}' session seal timed out waiting for active frames.`,
1334
- true
1335
- ));
1336
- });
1337
- }, this.sealWaitTimeoutMs));
1431
+ timer = startOutsideStateLane(() =>
1432
+ setTimeout(() => {
1433
+ this.lane.tryPost(() => {
1434
+ waiters.delete(waiter);
1435
+ if (waiters.size === 0) this.activeFrameWaiters.delete(actorId);
1436
+ waiter.reject(
1437
+ createInternalFrameworkException(
1438
+ ZLinkFrameworkInternalErrorKind.DeadlineExceeded,
1439
+ `Actor '${actorId}' session seal timed out waiting for active frames.`,
1440
+ true
1441
+ )
1442
+ );
1443
+ });
1444
+ }, this.sealWaitTimeoutMs)
1445
+ );
1338
1446
  timer.unref();
1339
1447
  if (signal === undefined) return;
1340
1448
  if (signal.aborted) onAbort();
@@ -1375,11 +1483,14 @@ export class ZLinkActorSessionBindingRegistry<
1375
1483
  const delivered = await entry.operation.deliver();
1376
1484
  await this.lane.run(() => {
1377
1485
  if (delivered) this.settleOutbound(queue, entry);
1378
- else this.failOutbound(
1379
- queue,
1380
- entry,
1381
- new Error(`Actor '${queue.actorId}' retained Session outbound delivery was rejected.`)
1382
- );
1486
+ else
1487
+ this.failOutbound(
1488
+ queue,
1489
+ entry,
1490
+ new Error(
1491
+ `Actor '${queue.actorId}' retained Session outbound delivery was rejected.`
1492
+ )
1493
+ );
1383
1494
  if (queue.outbound[0] === entry) queue.outbound.shift();
1384
1495
  });
1385
1496
  } catch (error) {
@@ -1391,11 +1502,14 @@ export class ZLinkActorSessionBindingRegistry<
1391
1502
  }
1392
1503
  });
1393
1504
  startOutsideStateLane(() => {
1394
- void drain.finally(async () => await this.lane.run(() => {
1395
- if (queue.drainPromise === drain) queue.drainPromise = undefined;
1396
- if (queue.outbound[0]?.released === true) this.startOutboundDrain(queue);
1397
- else this.deleteEmptyRelocationQueue(queue);
1398
- }));
1505
+ void drain.finally(
1506
+ async () =>
1507
+ await this.lane.run(() => {
1508
+ if (queue.drainPromise === drain) queue.drainPromise = undefined;
1509
+ if (queue.outbound[0]?.released === true) this.startOutboundDrain(queue);
1510
+ else this.deleteEmptyRelocationQueue(queue);
1511
+ })
1512
+ );
1399
1513
  });
1400
1514
  queue.drainPromise = drain;
1401
1515
  }
@@ -1434,59 +1548,69 @@ export class ZLinkActorSessionBindingRegistry<
1434
1548
  failRetainedOutbound(entry.operation, error);
1435
1549
  }
1436
1550
 
1437
- private outboundAdmissionError(
1438
- claim: ServiceSessionBindingAdmissionClaim
1439
- ): Error | undefined {
1551
+ private outboundAdmissionError(claim: ServiceSessionBindingAdmissionClaim): Error | undefined {
1440
1552
  if (
1441
- claim.actorId.length === 0
1442
- || claim.objectGeneration <= 0n
1443
- || claim.actorNodeRid.length === 0
1444
- || claim.actorNodeGeneration <= 0n
1445
- || claim.producerNodeRid.length === 0
1446
- || claim.producerNodeGeneration <= 0n
1447
- || claim.bindingGeneration <= 0n
1448
- || claim.sessionIdentity.length === 0
1449
- || !routingIdsEqual(claim.producerNodeRid, claim.actorNodeRid)
1450
- || claim.producerNodeGeneration !== claim.actorNodeGeneration
1553
+ claim.actorId.length === 0 ||
1554
+ claim.objectGeneration <= 0n ||
1555
+ claim.actorNodeRid.length === 0 ||
1556
+ claim.actorNodeGeneration <= 0n ||
1557
+ claim.producerNodeRid.length === 0 ||
1558
+ claim.producerNodeGeneration <= 0n ||
1559
+ claim.bindingGeneration <= 0n ||
1560
+ claim.sessionIdentity.length === 0 ||
1561
+ !routingIdsEqual(claim.producerNodeRid, claim.actorNodeRid) ||
1562
+ claim.producerNodeGeneration !== claim.actorNodeGeneration
1451
1563
  ) {
1452
1564
  return new Error(`Actor '${claim.actorId}' Session outbound admission claim is invalid.`);
1453
1565
  }
1454
1566
  const route = this.routes.get(claim.actorId);
1455
- const ref = route?.actor as (TActor & { readonly ref?: {
1456
- readonly actorId?: unknown;
1457
- readonly objectGeneration?: unknown;
1458
- readonly generation?: unknown;
1459
- readonly bindingGeneration?: unknown;
1460
- } }) | undefined;
1567
+ const ref = route?.actor as
1568
+ | (TActor & {
1569
+ readonly ref?: {
1570
+ readonly actorId?: unknown;
1571
+ readonly objectGeneration?: unknown;
1572
+ readonly generation?: unknown;
1573
+ readonly bindingGeneration?: unknown;
1574
+ };
1575
+ })
1576
+ | undefined;
1461
1577
  const actorRef = ref?.ref;
1462
1578
  const routeSessionIdentity = route?.sessionIdentity;
1463
1579
  if (
1464
- route === undefined
1465
- || actorRef === undefined
1466
- || String(actorRef.actorId ?? claim.actorId) !== claim.actorId
1467
- || BigInt(
1468
- actorRef.objectGeneration as bigint | number | string | boolean | undefined
1469
- ?? actorRef.generation as bigint | number | string | boolean | undefined
1470
- ?? -1
1471
- ) !== claim.objectGeneration
1472
- || BigInt(
1473
- actorRef.bindingGeneration as bigint | number | string | boolean | undefined ?? -1
1474
- ) !== claim.bindingGeneration
1475
- || String(routeSessionIdentity ?? '') !== claim.sessionIdentity
1580
+ route === undefined ||
1581
+ actorRef === undefined ||
1582
+ String(actorRef.actorId ?? claim.actorId) !== claim.actorId ||
1583
+ BigInt(
1584
+ (actorRef.objectGeneration as bigint | number | string | boolean | undefined) ??
1585
+ (actorRef.generation as bigint | number | string | boolean | undefined) ??
1586
+ -1
1587
+ ) !== claim.objectGeneration ||
1588
+ BigInt(
1589
+ (actorRef.bindingGeneration as bigint | number | string | boolean | undefined) ?? -1
1590
+ ) !== claim.bindingGeneration ||
1591
+ String(routeSessionIdentity ?? '') !== claim.sessionIdentity
1476
1592
  ) {
1477
- return new Error(`Actor '${claim.actorId}' Session outbound admission was fenced by its current binding.`);
1593
+ return new Error(
1594
+ `Actor '${claim.actorId}' Session outbound admission was fenced by its current binding.`
1595
+ );
1478
1596
  }
1479
1597
  return undefined;
1480
1598
  }
1481
1599
 
1482
1600
  private matchesCurrentProducerNode(claim: ServiceSessionBindingAdmissionClaim): boolean {
1483
1601
  const route = this.routes.get(claim.actorId);
1484
- const actorRef = (route?.actor as TActor & { readonly ref?: {
1485
- readonly nodeRid?: unknown;
1486
- } }).ref;
1487
- return route !== undefined
1488
- && actorRef !== undefined
1489
- && routingIdsEqual(String(actorRef.nodeRid ?? ''), claim.actorNodeRid);
1602
+ const actorRef = (
1603
+ route?.actor as TActor & {
1604
+ readonly ref?: {
1605
+ readonly nodeRid?: unknown;
1606
+ };
1607
+ }
1608
+ ).ref;
1609
+ return (
1610
+ route !== undefined &&
1611
+ actorRef !== undefined &&
1612
+ routingIdsEqual(String(actorRef.nodeRid ?? ''), claim.actorNodeRid)
1613
+ );
1490
1614
  }
1491
1615
 
1492
1616
  private rememberTerminalRelocation(state: ZLinkActorSessionRelocationState): void {
@@ -1507,11 +1631,11 @@ export class ZLinkActorSessionBindingRegistry<
1507
1631
 
1508
1632
  private deleteEmptyRelocationQueue(queue: ZLinkActorSessionRelocationQueue): void {
1509
1633
  if (
1510
- queue.activeSealId === undefined
1511
- && queue.seals.size === 0
1512
- && queue.outbound.length === 0
1513
- && queue.drainPromise === undefined
1514
- && this.relocations.get(queue.actorId) === queue
1634
+ queue.activeSealId === undefined &&
1635
+ queue.seals.size === 0 &&
1636
+ queue.outbound.length === 0 &&
1637
+ queue.drainPromise === undefined &&
1638
+ this.relocations.get(queue.actorId) === queue
1515
1639
  ) {
1516
1640
  this.relocations.delete(queue.actorId);
1517
1641
  }
@@ -1537,11 +1661,11 @@ function assertRelocationClaim(
1537
1661
  claim: ZLinkActorSessionRelocationClaim
1538
1662
  ): void {
1539
1663
  if (
1540
- state.actorGeneration !== claim.actorGeneration
1541
- || state.bindingGeneration !== claim.bindingGeneration
1542
- || state.sessionIdentity !== claim.sessionIdentity
1543
- || state.actorNodeRid !== claim.actorNodeRid
1544
- || state.actorNodeGeneration !== claim.actorNodeGeneration
1664
+ state.actorGeneration !== claim.actorGeneration ||
1665
+ state.bindingGeneration !== claim.bindingGeneration ||
1666
+ state.sessionIdentity !== claim.sessionIdentity ||
1667
+ state.actorNodeRid !== claim.actorNodeRid ||
1668
+ state.actorNodeGeneration !== claim.actorNodeGeneration
1545
1669
  ) {
1546
1670
  throw createInternalFrameworkException(
1547
1671
  ZLinkFrameworkInternalErrorKind.ActorLocationStale,
@@ -1559,47 +1683,54 @@ function matchesRelocationSourceProof(
1559
1683
  state: ZLinkActorSessionRelocationState,
1560
1684
  claim: ServiceSessionBindingAdmissionClaim
1561
1685
  ): boolean {
1562
- return state.actorId === claim.actorId
1563
- && state.actorGeneration === claim.objectGeneration
1564
- && state.bindingGeneration === claim.bindingGeneration
1565
- && state.sessionIdentity === claim.sessionIdentity
1566
- && state.actorNodeRid !== undefined
1567
- && routingIdsEqual(state.actorNodeRid, claim.actorNodeRid)
1568
- && state.actorNodeGeneration === claim.actorNodeGeneration;
1686
+ return (
1687
+ state.actorId === claim.actorId &&
1688
+ state.actorGeneration === claim.objectGeneration &&
1689
+ state.bindingGeneration === claim.bindingGeneration &&
1690
+ state.sessionIdentity === claim.sessionIdentity &&
1691
+ state.actorNodeRid !== undefined &&
1692
+ routingIdsEqual(state.actorNodeRid, claim.actorNodeRid) &&
1693
+ state.actorNodeGeneration === claim.actorNodeGeneration
1694
+ );
1569
1695
  }
1570
1696
 
1571
1697
  function matchesAcceptedProducerProof(
1572
1698
  proof: ZLinkActorSessionAcceptedProducerProof,
1573
1699
  claim: ServiceSessionBindingAdmissionClaim
1574
1700
  ): boolean {
1575
- return proof.actorId === claim.actorId
1576
- && proof.objectGeneration === claim.objectGeneration
1577
- && routingIdsEqual(proof.actorNodeRid, claim.actorNodeRid)
1578
- && proof.actorNodeGeneration === claim.actorNodeGeneration
1579
- && proof.sessionIdentity === claim.sessionIdentity
1580
- && proof.bindingGeneration === claim.bindingGeneration;
1701
+ return (
1702
+ proof.actorId === claim.actorId &&
1703
+ proof.objectGeneration === claim.objectGeneration &&
1704
+ routingIdsEqual(proof.actorNodeRid, claim.actorNodeRid) &&
1705
+ proof.actorNodeGeneration === claim.actorNodeGeneration &&
1706
+ proof.sessionIdentity === claim.sessionIdentity &&
1707
+ proof.bindingGeneration === claim.bindingGeneration
1708
+ );
1581
1709
  }
1582
1710
 
1583
1711
  function validAcceptedTargetProof(
1584
1712
  state: ZLinkActorSessionRelocationState,
1585
1713
  proof: ZLinkActorSessionAcceptedProducerProof
1586
1714
  ): boolean {
1587
- return proof.actorId === state.actorId
1588
- && proof.objectGeneration === state.actorGeneration
1589
- && proof.actorNodeRid.length > 0
1590
- && proof.actorNodeGeneration > 0n
1591
- && proof.sessionIdentity === state.sessionIdentity
1592
- && proof.bindingGeneration === state.bindingGeneration;
1715
+ return (
1716
+ proof.actorId === state.actorId &&
1717
+ proof.objectGeneration === state.actorGeneration &&
1718
+ proof.actorNodeRid.length > 0 &&
1719
+ proof.actorNodeGeneration > 0n &&
1720
+ proof.sessionIdentity === state.sessionIdentity &&
1721
+ proof.bindingGeneration === state.bindingGeneration
1722
+ );
1593
1723
  }
1594
1724
 
1595
1725
  function relocationSourceProof(
1596
1726
  state: ZLinkActorSessionRelocationState
1597
1727
  ): ZLinkActorSessionAcceptedProducerProof | undefined {
1598
1728
  if (
1599
- state.sessionIdentity === undefined
1600
- || state.actorNodeRid === undefined
1601
- || state.actorNodeGeneration === undefined
1602
- ) return undefined;
1729
+ state.sessionIdentity === undefined ||
1730
+ state.actorNodeRid === undefined ||
1731
+ state.actorNodeGeneration === undefined
1732
+ )
1733
+ return undefined;
1603
1734
  return {
1604
1735
  actorId: state.actorId,
1605
1736
  objectGeneration: state.actorGeneration,
@@ -1610,10 +1741,7 @@ function relocationSourceProof(
1610
1741
  };
1611
1742
  }
1612
1743
 
1613
- function failRetainedOutbound(
1614
- operation: ZLinkActorSessionRetainedOutbound,
1615
- error: unknown
1616
- ): void {
1744
+ function failRetainedOutbound(operation: ZLinkActorSessionRetainedOutbound, error: unknown): void {
1617
1745
  try {
1618
1746
  operation.fail(error);
1619
1747
  } catch {
@@ -1627,9 +1755,9 @@ function assertSuccessorSessionIdentity(
1627
1755
  successor: ZLinkActorSessionRelocationClaim
1628
1756
  ): void {
1629
1757
  if (
1630
- predecessor.actorGeneration !== successor.actorGeneration
1631
- || predecessor.bindingGeneration !== successor.bindingGeneration
1632
- || predecessor.sessionIdentity !== successor.sessionIdentity
1758
+ predecessor.actorGeneration !== successor.actorGeneration ||
1759
+ predecessor.bindingGeneration !== successor.bindingGeneration ||
1760
+ predecessor.sessionIdentity !== successor.sessionIdentity
1633
1761
  ) {
1634
1762
  throw createInternalFrameworkException(
1635
1763
  ZLinkFrameworkInternalErrorKind.ActorLocationStale,
@@ -1648,14 +1776,18 @@ function routeMatchesFence<
1648
1776
  TContext extends ZLinkActorSessionBindingContext<TActor>,
1649
1777
  TActor extends ZLinkActorSessionBindingActor
1650
1778
  >(route: ZLinkActorSessionRoute<TContext, TActor>, expected: ZLinkActorSessionRouteFence): boolean {
1651
- const ref = (route.actor as TActor & { readonly ref?: unknown }).ref as {
1652
- readonly objectGeneration?: bigint;
1653
- readonly generation?: bigint;
1654
- readonly bindingGeneration?: bigint;
1655
- } | undefined;
1656
- return ref !== undefined
1657
- && BigInt(ref.objectGeneration ?? ref.generation ?? -1n) === expected.objectGeneration
1658
- && ref.bindingGeneration === expected.bindingGeneration;
1779
+ const ref = (route.actor as TActor & { readonly ref?: unknown }).ref as
1780
+ | {
1781
+ readonly objectGeneration?: bigint;
1782
+ readonly generation?: bigint;
1783
+ readonly bindingGeneration?: bigint;
1784
+ }
1785
+ | undefined;
1786
+ return (
1787
+ ref !== undefined &&
1788
+ BigInt(ref.objectGeneration ?? ref.generation ?? -1n) === expected.objectGeneration &&
1789
+ ref.bindingGeneration === expected.bindingGeneration
1790
+ );
1659
1791
  }
1660
1792
 
1661
1793
  function sessionIdentityFromContext<
@@ -1665,10 +1797,7 @@ function sessionIdentityFromContext<
1665
1797
  return context.routingId === undefined ? undefined : String(context.routingId);
1666
1798
  }
1667
1799
 
1668
- function waitForSessionRelocation(
1669
- operation: Promise<void>,
1670
- signal?: AbortSignal
1671
- ): Promise<void> {
1800
+ function waitForSessionRelocation(operation: Promise<void>, signal?: AbortSignal): Promise<void> {
1672
1801
  if (signal === undefined) return operation;
1673
1802
  if (signal.aborted) return Promise.reject(signal.reason ?? createAbortError());
1674
1803
  return new Promise<void>((resolve, reject) => {
@@ -1682,7 +1811,7 @@ function waitForSessionRelocation(
1682
1811
  signal.removeEventListener('abort', onAbort);
1683
1812
  resolve();
1684
1813
  },
1685
- error => {
1814
+ (error) => {
1686
1815
  signal.removeEventListener('abort', onAbort);
1687
1816
  reject(error);
1688
1817
  }