@zlink-systems/framework 0.30.0 → 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.
Files changed (456) hide show
  1. package/LICENSE +150 -68
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
  4. package/dist/contracts/Channels/Calls.d.ts +2 -1
  5. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
  6. package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
  7. package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
  8. package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
  9. package/dist/contracts/Common/encoded-payload-storage.js +5 -2
  10. package/dist/contracts/Configuration/Builders.d.ts +1 -1
  11. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
  12. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
  13. package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
  14. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  15. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
  16. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  17. package/dist/contracts/Handlers/Attributes.js +7 -11
  18. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  19. package/dist/contracts/Handlers/JsonContract.js +4 -153
  20. package/dist/contracts/Locations/Rows.d.ts +2 -0
  21. package/dist/contracts/Spots/Contracts.d.ts +6 -1
  22. package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
  23. package/dist/nest-integration.d.ts +1 -1
  24. package/dist/nest-integration.js +2 -1
  25. package/dist/runtime/abort.d.ts +5 -0
  26. package/dist/runtime/abort.js +10 -0
  27. package/dist/runtime/actors/actor-authority-publication.js +3 -2
  28. package/dist/runtime/actors/actor-client.d.ts +1 -2
  29. package/dist/runtime/actors/actor-client.js +52 -57
  30. package/dist/runtime/actors/actor-context.d.ts +2 -0
  31. package/dist/runtime/actors/actor-context.js +46 -9
  32. package/dist/runtime/actors/actor-handoff.d.ts +8 -4
  33. package/dist/runtime/actors/actor-handoff.js +219 -92
  34. package/dist/runtime/actors/actor-join-relocation.d.ts +3 -0
  35. package/dist/runtime/actors/actor-local-native-join.js +13 -12
  36. package/dist/runtime/actors/actor-mailbox.js +27 -1
  37. package/dist/runtime/actors/actor-remote-joiner.js +3 -1
  38. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  39. package/dist/runtime/actors/actor-reply.d.ts +4 -0
  40. package/dist/runtime/actors/actor-reply.js +29 -0
  41. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  42. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  43. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
  44. package/dist/runtime/actors/actor-runtime-state.js +2 -20
  45. package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
  46. package/dist/runtime/actors/index.d.ts +8 -3
  47. package/dist/runtime/actors/index.js +55 -27
  48. package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
  49. package/dist/runtime/actors/session-disconnected-wire.js +48 -0
  50. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  51. package/dist/runtime/admission.d.ts +9 -1
  52. package/dist/runtime/admission.js +56 -23
  53. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
  54. package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
  55. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +15 -1
  56. package/dist/runtime/application-jobs/application-job-queue-scope.js +61 -20
  57. package/dist/runtime/application-jobs/contracts.d.ts +12 -1
  58. package/dist/runtime/backend/contracts/index.d.ts +37 -12
  59. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
  60. package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
  61. package/dist/runtime/backend/mesh-completion-table.js +154 -49
  62. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +28 -1
  63. package/dist/runtime/backend/mesh-dispatch-pump.js +208 -101
  64. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
  65. package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
  66. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  67. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  68. package/dist/runtime/backend/node/node-raw-binding-port.js +124 -72
  69. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +46 -13
  70. package/dist/runtime/backend/node/node-raw-mesh-backend.js +181 -164
  71. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
  72. package/dist/runtime/backend/node/node-socket-backend-adapter.js +11 -11
  73. package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
  74. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  75. package/dist/runtime/backend/runtime-message.js +5 -0
  76. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  77. package/dist/runtime/backend/runtime-values.js +2 -1
  78. package/dist/runtime/channels/channel-clients.d.ts +2 -0
  79. package/dist/runtime/channels/channel-clients.js +75 -23
  80. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +25 -5
  81. package/dist/runtime/channels/channel-dispatch-pipeline.js +111 -56
  82. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  83. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  84. package/dist/runtime/channels/channel-dispatchers.d.ts +4 -3
  85. package/dist/runtime/channels/channel-dispatchers.js +62 -54
  86. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  87. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  88. package/dist/runtime/channels/channel-envelope.d.ts +2 -0
  89. package/dist/runtime/channels/channel-envelope.js +146 -28
  90. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  91. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  92. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
  93. package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
  94. package/dist/runtime/channels/channel-runtime-manager.d.ts +9 -8
  95. package/dist/runtime/channels/channel-runtime-manager.js +16 -16
  96. package/dist/runtime/channels/channel-transports.d.ts +18 -16
  97. package/dist/runtime/channels/channel-transports.js +77 -58
  98. package/dist/runtime/channels/client-server-location-runtime.js +5 -4
  99. package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
  100. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  101. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  102. package/dist/runtime/channels/fanout-location-runtime.js +3 -3
  103. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  104. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  105. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  106. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  107. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  108. package/dist/runtime/channels/source-spot-router.js +4 -4
  109. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  110. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  111. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  112. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  113. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  114. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  115. package/dist/runtime/diagnostics/flow-context.js +19 -7
  116. package/dist/runtime/diagnostics/index.js +4 -9
  117. package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
  118. package/dist/runtime/diagnostics/message-flow.js +35 -5
  119. package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
  120. package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
  121. package/dist/runtime/execution/index.d.ts +4 -2
  122. package/dist/runtime/execution/index.js +33 -10
  123. package/dist/runtime/execution/serial-execution-queue.d.ts +5 -0
  124. package/dist/runtime/execution/serial-execution-queue.js +22 -2
  125. package/dist/runtime/execution/state-lane.d.ts +2 -0
  126. package/dist/runtime/execution/state-lane.js +5 -0
  127. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  128. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  129. package/dist/runtime/foundation/durable-service-request.js +98 -0
  130. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  131. package/dist/runtime/foundation/operation-identity.js +5 -1
  132. package/dist/runtime/foundation/operation-registry.d.ts +25 -1
  133. package/dist/runtime/foundation/operation-registry.js +86 -18
  134. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +61 -8
  135. package/dist/runtime/foundation/raw-service-mesh-runtime.js +486 -266
  136. package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
  137. package/dist/runtime/foundation/service-liveness-registry.js +38 -0
  138. package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
  139. package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
  140. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +3 -3
  141. package/dist/runtime/foundation/service-relocation-object-owner.js +48 -34
  142. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  143. package/dist/runtime/foundation/service-relocation-runtime.js +20 -4
  144. package/dist/runtime/foundation/service-runtime-contracts.d.ts +10 -1
  145. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
  146. package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
  147. package/dist/runtime/foundation/service-stateful-registry.js +24 -26
  148. package/dist/runtime/foundation/service-stateful-runtime.d.ts +75 -9
  149. package/dist/runtime/foundation/service-stateful-runtime.js +486 -218
  150. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -6
  151. package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
  152. package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
  153. package/dist/runtime/foundation/service-topology-registry.js +61 -27
  154. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
  155. package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
  156. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  157. package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
  158. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +13 -3
  159. package/dist/runtime/foundation/service-wire-m6a-codec.js +189 -78
  160. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  161. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  162. package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
  163. package/dist/runtime/host/actor-packet-relay.js +59 -72
  164. package/dist/runtime/host/actor-placement-coordinator.js +25 -8
  165. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  166. package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
  167. package/dist/runtime/host/actor-transfer-runtime.js +85 -331
  168. package/dist/runtime/host/application-job-queue.d.ts +40 -7
  169. package/dist/runtime/host/application-job-queue.js +137 -42
  170. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  171. package/dist/runtime/host/entry-actor-runtime.js +3 -0
  172. package/dist/runtime/host/index.d.ts +12 -2
  173. package/dist/runtime/host/index.js +300 -202
  174. package/dist/runtime/host/location-runtime-owner.js +2 -6
  175. package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
  176. package/dist/runtime/host/mesh-router-resolver.js +14 -6
  177. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
  178. package/dist/runtime/host/remote-bound-session-relay.js +73 -208
  179. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
  180. package/dist/runtime/host/route-mesh-runtime.js +6 -4
  181. package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
  182. package/dist/runtime/host/runtime-shutdown.js +3 -2
  183. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  184. package/dist/runtime/host/service-relocation-control.js +10 -4
  185. package/dist/runtime/host/service-relocation-host-runtime.d.ts +22 -14
  186. package/dist/runtime/host/service-relocation-host-runtime.js +754 -599
  187. package/dist/runtime/host/spot-address-transport.js +3 -2
  188. package/dist/runtime/host/spot-runtime-options-factory.js +16 -7
  189. package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
  190. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  191. package/dist/runtime/locations/actor-location-claims.js +34 -19
  192. package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
  193. package/dist/runtime/locations/auto-connect-loop.js +22 -14
  194. package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
  195. package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
  196. package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
  197. package/dist/runtime/locations/descriptor-publication.js +11 -0
  198. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  199. package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
  200. package/dist/runtime/locations/in-memory-authority-store.js +56 -19
  201. package/dist/runtime/locations/in-memory-location-store.js +1 -10
  202. package/dist/runtime/locations/index.d.ts +1 -0
  203. package/dist/runtime/locations/index.js +1 -0
  204. package/dist/runtime/locations/lease-tracker.js +1 -6
  205. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  206. package/dist/runtime/locations/lifecycle.js +2 -5
  207. package/dist/runtime/locations/location-store-repository.d.ts +51 -1
  208. package/dist/runtime/locations/location-store-repository.js +363 -139
  209. package/dist/runtime/locations/relocation-blob.d.ts +18 -1
  210. package/dist/runtime/locations/relocation-blob.js +52 -1
  211. package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
  212. package/dist/runtime/locations/request-source-resolver.js +80 -0
  213. package/dist/runtime/locations/resolvers.js +1 -1
  214. package/dist/runtime/locations/runtime.d.ts +7 -3
  215. package/dist/runtime/locations/runtime.js +61 -53
  216. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  217. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  218. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  219. package/dist/runtime/messaging/packet-name.js +8 -24
  220. package/dist/runtime/messaging/payload-codec.d.ts +7 -1
  221. package/dist/runtime/messaging/payload-codec.js +7 -6
  222. package/dist/runtime/messaging/request-result.d.ts +2 -0
  223. package/dist/runtime/messaging/request-result.js +57 -0
  224. package/dist/runtime/messaging/submission-result.d.ts +1 -0
  225. package/dist/runtime/messaging/submission-result.js +5 -2
  226. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +34 -1
  227. package/dist/runtime/protocol/service_wire_codec.generated.js +229 -0
  228. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +16 -1
  229. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +37 -8
  230. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
  231. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +36 -21
  232. package/dist/runtime/spots/index.d.ts +21 -11
  233. package/dist/runtime/spots/index.js +243 -178
  234. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  235. package/dist/runtime/spots/spot-activation-registry.js +21 -11
  236. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  237. package/dist/runtime/spots/spot-activation-state.js +7 -7
  238. package/dist/runtime/spots/spot-activation.d.ts +7 -3
  239. package/dist/runtime/spots/spot-activation.js +140 -52
  240. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
  241. package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
  242. package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
  243. package/dist/runtime/spots/spot-actor-membership.js +0 -8
  244. package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
  245. package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
  246. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
  247. package/dist/runtime/spots/spot-entry-activation.js +20 -11
  248. package/dist/runtime/spots/spot-handler-registry.d.ts +7 -4
  249. package/dist/runtime/spots/spot-handler-registry.js +24 -10
  250. package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
  251. package/dist/runtime/spots/spot-manager-public.js +2 -2
  252. package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
  253. package/dist/runtime/spots/spot-node-autoconnect.js +22 -42
  254. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
  255. package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
  256. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  257. package/dist/runtime/spots/spot-outbound.js +27 -18
  258. package/dist/runtime/spots/spot-remote-codec.js +5 -1
  259. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  260. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  261. package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -1
  262. package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
  263. package/dist/runtime/spots/spot-serial-executor.js +61 -8
  264. package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
  265. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -4
  266. package/dist/runtime/spots/spot-timer.d.ts +57 -5
  267. package/dist/runtime/spots/spot-timer.js +288 -103
  268. package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
  269. package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
  270. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
  271. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
  272. package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
  273. package/dist/runtime/streams/bound-session-service.d.ts +1 -1
  274. package/dist/runtime/streams/bound-session-service.js +6 -11
  275. package/dist/runtime/streams/index.d.ts +3 -2
  276. package/dist/runtime/streams/index.js +6 -4
  277. package/dist/runtime/streams/managed-stream.js +3 -2
  278. package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
  279. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
  280. package/dist/runtime/streams/session-actor-coordinator.js +15 -32
  281. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
  282. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  283. package/dist/runtime/streams/stream-session-runtime.js +14 -31
  284. package/dist/runtime/workers/index.js +1 -1
  285. package/package.json +3 -3
  286. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  287. package/src/contracts/Channels/Calls.ts +2 -1
  288. package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
  289. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  290. package/src/contracts/Common/encoded-payload-storage.ts +6 -3
  291. package/src/contracts/Configuration/Builders.ts +4 -1
  292. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
  293. package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
  294. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  295. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
  296. package/src/contracts/Handlers/Attributes.ts +14 -21
  297. package/src/contracts/Handlers/JsonContract.ts +8 -216
  298. package/src/contracts/Locations/Rows.ts +2 -0
  299. package/src/contracts/Spots/Contracts.ts +10 -1
  300. package/src/contracts/Spots/ZLinkSpot.ts +3 -3
  301. package/src/nest-integration.ts +1 -0
  302. package/src/runtime/abort.ts +12 -0
  303. package/src/runtime/actors/actor-authority-publication.ts +3 -2
  304. package/src/runtime/actors/actor-client.ts +100 -85
  305. package/src/runtime/actors/actor-context.ts +49 -9
  306. package/src/runtime/actors/actor-handoff.ts +291 -110
  307. package/src/runtime/actors/actor-join-relocation.ts +3 -0
  308. package/src/runtime/actors/actor-local-native-join.ts +21 -26
  309. package/src/runtime/actors/actor-mailbox.ts +40 -2
  310. package/src/runtime/actors/actor-remote-joiner.ts +6 -1
  311. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  312. package/src/runtime/actors/actor-reply.ts +42 -0
  313. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  314. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  315. package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
  316. package/src/runtime/actors/actor-runtime-state.ts +2 -20
  317. package/src/runtime/actors/actor-source-transfer.ts +1 -34
  318. package/src/runtime/actors/index.ts +60 -32
  319. package/src/runtime/actors/session-disconnected-wire.ts +66 -0
  320. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  321. package/src/runtime/admission.ts +69 -21
  322. package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
  323. package/src/runtime/application-jobs/application-job-queue-scope.ts +83 -22
  324. package/src/runtime/application-jobs/contracts.ts +16 -1
  325. package/src/runtime/backend/contracts/index.ts +92 -18
  326. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
  327. package/src/runtime/backend/mesh-completion-table.ts +160 -57
  328. package/src/runtime/backend/mesh-dispatch-pump.ts +237 -108
  329. package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
  330. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  331. package/src/runtime/backend/node/node-raw-binding-port.ts +148 -85
  332. package/src/runtime/backend/node/node-raw-mesh-backend.ts +315 -201
  333. package/src/runtime/backend/node/node-socket-backend-adapter.ts +26 -11
  334. package/src/runtime/backend/raw-binding-port.ts +7 -2
  335. package/src/runtime/backend/runtime-message.ts +6 -0
  336. package/src/runtime/backend/runtime-values.ts +1 -0
  337. package/src/runtime/channels/channel-clients.ts +132 -58
  338. package/src/runtime/channels/channel-dispatch-pipeline.ts +198 -114
  339. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  340. package/src/runtime/channels/channel-dispatchers.ts +136 -90
  341. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  342. package/src/runtime/channels/channel-envelope.ts +225 -31
  343. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  344. package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
  345. package/src/runtime/channels/channel-runtime-manager.ts +41 -17
  346. package/src/runtime/channels/channel-transports.ts +171 -112
  347. package/src/runtime/channels/client-server-location-runtime.ts +11 -10
  348. package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
  349. package/src/runtime/channels/fanout-location-runtime.ts +17 -9
  350. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  351. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  352. package/src/runtime/channels/source-spot-router.ts +8 -4
  353. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  354. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  355. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  356. package/src/runtime/diagnostics/flow-context.ts +20 -7
  357. package/src/runtime/diagnostics/index.ts +1 -7
  358. package/src/runtime/diagnostics/message-flow.ts +47 -9
  359. package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
  360. package/src/runtime/execution/index.ts +40 -14
  361. package/src/runtime/execution/serial-execution-queue.ts +33 -4
  362. package/src/runtime/execution/state-lane.ts +7 -0
  363. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  364. package/src/runtime/foundation/durable-service-request.ts +137 -0
  365. package/src/runtime/foundation/operation-identity.ts +5 -1
  366. package/src/runtime/foundation/operation-registry.ts +98 -20
  367. package/src/runtime/foundation/raw-service-mesh-runtime.ts +704 -336
  368. package/src/runtime/foundation/service-liveness-registry.ts +39 -0
  369. package/src/runtime/foundation/service-mailbox.ts +8 -0
  370. package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
  371. package/src/runtime/foundation/service-relocation-object-owner.ts +55 -36
  372. package/src/runtime/foundation/service-relocation-runtime.ts +25 -4
  373. package/src/runtime/foundation/service-runtime-contracts.ts +19 -2
  374. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
  375. package/src/runtime/foundation/service-stateful-registry.ts +38 -35
  376. package/src/runtime/foundation/service-stateful-runtime.ts +732 -275
  377. package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -16
  378. package/src/runtime/foundation/service-topology-registry.ts +91 -36
  379. package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
  380. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  381. package/src/runtime/foundation/service-wire-m6a-codec.ts +231 -76
  382. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  383. package/src/runtime/host/actor-packet-relay.ts +113 -94
  384. package/src/runtime/host/actor-placement-coordinator.ts +31 -8
  385. package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
  386. package/src/runtime/host/actor-transfer-runtime.ts +104 -430
  387. package/src/runtime/host/application-job-queue.ts +160 -41
  388. package/src/runtime/host/entry-actor-runtime.ts +4 -0
  389. package/src/runtime/host/index.ts +473 -271
  390. package/src/runtime/host/location-runtime-owner.ts +2 -6
  391. package/src/runtime/host/mesh-router-resolver.ts +13 -5
  392. package/src/runtime/host/remote-bound-session-relay.ts +88 -271
  393. package/src/runtime/host/route-mesh-runtime.ts +12 -6
  394. package/src/runtime/host/runtime-shutdown.ts +15 -4
  395. package/src/runtime/host/service-relocation-control.ts +11 -5
  396. package/src/runtime/host/service-relocation-host-runtime.ts +1092 -759
  397. package/src/runtime/host/spot-address-transport.ts +4 -2
  398. package/src/runtime/host/spot-runtime-options-factory.ts +20 -7
  399. package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
  400. package/src/runtime/locations/actor-location-claims.ts +52 -30
  401. package/src/runtime/locations/auto-connect-loop.ts +22 -14
  402. package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
  403. package/src/runtime/locations/auto-connect-types.ts +0 -1
  404. package/src/runtime/locations/descriptor-publication.ts +7 -0
  405. package/src/runtime/locations/domain-store-contract.ts +5 -0
  406. package/src/runtime/locations/in-memory-authority-store.ts +85 -23
  407. package/src/runtime/locations/in-memory-location-store.ts +1 -12
  408. package/src/runtime/locations/index.ts +1 -0
  409. package/src/runtime/locations/lease-tracker.ts +2 -9
  410. package/src/runtime/locations/lifecycle.ts +8 -26
  411. package/src/runtime/locations/location-store-repository.ts +628 -152
  412. package/src/runtime/locations/relocation-blob.ts +75 -1
  413. package/src/runtime/locations/request-source-resolver.ts +138 -0
  414. package/src/runtime/locations/resolvers.ts +2 -2
  415. package/src/runtime/locations/runtime.ts +98 -64
  416. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  417. package/src/runtime/messaging/packet-name.ts +5 -25
  418. package/src/runtime/messaging/payload-codec.ts +8 -11
  419. package/src/runtime/messaging/request-result.ts +62 -0
  420. package/src/runtime/messaging/submission-result.ts +5 -1
  421. package/src/runtime/protocol/service_wire_codec.generated.ts +218 -5
  422. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +16 -13
  423. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +46 -25
  424. package/src/runtime/spots/index.ts +389 -283
  425. package/src/runtime/spots/spot-activation-registry.ts +25 -13
  426. package/src/runtime/spots/spot-activation-state.ts +12 -19
  427. package/src/runtime/spots/spot-activation.ts +198 -96
  428. package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
  429. package/src/runtime/spots/spot-actor-membership.ts +0 -15
  430. package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
  431. package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
  432. package/src/runtime/spots/spot-entry-activation.ts +33 -21
  433. package/src/runtime/spots/spot-handler-registry.ts +56 -12
  434. package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
  435. package/src/runtime/spots/spot-manager-public.ts +2 -2
  436. package/src/runtime/spots/spot-node-autoconnect.ts +28 -47
  437. package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
  438. package/src/runtime/spots/spot-outbound.ts +39 -19
  439. package/src/runtime/spots/spot-remote-codec.ts +9 -2
  440. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  441. package/src/runtime/spots/spot-runtime-ports.ts +1 -1
  442. package/src/runtime/spots/spot-serial-executor.ts +97 -25
  443. package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
  444. package/src/runtime/spots/spot-subscription-dispatch.ts +1 -4
  445. package/src/runtime/spots/spot-timer.ts +418 -158
  446. package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
  447. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
  448. package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
  449. package/src/runtime/streams/bound-session-service.ts +7 -10
  450. package/src/runtime/streams/index.ts +12 -6
  451. package/src/runtime/streams/managed-stream.ts +4 -2
  452. package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
  453. package/src/runtime/streams/session-actor-coordinator.ts +39 -88
  454. package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
  455. package/src/runtime/streams/stream-session-runtime.ts +13 -34
  456. package/src/runtime/workers/index.ts +1 -1
