@zlink-systems/framework 0.30.1 → 0.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
  3. package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
  4. package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
  5. package/dist/contracts/Common/encoded-payload-storage.js +5 -2
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -1
  7. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
  8. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
  9. package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
  10. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  11. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
  12. package/dist/contracts/Locations/Rows.d.ts +2 -0
  13. package/dist/contracts/Spots/Contracts.d.ts +4 -0
  14. package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
  15. package/dist/runtime/abort.d.ts +5 -0
  16. package/dist/runtime/abort.js +10 -0
  17. package/dist/runtime/actors/actor-authority-publication.js +3 -2
  18. package/dist/runtime/actors/actor-client.d.ts +0 -1
  19. package/dist/runtime/actors/actor-client.js +38 -45
  20. package/dist/runtime/actors/actor-context.d.ts +2 -0
  21. package/dist/runtime/actors/actor-context.js +46 -9
  22. package/dist/runtime/actors/actor-handoff.d.ts +7 -3
  23. package/dist/runtime/actors/actor-handoff.js +212 -88
  24. package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
  25. package/dist/runtime/actors/actor-local-native-join.js +4 -0
  26. package/dist/runtime/actors/actor-mailbox.js +27 -1
  27. package/dist/runtime/actors/actor-remote-joiner.js +3 -1
  28. package/dist/runtime/actors/actor-reply.d.ts +4 -0
  29. package/dist/runtime/actors/actor-reply.js +29 -0
  30. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
  31. package/dist/runtime/actors/actor-runtime-state.js +2 -20
  32. package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
  33. package/dist/runtime/actors/index.d.ts +6 -2
  34. package/dist/runtime/actors/index.js +37 -21
  35. package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
  36. package/dist/runtime/actors/session-disconnected-wire.js +48 -0
  37. package/dist/runtime/admission.d.ts +9 -1
  38. package/dist/runtime/admission.js +55 -32
  39. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
  40. package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
  41. package/dist/runtime/application-jobs/contracts.d.ts +2 -0
  42. package/dist/runtime/backend/contracts/index.d.ts +19 -3
  43. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
  44. package/dist/runtime/backend/mesh-completion-table.js +5 -0
  45. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
  46. package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
  47. package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
  48. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
  49. package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
  50. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
  51. package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
  52. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  53. package/dist/runtime/channels/channel-clients.js +20 -5
  54. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
  55. package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
  56. package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
  57. package/dist/runtime/channels/channel-dispatchers.js +44 -37
  58. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  59. package/dist/runtime/channels/channel-envelope.js +74 -31
  60. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
  61. package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
  62. package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
  63. package/dist/runtime/channels/channel-runtime-manager.js +4 -4
  64. package/dist/runtime/channels/channel-transports.d.ts +0 -1
  65. package/dist/runtime/channels/channel-transports.js +35 -33
  66. package/dist/runtime/channels/client-server-location-runtime.js +5 -4
  67. package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
  68. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  69. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  70. package/dist/runtime/channels/fanout-location-runtime.js +3 -3
  71. package/dist/runtime/diagnostics/flow-context.js +19 -7
  72. package/dist/runtime/diagnostics/index.js +4 -9
  73. package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
  74. package/dist/runtime/diagnostics/message-flow.js +35 -5
  75. package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
  76. package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
  77. package/dist/runtime/execution/index.d.ts +4 -2
  78. package/dist/runtime/execution/index.js +33 -10
  79. package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
  80. package/dist/runtime/execution/serial-execution-queue.js +21 -2
  81. package/dist/runtime/execution/state-lane.d.ts +2 -0
  82. package/dist/runtime/execution/state-lane.js +5 -0
  83. package/dist/runtime/foundation/operation-registry.d.ts +25 -1
  84. package/dist/runtime/foundation/operation-registry.js +86 -18
  85. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
  86. package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
  87. package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
  88. package/dist/runtime/foundation/service-liveness-registry.js +38 -0
  89. package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
  90. package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
  91. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
  92. package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
  93. package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
  94. package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
  95. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
  96. package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
  97. package/dist/runtime/foundation/service-stateful-registry.js +24 -26
  98. package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
  99. package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
  100. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
  101. package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
  102. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
  103. package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
  104. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  105. package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
  106. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
  107. package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
  108. package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
  109. package/dist/runtime/host/actor-packet-relay.js +59 -72
  110. package/dist/runtime/host/actor-placement-coordinator.js +25 -8
  111. package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
  112. package/dist/runtime/host/actor-transfer-runtime.js +85 -331
  113. package/dist/runtime/host/application-job-queue.d.ts +24 -3
  114. package/dist/runtime/host/application-job-queue.js +28 -41
  115. package/dist/runtime/host/index.d.ts +5 -1
  116. package/dist/runtime/host/index.js +171 -97
  117. package/dist/runtime/host/location-runtime-owner.js +2 -6
  118. package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
  119. package/dist/runtime/host/mesh-router-resolver.js +14 -6
  120. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
  121. package/dist/runtime/host/remote-bound-session-relay.js +71 -190
  122. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
  123. package/dist/runtime/host/route-mesh-runtime.js +5 -3
  124. package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
  125. package/dist/runtime/host/runtime-shutdown.js +3 -2
  126. package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
  127. package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
  128. package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
  129. package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
  130. package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
  131. package/dist/runtime/locations/auto-connect-loop.js +22 -14
  132. package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
  133. package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
  134. package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
  135. package/dist/runtime/locations/descriptor-publication.js +11 -0
  136. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  137. package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
  138. package/dist/runtime/locations/in-memory-authority-store.js +56 -19
  139. package/dist/runtime/locations/in-memory-location-store.js +1 -10
  140. package/dist/runtime/locations/index.d.ts +1 -0
  141. package/dist/runtime/locations/index.js +1 -0
  142. package/dist/runtime/locations/lease-tracker.js +1 -6
  143. package/dist/runtime/locations/location-store-repository.d.ts +51 -1
  144. package/dist/runtime/locations/location-store-repository.js +363 -139
  145. package/dist/runtime/locations/relocation-blob.d.ts +18 -1
  146. package/dist/runtime/locations/relocation-blob.js +52 -1
  147. package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
  148. package/dist/runtime/locations/request-source-resolver.js +80 -0
  149. package/dist/runtime/locations/resolvers.js +1 -1
  150. package/dist/runtime/locations/runtime.d.ts +6 -2
  151. package/dist/runtime/locations/runtime.js +37 -30
  152. package/dist/runtime/messaging/payload-codec.d.ts +7 -1
  153. package/dist/runtime/messaging/payload-codec.js +7 -6
  154. package/dist/runtime/messaging/request-result.js +29 -26
  155. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
  156. package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
  157. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
  158. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
  159. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
  160. package/dist/runtime/spots/index.d.ts +18 -11
  161. package/dist/runtime/spots/index.js +234 -176
  162. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  163. package/dist/runtime/spots/spot-activation-registry.js +21 -11
  164. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  165. package/dist/runtime/spots/spot-activation-state.js +7 -7
  166. package/dist/runtime/spots/spot-activation.d.ts +6 -3
  167. package/dist/runtime/spots/spot-activation.js +123 -44
  168. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
  169. package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
  170. package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
  171. package/dist/runtime/spots/spot-actor-membership.js +0 -8
  172. package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
  173. package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
  174. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
  175. package/dist/runtime/spots/spot-entry-activation.js +14 -9
  176. package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
  177. package/dist/runtime/spots/spot-handler-registry.js +6 -2
  178. package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
  179. package/dist/runtime/spots/spot-manager-public.js +2 -2
  180. package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
  181. package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
  182. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
  183. package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
  184. package/dist/runtime/spots/spot-outbound.js +3 -3
  185. package/dist/runtime/spots/spot-remote-codec.js +5 -1
  186. package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
  187. package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
  188. package/dist/runtime/spots/spot-serial-executor.js +61 -8
  189. package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
  190. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
  191. package/dist/runtime/spots/spot-timer.d.ts +57 -5
  192. package/dist/runtime/spots/spot-timer.js +287 -103
  193. package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
  194. package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
  195. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
  196. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
  197. package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
  198. package/dist/runtime/streams/bound-session-service.d.ts +1 -1
  199. package/dist/runtime/streams/bound-session-service.js +6 -11
  200. package/dist/runtime/streams/index.d.ts +3 -2
  201. package/dist/runtime/streams/index.js +6 -4
  202. package/dist/runtime/streams/managed-stream.js +3 -2
  203. package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
  204. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
  205. package/dist/runtime/streams/session-actor-coordinator.js +15 -32
  206. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
  207. package/dist/runtime/streams/stream-session-runtime.js +1 -4
  208. package/dist/runtime/workers/index.js +1 -1
  209. package/package.json +3 -3
  210. package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
  211. package/src/contracts/Common/encoded-payload-storage.ts +6 -3
  212. package/src/contracts/Configuration/Builders.ts +4 -1
  213. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
  214. package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
  215. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  216. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
  217. package/src/contracts/Locations/Rows.ts +2 -0
  218. package/src/contracts/Spots/Contracts.ts +8 -0
  219. package/src/contracts/Spots/ZLinkSpot.ts +3 -3
  220. package/src/runtime/abort.ts +12 -0
  221. package/src/runtime/actors/actor-authority-publication.ts +3 -2
  222. package/src/runtime/actors/actor-client.ts +61 -70
  223. package/src/runtime/actors/actor-context.ts +49 -9
  224. package/src/runtime/actors/actor-handoff.ts +282 -106
  225. package/src/runtime/actors/actor-join-relocation.ts +2 -0
  226. package/src/runtime/actors/actor-local-native-join.ts +4 -0
  227. package/src/runtime/actors/actor-mailbox.ts +40 -2
  228. package/src/runtime/actors/actor-remote-joiner.ts +6 -1
  229. package/src/runtime/actors/actor-reply.ts +42 -0
  230. package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
  231. package/src/runtime/actors/actor-runtime-state.ts +2 -20
  232. package/src/runtime/actors/actor-source-transfer.ts +1 -34
  233. package/src/runtime/actors/index.ts +41 -27
  234. package/src/runtime/actors/session-disconnected-wire.ts +66 -0
  235. package/src/runtime/admission.ts +69 -34
  236. package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
  237. package/src/runtime/application-jobs/contracts.ts +2 -0
  238. package/src/runtime/backend/contracts/index.ts +39 -4
  239. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
  240. package/src/runtime/backend/mesh-completion-table.ts +4 -0
  241. package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
  242. package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
  243. package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
  244. package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
  245. package/src/runtime/channels/channel-clients.ts +49 -24
  246. package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
  247. package/src/runtime/channels/channel-dispatchers.ts +116 -72
  248. package/src/runtime/channels/channel-envelope.ts +105 -36
  249. package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
  250. package/src/runtime/channels/channel-runtime-manager.ts +12 -5
  251. package/src/runtime/channels/channel-transports.ts +49 -58
  252. package/src/runtime/channels/client-server-location-runtime.ts +11 -10
  253. package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
  254. package/src/runtime/channels/fanout-location-runtime.ts +17 -9
  255. package/src/runtime/diagnostics/flow-context.ts +20 -7
  256. package/src/runtime/diagnostics/index.ts +1 -7
  257. package/src/runtime/diagnostics/message-flow.ts +47 -9
  258. package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
  259. package/src/runtime/execution/index.ts +40 -14
  260. package/src/runtime/execution/serial-execution-queue.ts +31 -4
  261. package/src/runtime/execution/state-lane.ts +7 -0
  262. package/src/runtime/foundation/operation-registry.ts +98 -20
  263. package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
  264. package/src/runtime/foundation/service-liveness-registry.ts +39 -0
  265. package/src/runtime/foundation/service-mailbox.ts +8 -0
  266. package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
  267. package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
  268. package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
  269. package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
  270. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
  271. package/src/runtime/foundation/service-stateful-registry.ts +38 -35
  272. package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
  274. package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
  275. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  276. package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
  277. package/src/runtime/host/actor-packet-relay.ts +113 -94
  278. package/src/runtime/host/actor-placement-coordinator.ts +31 -8
  279. package/src/runtime/host/actor-transfer-runtime.ts +104 -430
  280. package/src/runtime/host/application-job-queue.ts +29 -44
  281. package/src/runtime/host/index.ts +286 -129
  282. package/src/runtime/host/location-runtime-owner.ts +2 -6
  283. package/src/runtime/host/mesh-router-resolver.ts +13 -5
  284. package/src/runtime/host/remote-bound-session-relay.ts +86 -248
  285. package/src/runtime/host/route-mesh-runtime.ts +11 -5
  286. package/src/runtime/host/runtime-shutdown.ts +15 -4
  287. package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
  288. package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
  290. package/src/runtime/locations/auto-connect-loop.ts +22 -14
  291. package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
  292. package/src/runtime/locations/auto-connect-types.ts +0 -1
  293. package/src/runtime/locations/descriptor-publication.ts +7 -0
  294. package/src/runtime/locations/domain-store-contract.ts +5 -0
  295. package/src/runtime/locations/in-memory-authority-store.ts +85 -23
  296. package/src/runtime/locations/in-memory-location-store.ts +1 -12
  297. package/src/runtime/locations/index.ts +1 -0
  298. package/src/runtime/locations/lease-tracker.ts +2 -9
  299. package/src/runtime/locations/location-store-repository.ts +628 -152
  300. package/src/runtime/locations/relocation-blob.ts +75 -1
  301. package/src/runtime/locations/request-source-resolver.ts +138 -0
  302. package/src/runtime/locations/resolvers.ts +2 -2
  303. package/src/runtime/locations/runtime.ts +70 -40
  304. package/src/runtime/messaging/payload-codec.ts +8 -11
  305. package/src/runtime/messaging/request-result.ts +33 -29
  306. package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
  307. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
  308. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
  309. package/src/runtime/spots/index.ts +375 -281
  310. package/src/runtime/spots/spot-activation-registry.ts +25 -13
  311. package/src/runtime/spots/spot-activation-state.ts +12 -19
  312. package/src/runtime/spots/spot-activation.ts +170 -86
  313. package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
  314. package/src/runtime/spots/spot-actor-membership.ts +0 -15
  315. package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
  316. package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
  317. package/src/runtime/spots/spot-entry-activation.ts +24 -19
  318. package/src/runtime/spots/spot-handler-registry.ts +15 -4
  319. package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
  320. package/src/runtime/spots/spot-manager-public.ts +2 -2
  321. package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
  322. package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
  323. package/src/runtime/spots/spot-outbound.ts +3 -3
  324. package/src/runtime/spots/spot-remote-codec.ts +9 -2
  325. package/src/runtime/spots/spot-runtime-ports.ts +0 -1
  326. package/src/runtime/spots/spot-serial-executor.ts +97 -25
  327. package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
  328. package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
  329. package/src/runtime/spots/spot-timer.ts +413 -157
  330. package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
  331. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
  332. package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
  333. package/src/runtime/streams/bound-session-service.ts +7 -10
  334. package/src/runtime/streams/index.ts +12 -6
  335. package/src/runtime/streams/managed-stream.ts +4 -2
  336. package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
  337. package/src/runtime/streams/session-actor-coordinator.ts +39 -88
  338. package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
  339. package/src/runtime/streams/stream-session-runtime.ts +1 -5
  340. package/src/runtime/workers/index.ts +1 -1
