@zlink-systems/framework 0.29.1 → 0.30.1

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 (322) 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/ZLinkMessageMetadata.js +11 -5
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  7. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  8. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  9. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  10. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  11. package/dist/contracts/Configuration/index.d.ts +1 -1
  12. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  13. package/dist/contracts/Handlers/Attributes.js +7 -11
  14. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  15. package/dist/contracts/Handlers/JsonContract.js +4 -153
  16. package/dist/contracts/Spots/Contracts.d.ts +2 -1
  17. package/dist/internal.d.ts +1 -0
  18. package/dist/internal.js +3 -1
  19. package/dist/nest-integration.d.ts +1 -1
  20. package/dist/nest-integration.js +2 -1
  21. package/dist/runtime/actors/actor-client.d.ts +1 -1
  22. package/dist/runtime/actors/actor-client.js +14 -12
  23. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  24. package/dist/runtime/actors/actor-handoff.js +15 -7
  25. package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
  26. package/dist/runtime/actors/actor-local-native-join.js +9 -12
  27. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  28. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  29. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  30. package/dist/runtime/actors/index.d.ts +2 -1
  31. package/dist/runtime/actors/index.js +18 -6
  32. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  33. package/dist/runtime/admission.d.ts +1 -1
  34. package/dist/runtime/admission.js +15 -5
  35. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +9 -9
  36. package/dist/runtime/application-jobs/application-ingress-record-owner.js +45 -23
  37. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +5 -2
  38. package/dist/runtime/application-jobs/application-job-queue-scope.js +41 -21
  39. package/dist/runtime/application-jobs/contracts.d.ts +15 -2
  40. package/dist/runtime/backend/contracts/index.d.ts +27 -27
  41. package/dist/runtime/backend/mesh-completion-table.d.ts +15 -5
  42. package/dist/runtime/backend/mesh-completion-table.js +160 -50
  43. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
  44. package/dist/runtime/backend/mesh-dispatch-pump.js +53 -36
  45. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  46. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  47. package/dist/runtime/backend/node/node-backend-adapter-support.js +33 -31
  48. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  49. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  50. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  51. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  52. package/dist/runtime/backend/node/node-raw-binding-port.js +50 -25
  53. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +22 -16
  54. package/dist/runtime/backend/node/node-raw-mesh-backend.js +133 -149
  55. package/dist/runtime/backend/node/node-socket-backend-adapter.js +15 -10
  56. package/dist/runtime/backend/raw-binding-port.d.ts +10 -3
  57. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  58. package/dist/runtime/backend/runtime-message.js +5 -0
  59. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  60. package/dist/runtime/backend/runtime-values.js +2 -1
  61. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  62. package/dist/runtime/channels/channel-clients.js +58 -21
  63. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
  64. package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
  65. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  66. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  67. package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
  68. package/dist/runtime/channels/channel-dispatchers.js +27 -26
  69. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  70. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  71. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  72. package/dist/runtime/channels/channel-envelope.js +83 -8
  73. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  74. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  75. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  76. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  77. package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
  78. package/dist/runtime/channels/channel-runtime-manager.js +12 -12
  79. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  80. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  81. package/dist/runtime/channels/channel-transports.d.ts +18 -15
  82. package/dist/runtime/channels/channel-transports.js +48 -31
  83. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  84. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  85. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  86. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  87. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  88. package/dist/runtime/channels/source-spot-router.js +4 -4
  89. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  90. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  91. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  92. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  93. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  94. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  95. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  96. package/dist/runtime/diagnostics/message-flow.js +3 -3
  97. package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
  98. package/dist/runtime/execution/serial-execution-queue.js +1 -0
  99. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  100. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  101. package/dist/runtime/foundation/durable-service-request.js +98 -0
  102. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  103. package/dist/runtime/foundation/operation-identity.js +5 -1
  104. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +37 -6
  105. package/dist/runtime/foundation/raw-service-mesh-runtime.js +473 -220
  106. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  107. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  108. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  109. package/dist/runtime/foundation/service-mailbox.js +2 -1
  110. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
  111. package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
  112. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  113. package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
  114. package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
  115. package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -9
  116. package/dist/runtime/foundation/service-stateful-runtime.js +78 -126
  117. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -7
  118. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  119. package/dist/runtime/foundation/service-topology-registry.d.ts +16 -4
  120. package/dist/runtime/foundation/service-topology-registry.js +69 -30
  121. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
  122. package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
  123. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  124. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  125. package/dist/runtime/host/actor-packet-relay.js +7 -7
  126. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  127. package/dist/runtime/host/application-job-queue.d.ts +28 -9
  128. package/dist/runtime/host/application-job-queue.js +214 -50
  129. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  130. package/dist/runtime/host/entry-actor-runtime.js +4 -1
  131. package/dist/runtime/host/index.d.ts +7 -1
  132. package/dist/runtime/host/index.js +154 -126
  133. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  134. package/dist/runtime/host/instance-activation-authority.js +89 -25
  135. package/dist/runtime/host/remote-bound-session-relay.js +2 -18
  136. package/dist/runtime/host/route-mesh-runtime.js +1 -1
  137. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  138. package/dist/runtime/host/service-relocation-control.js +10 -4
  139. package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
  140. package/dist/runtime/host/service-relocation-host-runtime.js +215 -243
  141. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  142. package/dist/runtime/host/spot-address-transport.js +28 -14
  143. package/dist/runtime/host/spot-runtime-options-factory.js +3 -2
  144. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  145. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  146. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  147. package/dist/runtime/locations/actor-location-claims.js +34 -19
  148. package/dist/runtime/locations/domain-store-contract.d.ts +2 -2
  149. package/dist/runtime/locations/in-memory-authority-store.d.ts +4 -2
  150. package/dist/runtime/locations/in-memory-authority-store.js +80 -8
  151. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  152. package/dist/runtime/locations/in-memory-location-store.js +19 -3
  153. package/dist/runtime/locations/internal-location-contracts.d.ts +3 -0
  154. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  155. package/dist/runtime/locations/lifecycle.js +2 -5
  156. package/dist/runtime/locations/location-store-repository.d.ts +3 -2
  157. package/dist/runtime/locations/location-store-repository.js +165 -22
  158. package/dist/runtime/locations/resolvers.d.ts +2 -1
  159. package/dist/runtime/locations/resolvers.js +10 -1
  160. package/dist/runtime/locations/runtime.d.ts +1 -1
  161. package/dist/runtime/locations/runtime.js +24 -23
  162. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  163. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  164. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  165. package/dist/runtime/messaging/packet-name.js +8 -24
  166. package/dist/runtime/messaging/request-result.d.ts +2 -0
  167. package/dist/runtime/messaging/request-result.js +54 -0
  168. package/dist/runtime/messaging/submission-result.d.ts +2 -1
  169. package/dist/runtime/messaging/submission-result.js +7 -4
  170. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
  171. package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
  172. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
  173. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
  174. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +9 -2
  175. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
  176. package/dist/runtime/spots/index.d.ts +7 -3
  177. package/dist/runtime/spots/index.js +23 -16
  178. package/dist/runtime/spots/spot-activation.d.ts +3 -1
  179. package/dist/runtime/spots/spot-activation.js +21 -12
  180. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  181. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  182. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  183. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  184. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  185. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  186. package/dist/runtime/spots/spot-entry-activation.js +9 -3
  187. package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
  188. package/dist/runtime/spots/spot-handler-registry.js +18 -8
  189. package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
  190. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +2 -1
  191. package/dist/runtime/spots/spot-node-runtime-manager.js +4 -11
  192. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  193. package/dist/runtime/spots/spot-outbound.js +24 -15
  194. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  195. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  196. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  197. package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -1
  198. package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
  199. package/dist/runtime/spots/spot-timer.js +1 -0
  200. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  201. package/dist/runtime/streams/stream-session-runtime.js +14 -28
  202. package/package.json +3 -3
  203. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  204. package/src/contracts/Channels/Calls.ts +2 -1
  205. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  206. package/src/contracts/Configuration/Builders.ts +1 -2
  207. package/src/contracts/Configuration/Configs.ts +0 -6
  208. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  209. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  210. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  211. package/src/contracts/Configuration/index.ts +1 -6
  212. package/src/contracts/Handlers/Attributes.ts +14 -21
  213. package/src/contracts/Handlers/JsonContract.ts +8 -216
  214. package/src/contracts/Spots/Contracts.ts +2 -1
  215. package/src/internal.ts +1 -0
  216. package/src/nest-integration.ts +1 -0
  217. package/src/runtime/actors/actor-client.ts +40 -16
  218. package/src/runtime/actors/actor-handoff.ts +22 -8
  219. package/src/runtime/actors/actor-join-relocation.ts +1 -0
  220. package/src/runtime/actors/actor-local-native-join.ts +17 -26
  221. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  222. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  223. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  224. package/src/runtime/actors/index.ts +19 -5
  225. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  226. package/src/runtime/admission.ts +18 -5
  227. package/src/runtime/application-jobs/application-ingress-record-owner.ts +53 -27
  228. package/src/runtime/application-jobs/application-job-queue-scope.ts +56 -22
  229. package/src/runtime/application-jobs/contracts.ts +28 -2
  230. package/src/runtime/backend/contracts/index.ts +63 -32
  231. package/src/runtime/backend/mesh-completion-table.ts +175 -59
  232. package/src/runtime/backend/mesh-dispatch-pump.ts +59 -32
  233. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  234. package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -31
  235. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  236. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  237. package/src/runtime/backend/node/node-raw-binding-port.ts +73 -37
  238. package/src/runtime/backend/node/node-raw-mesh-backend.ts +209 -176
  239. package/src/runtime/backend/node/node-socket-backend-adapter.ts +32 -13
  240. package/src/runtime/backend/raw-binding-port.ts +18 -3
  241. package/src/runtime/backend/runtime-message.ts +6 -0
  242. package/src/runtime/backend/runtime-values.ts +1 -0
  243. package/src/runtime/channels/channel-clients.ts +90 -41
  244. package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
  245. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  246. package/src/runtime/channels/channel-dispatchers.ts +29 -27
  247. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  248. package/src/runtime/channels/channel-envelope.ts +133 -8
  249. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  250. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  251. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  252. package/src/runtime/channels/channel-runtime-manager.ts +29 -12
  253. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  254. package/src/runtime/channels/channel-transports.ts +128 -60
  255. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  256. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  257. package/src/runtime/channels/source-spot-router.ts +8 -4
  258. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  259. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  260. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  261. package/src/runtime/diagnostics/message-flow.ts +1 -1
  262. package/src/runtime/execution/serial-execution-queue.ts +2 -0
  263. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  264. package/src/runtime/foundation/durable-service-request.ts +137 -0
  265. package/src/runtime/foundation/operation-identity.ts +5 -1
  266. package/src/runtime/foundation/raw-service-mesh-runtime.ts +642 -253
  267. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  268. package/src/runtime/foundation/service-mailbox.ts +7 -1
  269. package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
  270. package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
  271. package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
  272. package/src/runtime/foundation/service-stateful-runtime.ts +128 -160
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -84
  274. package/src/runtime/foundation/service-topology-registry.ts +103 -42
  275. package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
  276. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  277. package/src/runtime/host/actor-packet-relay.ts +7 -0
  278. package/src/runtime/host/actor-runtime-options-factory.ts +14 -2
  279. package/src/runtime/host/application-job-queue.ts +249 -48
  280. package/src/runtime/host/entry-actor-runtime.ts +5 -0
  281. package/src/runtime/host/index.ts +224 -160
  282. package/src/runtime/host/instance-activation-authority.ts +132 -27
  283. package/src/runtime/host/remote-bound-session-relay.ts +2 -23
  284. package/src/runtime/host/route-mesh-runtime.ts +1 -1
  285. package/src/runtime/host/service-relocation-control.ts +11 -5
  286. package/src/runtime/host/service-relocation-host-runtime.ts +317 -291
  287. package/src/runtime/host/spot-address-transport.ts +49 -24
  288. package/src/runtime/host/spot-runtime-options-factory.ts +4 -0
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  290. package/src/runtime/locations/actor-location-claims.ts +52 -30
  291. package/src/runtime/locations/domain-store-contract.ts +6 -2
  292. package/src/runtime/locations/in-memory-authority-store.ts +113 -9
  293. package/src/runtime/locations/in-memory-location-store.ts +25 -3
  294. package/src/runtime/locations/internal-location-contracts.ts +4 -0
  295. package/src/runtime/locations/lifecycle.ts +8 -26
  296. package/src/runtime/locations/location-store-repository.ts +220 -15
  297. package/src/runtime/locations/resolvers.ts +25 -2
  298. package/src/runtime/locations/runtime.ts +28 -24
  299. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  300. package/src/runtime/messaging/packet-name.ts +5 -25
  301. package/src/runtime/messaging/request-result.ts +58 -0
  302. package/src/runtime/messaging/submission-result.ts +7 -3
  303. package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
  304. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  305. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +45 -23
  306. package/src/runtime/spots/index.ts +30 -2
  307. package/src/runtime/spots/spot-activation.ts +33 -10
  308. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  309. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  310. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  311. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  312. package/src/runtime/spots/spot-entry-activation.ts +12 -2
  313. package/src/runtime/spots/spot-handler-registry.ts +41 -8
  314. package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
  315. package/src/runtime/spots/spot-node-runtime-manager.ts +7 -12
  316. package/src/runtime/spots/spot-outbound.ts +36 -16
  317. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  318. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  319. package/src/runtime/spots/spot-runtime-ports.ts +3 -0
  320. package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
  321. package/src/runtime/spots/spot-timer.ts +5 -1
  322. package/src/runtime/streams/stream-session-runtime.ts +13 -30