@@ -1,25 +1,47 @@
1
- import { AsyncResource } from 'node:async_hooks';
2
1
  import {
3
2
  ZLinkFrameworkErrorKind,
4
3
  ZLinkFrameworkException
5
4
  } from '../../contracts/Errors/ZLinkFrameworkException';
6
5
  import { zlinkDefaultLocationOptions } from '../../contracts/Locations/Options';
7
6
  import { createAbortError, throwIfAborted } from '../abort';
8
- import { ZLinkStateLane } from '../execution/state-lane';
7
+ import { startOutsideStateLane, ZLinkStateLane } from '../execution/state-lane';
8
+ import type { RoutingId } from '../../contracts';
9
+ import { routingIdsEqual } from '../routing-id';
9
10
  import {
10
11
  ZLinkFrameworkInternalErrorKind,
11
12
  createInternalFrameworkException
12
13
  } from '../framework-errors-internal';
14
+ import {
15
+ encodeSessionRelocationSeal,
16
+ encodeSessionRelocationRoute,
17
+ type ServiceSessionRelocationRoute,
18
+ serviceSessionRelocationIdentityKey,
19
+ type ServiceSessionRelocationSeal,
20
+ type ServiceSessionRelocationSealed
21
+ } from '../foundation/service-stateful-wire-codec';
22
+ import { ServiceWireProtocolError } from '../foundation/service-wire-m6a-codec';
23
+ import { ZLinkRemoteBoundSessionFenceError } from '../actors/bound-session-wire';
24
+
25
+ export interface ZLinkPreparedSessionRelocationSeal {
26
+ readonly response: ServiceSessionRelocationSealed;
27
+ readonly ready: Promise<void>;
28
+ }
29
+
30
+ interface SessionRelocationResult extends ZLinkPreparedSessionRelocationSeal {
31
+ readonly key: string;
32
+ readonly fingerprint: string;
33
+ readonly seal?: ZLinkActorSessionRelocationState;
34
+ }
35
+
13
36
  export const DEFAULT_TERMINAL_RELOCATION_CAPACITY = 4096;