@@ -1,3 +1,14 @@
1
+ import type { RoutingId } from '../../contracts';
2
+ import { type ServiceSessionRelocationRoute, type ServiceSessionRelocationSeal, type ServiceSessionRelocationSealed } from '../foundation/service-stateful-wire-codec';
3
+ export interface ZLinkPreparedSessionRelocationSeal {
4
+ readonly response: ServiceSessionRelocationSealed;
5
+ readonly ready: Promise<void>;
6
+ }
7
+ interface SessionRelocationResult extends ZLinkPreparedSessionRelocationSeal {
8
+ readonly key: string;
9
+ readonly fingerprint: string;
10
+ readonly seal?: ZLinkActorSessionRelocationState;
11
+ }
1
12
  export declare const DEFAULT_TERMINAL_RELOCATION_CAPACITY = 4096;
2
13
  export interface ZLinkActorSessionBindingActor {
3
14
  readonly actorId: string;
@@ -7,7 +18,7 @@ export interface ZLinkActorSessionBindingActor {
7
18
  };
8
19
  }
9
20
  export interface ZLinkActorSessionBindingContext<TActor extends ZLinkActorSessionBindingActor> {
10
- readonly routingId?: unknown;
21
+ readonly routingId?: RoutingId;
11
22
  readonly actorSlotControls?: {
12
23
  enqueueBound(actorSlot: number, actorId: string): Promise<void>;
13
24
  enqueueUnbound(actorSlot: number): Promise<void>;
@@ -20,17 +31,18 @@ export interface ZLinkActorSessionRoute<TContext extends ZLinkActorSessionBindin
20
31
  readonly actor: TActor;
21
32
  readonly bindingToken: string;
22
33
  readonly actorSlot?: number;
23
- readonly sessionIdentity?: string;
34
+ readonly sessionIdentity?: RoutingId;
24
35
  readonly activeFrames: ZLinkActorSessionActiveFrames;
25
36
  sealId?: string;
37
+ sessionRelocationResult?: SessionRelocationResult;
26
38
  authorityFence?: ZLinkActorSessionAuthorityFence;
27
39
  }
28
40
  export interface ZLinkActorSessionRelocationClaim {
29
41
  readonly actorId: string;
30
42
  readonly actorGeneration: bigint;
31
43
  readonly bindingGeneration: bigint;
32
- readonly sessionIdentity?: string;
33
- readonly actorNodeRid?: string;
44
+ readonly sessionIdentity?: RoutingId;
45
+ readonly actorNodeRid?: RoutingId;
34
46
  readonly actorNodeGeneration?: bigint;
35
47
  readonly sealId: string;
36
48
  }
@@ -57,6 +69,21 @@ interface ZLinkActorSessionActiveFrames {
57
69
  captureBySeal(): void;
58
70
  }>;
59
71
  }