@@ -551,13 +551,19 @@ export class ZLinkChannelRuntimeLifecycle {
551
551
  unhandled: this.options.registration.dispatch?.unhandled
552
552
  });
553
553
  const spotRouteBridge = this.createSpotRouteBridgeForRouter(channelName, router);
554
+ const serverPeers = this.options.sockets.clientServerServerPeersForChannel(channelName);
554
555
  const loop = new ZLinkChannelReceiveLoop(
555
556
  channelName,
556
557
  router,
557
558
  dispatcher,
558
559
  spotRouteBridge,
559
560
  (received, socket) =>
560
- this.options.sockets.tryHandleClientServerControl(channelName, received, socket),
561
+ this.options.sockets.tryHandleClientServerControl(
562
+ channelName,
563
+ received,
564
+ socket,
565
+ serverPeers
566
+ ),
561
567
  this.options.adapter.createReadablePoller(router),
562
568
  this.options.applicationJobQueue,
563
569
  (error) =>
@@ -244,7 +244,8 @@ export class ZLinkChannelRuntimeManager {
244
244
  request: unknown,
245
245
  timeoutMs: number | undefined,
246
246
  signal?: AbortSignal,
247
- metadata?: ReadonlyMap<string, string>
247
+ metadata?: ReadonlyMap<string, string>,
248
+ onAdmitted?: () => void
248
249
  ): Promise<TReply> {
249
250
  return this.outbound.request<TReply>(
250
251
  channelName,
@@ -252,7 +253,8 @@ export class ZLinkChannelRuntimeManager {
252
253
  request,
253
254
  timeoutMs,
254
255
  signal,
255
- metadata
256
+ metadata,
257
+ onAdmitted
256
258
  );
257
259
  }
258
260
 
@@ -294,7 +296,8 @@ export class ZLinkChannelRuntimeManager {
294
296
  request: unknown,
295
297
  timeoutMs: number | undefined,
296
298
  signal?: AbortSignal,
297
- metadata?: ReadonlyMap<string, string>
299
+ metadata?: ReadonlyMap<string, string>,
300
+ onAdmitted?: () => void
298
301
  ): Promise<TReply> {
299
302
  return this.outbound.routeRequest<TReply>(
300
303
  routerChannelId,
@@ -303,7 +306,8 @@ export class ZLinkChannelRuntimeManager {
303
306
  request,
304
307
  timeoutMs,
305
308
  signal,
306
- metadata
309
+ metadata,
310
+ onAdmitted
307
311
  );
308
312
  }
309
313
 
@@ -322,7 +326,8 @@ export class ZLinkChannelRuntimeManager {
322
326
  request: unknown,
323
327
  timeoutMs: number | undefined,
324
328
  signal?: AbortSignal,
325
- metadata?: ReadonlyMap<string, string>
329
+ metadata?: ReadonlyMap<string, string>,
330
+ onAdmitted?: () => void
326
331
  ): Promise<TReply> {
327
332
  return this.spotRoutes.routeRequestToSpot<TReply>(
328
333
  spotRouteTarget,
@@ -330,7 +335,8 @@ export class ZLinkChannelRuntimeManager {
330
335
  request,
331
336
  timeoutMs,
332
337
  signal,
333
- metadata
338
+ metadata,
339
+ onAdmitted
334
340
  );
335
341
  }
336
342
 
@@ -340,7 +346,8 @@ export class ZLinkChannelRuntimeManager {
340
346
  packetName: string | undefined,
341
347
  request: unknown,
342
348
  timeoutMs: number | undefined,
343
- signal?: AbortSignal
349
+ signal?: AbortSignal,
350
+ onAdmitted?: () => void
344
351
  ): Promise<TReply> {
345
352
  return this.spotRoutes.routeRequestFromSpotToSpot<TReply>(
346
353
  sourceSpot,
@@ -348,7 +355,8 @@ export class ZLinkChannelRuntimeManager {
348
355
  packetName,
349
356
  request,
350
357
  timeoutMs,
351
- signal
358
+ signal,
359
+ onAdmitted
352
360
  );
353
361
  }
354
362
 
@@ -373,14 +381,16 @@ export class ZLinkChannelRuntimeManager {
373
381
  spotRouteTarget: ZLinkSpotRouteTarget,
374
382
  request: Message,
375
383
  timeoutMs: number | undefined,
376
- signal?: AbortSignal
384
+ signal?: AbortSignal,
385
+ onAdmitted?: () => void
377
386
  ): Promise<readonly Message[]> {
378
387
  return this.spotRoutes.routeRequestRawFromSpotToSpot(
379
388
  sourceSpot,
380
389
  spotRouteTarget,
381
390
  request,
382
391
  timeoutMs,
383
- signal
392
+ signal,
393
+ onAdmitted
384
394
  );
385
395
  }
386
396
 
@@ -388,9 +398,16 @@ export class ZLinkChannelRuntimeManager {
388
398
  spotRouteTarget: ZLinkSpotRouteTarget,
389
399
  request: Message,
390
400
  timeoutMs: number | undefined,
391
- signal?: AbortSignal
401
+ signal?: AbortSignal,
402
+ onAdmitted?: () => void
392
403
  ): Promise<readonly Message[]> {
393
- return this.spotRoutes.routeRequestRawToSpot(spotRouteTarget, request, timeoutMs, signal);
404
+ return this.spotRoutes.routeRequestRawToSpot(
405
+ spotRouteTarget,
406
+ request,
407
+ timeoutMs,
408
+ signal,
409
+ onAdmitted
410
+ );
394
411
  }
395
412
 
396
413
  canRouteChannel(routerChannelId: string): boolean {
@@ -1,6 +1,7 @@
1
1
  import { RuntimeDisposal } from '../disposal';
2
2
  import { UINT64_MAX } from '@zlink-systems/stream-wire';
3
3
  import { randomBytes, randomUUID } from 'node:crypto';
4
+ import { ReceiveFlowState } from '@zlink-systems/zlink';
4
5
  import {
5
6
  ZLinkFrameworkRuntimeState,
6
7
  type RoutingId,
@@ -41,6 +42,7 @@ import { ZLinkListenerRecords } from '../foundation/listener-records';
41
42
  import { discoveryAvailabilityForRuntimeState } from '../foundation/runtime-state-projections';
42
43
  import { ServiceDiscoveryRegistry } from '../foundation/service-discovery-registry';
43
44
  import {
45
+ ServiceLivenessConnection,
44
46
  DEFAULT_SERVICE_PEER_TIMEOUT_MS,
45
47
  DEFAULT_SERVICE_PROBE_INTERVAL_MS
46
48
  } from '../foundation/service-liveness-registry';
@@ -101,9 +103,7 @@ interface ClientServerPhysicalConnection {
101
103
  physicalConnectionId: symbol;
102
104
  readyConnectionId?: string;
103
105
  admittedDescriptor?: ClientServerDiscoveryDescriptor;
104
- nextProbeAt?: number;
105
- deadlineAt?: number;
106
- outstandingProbeId?: bigint;
106
+ liveness?: ServiceLivenessConnection;
107
107
  admissionAttempt?: symbol;
108
108
  }
109
109
 
@@ -112,6 +112,13 @@ export interface ZLinkFanoutConnectionCallbacks {
112
112
  readonly onTerminated: (reason: 'disconnect' | 'deadline' | 'protocol') => void;
113
113
  }
114
114
 
115
+ interface ClientServerServerPeer {
116
+ readonly channelName: string;
117
+ readonly routingId: RoutingId;
118
+ readonly normalizedEffectiveMaxMessageBytes: number;
119
+ readonly liveness: ServiceLivenessConnection;
120
+ }
121
+
115
122
  interface FanoutPublisherConnection {
116
123
  readonly channelName: string;
117
124
  readonly endpoint: string;
@@ -124,8 +131,6 @@ interface FanoutPublisherConnection {
124
131
  deadlineAt?: number;
125
132
  }
126
133
 
127
- type ReceiveFlowSocket = ZLinkBackendDealerSocket | ZLinkBackendRouterSocket;
128
-
129
134
  export class ZLinkChannelSocketRegistry {
130
135
  private readonly clientDealers = new Map<string, ZLinkBackendDealerSocket>();
131
136
  private readonly channelRouters = new Map<string, ZLinkBackendRouterSocket>();
@@ -155,18 +160,9 @@ export class ZLinkChannelSocketRegistry {
155
160
  >();
156
161
  private readonly clientServerPublicWeights = new Map<string, number>();
157
162
  private readonly routeMeshPublicWeights = new Map<string, number>();
158
- private readonly clientServerAdmittedClients = new Map<string, Set<RoutingId>>();
159
163
  private readonly clientServerServerPeers = new Map<
160
164
  string,
161
- {
162
- readonly channelName: string;
163
- readonly routingId: RoutingId;
164
- readonly physicalConnectionId: symbol;
165
- readonly normalizedEffectiveMaxMessageBytes: number;
166
- nextProbeAt: number;
167
- deadlineAt: number;
168
- outstandingProbeId?: bigint;
169
- }
165
+ Map<RoutingId, ClientServerServerPeer>
170
166
  >();
171
167
  private readonly disposal = new RuntimeDisposal();
172
168
  private readonly ownedResources = new Set<
@@ -226,9 +222,7 @@ export class ZLinkChannelSocketRegistry {
226
222
  ...this.publishers.values(),
227
223
  ...this.routeRouters.values()
228
224
  ];
229
- for (const socket of new Set<ReceiveFlowSocket>([
230
- ...this.clientDealers.values(),
231
- ...clientServerConnections.map((value) => value.dealer),
225
+ for (const socket of new Set<ZLinkBackendRouterSocket>([
232
226
  ...this.channelRouters.values(),
233
227
  ...this.routeRouters.values()
234
228
  ]))
@@ -237,7 +231,7 @@ export class ZLinkChannelSocketRegistry {
237
231
  this.clientServerServerDescriptors.clear();
238
232
  this.clientServerPublicWeights.clear();
239
233
  this.routeMeshPublicWeights.clear();
240
- this.clientServerAdmittedClients.clear();
234
+ for (const peers of this.clientServerServerPeers.values()) peers.clear();
241
235
  this.clientServerServerPeers.clear();
242
236
  this.clientServerMonitorHandlers.clear();
243
237
  this.fanoutMonitorHandlers.clear();
@@ -294,7 +288,6 @@ export class ZLinkChannelSocketRegistry {
294
288
 
295
289
  const dealer = this.adapter.createDealerSocket(this.context);
296
290
  this.clientDealers.set(channelName, dealer);
297
- this.registerReceiveFlowSocket(dealer);
298
291
  dealer.setChannelName(channelName);
299
292
  if (channel?.routingId !== undefined && channel.routingId.length > 0) {
300
293
  dealer.setRoutingId(deriveRoutingId(channel.routingId, 'dealer'));
@@ -350,8 +343,7 @@ export class ZLinkChannelSocketRegistry {
350
343
  )
351
344
  return;
352
345
  const routingId = String(event.routingId);
353
- this.clientServerServerPeers.delete(clientServerServerPeerKey(channelName, routingId));
354
- this.clientServerAdmittedClients.get(channelName)?.delete(routingId);
346
+ this.clientServerServerPeers.get(channelName)?.delete(routingId);
355
347
  });
356
348
  }
357
349
  const endpoint = advertisedEndpoint(
@@ -450,7 +442,6 @@ export class ZLinkChannelSocketRegistry {
450
442
  )[] = [dealer];
451
443
  try {
452
444
  this.clientServerConnections.set(connectionId, connection);
453
- this.registerReceiveFlowSocket(dealer);
454
445
  dealer.setChannelName(channelName);
455
446
  dealer.setRoutingId(`cs-client-${randomUUID()}`);
456
447
  applySocketConfig(dealer, {
@@ -501,7 +492,6 @@ export class ZLinkChannelSocketRegistry {
501
492
  return dealer;
502
493
  } catch (error) {
503
494
  this.clientServerConnections.delete(connectionId);
504
- this.unregisterReceiveFlowSocket(dealer);
505
495
  void Promise.allSettled(
506
496
  created.map(async (resource) => {
507
497
  await resource.dispose();
@@ -561,7 +551,6 @@ export class ZLinkChannelSocketRegistry {
561
551
  } catch {
562
552
  // The socket close below releases an endpoint that is already disconnected.
563
553
  }
564
- this.unregisterReceiveFlowSocket(current.dealer);
565
554
  if (current.readablePoller !== undefined) {
566
555
  current.readablePoller.dispose();
567
556
  this.ownedResources.delete(current.readablePoller);
@@ -623,9 +612,8 @@ export class ZLinkChannelSocketRegistry {
623
612
  const admitted = this.clientServerDiscovery.admitClientServer(descriptor, connectionId);
624
613
  if (admitted) {
625
614
  const now = performance.now();
626
- connection.nextProbeAt = now + CLIENT_SERVER_PROBE_INTERVAL_MS;
627
- connection.deadlineAt = now + CLIENT_SERVER_PEER_DEADLINE_MS;
628
- connection.outstandingProbeId = undefined;
615
+ connection.liveness = new ServiceLivenessConnection(connectionId, now);
616
+ connection.dealer.receiveAdmission = connection.liveness;
629
617
  this.clientServerReadyIdentities.set(connectionId, {
630
618
  channelName: descriptor.channelName,
631
619
  serverRoutingId: descriptor.serverRoutingId,
@@ -653,9 +641,8 @@ export class ZLinkChannelSocketRegistry {
653
641
  const connection = this.clientServerConnections.get(connectionId);
654
642
  if (connection?.readyConnectionId === connectionId) {
655
643
  connection.readyConnectionId = undefined;
656
- connection.deadlineAt = undefined;
657
- connection.nextProbeAt = undefined;
658
- connection.outstandingProbeId = undefined;
644
+ connection.liveness = undefined;
645
+ connection.dealer.receiveAdmission = undefined;
659
646
  }
660
647
  }
661
648
  this.notifyClientServerTopology(channelName);
@@ -898,6 +885,15 @@ export class ZLinkChannelSocketRegistry {
898
885
  for (const handler of this.clientServerMonitorHandlers.get(channelName) ?? []) handler();
899
886
  }
900
887
 
888
+ clientServerServerPeersForChannel(channelName: string): Map<RoutingId, ClientServerServerPeer> {
889
+ let peers = this.clientServerServerPeers.get(channelName);
890
+ if (peers === undefined) {
891
+ peers = new Map();
892
+ this.clientServerServerPeers.set(channelName, peers);
893
+ }
894
+ return peers;
895
+ }
896
+
901
897
  tryHandleClientServerControl(
902
898
  channelName: string,
903
899
  received: {
@@ -905,8 +901,12 @@ export class ZLinkChannelSocketRegistry {
905
901
  readonly replyToken: unknown | null;
906
902
  readonly routingId: unknown;
907
903
  },
908
- router: ZLinkBackendRouterSocket
904
+ router: ZLinkBackendRouterSocket,
905
+ peers = this.clientServerServerPeersForChannel(channelName)
909
906
  ): boolean {
907
+ const routingId = String(received.routingId) as RoutingId;
908
+ const peer = peers.get(routingId);
909
+ peer?.liveness.recordReceived();
910
910
  if (received.parts.length === 0) return false;
911
911
  const first = received.parts[0];
912
912
  if (!isClientServerControlFrame(first.data())) return false;
@@ -924,18 +924,8 @@ export class ZLinkChannelSocketRegistry {
924
924
  received.parts.length === 1 &&
925
925
  received.replyToken === null
926
926
  ) {
927
- if (
928
- !this.acceptClientServerServerLivenessAck(
929
- channelName,
930
- String(received.routingId),
931
- record.probeId
932
- )
933
- ) {
934
- this.reportStaleClientServerLivenessAck(
935
- channelName,
936
- String(received.routingId),
937
- record.probeId
938
- );
927
+ if (!this.acceptClientServerServerLivenessAck(peer, record.probeId)) {
928
+ this.reportStaleClientServerLivenessAck(channelName, routingId, record.probeId);
939
929
  }
940
930
  return true;
941
931
  } else if (
@@ -960,7 +950,7 @@ export class ZLinkChannelSocketRegistry {
960
950
  reply = encodeClientServerAdmit(descriptor, normalizedEffectiveMaxMessageBytes);
961
951
  this.admitClientServerServerPeer(
962
952
  channelName,
963
- String(received.routingId),
953
+ routingId,
964
954
  normalizedEffectiveMaxMessageBytes
965
955
  );
966
956
  }
@@ -971,7 +961,7 @@ export class ZLinkChannelSocketRegistry {
971
961
  if (received.replyToken !== null) {
972
962
  const message = RuntimeMessage.from(reply);
973
963
  try {
974
- router.reply(received.routingId as RoutingId, received.replyToken, message);
964
+ router.reply(routingId, received.replyToken, message);
975
965
  } finally {
976
966
  message.close();
977
967
  }
@@ -987,34 +977,32 @@ export class ZLinkChannelSocketRegistry {
987
977
  (connection.aliases.values().next().value as string | undefined);
988
978
  if (connectionId === undefined) continue;
989
979
  this.drainClientServerControl(connectionId, connection);
990
- if (connection.deadlineAt === undefined) continue;
991
- if (nowMs >= connection.deadlineAt) {
980
+ if (connection.liveness === undefined) continue;
981
+ if (connection.liveness.isExpired(nowMs)) {
992
982
  this.restartClientServerAdmission(connectionId, connection);
993
983
  continue;
994
984
  }
995
- if (connection.nextProbeAt === undefined || nowMs < connection.nextProbeAt) continue;
996
- connection.nextProbeAt = nowMs + CLIENT_SERVER_PROBE_INTERVAL_MS;
997
- const probeId = connection.outstandingProbeId ?? this.allocateClientServerProbeId();
998
- connection.outstandingProbeId = probeId;
985
+ const probeId = connection.liveness.tryGetProbe(nowMs, () =>
986
+ this.allocateClientServerProbeId()
987
+ );
988
+ if (probeId === undefined) continue;
999
989
  this.requestClientServerLiveness(connectionId, connection, probeId);
1000
990
  }
1001
991
 
1002
- for (const [key, peer] of [...this.clientServerServerPeers]) {
1003
- if (nowMs >= peer.deadlineAt) {
1004
- this.clientServerServerPeers.delete(key);
1005
- this.clientServerAdmittedClients.get(peer.channelName)?.delete(peer.routingId);
1006
- try {
1007
- this.channelRouters.get(peer.channelName)?.disconnectPeer(peer.routingId);
1008
- } catch (error) {
1009
- this.oneWayFailureSink?.(error);
992
+ for (const peers of this.clientServerServerPeers.values()) {
993
+ for (const [routingId, peer] of peers) {
994
+ if (peer.liveness.isExpired(nowMs)) {
995
+ peers.delete(routingId);
996
+ try {
997
+ this.channelRouters.get(peer.channelName)?.disconnectPeer(peer.routingId);
998
+ } catch (error) {
999
+ this.oneWayFailureSink?.(error);
1000
+ }
1001
+ continue;
1010
1002
  }
1011
- continue;
1003
+ const probeId = peer.liveness.tryGetProbe(nowMs, () => this.allocateClientServerProbeId());
1004
+ if (probeId !== undefined) this.requestClientServerServerLiveness(peer, probeId);
1012
1005
  }
1013
- if (nowMs < peer.nextProbeAt) continue;
1014
- peer.nextProbeAt = nowMs + CLIENT_SERVER_PROBE_INTERVAL_MS;
1015
- const probeId = peer.outstandingProbeId ?? this.allocateClientServerProbeId();
1016
- peer.outstandingProbeId = probeId;
1017
- this.requestClientServerServerLiveness(peer, probeId);
1018
1006
  }
1019
1007
  this.tickFanoutLiveness(nowMs);
1020
1008
  }
@@ -1376,6 +1364,7 @@ export class ZLinkChannelSocketRegistry {
1376
1364
  connectionId: string,
1377
1365
  connection: ClientServerPhysicalConnection
1378
1366
  ): void {
1367
+ const admission = connection.liveness;
1379
1368
  for (;;) {
1380
1369
  if (connection.readablePoller === undefined || !connection.readablePoller.wait(0)) return;
1381
1370
  const received = connection.dealer.recv(1);
@@ -1383,6 +1372,7 @@ export class ZLinkChannelSocketRegistry {
1383
1372
  connection.readablePoller.markDrained();
1384
1373
  return;
1385
1374
  }
1375
+ admission?.recordReceived();
1386
1376
  try {
1387
1377
  if (received.parts.length !== 1 || !isClientServerControlFrame(received.parts[0]!.data())) {
1388
1378
  throw new ZLinkConfigurationException(
@@ -1534,24 +1524,18 @@ export class ZLinkChannelSocketRegistry {
1534
1524
  if (connection.readyConnectionId === connectionId) {
1535
1525
  connection.readyConnectionId = undefined;
1536
1526
  }
1537
- connection.deadlineAt = undefined;
1538
- connection.nextProbeAt = undefined;
1539
- connection.outstandingProbeId = undefined;
1527
+ connection.liveness = undefined;
1528
+ connection.dealer.receiveAdmission = undefined;
1540
1529
  }
1541
1530
  this.notifyClientServerTopology(identity.channelName);
1542
1531
  }
1543
1532
 
1544
1533
  private requestClientServerLiveness(
1545
1534
  connectionId: string,
1546
- connection: {
1547
- readonly channelName: string;
1548
- readonly dealer: ZLinkBackendDealerSocket;
1549
- readonly physicalConnectionId: symbol;
1550
- outstandingProbeId?: bigint;
1551
- deadlineAt?: number;
1552
- },
1535
+ connection: ClientServerPhysicalConnection,
1553
1536
  probeId: bigint
1554
1537
  ): void {
1538
+ const admission = connection.liveness;
1555
1539
  const message = RuntimeMessage.from(encodeClientServerLivenessProbe(probeId));
1556
1540
  void connection.dealer
1557
1541
  .request(message, CLIENT_SERVER_PEER_DEADLINE_MS)
@@ -1561,12 +1545,16 @@ export class ZLinkChannelSocketRegistry {
1561
1545
  if (
1562
1546
  current === undefined ||
1563
1547
  current.physicalConnectionId !== connection.physicalConnectionId ||
1548
+ current.liveness !== admission ||
1564
1549
  parts.length !== 1
1565
1550
  )
1566
1551
  return;
1567
1552
  const record = decodeClientServerControl(parts[0]!.data());
1568
1553
  if (record.kind !== 'livenessAck') return;
1569
- if (current.outstandingProbeId !== probeId || record.probeId !== probeId) {
1554
+ if (
1555
+ admission === undefined ||
1556
+ !admission.acknowledge(record.probeId, performance.now())
1557
+ ) {
1570
1558
  this.reportStaleClientServerLivenessAck(
1571
1559
  connection.channelName,
1572
1560
  connectionId,
@@ -1574,8 +1562,6 @@ export class ZLinkChannelSocketRegistry {
1574
1562
  );
1575
1563
  return;
1576
1564
  }
1577
- current.outstandingProbeId = undefined;
1578
- current.deadlineAt = performance.now() + CLIENT_SERVER_PEER_DEADLINE_MS;
1579
1565
  } finally {
1580
1566
  closeMessages(parts);
1581
1567
  }
@@ -1589,36 +1575,20 @@ export class ZLinkChannelSocketRegistry {
1589
1575
  routingId: RoutingId,
1590
1576
  normalizedEffectiveMaxMessageBytes: number
1591
1577
  ): void {
1592
- const key = clientServerServerPeerKey(channelName, routingId);
1593
- const now = performance.now();
1594
- const peer = {
1578
+ const peer: ClientServerServerPeer = {
1595
1579
  channelName,
1596
1580
  routingId,
1597
- physicalConnectionId: Symbol(key),
1598
1581
  normalizedEffectiveMaxMessageBytes,
1599
- nextProbeAt: now + CLIENT_SERVER_PROBE_INTERVAL_MS,
1600
- deadlineAt: now + CLIENT_SERVER_PEER_DEADLINE_MS
1582
+ liveness: new ServiceLivenessConnection(
1583
+ clientServerServerPeerKey(channelName, routingId),
1584
+ performance.now()
1585
+ )
1601
1586
  };
1602
- this.clientServerServerPeers.set(key, peer);
1603
- let clients = this.clientServerAdmittedClients.get(channelName);
1604
- if (clients === undefined) {
1605
- clients = new Set();
1606
- this.clientServerAdmittedClients.set(channelName, clients);
1607
- }
1608
- clients.add(routingId);
1587
+ this.clientServerServerPeersForChannel(channelName).set(routingId, peer);
1609
1588
  this.ensureClientServerLivenessTimer();
1610
1589
  }
1611
1590
 
1612
- private requestClientServerServerLiveness(
1613
- peer: {
1614
- readonly channelName: string;
1615
- readonly routingId: RoutingId;
1616
- readonly physicalConnectionId: symbol;
1617
- outstandingProbeId?: bigint;
1618
- deadlineAt: number;
1619
- },
1620
- probeId: bigint
1621
- ): void {
1591
+ private requestClientServerServerLiveness(peer: ClientServerServerPeer, probeId: bigint): void {
1622
1592
  const router = this.channelRouters.get(peer.channelName);
1623
1593
  if (router === undefined) return;
1624
1594
  const message = RuntimeMessage.from(encodeClientServerLivenessProbe(probeId));
@@ -1629,17 +1599,10 @@ export class ZLinkChannelSocketRegistry {
1629
1599
  }
1630
1600
 
1631
1601
  private acceptClientServerServerLivenessAck(
1632
- channelName: string,
1633
- routingId: RoutingId,
1602
+ peer: ClientServerServerPeer | undefined,
1634
1603
  probeId: bigint
1635
1604
  ): boolean {
1636
- const peer = this.clientServerServerPeers.get(
1637
- clientServerServerPeerKey(channelName, routingId)
1638
- );
1639
- if (peer === undefined || peer.outstandingProbeId !== probeId) return false;
1640
- peer.outstandingProbeId = undefined;
1641
- peer.deadlineAt = performance.now() + CLIENT_SERVER_PEER_DEADLINE_MS;
1642
- return true;
1605
+ return peer?.liveness.acknowledge(probeId, performance.now()) ?? false;
1643
1606
  }
1644
1607
 
1645
1608
  private reportStaleClientServerLivenessAck(
@@ -1661,23 +1624,15 @@ export class ZLinkChannelSocketRegistry {
1661
1624
  descriptor: ZLinkClientServerServerDescriptor
1662
1625
  ): void {
1663
1626
  const router = this.channelRouters.get(channelName);
1664
- const clients = this.clientServerAdmittedClients.get(channelName);
1665
- if (router === undefined || clients === undefined) return;
1666
- for (const routingId of [...clients]) {
1667
- const peer = this.clientServerServerPeers.get(
1668
- clientServerServerPeerKey(channelName, routingId)
1669
- );
1670
- if (peer === undefined) {
1671
- clients.delete(routingId);
1672
- continue;
1673
- }
1627
+ const peers = this.clientServerServerPeers.get(channelName);
1628
+ if (router === undefined || peers === undefined) return;
1629
+ for (const [routingId, peer] of peers) {
1674
1630
  const message = RuntimeMessage.from(
1675
1631
  encodeClientServerUpdate(descriptor, peer.normalizedEffectiveMaxMessageBytes)
1676
1632
  );
1677
1633
  void router
1678
1634
  .send(routingId, message)
1679
1635
  .catch((error) => {
1680
- clients.delete(routingId);
1681
1636
  this.oneWayFailureSink?.(error);
1682
1637
  })
1683
1638
  .finally(() => message.close());
@@ -1786,15 +1741,18 @@ export class ZLinkChannelSocketRegistry {
1786
1741
  router.peerWeight = rawAvailabilityWeight(weight);
1787
1742
  }
1788
1743
 
1789
- private registerReceiveFlowSocket(socket: ReceiveFlowSocket): void {
1744
+ private registerReceiveFlowSocket(socket: ZLinkBackendRouterSocket): void {
1790
1745
  this.applicationJobQueue?.registerReceiveFlowTarget(
1791
1746
  socket,
1792
- (state) => socket.setReceiveFlowState(state === 'paused' ? 1 : 0),
1747
+ (state) =>
1748
+ socket.setReceiveFlowState(
1749
+ state === 'paused' ? ReceiveFlowState.PAUSED : ReceiveFlowState.RUNNING
1750
+ ),
1793
1751
  this.oneWayFailureSink
1794
1752
  );
1795
1753
  }
1796
1754
 
1797
- private unregisterReceiveFlowSocket(socket: ReceiveFlowSocket): void {
1755
+ private unregisterReceiveFlowSocket(socket: ZLinkBackendRouterSocket): void {
1798
1756
  this.applicationJobQueue?.unregisterReceiveFlowTarget(socket);
1799
1757
  }
1800
1758
 
@@ -1962,7 +1920,7 @@ function applyFanoutPublisherSocketOptions(
1962
1920
  channel: ZLinkChannelOptions
1963
1921
  ): void {
1964
1922
  publisher.noDrop = channel.noDrop ?? false;
1965
- publisher.sendTimeoutMs = configuredSendTimeoutMs(channel.publisher?.sendTimeoutMs);
1923
+ publisher.sendTimeoutMs = channel.sendTimeoutMs ?? DEFAULT_SEND_TIMEOUT_MS;
1966
1924
  }
1967
1925
 
1968
1926
  function fanoutDiscoveryConnectionId(connectionId: string): string {
@@ -2022,7 +1980,3 @@ function applySocketConfig(
2022
1980
  socket.maxMessageSize = config.maxMessageSize;
2023
1981
  }
2024
1982
  }
2025
-
2026
- function configuredSendTimeoutMs(value: number | undefined): number {
2027
- return value ?? DEFAULT_SEND_TIMEOUT_MS;
2028
- }