14
37
 
15
- const detachedStateLaneResource = new AsyncResource('zlink:actor-session-binding-registry');
16
38
  export interface ZLinkActorSessionBindingActor {
17
39
  readonly actorId: string;
18
40
  readonly ref: { readonly actorId: string; readonly bindingGeneration?: bigint };
19
41
  }
20
42
 
21
43
  export interface ZLinkActorSessionBindingContext<TActor extends ZLinkActorSessionBindingActor> {
22
- readonly routingId?: unknown;
44
+ readonly routingId?: RoutingId;
23
45
  readonly actorSlotControls?: {
24
46
  enqueueBound(actorSlot: number, actorId: string): Promise<void>;
25
47
  enqueueUnbound(actorSlot: number): Promise<void>;
@@ -36,9 +58,10 @@ export interface ZLinkActorSessionRoute<
36
58
  readonly actor: TActor;
37
59
  readonly bindingToken: string;
38
60
  readonly actorSlot?: number;
39
- readonly sessionIdentity?: string;
61
+ readonly sessionIdentity?: RoutingId;
40
62
  readonly activeFrames: ZLinkActorSessionActiveFrames;
41
63
  sealId?: string;
64
+ sessionRelocationResult?: SessionRelocationResult;
42
65
  authorityFence?: ZLinkActorSessionAuthorityFence;
43
66
  }
44
67
 
@@ -46,8 +69,8 @@ export interface ZLinkActorSessionRelocationClaim {
46
69
  readonly actorId: string;
47
70
  readonly actorGeneration: bigint;
48
71
  readonly bindingGeneration: bigint;
49
- readonly sessionIdentity?: string;
50
- readonly actorNodeRid?: string;
72
+ readonly sessionIdentity?: RoutingId;
73
+ readonly actorNodeRid?: RoutingId;
51
74
  readonly actorNodeGeneration?: bigint;
52
75
  readonly sealId: string;
53
76
  }
@@ -88,8 +111,8 @@ interface ZLinkActorSessionRelocationState {
88
111
  readonly actorId: string;
89
112
  readonly actorGeneration: bigint;
90
113
  readonly bindingGeneration: bigint;
91
- readonly sessionIdentity?: string;
92
- readonly actorNodeRid?: string;
114
+ readonly sessionIdentity?: RoutingId;
115
+ readonly actorNodeRid?: RoutingId;
93
116
  readonly actorNodeGeneration?: bigint;
94
117
  readonly sealId: string;
95
118
  phase: 'sealed' | 'applying' | 'applied' | 'terminal';
@@ -143,6 +166,13 @@ export class ZLinkActorSessionBindingRegistry<
143
166
  >();
144
167
  private readonly activeFrameWaiters = new Map<string, Set<ZLinkActorSessionActiveFrameWaiter>>();
145
168
  private readonly relocations = new Map<string, ZLinkActorSessionRelocationQueue>();
169
+ private readonly absentSessionRelocationResults = new Map<
170
+ string,
171
+ {
172
+ readonly result: SessionRelocationResult;
173
+ readonly expiry: ReturnType<typeof setTimeout>;
174
+ }
175
+ >();
146
176
  private readonly terminalRelocations = new Map<ZLinkActorSessionRelocationState, true>();
147
177
 
148
178
  constructor(
@@ -170,7 +200,7 @@ export class ZLinkActorSessionBindingRegistry<
170
200
  actor: TActor,
171
201
  bindingToken: string,
172
202
  authorityFence?: ZLinkActorSessionAuthorityFence,
173
- sessionIdentity?: string,
203
+ sessionIdentity?: RoutingId,
174
204
  commitActor?: () => void
175
205
  ): Promise<void> {
176
206
  await this.lane.run(() =>
@@ -192,7 +222,7 @@ export class ZLinkActorSessionBindingRegistry<
192
222
  actor: TActor,
193
223
  bindingToken: string,
194
224
  authorityFence?: ZLinkActorSessionAuthorityFence,
195
- sessionIdentity?: string,
225
+ sessionIdentity?: RoutingId,
196
226
  commitActor?: () => void
197
227
  ): void {
198
228
  const current = this.routes.get(actor.actorId);
@@ -204,29 +234,29 @@ export class ZLinkActorSessionBindingRegistry<
204
234
  );
205
235
  }
206
236
 
237
+ const currentSessionIdentity = sessionIdentity ?? sessionIdentityFromContext(context);
207
238
  const sameBinding =
208
239
  previous !== undefined &&
209
- previous.context === context &&
210
- previous.bindingToken === bindingToken;
240
+ previous.bindingToken === bindingToken &&
241
+ (previous.context === context ||
242
+ (previous.sessionIdentity !== undefined &&
243
+ currentSessionIdentity !== undefined &&
244
+ routingIdsEqual(previous.sessionIdentity, currentSessionIdentity)));
211
245
  const actorSlot = sameBinding ? previous.actorSlot : this.issueActorSlot(context);
212
246
  commitActor?.();
213
247
  context.bindLocal(actor, bindingToken, actorSlot);
214
248
 
215
249
  try {
216
250
  if (previous !== undefined && !sameBinding) {
217
- this.routes.delete(actor.actorId);
218
- previous.context.unbindLocal(actor.actorId, previous.bindingToken);
219
- if (previous.actorSlot !== undefined) {
220
- let unbound: Promise<void> | undefined;
221
- try {
222
- unbound = previous.context.actorSlotControls?.enqueueUnbound(previous.actorSlot);
223
- } catch (error) {
224
- unbound = Promise.reject(error);
225
- }
226
- void unbound?.catch((error) =>
227
- this.errorSink?.()?.reportRuntimeTaskException('retired session actor unbound', error)
228
- );
229
- }
251
+ const unbound = this.unbindCore(
252
+ actor.actorId,
253
+ previous.context,
254
+ previous.bindingToken,
255
+ ZLinkActorSessionBindingTermination.BindingEnd
256
+ );
257
+ void unbound?.catch((error) =>
258
+ this.errorSink?.()?.reportRuntimeTaskException('retired session actor unbound', error)
259
+ );
230
260
  }
231
261
 
232
262
  if (!sameBinding && actorSlot !== undefined) {
@@ -254,15 +284,19 @@ export class ZLinkActorSessionBindingRegistry<
254
284
  throw error;
255
285
  }
256
286
 
287
+ const bindingState = sameBinding ? previous : undefined;
257
288
  this.routes.set(actor.actorId, {
258
289
  context,
259
290
  actor,
260
291
  bindingToken,
261
292
  actorSlot,
262
- sessionIdentity: sessionIdentity ?? sessionIdentityFromContext(context),
293
+ sessionIdentity: currentSessionIdentity,
294
+ // Accepted frames retain their completion fence across route replacement;
295
+ // the successor's seal must still drain them (Session binding §8.1).
263
296
  activeFrames: previous?.activeFrames ?? { count: 0, requests: new Set() },
264
- sealId: previous?.sealId,
265
- authorityFence: authorityFence ?? previous?.authorityFence
297
+ sealId: bindingState?.sealId,
298
+ sessionRelocationResult: bindingState?.sessionRelocationResult,
299
+ authorityFence: authorityFence ?? bindingState?.authorityFence
266
300
  });
267
301
  }
268
302
 
@@ -285,7 +319,7 @@ export class ZLinkActorSessionBindingRegistry<
285
319
  actor: TActor,
286
320
  bindingToken: string,
287
321
  authorityFence?: ZLinkActorSessionAuthorityFence,
288
- sessionIdentity?: string,
322
+ sessionIdentity?: RoutingId,
289
323
  commitActor?: () => void
290
324
  ): Promise<void> {
291
325
  await this.lane.run(() =>
@@ -308,7 +342,7 @@ export class ZLinkActorSessionBindingRegistry<
308
342
  bindingToken: string,
309
343
  sealId: string,
310
344
  authorityFence?: ZLinkActorSessionAuthorityFence,
311
- sessionIdentity?: string,
345
+ sessionIdentity?: RoutingId,
312
346
  commitActor?: () => void
313
347
  ): Promise<void> {
314
348
  await this.lane.run(() =>
@@ -332,7 +366,7 @@ export class ZLinkActorSessionBindingRegistry<
332
366
  bindingToken: string,
333
367
  sealId: string,
334
368
  authorityFence?: ZLinkActorSessionAuthorityFence,
335
- sessionIdentity?: string,
369
+ sessionIdentity?: RoutingId,
336
370
  commitActor?: () => void
337
371
  ): void {
338
372
  if (previous.sealId !== sealId) {
@@ -378,13 +412,13 @@ export class ZLinkActorSessionBindingRegistry<
378
412
  /** Selects the route only when it is the exact Session binding (§8.1 validation values). */
379
413
  async routeForSessionBinding(
380
414
  actorId: string,
381
- sessionRid: string,
415
+ sessionRid: RoutingId,
382
416
  bindingGeneration?: bigint
383
417
  ): Promise<ZLinkActorSessionRoute<TContext, TActor> | undefined> {
384
418
  return await this.lane.run(() => {
385
419
  const route = this.routeCore(actorId);
386
420
  const generation = route?.actor.ref.bindingGeneration;
387
- return route?.sessionIdentity === sessionRid &&
421
+ return routingIdsEqual(route?.sessionIdentity, sessionRid) &&
388
422
  (bindingGeneration === undefined || generation === bindingGeneration)
389
423
  ? route
390
424
  : undefined;
@@ -455,7 +489,11 @@ export class ZLinkActorSessionBindingRegistry<
455
489
  termination === ZLinkActorSessionBindingTermination.BindingEnd &&
456
490
  route.actorSlot !== undefined
457
491
  ) {
458
- return context.actorSlotControls?.enqueueUnbound(route.actorSlot);
492
+ try {
493
+ return context.actorSlotControls?.enqueueUnbound(route.actorSlot);
494
+ } catch (error) {
495
+ return Promise.reject(error);
496
+ }
459
497
  }
460
498
  return undefined;
461
499
  }
@@ -778,6 +816,145 @@ export class ZLinkActorSessionBindingRegistry<
778
816
  await this.waitForActiveFrames(actorId, signal);
779
817
  }
780
818
 
819
+ async prepareSessionRelocationSeal(
820
+ value: ServiceSessionRelocationSeal,
821
+ signal?: AbortSignal
822
+ ): Promise<ZLinkPreparedSessionRelocationSeal | undefined> {
823
+ for (;;) {
824
+ const step = await this.lane.run(() => this.prepareSessionRelocationSealCore(value, signal));
825
+ if (step === undefined || !('predecessor' in step)) return step;
826
+ await waitForSessionRelocation(step.predecessor, signal);
827
+ }
828
+ }
829
+
830
+ private prepareSessionRelocationSealCore(
831
+ value: ServiceSessionRelocationSeal,
832
+ signal?: AbortSignal
833
+ ): ZLinkPreparedSessionRelocationSeal | { readonly predecessor: Promise<void> } | undefined {
834
+ const actorId = value.actor.actor.actorId;
835
+ const key = serviceSessionRelocationIdentityKey(value);
836
+ const fingerprint = encodeSessionRelocationSeal(value).toString('base64');
837
+ const route = this.routes.get(actorId);
838
+ const bindingResult = route?.sessionRelocationResult;
839
+ const recorded =
840
+ this.absentSessionRelocationResults.get(key)?.result ??
841
+ (bindingResult?.key === key ? bindingResult : undefined);
842
+ if (recorded !== undefined) {
843
+ if (recorded.fingerprint !== fingerprint) {
844
+ throw new ServiceWireProtocolError(
845
+ `Session relocation '${key}' repeated command 42 with different bytes.`
846
+ );
847
+ }
848
+ if (recorded.seal?.phase === 'terminal') {
849
+ console.warn(`late_session_relocation_seal session=${value.session.sessionRid}`);
850
+ return undefined;
851
+ }
852
+ return recorded;
853
+ }
854
+ throwIfAborted(signal);
855
+ const response: ServiceSessionRelocationSealed = {
856
+ relocation: value.relocation,
857
+ coordinator: value.coordinator,
858
+ actor: value.actor,
859
+ session: value.session,
860
+ sealResult: route === undefined ? 'bindingAbsent' : 'sealed'
861
+ };
862
+ if (route === undefined) {
863
+ const result: SessionRelocationResult = {
864
+ key,
865
+ fingerprint,
866
+ response,
867
+ ready: Promise.resolve()
868
+ };
869
+ const expiry = startOutsideStateLane(() =>
870
+ setTimeout(() => {
871
+ void (async () => {
872
+ await this.lane.run(() => this.absentSessionRelocationResults.delete(key));
873
+ })().catch((error) =>
874
+ this.errorSink?.()?.reportRuntimeTaskException(
875
+ 'session relocation result expiry',
876
+ error
877
+ )
878
+ );
879
+ }, this.sealWaitTimeoutMs)
880
+ );
881
+ expiry.unref();
882
+ this.absentSessionRelocationResults.set(key, { result, expiry });
883
+ return result;
884
+ }
885
+ const expected = {
886
+ objectGeneration: value.actor.actor.generation,
887
+ bindingGeneration: value.session.bindingGeneration
888
+ };
889
+ if (
890
+ !routingIdsEqual(route.sessionIdentity, value.session.sessionRid) ||
891
+ !routeMatchesFence(route, expected) ||
892
+ (route.authorityFence !== undefined &&
893
+ value.actor.ownerLeaseGeneration < route.authorityFence.ownerLeaseGeneration) ||
894
+ (route.sealId !== undefined && route.sealId !== key)
895
+ ) {
896
+ throw new ZLinkRemoteBoundSessionFenceError(
897
+ `Actor '${actorId}' command 42 was fenced by its exact Session route.`
898
+ );
899
+ }
900
+ const step = this.prepareRelocationSeal(
901
+ {
902
+ actorId,
903
+ actorGeneration: value.actor.actor.generation,
904
+ bindingGeneration: value.session.bindingGeneration,
905
+ sessionIdentity: value.session.sessionRid,
906
+ actorNodeRid: value.actor.actor.nodeRid,
907
+ actorNodeGeneration: value.actor.targetNodeGeneration,
908
+ sealId: key
909
+ },
910
+ expected,
911
+ signal
912
+ );
913
+ if (step.kind === 'predecessor') return { predecessor: step.wait };
914
+ const result: SessionRelocationResult = {
915
+ key,
916
+ fingerprint,
917
+ response,
918
+ ready: step.wait,
919
+ seal: this.relocations.get(actorId)!.seals.get(key)!
920
+ };
921
+ route.sessionRelocationResult = result;
922
+ return result;
923
+ }
924
+
925
+ async acceptSessionRelocationRoute(
926
+ value: ServiceSessionRelocationRoute,
927
+ apply: () => Promise<void>
928
+ ): Promise<boolean> {
929
+ const key = serviceSessionRelocationIdentityKey(value);
930
+ const fingerprint = encodeSessionRelocationRoute(value).toString('base64');
931
+ const prepared = await this.lane.run(() => {
932
+ if (this.absentSessionRelocationResults.has(key)) return undefined;
933
+ const result = this.routes.get(value.actor.actorId)?.sessionRelocationResult;
934
+ if (result?.key !== key || result.seal === undefined) return undefined;
935
+ const seal = result.seal;
936
+ if (seal.applyFingerprint !== undefined && seal.applyFingerprint !== fingerprint) {
937
+ throw new ServiceWireProtocolError(
938
+ `Session relocation '${key}' repeated command 44 with different bytes.`
939
+ );
940
+ }
941
+ if (seal.phase === 'terminal') return undefined;
942
+ return this.prepareRelocationApply(value.actor.actorId, key, fingerprint);
943
+ });
944
+ if (prepared === undefined) return false;
945
+ await this.runRelocationApply(prepared, apply);
946
+ await this.observeRelocationTerminal(value.actor.actorId, key, fingerprint);
947
+ return true;
948
+ }
949
+
950
+ async clearSessionRelocationResults(): Promise<void> {
951
+ await this.lane.run(() => {
952
+ for (const { expiry } of this.absentSessionRelocationResults.values()) clearTimeout(expiry);
953
+ this.absentSessionRelocationResults.clear();
954
+ for (const route of this.routes.values()) route.sessionRelocationResult = undefined;
955
+ });
956
+ }
957
+
781
958
  async sealRelocation(
782
959
  claim: ZLinkActorSessionRelocationClaim,
783
960
  expected: ZLinkActorSessionRouteFence,
@@ -869,6 +1046,15 @@ export class ZLinkActorSessionBindingRegistry<
869
1046
  const prepared = await this.lane.run(() =>
870
1047
  this.prepareRelocationApply(actorId, sealId, applyFingerprint)
871
1048
  );
1049
+ await this.runRelocationApply(prepared, commitOwnerTransition);
1050
+ }
1051
+
1052
+ private async runRelocationApply(
1053
+ prepared: ReturnType<
1054
+ ZLinkActorSessionBindingRegistry<TContext, TActor>['prepareRelocationApply']
1055
+ >,
1056
+ commitOwnerTransition: () => Promise<void>
1057
+ ): Promise<void> {
872
1058
  if (prepared.applyPromise !== undefined) {
873
1059
  await prepared.applyPromise;
874
1060
  return;
@@ -997,11 +1183,14 @@ export class ZLinkActorSessionBindingRegistry<
997
1183
  * single physical route's disconnect, which must not disturb a relocation
998
1184
  * seal it does not own (see `clearRouteRelocation`).
999
1185
  */
1000
- async clearRelocation(actorId: string, error: unknown): Promise<void> {
1001
- await this.lane.run(() => this.clearRelocationCore(actorId, error));
1186
+ async clearRelocation(actorId: string, error: unknown, sealId?: string): Promise<void> {
1187
+ await this.lane.run(() => this.clearRelocationCore(actorId, error, sealId));
1002
1188
  }
1003
1189
 
1004
- private clearRelocationCore(actorId: string, error: unknown): void {
1190
+ private clearRelocationCore(actorId: string, error: unknown, sealId?: string): void {
1191
+ const result = this.routes.get(actorId)?.sessionRelocationResult;
1192
+ if (sealId !== undefined && (result?.key !== sealId || result.seal?.phase === 'terminal'))
1193
+ return;
1005
1194
  const queue = this.relocations.get(actorId);
1006
1195
  if (queue === undefined) return;
1007
1196
  this.rejectSealWaiters(
@@ -1018,7 +1207,8 @@ export class ZLinkActorSessionBindingRegistry<
1018
1207
  this.relocations.delete(actorId);
1019
1208
  for (const state of queue.seals.values()) {
1020
1209
  this.terminalRelocations.delete(state);
1021
- if (state.phase !== 'terminal') state.resolveTerminal();
1210
+ state.phase = 'terminal';
1211
+ state.resolveTerminal();
1022
1212
  }
1023
1213
  }
1024
1214
 
@@ -1044,7 +1234,7 @@ export class ZLinkActorSessionBindingRegistry<
1044
1234
  const ownsActiveSeal =
1045
1235
  activeState !== undefined &&
1046
1236
  activeState.phase !== 'terminal' &&
1047
- activeState.sessionIdentity === route.sessionIdentity;
1237
+ routingIdsEqual(activeState.sessionIdentity, route.sessionIdentity);
1048
1238
  if (!ownsActiveSeal) {
1049
1239
  // Nothing this exact route still holds open — leave terminal
1050
1240
  // retention and any other Session's active seal untouched.
@@ -1054,6 +1244,7 @@ export class ZLinkActorSessionBindingRegistry<
1054
1244
  queue.activeSealId = undefined;
1055
1245
  queue.seals.delete(activeSealId!);
1056
1246
  this.terminalRelocations.delete(activeState);
1247
+ activeState.phase = 'terminal';
1057
1248
  activeState.resolveTerminal();
1058
1249
  this.deleteEmptyRelocationQueue(queue);
1059
1250
  }
@@ -1070,21 +1261,6 @@ export class ZLinkActorSessionBindingRegistry<
1070
1261
  return true;
1071
1262
  }
1072
1263
 
1073
- async updateAuthorityFence(
1074
- actorId: string,
1075
- authorityFence: ZLinkActorSessionAuthorityFence
1076
- ): Promise<void> {
1077
- await this.lane.run(() => this.updateAuthorityFenceCore(actorId, authorityFence));
1078
- }
1079
-
1080
- private updateAuthorityFenceCore(
1081
- actorId: string,
1082
- authorityFence: ZLinkActorSessionAuthorityFence
1083
- ): void {
1084
- const route = this.requireRouteCore(actorId);
1085
- route.authorityFence = authorityFence;
1086
- }
1087
-
1088
1264
  async validateSeal(actorId: string, sealId: string): Promise<boolean> {
1089
1265
  return await this.lane.run(() => this.validateSealCore(actorId, sealId));
1090
1266
  }
@@ -1356,8 +1532,8 @@ function assertRelocationClaim(
1356
1532
  if (
1357
1533
  state.actorGeneration !== claim.actorGeneration ||
1358
1534
  state.bindingGeneration !== claim.bindingGeneration ||
1359
- state.sessionIdentity !== claim.sessionIdentity ||
1360
- state.actorNodeRid !== claim.actorNodeRid ||
1535
+ !routingIdsEqual(state.sessionIdentity, claim.sessionIdentity) ||
1536
+ !routingIdsEqual(state.actorNodeRid, claim.actorNodeRid) ||
1361
1537
  state.actorNodeGeneration !== claim.actorNodeGeneration
1362
1538
  ) {
1363
1539
  throw createInternalFrameworkException(
@@ -1368,10 +1544,6 @@ function assertRelocationClaim(
1368
1544
  }
1369
1545
  }
1370
1546
 
1371
- function startOutsideStateLane<T>(work: () => T): T {
1372
- return detachedStateLaneResource.runInAsyncScope(work);
1373
- }
1374
-
1375
1547
  function assertSuccessorSessionIdentity(
1376
1548
  predecessor: ZLinkActorSessionRelocationState,
1377
1549
  successor: ZLinkActorSessionRelocationClaim
@@ -1379,7 +1551,7 @@ function assertSuccessorSessionIdentity(
1379
1551
  if (
1380
1552
  predecessor.actorGeneration !== successor.actorGeneration ||
1381
1553
  predecessor.bindingGeneration !== successor.bindingGeneration ||
1382
- predecessor.sessionIdentity !== successor.sessionIdentity
1554
+ !routingIdsEqual(predecessor.sessionIdentity, successor.sessionIdentity)
1383
1555
  ) {
1384
1556
  throw createInternalFrameworkException(
1385
1557
  ZLinkFrameworkInternalErrorKind.ActorLocationStale,
@@ -1415,8 +1587,8 @@ function routeMatchesFence<
1415
1587
  function sessionIdentityFromContext<
1416
1588
  TActor extends ZLinkActorSessionBindingActor,
1417
1589
  TContext extends ZLinkActorSessionBindingContext<TActor>
1418
- >(context: TContext): string | undefined {
1419
- return context.routingId === undefined ? undefined : String(context.routingId);
1590
+ >(context: TContext): RoutingId | undefined {
1591
+ return context.routingId;
1420
1592
  }
1421
1593
 
1422
1594
  function waitForSessionRelocation(operation: Promise<void>, signal?: AbortSignal): Promise<void> {
@@ -1,18 +1,26 @@
1
+ import type { RoutingId } from '../../contracts';
2
+ import type {
3
+ ServiceSessionRelocationSeal,
4
+ ServiceSessionRelocationRoute
5
+ } from '../foundation/service-stateful-wire-codec';
1
6
  import type { ActorRef } from '../../contracts';
2
7
  import type {
3
8
  ZLinkActorSessionAuthorityFence,
4
- ZLinkActorSessionRelocationClaim,
5
9
  ZLinkActorSessionRelocationSnapshot,
6
- ZLinkActorSessionRouteFence
10
+ ZLinkPreparedSessionRelocationSeal
7
11
  } from './actor-session-binding-registry';
8
12
 
9
13
  export interface ZLinkActorSessionBindingRuntimeOwner {
10
- actorSlot(actorId: string, sessionRid: string): Promise<number | undefined>;
11
- sealRelocation(
12
- claim: ZLinkActorSessionRelocationClaim,
13
- expected: ZLinkActorSessionRouteFence,
14
+ prepareSessionRelocationSeal(
15
+ value: ServiceSessionRelocationSeal,
14
16
  signal?: AbortSignal
15
- ): Promise<void>;
17
+ ): Promise<ZLinkPreparedSessionRelocationSeal | undefined>;
18
+ acceptSessionRelocationRoute(
19
+ value: ServiceSessionRelocationRoute,
20
+ apply: () => Promise<void>
21
+ ): Promise<boolean>;
22
+ clearSessionRelocationResults(): Promise<void>;
23
+ actorSlot(actorId: string, sessionRid: RoutingId): Promise<number | undefined>;
16
24
  relocationSnapshot(
17
25
  actorId: string,
18
26
  sealId: string
@@ -28,7 +36,7 @@ export interface ZLinkActorSessionBindingRuntimeOwner {
28
36
  sealId: string,
29
37
  applyFingerprint: string
30
38
  ): Promise<void>;
31
- clearRelocation(actorId: string, error: unknown): Promise<void>;
39
+ clearRelocation(actorId: string, error: unknown, sealId?: string): Promise<void>;
32
40
  committedRoute(actorId: string): Promise<
33
41
  | {
34
42
  readonly actor: ActorRef;
@@ -23,6 +23,7 @@ import {
23
23
  } from './protocol';
24
24
  import { DefaultZLinkSessionActor, DefaultZLinkSessionContext } from './session-context';
25
25
  import { ZLinkStreamFrameMessageFactory } from './stream-frame-factory';
26
+ import type { ServiceStreamSessionBinding } from '../foundation/service-runtime-contracts';
26
27
  export const DEFAULT_RELAY_ACTOR_BIND_TIMEOUT_MS = 2000;
27
28
 
28
29
  export interface ZLinkBoundActorRelaySenderOptions {
@@ -34,7 +35,11 @@ export interface ZLinkBoundActorRelaySenderOptions {
34
35
  header: ZLinkStreamFrameHeader,
35
36
  payload: Message
36
37
  ) => Promise<boolean>;
37
- readonly notifyDisconnected?: (actor: ZLinkSessionActor, signal?: AbortSignal) => Promise<void>;
38
+ readonly notifyDisconnected?: (
39
+ actor: ZLinkSessionActor,
40
+ signal?: AbortSignal,
41
+ binding?: ServiceStreamSessionBinding
42
+ ) => Promise<void>;
38
43
  }
39
44
 
40
45
  export class ZLinkBoundActorRelaySender {
@@ -246,21 +251,25 @@ export class ZLinkBoundActorRelaySender {
246
251
  const detached = await this.lifecycle.run(actor.actorId, async () => {
247
252
  await this.routes.requireCurrentToken(actor.actorId, actor.bindingToken);
248
253
  const route = await this.routes.requireRoute(actor.actorId);
254
+ const binding =
255
+ route.context.stream instanceof ZLinkManagedStream
256
+ ? route.context.stream.actorBinding(actor.actorId)
257
+ : undefined;
249
258
  await this.routes.unbind(actor.actorId, route.context, actor.bindingToken);
250
- return route;
259
+ return { route, binding };
251
260
  });
252
261
  if (
253
262
  unbindNative &&
254
- detached.bindingToken === actor.bindingToken &&
255
- detached.context.stream instanceof ZLinkManagedStream
263
+ detached.route.bindingToken === actor.bindingToken &&
264
+ detached.route.context.stream instanceof ZLinkManagedStream
256
265
  ) {
257
- await detached.context.stream.unbindActor(
266
+ await detached.route.context.stream.unbindActor(
258
267
  actor.actorId,
259
268
  this.options.actorBindTimeoutMs ?? DEFAULT_RELAY_ACTOR_BIND_TIMEOUT_MS,
260
269
  signal
261
270
  );
262
271
  }
263
- await this.options.notifyDisconnected?.(actor, signal);
272
+ await this.options.notifyDisconnected?.(actor, signal, detached.binding);
264
273
  }
265
274
 
266
275
  async notifyPhysicalDisconnect(context: DefaultZLinkSessionContext): Promise<void> {
@@ -281,20 +290,25 @@ export class ZLinkBoundActorRelaySender {
281
290
  // The transport is already closed, so remove its exact route before
282
291
  // invoking application lifecycle code. A reconnect can then install
283
292
  // a successor while this best-effort notification is in flight.
293
+ const binding =
294
+ context.stream instanceof ZLinkManagedStream
295
+ ? context.stream.actorBinding(actor.actorId)
296
+ : undefined;
284
297
  await this.routes.unbind(
285
298
  actor.actorId,
286
299
  context,
287
300
  actor.bindingToken,
288
301
  ZLinkActorSessionBindingTermination.PhysicalDisconnect
289
302
  );
290
- return true;
303
+ return { binding };
291
304
  });
292
- if (!detached) return;
305
+ if (detached === false) return;
293
306
  const controller = new AbortController();
294
307
  const timer = setTimeout(() => controller.abort(), timeoutMs);
295
308
  try {
296
309
  await Promise.race([
297
- this.options.notifyDisconnected?.(actor, controller.signal) ?? Promise.resolve(),
310
+ this.options.notifyDisconnected?.(actor, controller.signal, detached.binding) ??
311
+ Promise.resolve(),
298
312
  new Promise<never>((_, reject) => {
299
313
  controller.signal.addEventListener(
300
314
  'abort',
@@ -279,13 +279,14 @@ export class ZLinkBoundSessionService {
279
279
  async disconnectNativeBoundSession(
280
280
  node: ZLinkBackendActorSessionNode,
281
281
  actorRef: ActorRef,
282
+ timeoutMs: number,
282
283
  signal?: AbortSignal
283
284
  ): Promise<void> {
284
285
  throwIfAborted(signal);
285
286
  await node.closeActorBoundSession(
286
- actorRef as unknown as ZLinkBackendActorRef,
287
+ toBoundSessionSendActorRef(actorRef),
287
288
  requireBoundSessionGeneration(actorRef),
288
- 0,
289
+ timeoutMs,
289
290
  signal
290
291
  );
291
292
  }
@@ -293,14 +294,10 @@ export class ZLinkBoundSessionService {
293
294
  async disconnectBoundSession(actorId: string, signal?: AbortSignal): Promise<void> {
294
295
  throwIfAborted(signal);
295
296
  const route = await this.routes.requireRoute(actorId);
296
- try {
297
- await this.requireTransport().disconnect(actorId, {
298
- bindingToken: route.bindingToken,
299
- signal
300
- });
301
- } finally {
302
- await this.routes.unbind(actorId, route.context, route.bindingToken);
303
- }
297
+ await this.requireTransport().disconnect(actorId, {
298
+ bindingToken: route.bindingToken,
299
+ signal
300
+ });
304
301
  }
305
302
 
306
303
  /**