72
+ interface ZLinkActorSessionRelocationState {
73
+ readonly actorId: string;
74
+ readonly actorGeneration: bigint;
75
+ readonly bindingGeneration: bigint;
76
+ readonly sessionIdentity?: RoutingId;
77
+ readonly actorNodeRid?: RoutingId;
78
+ readonly actorNodeGeneration?: bigint;
79
+ readonly sealId: string;
80
+ phase: 'sealed' | 'applying' | 'applied' | 'terminal';
81
+ applyFingerprint?: string;
82
+ applyPromise?: Promise<void>;
83
+ readonly ready: Promise<void>;
84
+ readonly terminal: Promise<void>;
85
+ readonly resolveTerminal: () => void;
86
+ }
60
87
  export interface ZLinkActorSessionAuthorityFence {
61
88
  readonly authorityOwnerGeneration: bigint;
62
89
  readonly ownerLeaseGeneration: bigint;
@@ -79,21 +106,22 @@ export declare class ZLinkActorSessionBindingRegistry<TContext extends ZLinkActo
79
106
  private readonly sealWaiters;
80
107
  private readonly activeFrameWaiters;
81
108
  private readonly relocations;
109
+ private readonly absentSessionRelocationResults;
82
110
  private readonly terminalRelocations;
83
111
  constructor(terminalRelocationCapacity?: number, sealWaitTimeoutMs?: number, errorSink?: (() => {
84
112
  reportRuntimeTaskException(taskName: string, error: unknown): void;
85
113
  } | undefined) | undefined);
86
- bind(context: TContext, actor: TActor, bindingToken: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?: string, commitActor?: () => void): Promise<void>;
114
+ bind(context: TContext, actor: TActor, bindingToken: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?: RoutingId, commitActor?: () => void): Promise<void>;
87
115
  private commitCore;
88
116
  private issueActorSlot;
89
- replace(previous: ZLinkActorSessionRoute<TContext, TActor>, context: TContext, actor: TActor, bindingToken: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?: string, commitActor?: () => void): Promise<void>;
90
- replaceAndReleaseSeal(previous: ZLinkActorSessionRoute<TContext, TActor>, context: TContext, actor: TActor, bindingToken: string, sealId: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?: string, commitActor?: () => void): Promise<void>;
117
+ replace(previous: ZLinkActorSessionRoute<TContext, TActor>, context: TContext, actor: TActor, bindingToken: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?: RoutingId, commitActor?: () => void): Promise<void>;
118
+ replaceAndReleaseSeal(previous: ZLinkActorSessionRoute<TContext, TActor>, context: TContext, actor: TActor, bindingToken: string, sealId: string, authorityFence?: ZLinkActorSessionAuthorityFence, sessionIdentity?: RoutingId, commitActor?: () => void): Promise<void>;
91
119
  private replaceAndReleaseSealCore;
92
120
  find(actorId: string): Promise<TActor | undefined>;
93
121
  private findCore;
94
122
  route(actorId: string): Promise<ZLinkActorSessionRoute<TContext, TActor> | undefined>;
95
123
  /** Selects the route only when it is the exact Session binding (§8.1 validation values). */
96
- routeForSessionBinding(actorId: string, sessionRid: string, bindingGeneration?: bigint): Promise<ZLinkActorSessionRoute<TContext, TActor> | undefined>;
124
+ routeForSessionBinding(actorId: string, sessionRid: RoutingId, bindingGeneration?: bigint): Promise<ZLinkActorSessionRoute<TContext, TActor> | undefined>;
97
125
  private routeCore;
98
126
  capturePendingReplyClaim(actorId: string, actor: ZLinkActorSessionBindingActor, bindingToken: string): Promise<{
99
127
  readonly context: TContext;
@@ -131,11 +159,16 @@ export declare class ZLinkActorSessionBindingRegistry<TContext extends ZLinkActo
131
159
  seal(actorId: string, sealId: string, expected: ZLinkActorSessionRouteFence): Promise<void>;
132
160
  private sealCore;
133
161
  sealAndWait(actorId: string, sealId: string, expected: ZLinkActorSessionRouteFence, signal?: AbortSignal): Promise<void>;
162
+ prepareSessionRelocationSeal(value: ServiceSessionRelocationSeal, signal?: AbortSignal): Promise<ZLinkPreparedSessionRelocationSeal | undefined>;
163
+ private prepareSessionRelocationSealCore;
164
+ acceptSessionRelocationRoute(value: ServiceSessionRelocationRoute, apply: () => Promise<void>): Promise<boolean>;
165
+ clearSessionRelocationResults(): Promise<void>;
134
166
  sealRelocation(claim: ZLinkActorSessionRelocationClaim, expected: ZLinkActorSessionRouteFence, signal?: AbortSignal): Promise<void>;
135
167
  private prepareRelocationSeal;
136
168
  relocationSnapshot(actorId: string, sealId: string): Promise<ZLinkActorSessionRelocationSnapshot | undefined>;
137
169
  private relocationSnapshotCore;
138
170
  applyRelocation(actorId: string, sealId: string, applyFingerprint: string, commitOwnerTransition: () => Promise<void>): Promise<void>;
171
+ private runRelocationApply;
139
172
  private prepareRelocationApply;
140
173
  private completeRelocationApply;
141
174
  private failRelocationApply;
@@ -149,7 +182,7 @@ export declare class ZLinkActorSessionBindingRegistry<TContext extends ZLinkActo
149
182
  * single physical route's disconnect, which must not disturb a relocation
150
183
  * seal it does not own (see `clearRouteRelocation`).
151
184
  */
152
- clearRelocation(actorId: string, error: unknown): Promise<void>;
185
+ clearRelocation(actorId: string, error: unknown, sealId?: string): Promise<void>;
153
186
  private clearRelocationCore;
154
187
  /**
155
188
  * Spec 48 §137: a relocation seal's lifecycle is independent of any single
@@ -165,8 +198,6 @@ export declare class ZLinkActorSessionBindingRegistry<TContext extends ZLinkActo
165
198
  private clearRouteRelocation;
166
199
  abortSeal(actorId: string, sealId: string): Promise<boolean>;
167
200
  private abortSealCore;
168
- updateAuthorityFence(actorId: string, authorityFence: ZLinkActorSessionAuthorityFence): Promise<void>;
169
- private updateAuthorityFenceCore;
170
201
  validateSeal(actorId: string, sealId: string): Promise<boolean>;
171
202
  private validateSealCore;
172
203
  /** True while a relocation seal currently holds this actor's ingress. */
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZLinkActorSessionBindingRegistry = exports.ZLinkActorSessionBindingTermination = exports.DEFAULT_TERMINAL_RELOCATION_CAPACITY = void 0;
4
- const node_async_hooks_1 = require("node:async_hooks");
5
4
  const ZLinkFrameworkException_1 = require("../../contracts/Errors/ZLinkFrameworkException");
6
5
  const Options_1 = require("../../contracts/Locations/Options");
7
6
  const abort_1 = require("../abort");
8
7
  const state_lane_1 = require("../execution/state-lane");
8
+ const routing_id_1 = require("../routing-id");
9
9
  const framework_errors_internal_1 = require("../framework-errors-internal");
10
+ const service_stateful_wire_codec_1 = require("../foundation/service-stateful-wire-codec");
11
+ const service_wire_m6a_codec_1 = require("../foundation/service-wire-m6a-codec");
12
+ const bound_session_wire_1 = require("../actors/bound-session-wire");
10
13
  exports.DEFAULT_TERMINAL_RELOCATION_CAPACITY = 4096;
11
- const detachedStateLaneResource = new node_async_hooks_1.AsyncResource('zlink:actor-session-binding-registry');
12
14
  var ZLinkActorSessionBindingTermination;
13
15
  (function (ZLinkActorSessionBindingTermination) {
14
16
  ZLinkActorSessionBindingTermination[ZLinkActorSessionBindingTermination["BindingEnd"] = 0] = "BindingEnd";
@@ -24,6 +26,7 @@ class ZLinkActorSessionBindingRegistry {
24
26
  sealWaiters = new Map();
25
27
  activeFrameWaiters = new Map();
26
28
  relocations = new Map();
29
+ absentSessionRelocationResults = new Map();
27
30
  terminalRelocations = new Map();
28
31
  constructor(terminalRelocationCapacity = exports.DEFAULT_TERMINAL_RELOCATION_CAPACITY,
29
32
  // Spec 06 — SessionRelocationSealTimeout bounds how long a session
@@ -51,26 +54,20 @@ class ZLinkActorSessionBindingRegistry {
51
54
  if (current !== previous) {
52
55
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorSessionNotBound, `Actor '${actor.actorId}' session binding changed before route commit.`, true);
53
56
  }
57
+ const currentSessionIdentity = sessionIdentity ?? sessionIdentityFromContext(context);
54
58
  const sameBinding = previous !== undefined &&
55
- previous.context === context &&
56
- previous.bindingToken === bindingToken;
59
+ previous.bindingToken === bindingToken &&
60
+ (previous.context === context ||
61
+ (previous.sessionIdentity !== undefined &&
62
+ currentSessionIdentity !== undefined &&
63
+ (0, routing_id_1.routingIdsEqual)(previous.sessionIdentity, currentSessionIdentity)));
57
64
  const actorSlot = sameBinding ? previous.actorSlot : this.issueActorSlot(context);
58
65
  commitActor?.();
59
66
  context.bindLocal(actor, bindingToken, actorSlot);
60
67
  try {
61
68
  if (previous !== undefined && !sameBinding) {
62
- this.routes.delete(actor.actorId);
63
- previous.context.unbindLocal(actor.actorId, previous.bindingToken);
64
- if (previous.actorSlot !== undefined) {
65
- let unbound;
66
- try {
67
- unbound = previous.context.actorSlotControls?.enqueueUnbound(previous.actorSlot);
68
- }
69
- catch (error) {
70
- unbound = Promise.reject(error);
71
- }
72
- void unbound?.catch((error) => this.errorSink?.()?.reportRuntimeTaskException('retired session actor unbound', error));
73
- }
69
+ const unbound = this.unbindCore(actor.actorId, previous.context, previous.bindingToken, ZLinkActorSessionBindingTermination.BindingEnd);
70
+ void unbound?.catch((error) => this.errorSink?.()?.reportRuntimeTaskException('retired session actor unbound', error));
74
71
  }
75
72
  if (!sameBinding && actorSlot !== undefined) {
76
73
  // Session–Actor binding §5-2: `$zlink.actor.bound` enters the ordered
@@ -90,15 +87,19 @@ class ZLinkActorSessionBindingRegistry {
90
87
  context.unbindLocal(actor.actorId, bindingToken);
91
88
  throw error;
92
89
  }
90
+ const bindingState = sameBinding ? previous : undefined;
93
91
  this.routes.set(actor.actorId, {
94
92
  context,
95
93
  actor,
96
94
  bindingToken,
97
95
  actorSlot,
98
- sessionIdentity: sessionIdentity ?? sessionIdentityFromContext(context),
96
+ sessionIdentity: currentSessionIdentity,
97
+ // Accepted frames retain their completion fence across route replacement;
98
+ // the successor's seal must still drain them (Session binding §8.1).
99
99
  activeFrames: previous?.activeFrames ?? { count: 0, requests: new Set() },
100
- sealId: previous?.sealId,
101
- authorityFence: authorityFence ?? previous?.authorityFence
100
+ sealId: bindingState?.sealId,
101
+ sessionRelocationResult: bindingState?.sessionRelocationResult,
102
+ authorityFence: authorityFence ?? bindingState?.authorityFence
102
103
  });
103
104
  }
104
105
  issueActorSlot(context) {
@@ -143,7 +144,7 @@ class ZLinkActorSessionBindingRegistry {
143
144
  return await this.lane.run(() => {
144
145
  const route = this.routeCore(actorId);
145
146
  const generation = route?.actor.ref.bindingGeneration;
146
- return route?.sessionIdentity === sessionRid &&
147
+ return (0, routing_id_1.routingIdsEqual)(route?.sessionIdentity, sessionRid) &&
147
148
  (bindingGeneration === undefined || generation === bindingGeneration)
148
149
  ? route
149
150
  : undefined;
@@ -181,7 +182,12 @@ class ZLinkActorSessionBindingRegistry {
181
182
  this.clearRouteRelocation(actorId, route);
182
183
  if (termination === ZLinkActorSessionBindingTermination.BindingEnd &&
183
184
  route.actorSlot !== undefined) {
184
- return context.actorSlotControls?.enqueueUnbound(route.actorSlot);
185
+ try {
186
+ return context.actorSlotControls?.enqueueUnbound(route.actorSlot);
187
+ }
188
+ catch (error) {
189
+ return Promise.reject(error);
190
+ }
185
191
  }
186
192
  return undefined;
187
193
  }
@@ -409,6 +415,120 @@ class ZLinkActorSessionBindingRegistry {
409
415
  await this.lane.run(() => this.sealCore(actorId, sealId, expected));
410
416
  await this.waitForActiveFrames(actorId, signal);
411
417
  }
418
+ async prepareSessionRelocationSeal(value, signal) {
419
+ for (;;) {
420
+ const step = await this.lane.run(() => this.prepareSessionRelocationSealCore(value, signal));
421
+ if (step === undefined || !('predecessor' in step))
422
+ return step;
423
+ await waitForSessionRelocation(step.predecessor, signal);
424
+ }
425
+ }
426
+ prepareSessionRelocationSealCore(value, signal) {
427
+ const actorId = value.actor.actor.actorId;
428
+ const key = (0, service_stateful_wire_codec_1.serviceSessionRelocationIdentityKey)(value);
429
+ const fingerprint = (0, service_stateful_wire_codec_1.encodeSessionRelocationSeal)(value).toString('base64');
430
+ const route = this.routes.get(actorId);
431
+ const bindingResult = route?.sessionRelocationResult;
432
+ const recorded = this.absentSessionRelocationResults.get(key)?.result ??
433
+ (bindingResult?.key === key ? bindingResult : undefined);
434
+ if (recorded !== undefined) {
435
+ if (recorded.fingerprint !== fingerprint) {
436
+ throw new service_wire_m6a_codec_1.ServiceWireProtocolError(`Session relocation '${key}' repeated command 42 with different bytes.`);
437
+ }
438
+ if (recorded.seal?.phase === 'terminal') {
439
+ console.warn(`late_session_relocation_seal session=${value.session.sessionRid}`);
440
+ return undefined;
441
+ }
442
+ return recorded;
443
+ }
444
+ (0, abort_1.throwIfAborted)(signal);
445
+ const response = {
446
+ relocation: value.relocation,
447
+ coordinator: value.coordinator,
448
+ actor: value.actor,
449
+ session: value.session,
450
+ sealResult: route === undefined ? 'bindingAbsent' : 'sealed'
451
+ };
452
+ if (route === undefined) {
453
+ const result = {
454
+ key,
455
+ fingerprint,
456
+ response,
457
+ ready: Promise.resolve()
458
+ };
459
+ const expiry = (0, state_lane_1.startOutsideStateLane)(() => setTimeout(() => {
460
+ void (async () => {
461
+ await this.lane.run(() => this.absentSessionRelocationResults.delete(key));
462
+ })().catch((error) => this.errorSink?.()?.reportRuntimeTaskException('session relocation result expiry', error));
463
+ }, this.sealWaitTimeoutMs));
464
+ expiry.unref();
465
+ this.absentSessionRelocationResults.set(key, { result, expiry });
466
+ return result;
467
+ }
468
+ const expected = {
469
+ objectGeneration: value.actor.actor.generation,
470
+ bindingGeneration: value.session.bindingGeneration
471
+ };
472
+ if (!(0, routing_id_1.routingIdsEqual)(route.sessionIdentity, value.session.sessionRid) ||
473
+ !routeMatchesFence(route, expected) ||
474
+ (route.authorityFence !== undefined &&
475
+ value.actor.ownerLeaseGeneration < route.authorityFence.ownerLeaseGeneration) ||
476
+ (route.sealId !== undefined && route.sealId !== key)) {
477
+ throw new bound_session_wire_1.ZLinkRemoteBoundSessionFenceError(`Actor '${actorId}' command 42 was fenced by its exact Session route.`);
478
+ }
479
+ const step = this.prepareRelocationSeal({
480
+ actorId,
481
+ actorGeneration: value.actor.actor.generation,
482
+ bindingGeneration: value.session.bindingGeneration,
483
+ sessionIdentity: value.session.sessionRid,
484
+ actorNodeRid: value.actor.actor.nodeRid,
485
+ actorNodeGeneration: value.actor.targetNodeGeneration,
486
+ sealId: key
487
+ }, expected, signal);
488
+ if (step.kind === 'predecessor')
489
+ return { predecessor: step.wait };
490
+ const result = {
491
+ key,
492
+ fingerprint,
493
+ response,
494
+ ready: step.wait,
495
+ seal: this.relocations.get(actorId).seals.get(key)
496
+ };
497
+ route.sessionRelocationResult = result;
498
+ return result;
499
+ }
500
+ async acceptSessionRelocationRoute(value, apply) {
501
+ const key = (0, service_stateful_wire_codec_1.serviceSessionRelocationIdentityKey)(value);
502
+ const fingerprint = (0, service_stateful_wire_codec_1.encodeSessionRelocationRoute)(value).toString('base64');
503
+ const prepared = await this.lane.run(() => {
504
+ if (this.absentSessionRelocationResults.has(key))
505
+ return undefined;
506
+ const result = this.routes.get(value.actor.actorId)?.sessionRelocationResult;
507
+ if (result?.key !== key || result.seal === undefined)
508
+ return undefined;
509
+ const seal = result.seal;
510
+ if (seal.applyFingerprint !== undefined && seal.applyFingerprint !== fingerprint) {
511
+ throw new service_wire_m6a_codec_1.ServiceWireProtocolError(`Session relocation '${key}' repeated command 44 with different bytes.`);
512
+ }
513
+ if (seal.phase === 'terminal')
514
+ return undefined;
515
+ return this.prepareRelocationApply(value.actor.actorId, key, fingerprint);
516
+ });
517
+ if (prepared === undefined)
518
+ return false;
519
+ await this.runRelocationApply(prepared, apply);
520
+ await this.observeRelocationTerminal(value.actor.actorId, key, fingerprint);
521
+ return true;
522
+ }
523
+ async clearSessionRelocationResults() {
524
+ await this.lane.run(() => {
525
+ for (const { expiry } of this.absentSessionRelocationResults.values())
526
+ clearTimeout(expiry);
527
+ this.absentSessionRelocationResults.clear();
528
+ for (const route of this.routes.values())
529
+ route.sessionRelocationResult = undefined;
530
+ });
531
+ }
412
532
  async sealRelocation(claim, expected, signal) {
413
533
  for (;;) {
414
534
  (0, abort_1.throwIfAborted)(signal);
@@ -467,11 +587,14 @@ class ZLinkActorSessionBindingRegistry {
467
587
  }
468
588
  async applyRelocation(actorId, sealId, applyFingerprint, commitOwnerTransition) {
469
589
  const prepared = await this.lane.run(() => this.prepareRelocationApply(actorId, sealId, applyFingerprint));
590
+ await this.runRelocationApply(prepared, commitOwnerTransition);
591
+ }
592
+ async runRelocationApply(prepared, commitOwnerTransition) {
470
593
  if (prepared.applyPromise !== undefined) {
471
594
  await prepared.applyPromise;
472
595
  return;
473
596
  }
474
- startOutsideStateLane(() => {
597
+ (0, state_lane_1.startOutsideStateLane)(() => {
475
598
  void (async () => {
476
599
  try {
477
600
  await commitOwnerTransition();
@@ -552,10 +675,13 @@ class ZLinkActorSessionBindingRegistry {
552
675
  * single physical route's disconnect, which must not disturb a relocation
553
676
  * seal it does not own (see `clearRouteRelocation`).
554
677
  */
555
- async clearRelocation(actorId, error) {
556
- await this.lane.run(() => this.clearRelocationCore(actorId, error));
678
+ async clearRelocation(actorId, error, sealId) {
679
+ await this.lane.run(() => this.clearRelocationCore(actorId, error, sealId));
557
680
  }
558
- clearRelocationCore(actorId, error) {
681
+ clearRelocationCore(actorId, error, sealId) {
682
+ const result = this.routes.get(actorId)?.sessionRelocationResult;
683
+ if (sealId !== undefined && (result?.key !== sealId || result.seal?.phase === 'terminal'))
684
+ return;
559
685
  const queue = this.relocations.get(actorId);
560
686
  if (queue === undefined)
561
687
  return;
@@ -569,8 +695,8 @@ class ZLinkActorSessionBindingRegistry {
569
695
  this.relocations.delete(actorId);
570
696
  for (const state of queue.seals.values()) {
571
697
  this.terminalRelocations.delete(state);
572
- if (state.phase !== 'terminal')
573
- state.resolveTerminal();
698
+ state.phase = 'terminal';
699
+ state.resolveTerminal();
574
700
  }
575
701
  }
576
702
  /**
@@ -592,7 +718,7 @@ class ZLinkActorSessionBindingRegistry {
592
718
  const activeState = activeSealId === undefined ? undefined : queue.seals.get(activeSealId);
593
719
  const ownsActiveSeal = activeState !== undefined &&
594
720
  activeState.phase !== 'terminal' &&
595
- activeState.sessionIdentity === route.sessionIdentity;
721
+ (0, routing_id_1.routingIdsEqual)(activeState.sessionIdentity, route.sessionIdentity);
596
722
  if (!ownsActiveSeal) {
597
723
  // Nothing this exact route still holds open — leave terminal
598
724
  // retention and any other Session's active seal untouched.
@@ -602,6 +728,7 @@ class ZLinkActorSessionBindingRegistry {
602
728
  queue.activeSealId = undefined;
603
729
  queue.seals.delete(activeSealId);
604
730
  this.terminalRelocations.delete(activeState);
731
+ activeState.phase = 'terminal';
605
732
  activeState.resolveTerminal();
606
733
  this.deleteEmptyRelocationQueue(queue);
607
734
  }
@@ -616,13 +743,6 @@ class ZLinkActorSessionBindingRegistry {
616
743
  this.resolveSealWaiters(actorId, sealId);
617
744
  return true;
618
745
  }
619
- async updateAuthorityFence(actorId, authorityFence) {
620
- await this.lane.run(() => this.updateAuthorityFenceCore(actorId, authorityFence));
621
- }
622
- updateAuthorityFenceCore(actorId, authorityFence) {
623
- const route = this.requireRouteCore(actorId);
624
- route.authorityFence = authorityFence;
625
- }
626
746
  async validateSeal(actorId, sealId) {
627
747
  return await this.lane.run(() => this.validateSealCore(actorId, sealId));
628
748
  }
@@ -679,7 +799,7 @@ class ZLinkActorSessionBindingRegistry {
679
799
  if (waiters.size === 0)
680
800
  this.sealWaiters.delete(actorId);
681
801
  };
682
- timer = startOutsideStateLane(() => setTimeout(() => {
802
+ timer = (0, state_lane_1.startOutsideStateLane)(() => setTimeout(() => {
683
803
  this.lane.tryPost(() => {
684
804
  removeWaiter();
685
805
  rejectWaiter((0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.DeadlineExceeded, `Actor '${actorId}' session seal was not released within the relocation seal timeout.`, true));
@@ -698,7 +818,7 @@ class ZLinkActorSessionBindingRegistry {
698
818
  onAbort();
699
819
  return;
700
820
  }
701
- startOutsideStateLane(() => signal.addEventListener('abort', onAbort, { once: true }));
821
+ (0, state_lane_1.startOutsideStateLane)(() => signal.addEventListener('abort', onAbort, { once: true }));
702
822
  });
703
823
  }
704
824
  async waitForActiveFrames(actorId, signal) {
@@ -749,7 +869,7 @@ class ZLinkActorSessionBindingRegistry {
749
869
  // Spec 48:205 — transport/deadline limits keep applying during
750
870
  // relocation: the sealing side must not wait forever for active
751
871
  // frames that themselves may be waiting on this relocation.
752
- timer = startOutsideStateLane(() => setTimeout(() => {
872
+ timer = (0, state_lane_1.startOutsideStateLane)(() => setTimeout(() => {
753
873
  this.lane.tryPost(() => {
754
874
  waiters.delete(waiter);
755
875
  if (waiters.size === 0)
@@ -763,7 +883,7 @@ class ZLinkActorSessionBindingRegistry {
763
883
  if (signal.aborted)
764
884
  onAbort();
765
885
  else
766
- startOutsideStateLane(() => signal.addEventListener('abort', onAbort, { once: true }));
886
+ (0, state_lane_1.startOutsideStateLane)(() => signal.addEventListener('abort', onAbort, { once: true }));
767
887
  });
768
888
  }
769
889
  resolveActiveFrameWaiters(actorId) {
@@ -838,7 +958,7 @@ class ZLinkActorSessionBindingRegistry {
838
958
  startHeldOneWayDrain(actorId, queue) {
839
959
  if (queue.ingressDrain !== undefined)
840
960
  return;
841
- const drain = startOutsideStateLane(async () => {
961
+ const drain = (0, state_lane_1.startOutsideStateLane)(async () => {
842
962
  for (;;) {
843
963
  const next = await this.lane.run(() => {
844
964
  if (this.relocations.get(actorId) !== queue)
@@ -859,7 +979,7 @@ class ZLinkActorSessionBindingRegistry {
859
979
  }
860
980
  });
861
981
  queue.ingressDrain = drain;
862
- startOutsideStateLane(() => {
982
+ (0, state_lane_1.startOutsideStateLane)(() => {
863
983
  void drain.finally(async () => {
864
984
  await this.lane.run(() => {
865
985
  if (queue.ingressDrain !== drain)
@@ -878,19 +998,16 @@ exports.ZLinkActorSessionBindingRegistry = ZLinkActorSessionBindingRegistry;
878
998
  function assertRelocationClaim(state, claim) {
879
999
  if (state.actorGeneration !== claim.actorGeneration ||
880
1000
  state.bindingGeneration !== claim.bindingGeneration ||
881
- state.sessionIdentity !== claim.sessionIdentity ||
882
- state.actorNodeRid !== claim.actorNodeRid ||
1001
+ !(0, routing_id_1.routingIdsEqual)(state.sessionIdentity, claim.sessionIdentity) ||
1002
+ !(0, routing_id_1.routingIdsEqual)(state.actorNodeRid, claim.actorNodeRid) ||
883
1003
  state.actorNodeGeneration !== claim.actorNodeGeneration) {
884
1004
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorLocationStale, `Actor '${claim.actorId}' repeated Session seal changed its exact identity.`, true);
885
1005
  }
886
1006
  }
887
- function startOutsideStateLane(work) {
888
- return detachedStateLaneResource.runInAsyncScope(work);
889
- }
890
1007
  function assertSuccessorSessionIdentity(predecessor, successor) {
891
1008
  if (predecessor.actorGeneration !== successor.actorGeneration ||
892
1009
  predecessor.bindingGeneration !== successor.bindingGeneration ||
893
- predecessor.sessionIdentity !== successor.sessionIdentity) {
1010
+ !(0, routing_id_1.routingIdsEqual)(predecessor.sessionIdentity, successor.sessionIdentity)) {
894
1011
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorLocationStale, `Actor '${successor.actorId}' successor Session seal changed its exact Session identity.`, true);
895
1012
  }
896
1013
  }
@@ -901,7 +1018,7 @@ function routeMatchesFence(route, expected) {
901
1018
  ref.bindingGeneration === expected.bindingGeneration);
902
1019
  }
903
1020
  function sessionIdentityFromContext(context) {
904
- return context.routingId === undefined ? undefined : String(context.routingId);
1021
+ return context.routingId;
905
1022
  }
906
1023
  function waitForSessionRelocation(operation, signal) {
907
1024
  if (signal === undefined)
@@ -1,12 +1,16 @@
1
+ import type { RoutingId } from '../../contracts';
2
+ import type { ServiceSessionRelocationSeal, ServiceSessionRelocationRoute } from '../foundation/service-stateful-wire-codec';
1
3
  import type { ActorRef } from '../../contracts';
2
- import type { ZLinkActorSessionAuthorityFence, ZLinkActorSessionRelocationClaim, ZLinkActorSessionRelocationSnapshot, ZLinkActorSessionRouteFence } from './actor-session-binding-registry';
4
+ import type { ZLinkActorSessionAuthorityFence, ZLinkActorSessionRelocationSnapshot, ZLinkPreparedSessionRelocationSeal } from './actor-session-binding-registry';
3
5
  export interface ZLinkActorSessionBindingRuntimeOwner {
4
- actorSlot(actorId: string, sessionRid: string): Promise<number | undefined>;
5
- sealRelocation(claim: ZLinkActorSessionRelocationClaim, expected: ZLinkActorSessionRouteFence, signal?: AbortSignal): Promise<void>;
6
+ prepareSessionRelocationSeal(value: ServiceSessionRelocationSeal, signal?: AbortSignal): Promise<ZLinkPreparedSessionRelocationSeal | undefined>;
7
+ acceptSessionRelocationRoute(value: ServiceSessionRelocationRoute, apply: () => Promise<void>): Promise<boolean>;
8
+ clearSessionRelocationResults(): Promise<void>;
9
+ actorSlot(actorId: string, sessionRid: RoutingId): Promise<number | undefined>;
6
10
  relocationSnapshot(actorId: string, sealId: string): Promise<ZLinkActorSessionRelocationSnapshot | undefined>;
7
11
  applyRelocation(actorId: string, sealId: string, applyFingerprint: string, commitOwnerTransition: () => Promise<void>): Promise<void>;
8
12
  observeRelocationTerminal(actorId: string, sealId: string, applyFingerprint: string): Promise<void>;
9
- clearRelocation(actorId: string, error: unknown): Promise<void>;
13
+ clearRelocation(actorId: string, error: unknown, sealId?: string): Promise<void>;
10
14
  committedRoute(actorId: string): Promise<{
11
15
  readonly actor: ActorRef;
12
16
  readonly authorityFence?: ZLinkActorSessionAuthorityFence;
@@ -7,13 +7,14 @@ import { ZLinkActorSessionLifecycleCoordinator } from './actor-session-lifecycle
7
7
  import { type ZLinkStreamFrameHeader } from './protocol';
8
8
  import { DefaultZLinkSessionActor, DefaultZLinkSessionContext } from './session-context';
9
9
  import { ZLinkStreamFrameMessageFactory } from './stream-frame-factory';
10
+ import type { ServiceStreamSessionBinding } from '../foundation/service-runtime-contracts';
10
11
  export declare const DEFAULT_RELAY_ACTOR_BIND_TIMEOUT_MS = 2000;
11
12
  export interface ZLinkBoundActorRelaySenderOptions {
12
13
  readonly dispatchErrors?: ZLinkDispatchErrorReporter;
13
14
  readonly actorBindTimeoutMs?: number;
14
15
  readonly messageSerializers?: ReadonlyMap<string, ZLinkMessageSerializer>;
15
16
  readonly relay?: (actor: ZLinkSessionActor, header: ZLinkStreamFrameHeader, payload: Message) => Promise<boolean>;
16
- readonly notifyDisconnected?: (actor: ZLinkSessionActor, signal?: AbortSignal) => Promise<void>;
17
+ readonly notifyDisconnected?: (actor: ZLinkSessionActor, signal?: AbortSignal, binding?: ServiceStreamSessionBinding) => Promise<void>;
17
18
  }
18
19
  export declare class ZLinkBoundActorRelaySender {
19
20
  private readonly routes;
@@ -159,15 +159,18 @@ class ZLinkBoundActorRelaySender {
159
159
  const detached = await this.lifecycle.run(actor.actorId, async () => {
160
160
  await this.routes.requireCurrentToken(actor.actorId, actor.bindingToken);
161
161
  const route = await this.routes.requireRoute(actor.actorId);
162
+ const binding = route.context.stream instanceof managed_stream_1.ZLinkManagedStream
163
+ ? route.context.stream.actorBinding(actor.actorId)
164
+ : undefined;
162
165
  await this.routes.unbind(actor.actorId, route.context, actor.bindingToken);
163
- return route;
166
+ return { route, binding };
164
167
  });
165
168
  if (unbindNative &&
166
- detached.bindingToken === actor.bindingToken &&
167
- detached.context.stream instanceof managed_stream_1.ZLinkManagedStream) {
168
- await detached.context.stream.unbindActor(actor.actorId, this.options.actorBindTimeoutMs ?? exports.DEFAULT_RELAY_ACTOR_BIND_TIMEOUT_MS, signal);
169
+ detached.route.bindingToken === actor.bindingToken &&
170
+ detached.route.context.stream instanceof managed_stream_1.ZLinkManagedStream) {
171
+ await detached.route.context.stream.unbindActor(actor.actorId, this.options.actorBindTimeoutMs ?? exports.DEFAULT_RELAY_ACTOR_BIND_TIMEOUT_MS, signal);
169
172
  }
170
- await this.options.notifyDisconnected?.(actor, signal);
173
+ await this.options.notifyDisconnected?.(actor, signal, detached.binding);
171
174
  }
172
175
  async notifyPhysicalDisconnect(context) {
173
176
  const snapshot = [...context.boundActors];
@@ -184,16 +187,20 @@ class ZLinkBoundActorRelaySender {
184
187
  // The transport is already closed, so remove its exact route before
185
188
  // invoking application lifecycle code. A reconnect can then install
186
189
  // a successor while this best-effort notification is in flight.
190
+ const binding = context.stream instanceof managed_stream_1.ZLinkManagedStream
191
+ ? context.stream.actorBinding(actor.actorId)
192
+ : undefined;
187
193
  await this.routes.unbind(actor.actorId, context, actor.bindingToken, actor_session_binding_registry_1.ZLinkActorSessionBindingTermination.PhysicalDisconnect);
188
- return true;
194
+ return { binding };
189
195
  });
190
- if (!detached)
196
+ if (detached === false)
191
197
  return;
192
198
  const controller = new AbortController();
193
199
  const timer = setTimeout(() => controller.abort(), timeoutMs);
194
200
  try {
195
201
  await Promise.race([
196
- this.options.notifyDisconnected?.(actor, controller.signal) ?? Promise.resolve(),
202
+ this.options.notifyDisconnected?.(actor, controller.signal, detached.binding) ??
203
+ Promise.resolve(),
197
204
  new Promise((_, reject) => {
198
205
  controller.signal.addEventListener('abort', () => reject(new Error(`Actor '${actor.actorId}' disconnect notification exceeded ${timeoutMs} ms.`)), { once: true });
199
206
  })
@@ -38,7 +38,7 @@ export declare class ZLinkBoundSessionService {
38
38
  sendNativeBoundSession(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, message: unknown, packetName: string | undefined, metadata: ReadonlyMap<string, string>, signal?: AbortSignal): Promise<ZLinkSubmitResult>;
39
39
  sendNativeBoundSessionResponse(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, packetName: string, requestSeq: bigint, message: unknown, metadata: ReadonlyMap<string, string>, compressPayload: boolean, signal?: AbortSignal): Promise<void>;
40
40
  sendNativeBoundSessionError(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, packetName: string, requestSeq: bigint, error: unknown, metadata: ReadonlyMap<string, string>, signal?: AbortSignal): Promise<void>;
41
- disconnectNativeBoundSession(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, signal?: AbortSignal): Promise<void>;
41
+ disconnectNativeBoundSession(node: ZLinkBackendActorSessionNode, actorRef: ActorRef, timeoutMs: number, signal?: AbortSignal): Promise<void>;
42
42
  disconnectBoundSession(actorId: string, signal?: AbortSignal): Promise<void>;
43
43
  /**
44
44
  * Closes the physical Session of one exact binding after its relocation
@@ -86,22 +86,17 @@ class ZLinkBoundSessionService {
86
86
  (0, abort_1.throwIfAborted)(signal);
87
87
  await this.sendNativeBoundSessionPayload(node, actorRef, protocol_1.ZLinkStreamMessageKind.Error, packetName, metadata, false, requestSeq, (0, bound_session_response_target_1.boundSessionErrorPayload)(error), signal);
88
88
  }
89
- async disconnectNativeBoundSession(node, actorRef, signal) {
89
+ async disconnectNativeBoundSession(node, actorRef, timeoutMs, signal) {
90
90
  (0, abort_1.throwIfAborted)(signal);
91
- await node.closeActorBoundSession(actorRef, requireBoundSessionGeneration(actorRef), 0, signal);
91
+ await node.closeActorBoundSession(toBoundSessionSendActorRef(actorRef), requireBoundSessionGeneration(actorRef), timeoutMs, signal);
92
92
  }
93
93
  async disconnectBoundSession(actorId, signal) {
94
94
  (0, abort_1.throwIfAborted)(signal);
95
95
  const route = await this.routes.requireRoute(actorId);
96
- try {
97
- await this.requireTransport().disconnect(actorId, {
98
- bindingToken: route.bindingToken,
99
- signal
100
- });
101
- }
102
- finally {
103
- await this.routes.unbind(actorId, route.context, route.bindingToken);
104
- }
96
+ await this.requireTransport().disconnect(actorId, {
97
+ bindingToken: route.bindingToken,
98
+ signal
99
+ });
105
100
  }
106
101
  /**
107
102
  * Closes the physical Session of one exact binding after its relocation