@zlink-systems/framework 0.25.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (557) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Channels/IZLinkFanoutClient.d.ts +0 -6
  3. package/dist/contracts/Common/CoreTypes.d.ts +6 -0
  4. package/dist/contracts/Common/CoreTypes.js +7 -0
  5. package/dist/contracts/Common/index.d.ts +1 -1
  6. package/dist/contracts/Common/index.js +0 -1
  7. package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
  8. package/dist/contracts/Configuration/InternalDefaults.js +9 -1
  9. package/dist/contracts/Configuration/Registration.d.ts +13 -2
  10. package/dist/contracts/Configuration/Registration.js +58 -36
  11. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
  12. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
  13. package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
  14. package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
  15. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  16. package/dist/contracts/Configuration/RegistrationValidators.js +15 -12
  17. package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
  18. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
  19. package/dist/contracts/Handlers/JsonContract.js +10 -4
  20. package/dist/contracts/Locations/Authority.d.ts +1 -1
  21. package/dist/contracts/Locations/Authority.js +3 -2
  22. package/dist/contracts/Locations/Options.js +1 -1
  23. package/dist/contracts/Locations/Stores.d.ts +12 -0
  24. package/dist/contracts/Locations/Stores.js +9 -0
  25. package/dist/contracts/RouteMesh/RuntimeTopology.d.ts +8 -0
  26. package/dist/contracts/Spots/Contracts.d.ts +1 -1
  27. package/dist/internal.d.ts +5 -0
  28. package/dist/internal.js +16 -1
  29. package/dist/nest-integration.d.ts +4 -2
  30. package/dist/nest-integration.js +14 -4
  31. package/dist/runtime/abort.d.ts +1 -0
  32. package/dist/runtime/abort.js +8 -5
  33. package/dist/runtime/activation-admission.d.ts +28 -0
  34. package/dist/runtime/activation-admission.js +57 -0
  35. package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
  36. package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
  37. package/dist/runtime/actors/actor-client.d.ts +2 -2
  38. package/dist/runtime/actors/actor-client.js +42 -143
  39. package/dist/runtime/actors/actor-context.d.ts +3 -5
  40. package/dist/runtime/actors/actor-context.js +19 -17
  41. package/dist/runtime/actors/actor-handoff.d.ts +13 -7
  42. package/dist/runtime/actors/actor-handoff.js +36 -25
  43. package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
  44. package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
  45. package/dist/runtime/actors/actor-local-native-join.js +85 -123
  46. package/dist/runtime/actors/actor-native-lookup.js +2 -8
  47. package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
  48. package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
  49. package/dist/runtime/actors/actor-remote-joiner.d.ts +3 -3
  50. package/dist/runtime/actors/actor-remote-joiner.js +11 -17
  51. package/dist/runtime/actors/actor-remote-wire.js +5 -3
  52. package/dist/runtime/actors/actor-request-deadline.d.ts +3 -0
  53. package/dist/runtime/actors/actor-request-deadline.js +31 -0
  54. package/dist/runtime/actors/actor-retry-delay.js +2 -1
  55. package/dist/runtime/actors/actor-runtime-contracts.d.ts +4 -2
  56. package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
  57. package/dist/runtime/actors/actor-runtime-state.js +70 -187
  58. package/dist/runtime/actors/actor-source-transfer.d.ts +5 -5
  59. package/dist/runtime/actors/bound-session-wire.js +2 -7
  60. package/dist/runtime/actors/deferred-join-completion.d.ts +19 -0
  61. package/dist/runtime/actors/deferred-join-completion.js +21 -0
  62. package/dist/runtime/actors/index.d.ts +10 -8
  63. package/dist/runtime/actors/index.js +101 -73
  64. package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
  65. package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
  66. package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
  67. package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
  68. package/dist/runtime/admission.d.ts +7 -1
  69. package/dist/runtime/admission.js +11 -1
  70. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
  71. package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
  72. package/dist/runtime/backend/contracts/index.d.ts +8 -33
  73. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +3 -26
  74. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
  75. package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
  76. package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +1 -2
  77. package/dist/runtime/backend/node/node-backend-adapter-factory.js +4 -18
  78. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +7 -4
  79. package/dist/runtime/backend/node/node-backend-adapter-support.js +28 -34
  80. package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
  81. package/dist/runtime/backend/node/node-event-loop-poller.js +11 -6
  82. package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
  83. package/dist/runtime/backend/node/node-raw-binding-port.d.ts +1 -1
  84. package/dist/runtime/backend/node/node-raw-binding-port.js +51 -19
  85. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +21 -19
  86. package/dist/runtime/backend/node/node-raw-mesh-backend.js +171 -111
  87. package/dist/runtime/backend/node/node-socket-backend-adapter.js +4 -3
  88. package/dist/runtime/backend/raw-binding-port.d.ts +13 -1
  89. package/dist/runtime/backend/runtime-values.d.ts +4 -1
  90. package/dist/runtime/backend/runtime-values.js +2 -0
  91. package/dist/runtime/channels/channel-clients.d.ts +20 -9
  92. package/dist/runtime/channels/channel-clients.js +68 -60
  93. package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
  94. package/dist/runtime/channels/channel-envelope.js +47 -29
  95. package/dist/runtime/channels/channel-outbound-operations.d.ts +3 -0
  96. package/dist/runtime/channels/channel-outbound-operations.js +9 -18
  97. package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
  98. package/dist/runtime/channels/channel-receive-loops.js +27 -6
  99. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
  100. package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
  101. package/dist/runtime/channels/channel-runtime-manager.d.ts +2 -5
  102. package/dist/runtime/channels/channel-runtime-manager.js +4 -12
  103. package/dist/runtime/channels/channel-socket-options.js +3 -2
  104. package/dist/runtime/channels/channel-socket-registry.d.ts +30 -32
  105. package/dist/runtime/channels/channel-socket-registry.js +296 -235
  106. package/dist/runtime/channels/channel-transports.d.ts +11 -20
  107. package/dist/runtime/channels/channel-transports.js +68 -47
  108. package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
  109. package/dist/runtime/channels/client-server-location-runtime.js +10 -11
  110. package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
  111. package/dist/runtime/channels/client-server-service-wire.js +32 -11
  112. package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
  113. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  114. package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
  115. package/dist/runtime/channels/fanout-location-runtime.js +133 -81
  116. package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
  117. package/dist/runtime/channels/spot-direct-envelope.js +4 -3
  118. package/dist/runtime/channels/spot-node-route-transport.js +3 -2
  119. package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
  120. package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
  121. package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
  122. package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
  123. package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
  124. package/dist/runtime/diagnostics/flow-context.js +16 -2
  125. package/dist/runtime/diagnostics/index.d.ts +4 -2
  126. package/dist/runtime/diagnostics/index.js +14 -4
  127. package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
  128. package/dist/runtime/diagnostics/message-flow.js +10 -19
  129. package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
  130. package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
  131. package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
  132. package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
  133. package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
  134. package/dist/runtime/disposal.d.ts +5 -0
  135. package/dist/runtime/disposal.js +22 -0
  136. package/dist/runtime/execution/index.d.ts +22 -9
  137. package/dist/runtime/execution/index.js +107 -37
  138. package/dist/runtime/execution/serial-execution-queue.d.ts +12 -7
  139. package/dist/runtime/execution/serial-execution-queue.js +99 -26
  140. package/dist/runtime/execution/state-lane.d.ts +8 -1
  141. package/dist/runtime/execution/state-lane.js +118 -3
  142. package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
  143. package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
  144. package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
  145. package/dist/runtime/foundation/event-loop-resources.js +6 -119
  146. package/dist/runtime/foundation/listener-records.d.ts +11 -0
  147. package/dist/runtime/foundation/listener-records.js +20 -0
  148. package/dist/runtime/foundation/operation-identity.d.ts +2 -0
  149. package/dist/runtime/foundation/operation-identity.js +9 -5
  150. package/dist/runtime/foundation/operation-registry.d.ts +5 -7
  151. package/dist/runtime/foundation/operation-registry.js +34 -44
  152. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +18 -26
  153. package/dist/runtime/foundation/raw-service-mesh-runtime.js +122 -469
  154. package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
  155. package/dist/runtime/foundation/runtime-state-projections.js +8 -0
  156. package/dist/runtime/foundation/service-authority-payload-codec.d.ts +1 -0
  157. package/dist/runtime/foundation/service-authority-payload-codec.js +30 -12
  158. package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
  159. package/dist/runtime/foundation/service-discovery-registry.js +22 -3
  160. package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
  161. package/dist/runtime/foundation/service-liveness-registry.js +2 -1
  162. package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
  163. package/dist/runtime/foundation/service-maintenance-runtime.js +23 -8
  164. package/dist/runtime/foundation/service-metadata-codec.js +3 -3
  165. package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
  166. package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
  167. package/dist/runtime/foundation/service-relocation-coordinator.d.ts +9 -0
  168. package/dist/runtime/foundation/service-relocation-coordinator.js +14 -1
  169. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +8 -0
  170. package/dist/runtime/foundation/service-relocation-object-owner.js +19 -6
  171. package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
  172. package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
  173. package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
  174. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -19
  175. package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
  176. package/dist/runtime/foundation/service-stateful-registry.js +10 -2
  177. package/dist/runtime/foundation/service-stateful-runtime.d.ts +28 -24
  178. package/dist/runtime/foundation/service-stateful-runtime.js +297 -244
  179. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +12 -7
  180. package/dist/runtime/foundation/service-stateful-wire-codec.js +240 -143
  181. package/dist/runtime/foundation/service-topology-registry.d.ts +1 -3
  182. package/dist/runtime/foundation/service-topology-registry.js +22 -61
  183. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
  184. package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
  185. package/dist/runtime/foundation/service-wire-codec.js +10 -8
  186. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  187. package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
  188. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
  189. package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
  190. package/dist/runtime/framework-errors-internal.d.ts +2 -1
  191. package/dist/runtime/framework-errors-internal.js +343 -122
  192. package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
  193. package/dist/runtime/handlers/handler-instance-scope.js +61 -74
  194. package/dist/runtime/host/actor-packet-relay.d.ts +9 -6
  195. package/dist/runtime/host/actor-packet-relay.js +48 -91
  196. package/dist/runtime/host/actor-placement-coordinator.js +7 -5
  197. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
  198. package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
  199. package/dist/runtime/host/actor-transfer-runtime.d.ts +28 -28
  200. package/dist/runtime/host/actor-transfer-runtime.js +210 -256
  201. package/dist/runtime/host/application-job-queue.js +16 -33
  202. package/dist/runtime/host/bound-session-relay.js +1 -1
  203. package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
  204. package/dist/runtime/host/index.d.ts +19 -14
  205. package/dist/runtime/host/index.js +234 -175
  206. package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
  207. package/dist/runtime/host/instance-activation-authority.js +17 -45
  208. package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
  209. package/dist/runtime/host/location-runtime-owner.js +2 -2
  210. package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
  211. package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
  212. package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
  213. package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
  214. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
  215. package/dist/runtime/host/remote-bound-session-relay.js +11 -23
  216. package/dist/runtime/host/route-mesh-runtime.d.ts +14 -10
  217. package/dist/runtime/host/route-mesh-runtime.js +178 -257
  218. package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
  219. package/dist/runtime/host/runtime-shutdown.js +18 -21
  220. package/dist/runtime/host/service-relocation-control.js +6 -1
  221. package/dist/runtime/host/service-relocation-host-runtime.d.ts +71 -38
  222. package/dist/runtime/host/service-relocation-host-runtime.js +816 -651
  223. package/dist/runtime/host/spot-address-transport.d.ts +2 -3
  224. package/dist/runtime/host/spot-address-transport.js +34 -136
  225. package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
  226. package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
  227. package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -7
  228. package/dist/runtime/host/spot-runtime-options-factory.js +53 -21
  229. package/dist/runtime/host/stateful-authority-route-runtime.js +6 -2
  230. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +14 -6
  231. package/dist/runtime/host/user-spot-creation-coordinator.js +96 -95
  232. package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
  233. package/dist/runtime/locations/authority-key-codec.js +4 -3
  234. package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
  235. package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
  236. package/dist/runtime/locations/creation-operation-id.js +6 -4
  237. package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
  238. package/dist/runtime/locations/in-memory-authority-store.js +31 -15
  239. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  240. package/dist/runtime/locations/in-memory-location-store.js +17 -14
  241. package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
  242. package/dist/runtime/locations/in-memory-provider-location-store.js +79 -27
  243. package/dist/runtime/locations/key-codec.js +3 -2
  244. package/dist/runtime/locations/lease-tracker.d.ts +3 -5
  245. package/dist/runtime/locations/lease-tracker.js +7 -11
  246. package/dist/runtime/locations/lifecycle.d.ts +5 -10
  247. package/dist/runtime/locations/lifecycle.js +4 -33
  248. package/dist/runtime/locations/location-store-failure.d.ts +2 -0
  249. package/dist/runtime/locations/location-store-failure.js +7 -0
  250. package/dist/runtime/locations/location-store-pages.d.ts +3 -0
  251. package/dist/runtime/locations/location-store-pages.js +13 -0
  252. package/dist/runtime/locations/location-store-repository.d.ts +5 -7
  253. package/dist/runtime/locations/location-store-repository.js +303 -332
  254. package/dist/runtime/locations/relocation-blob.js +18 -5
  255. package/dist/runtime/locations/resolvers.d.ts +5 -5
  256. package/dist/runtime/locations/resolvers.js +44 -30
  257. package/dist/runtime/locations/runtime.d.ts +5 -4
  258. package/dist/runtime/locations/runtime.js +123 -92
  259. package/dist/runtime/locations/spot-location-claims.d.ts +8 -2
  260. package/dist/runtime/locations/spot-location-claims.js +40 -23
  261. package/dist/runtime/messaging/payload-codec.js +26 -20
  262. package/dist/runtime/messaging/submission-result.d.ts +3 -0
  263. package/dist/runtime/messaging/submission-result.js +48 -0
  264. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +2 -0
  265. package/dist/runtime/protocol/service_wire_codec.generated.js +17 -8
  266. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +1 -0
  267. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +3 -2
  268. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +3 -3
  269. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +4 -4
  270. package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +6 -3
  271. package/dist/runtime/spots/index.d.ts +29 -29
  272. package/dist/runtime/spots/index.js +441 -313
  273. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -4
  274. package/dist/runtime/spots/spot-activation-registry.js +27 -60
  275. package/dist/runtime/spots/spot-activation-state.d.ts +2 -11
  276. package/dist/runtime/spots/spot-activation-state.js +4 -17
  277. package/dist/runtime/spots/spot-activation.d.ts +10 -9
  278. package/dist/runtime/spots/spot-activation.js +103 -81
  279. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
  280. package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
  281. package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
  282. package/dist/runtime/spots/spot-actor-join-dispatch.js +5 -55
  283. package/dist/runtime/spots/spot-actor-lifecycle-drain.js +2 -2
  284. package/dist/runtime/spots/spot-actor-membership.d.ts +7 -5
  285. package/dist/runtime/spots/spot-actor-membership.js +44 -53
  286. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
  287. package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
  288. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
  289. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
  290. package/dist/runtime/spots/spot-context.d.ts +2 -2
  291. package/dist/runtime/spots/spot-entry-activation.d.ts +3 -4
  292. package/dist/runtime/spots/spot-entry-activation.js +9 -21
  293. package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
  294. package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
  295. package/dist/runtime/spots/spot-manager-public.js +6 -5
  296. package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
  297. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +22 -21
  298. package/dist/runtime/spots/spot-node-runtime-manager.js +73 -82
  299. package/dist/runtime/spots/spot-outbound.d.ts +4 -3
  300. package/dist/runtime/spots/spot-outbound.js +10 -37
  301. package/dist/runtime/spots/spot-remote-codec.js +5 -3
  302. package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
  303. package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
  304. package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
  305. package/dist/runtime/spots/spot-route-replies.js +3 -1
  306. package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -2
  307. package/dist/runtime/spots/spot-routed-actor-admission.js +3 -2
  308. package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +2 -7
  309. package/dist/runtime/spots/spot-routed-frame-dispatch.js +1 -70
  310. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
  311. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
  312. package/dist/runtime/spots/spot-runtime-ports.d.ts +4 -20
  313. package/dist/runtime/spots/spot-serial-executor.d.ts +5 -0
  314. package/dist/runtime/spots/spot-serial-executor.js +9 -2
  315. package/dist/runtime/spots/spot-serial-turn-executor.d.ts +29 -6
  316. package/dist/runtime/spots/spot-serial-turn-executor.js +89 -13
  317. package/dist/runtime/spots/spot-timer.d.ts +3 -2
  318. package/dist/runtime/streams/actor-session-binding-registry.d.ts +17 -32
  319. package/dist/runtime/streams/actor-session-binding-registry.js +145 -367
  320. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +2 -6
  321. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +6 -2
  322. package/dist/runtime/streams/bound-actor-relay-sender.js +57 -33
  323. package/dist/runtime/streams/bound-session-service.d.ts +7 -0
  324. package/dist/runtime/streams/bound-session-service.js +12 -19
  325. package/dist/runtime/streams/index.d.ts +15 -14
  326. package/dist/runtime/streams/index.js +38 -39
  327. package/dist/runtime/streams/managed-stream.d.ts +3 -0
  328. package/dist/runtime/streams/managed-stream.js +17 -8
  329. package/dist/runtime/streams/native-fallback-bound-session.js +1 -3
  330. package/dist/runtime/streams/protocol.d.ts +6 -33
  331. package/dist/runtime/streams/protocol.js +38 -110
  332. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
  333. package/dist/runtime/streams/session-actor-coordinator.js +12 -4
  334. package/dist/runtime/streams/session-calls.d.ts +1 -1
  335. package/dist/runtime/streams/session-calls.js +5 -4
  336. package/dist/runtime/streams/session-context.d.ts +6 -6
  337. package/dist/runtime/streams/session-context.js +22 -4
  338. package/dist/runtime/streams/session-requests.js +2 -1
  339. package/dist/runtime/streams/session-serial-executor.js +2 -2
  340. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
  341. package/dist/runtime/streams/stream-frame-factory.js +2 -2
  342. package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
  343. package/dist/runtime/streams/stream-session-runtime.js +25 -33
  344. package/dist/runtime/workers/index.d.ts +2 -2
  345. package/dist/runtime/workers/index.js +5 -4
  346. package/package.json +3 -3
  347. package/src/contracts/Channels/IZLinkFanoutClient.ts +0 -7
  348. package/src/contracts/Common/CoreTypes.ts +7 -0
  349. package/src/contracts/Common/index.ts +1 -1
  350. package/src/contracts/Configuration/InternalDefaults.ts +12 -0
  351. package/src/contracts/Configuration/Registration.ts +92 -48
  352. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
  353. package/src/contracts/Configuration/RegistrationBuilders.ts +77 -68
  354. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  355. package/src/contracts/Configuration/RegistrationValidators.ts +19 -13
  356. package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
  357. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
  358. package/src/contracts/Handlers/JsonContract.ts +14 -4
  359. package/src/contracts/Locations/Authority.ts +7 -3
  360. package/src/contracts/Locations/Options.ts +1 -1
  361. package/src/contracts/Locations/Stores.ts +14 -0
  362. package/src/contracts/RouteMesh/RuntimeTopology.ts +10 -0
  363. package/src/contracts/Spots/Contracts.ts +1 -1
  364. package/src/internal.ts +15 -0
  365. package/src/nest-integration.ts +28 -10
  366. package/src/runtime/abort.ts +6 -5
  367. package/src/runtime/activation-admission.ts +72 -0
  368. package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
  369. package/src/runtime/actors/actor-client.ts +77 -204
  370. package/src/runtime/actors/actor-context.ts +45 -39
  371. package/src/runtime/actors/actor-handoff.ts +55 -45
  372. package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
  373. package/src/runtime/actors/actor-local-native-join.ts +174 -215
  374. package/src/runtime/actors/actor-native-lookup.ts +2 -9
  375. package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
  376. package/src/runtime/actors/actor-remote-joiner.ts +15 -36
  377. package/src/runtime/actors/actor-remote-wire.ts +5 -3
  378. package/src/runtime/actors/actor-request-deadline.ts +49 -0
  379. package/src/runtime/actors/actor-retry-delay.ts +2 -1
  380. package/src/runtime/actors/actor-runtime-contracts.ts +4 -10
  381. package/src/runtime/actors/actor-runtime-state.ts +85 -247
  382. package/src/runtime/actors/actor-source-transfer.ts +5 -18
  383. package/src/runtime/actors/bound-session-wire.ts +2 -8
  384. package/src/runtime/actors/deferred-join-completion.ts +44 -0
  385. package/src/runtime/actors/index.ts +122 -88
  386. package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
  387. package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
  388. package/src/runtime/admission.ts +13 -2
  389. package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
  390. package/src/runtime/backend/contracts/index.ts +15 -42
  391. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -28
  392. package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
  393. package/src/runtime/backend/node/node-backend-adapter-factory.ts +5 -25
  394. package/src/runtime/backend/node/node-backend-adapter-support.ts +32 -35
  395. package/src/runtime/backend/node/node-event-loop-poller.ts +16 -8
  396. package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
  397. package/src/runtime/backend/node/node-raw-binding-port.ts +58 -23
  398. package/src/runtime/backend/node/node-raw-mesh-backend.ts +252 -162
  399. package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -4
  400. package/src/runtime/backend/raw-binding-port.ts +14 -1
  401. package/src/runtime/backend/runtime-values.ts +4 -1
  402. package/src/runtime/channels/channel-clients.ts +132 -96
  403. package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
  404. package/src/runtime/channels/channel-envelope.ts +58 -29
  405. package/src/runtime/channels/channel-outbound-operations.ts +10 -31
  406. package/src/runtime/channels/channel-receive-loops.ts +39 -7
  407. package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
  408. package/src/runtime/channels/channel-runtime-manager.ts +8 -15
  409. package/src/runtime/channels/channel-socket-options.ts +8 -2
  410. package/src/runtime/channels/channel-socket-registry.ts +369 -262
  411. package/src/runtime/channels/channel-transports.ts +161 -115
  412. package/src/runtime/channels/client-server-location-runtime.ts +17 -17
  413. package/src/runtime/channels/client-server-service-wire.ts +40 -12
  414. package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
  415. package/src/runtime/channels/fanout-location-runtime.ts +175 -106
  416. package/src/runtime/channels/spot-direct-envelope.ts +1 -1
  417. package/src/runtime/channels/spot-node-route-transport.ts +5 -2
  418. package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
  419. package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
  420. package/src/runtime/diagnostics/flow-context.ts +16 -2
  421. package/src/runtime/diagnostics/index.ts +27 -17
  422. package/src/runtime/diagnostics/message-flow.ts +15 -25
  423. package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
  424. package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
  425. package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
  426. package/src/runtime/disposal.ts +19 -0
  427. package/src/runtime/execution/index.ts +116 -38
  428. package/src/runtime/execution/serial-execution-queue.ts +179 -34
  429. package/src/runtime/execution/state-lane.ts +142 -4
  430. package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
  431. package/src/runtime/foundation/event-loop-resources.ts +5 -122
  432. package/src/runtime/foundation/listener-records.ts +21 -0
  433. package/src/runtime/foundation/operation-identity.ts +11 -5
  434. package/src/runtime/foundation/operation-registry.ts +33 -50
  435. package/src/runtime/foundation/raw-service-mesh-runtime.ts +170 -571
  436. package/src/runtime/foundation/runtime-state-projections.ts +9 -1
  437. package/src/runtime/foundation/service-authority-payload-codec.ts +41 -13
  438. package/src/runtime/foundation/service-discovery-registry.ts +32 -3
  439. package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
  440. package/src/runtime/foundation/service-liveness-registry.ts +2 -1
  441. package/src/runtime/foundation/service-maintenance-runtime.ts +30 -19
  442. package/src/runtime/foundation/service-metadata-codec.ts +2 -2
  443. package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
  444. package/src/runtime/foundation/service-relocation-coordinator.ts +13 -0
  445. package/src/runtime/foundation/service-relocation-object-owner.ts +23 -7
  446. package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
  447. package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
  448. package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -25
  449. package/src/runtime/foundation/service-stateful-registry.ts +14 -2
  450. package/src/runtime/foundation/service-stateful-runtime.ts +435 -327
  451. package/src/runtime/foundation/service-stateful-wire-codec.ts +329 -199
  452. package/src/runtime/foundation/service-topology-registry.ts +30 -79
  453. package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
  454. package/src/runtime/foundation/service-wire-codec.ts +15 -8
  455. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  456. package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
  457. package/src/runtime/framework-errors-internal.ts +380 -134
  458. package/src/runtime/handlers/handler-instance-scope.ts +68 -95
  459. package/src/runtime/host/actor-packet-relay.ts +57 -147
  460. package/src/runtime/host/actor-placement-coordinator.ts +8 -5
  461. package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
  462. package/src/runtime/host/actor-transfer-runtime.ts +266 -418
  463. package/src/runtime/host/application-job-queue.ts +28 -34
  464. package/src/runtime/host/bound-session-relay.ts +1 -2
  465. package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
  466. package/src/runtime/host/index.ts +408 -312
  467. package/src/runtime/host/instance-activation-authority.ts +89 -109
  468. package/src/runtime/host/location-runtime-owner.ts +4 -2
  469. package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
  470. package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
  471. package/src/runtime/host/remote-bound-session-relay.ts +12 -44
  472. package/src/runtime/host/route-mesh-runtime.ts +236 -275
  473. package/src/runtime/host/runtime-shutdown.ts +17 -21
  474. package/src/runtime/host/service-relocation-control.ts +14 -1
  475. package/src/runtime/host/service-relocation-host-runtime.ts +1161 -904
  476. package/src/runtime/host/spot-address-transport.ts +73 -195
  477. package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
  478. package/src/runtime/host/spot-runtime-options-factory.ts +92 -30
  479. package/src/runtime/host/stateful-authority-route-runtime.ts +8 -4
  480. package/src/runtime/host/user-spot-creation-coordinator.ts +182 -163
  481. package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
  482. package/src/runtime/locations/authority-key-codec.ts +7 -3
  483. package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
  484. package/src/runtime/locations/creation-operation-id.ts +6 -3
  485. package/src/runtime/locations/domain-store-contract.ts +12 -3
  486. package/src/runtime/locations/in-memory-authority-store.ts +44 -15
  487. package/src/runtime/locations/in-memory-location-store.ts +50 -39
  488. package/src/runtime/locations/in-memory-provider-location-store.ts +110 -31
  489. package/src/runtime/locations/key-codec.ts +3 -2
  490. package/src/runtime/locations/lease-tracker.ts +8 -14
  491. package/src/runtime/locations/lifecycle.ts +16 -45
  492. package/src/runtime/locations/location-store-failure.ts +4 -0
  493. package/src/runtime/locations/location-store-pages.ts +18 -0
  494. package/src/runtime/locations/location-store-repository.ts +450 -478
  495. package/src/runtime/locations/relocation-blob.ts +17 -6
  496. package/src/runtime/locations/resolvers.ts +90 -58
  497. package/src/runtime/locations/runtime.ts +220 -110
  498. package/src/runtime/locations/spot-location-claims.ts +54 -26
  499. package/src/runtime/messaging/payload-codec.ts +35 -24
  500. package/src/runtime/messaging/submission-result.ts +57 -1
  501. package/src/runtime/protocol/service_wire_codec.generated.ts +27 -10
  502. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  503. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +6 -6
  504. package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +6 -3
  505. package/src/runtime/spots/index.ts +687 -437
  506. package/src/runtime/spots/spot-activation-registry.ts +42 -71
  507. package/src/runtime/spots/spot-activation-state.ts +4 -16
  508. package/src/runtime/spots/spot-activation.ts +167 -115
  509. package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
  510. package/src/runtime/spots/spot-actor-join-dispatch.ts +25 -79
  511. package/src/runtime/spots/spot-actor-lifecycle-drain.ts +20 -18
  512. package/src/runtime/spots/spot-actor-membership.ts +107 -75
  513. package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
  514. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
  515. package/src/runtime/spots/spot-context.ts +3 -3
  516. package/src/runtime/spots/spot-entry-activation.ts +13 -33
  517. package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
  518. package/src/runtime/spots/spot-manager-public.ts +29 -21
  519. package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
  520. package/src/runtime/spots/spot-node-runtime-manager.ts +145 -140
  521. package/src/runtime/spots/spot-outbound.ts +47 -68
  522. package/src/runtime/spots/spot-remote-codec.ts +7 -3
  523. package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
  524. package/src/runtime/spots/spot-route-replies.ts +6 -4
  525. package/src/runtime/spots/spot-routed-actor-admission.ts +13 -6
  526. package/src/runtime/spots/spot-routed-frame-dispatch.ts +6 -77
  527. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
  528. package/src/runtime/spots/spot-runtime-ports.ts +10 -43
  529. package/src/runtime/spots/spot-serial-executor.ts +10 -2
  530. package/src/runtime/spots/spot-serial-turn-executor.ts +120 -13
  531. package/src/runtime/spots/spot-timer.ts +3 -2
  532. package/src/runtime/streams/actor-session-binding-registry.ts +182 -560
  533. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +1 -19
  534. package/src/runtime/streams/bound-actor-relay-sender.ts +89 -43
  535. package/src/runtime/streams/bound-session-service.ts +23 -37
  536. package/src/runtime/streams/index.ts +102 -88
  537. package/src/runtime/streams/managed-stream.ts +29 -10
  538. package/src/runtime/streams/native-fallback-bound-session.ts +1 -3
  539. package/src/runtime/streams/protocol.ts +34 -88
  540. package/src/runtime/streams/session-actor-coordinator.ts +17 -5
  541. package/src/runtime/streams/session-calls.ts +6 -5
  542. package/src/runtime/streams/session-context.ts +54 -10
  543. package/src/runtime/streams/session-requests.ts +2 -1
  544. package/src/runtime/streams/session-serial-executor.ts +2 -2
  545. package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
  546. package/src/runtime/streams/stream-frame-factory.ts +2 -3
  547. package/src/runtime/streams/stream-session-runtime.ts +57 -59
  548. package/src/runtime/workers/index.ts +13 -12
  549. package/dist/runtime/actors/deferred-join-accepted-journal.d.ts +0 -47
  550. package/dist/runtime/actors/deferred-join-accepted-journal.js +0 -992
  551. package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
  552. package/dist/runtime/actors/post-commit-actor-location.js +0 -72
  553. package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
  554. package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
  555. package/src/runtime/actors/deferred-join-accepted-journal.ts +0 -1346
  556. package/src/runtime/actors/post-commit-actor-location.ts +0 -121
  557. package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
@@ -1,42 +1,58 @@
1
+ import { RuntimeDisposal } from '../disposal';
2
+ import { UINT64_MAX } from '@zlink-systems/stream-wire';
3
+ import { randomBytes, randomUUID } from 'node:crypto';
1
4
  import {
2
5
  ZLinkFrameworkRuntimeState,
3
6
  type RoutingId,
4
7
  type ZLinkClientServerServerDescriptor,
5
8
  type ZLinkFanoutPublisherDescriptor
6
9
  } from '../../contracts';
7
- import type { ZLinkChannelOptions } from '../../contracts/Configuration/RegistrationTypes';
8
- import { ZLinkSocketNativeEventType } from '../diagnostics/internal-event-contracts';
10
+ import { ZLINK_MAX_ROUTING_ID_BYTES } from '../../contracts/Common/CoreTypes';
11
+ import type { Message } from '../../contracts/Common/Message';
9
12
  import {
10
- buildAdvertisedEndpoint,
11
- ZLinkConfigurationException,
12
- type ZLinkFrameworkRegistration
13
- } from '../configuration';
13
+ isValidPublicWeight,
14
+ ZLINK_DEFAULT_PUBLIC_WEIGHT,
15
+ ZLINK_MAX_PUBLIC_WEIGHT
16
+ } from '../../contracts/Configuration/RegistrationBuilderPolicy';
17
+ import type { ZLinkChannelOptions } from '../../contracts/Configuration/RegistrationTypes';
18
+ import { attachEndpointConnections } from '../../contracts/Configuration/RuntimeEndpointConnections';
19
+ import { createAbortError, throwIfAborted } from '../abort';
14
20
  import type {
15
21
  ZLinkBackendContext,
16
22
  ZLinkBackendDealerSocket,
17
23
  ZLinkBackendPublisherSocket,
18
- ZLinkBackendRouterSocket,
19
24
  ZLinkBackendReadablePoller,
25
+ ZLinkBackendRouterSocket,
20
26
  ZLinkBackendSocketMonitor,
21
27
  ZLinkBackendSocketMonitorEvent,
22
28
  ZLinkBackendSubscriberSocket,
23
29
  ZLinkChannelBackendAdapter,
24
30
  ZLinkMonitoringBackendAdapter
25
31
  } from '../backend/contracts';
26
- import { throwIfAborted } from '../abort';
27
- import { attachEndpointConnections } from '../../contracts/Configuration/RuntimeEndpointConnections';
28
- import { ZLinkRouteMemberSnapshot } from './route-member-snapshot';
29
- import {
30
- ZLinkFrameworkInternalErrorKind,
31
- createInternalFrameworkException
32
- } from '../framework-errors-internal';
33
- import { randomBytes, randomUUID } from 'node:crypto';
34
32
  import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
35
- import type { Message } from '../../contracts/Common/Message';
36
- import { ServiceDiscoveryRegistry } from '../foundation/service-discovery-registry';
33
+ import { isBackendRequestTimeoutError } from '../backend/runtime-values';
34
+ import {
35
+ buildAdvertisedEndpoint,
36
+ ZLinkConfigurationException,
37
+ type ZLinkFrameworkRegistration
38
+ } from '../configuration';
39
+ import { ZLinkSocketNativeEventType } from '../diagnostics/internal-event-contracts';
40
+ import { ZLinkListenerRecords } from '../foundation/listener-records';
37
41
  import { discoveryAvailabilityForRuntimeState } from '../foundation/runtime-state-projections';
42
+ import { ServiceDiscoveryRegistry } from '../foundation/service-discovery-registry';
43
+ import {
44
+ DEFAULT_SERVICE_PEER_TIMEOUT_MS,
45
+ DEFAULT_SERVICE_PROBE_INTERVAL_MS
46
+ } from '../foundation/service-liveness-registry';
38
47
  import { ServiceWireProtocolError } from '../foundation/service-wire-m6a-codec';
39
48
  import {
49
+ createInternalFrameworkException,
50
+ ZLinkFrameworkInternalErrorKind
51
+ } from '../framework-errors-internal';
52
+ import type { ApplicationJobQueue } from '../host/application-job-queue';
53
+ import type { ZLinkChannelEnvelopeHeader } from './channel-envelope';
54
+ import {
55
+ ClientServerRejectReason,
40
56
  decodeClientServerControl,
41
57
  encodeClientServerAdmit,
42
58
  encodeClientServerHello,
@@ -45,6 +61,7 @@ import {
45
61
  encodeClientServerReject,
46
62
  encodeClientServerUpdate,
47
63
  isClientServerControlFrame,
64
+ normalizeClientServerMessageLimit,
48
65
  type ZLinkClientServerAdmission
49
66
  } from './client-server-service-wire';
50
67
  import {
@@ -52,16 +69,13 @@ import {
52
69
  FANOUT_LIVENESS_TOPIC,
53
70
  inspectFanoutInbound
54
71
  } from './fanout-service-wire';
55
- import type { ZLinkChannelEnvelopeHeader } from './channel-envelope';
56
- import type { ApplicationJobQueue } from '../host/application-job-queue';
57
- import { isBackendRequestTimeoutError } from '../backend/runtime-values';
72
+ import { ZLinkRouteMemberSnapshot } from './route-member-snapshot';
58
73
 
59
74
  const MAX_LIFECYCLE_GENERATION = 0x7fff_ffff_ffff_ffffn;
60
- const CLIENT_SERVER_PROBE_INTERVAL_MS = 5_000;
61
- const CLIENT_SERVER_PEER_DEADLINE_MS = 15_000;
62
- const CLIENT_SERVER_READY_WAIT_CAP_MS = 5_000;
63
- const CLIENT_SERVER_READY_POLL_INTERVAL_MS = 5;
64
- const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
75
+ const CLIENT_SERVER_PROBE_INTERVAL_MS = DEFAULT_SERVICE_PROBE_INTERVAL_MS;
76
+ const CLIENT_SERVER_PEER_DEADLINE_MS = DEFAULT_SERVICE_PEER_TIMEOUT_MS;
77
+ const CLIENT_SERVER_LIVENESS_TICK_MS = 100;
78
+ const DEFAULT_SEND_TIMEOUT_MS = 1_000;
65
79
 
66
80
  export interface ZLinkClientServerServerSocketIdentity {
67
81
  readonly serverRid: string;
@@ -80,12 +94,11 @@ interface ClientServerPhysicalConnection {
80
94
  readonly channelName: string;
81
95
  readonly endpoint: string;
82
96
  readonly dealer: ZLinkBackendDealerSocket;
83
- readonly readablePoller: ZLinkBackendReadablePoller;
84
- readonly monitor: ZLinkBackendSocketMonitor;
97
+ readablePoller?: ZLinkBackendReadablePoller;
98
+ monitor?: ZLinkBackendSocketMonitor;
85
99
  readonly aliases: Set<string>;
86
100
  readonly callbacksByAlias: Map<string, ZLinkClientServerConnectionCallbacks>;
87
101
  physicalConnectionId: symbol;
88
- terminationRequested: boolean;
89
102
  readyConnectionId?: string;
90
103
  admittedDescriptor?: ClientServerDiscoveryDescriptor;
91
104
  nextProbeAt?: number;
@@ -103,7 +116,7 @@ interface FanoutPublisherConnection {
103
116
  readonly channelName: string;
104
117
  readonly endpoint: string;
105
118
  readonly subscriber: ZLinkBackendSubscriberSocket;
106
- readonly monitor: ZLinkBackendSocketMonitor;
119
+ monitor?: ZLinkBackendSocketMonitor;
107
120
  readonly callbacks: ZLinkFanoutConnectionCallbacks;
108
121
  readonly physicalConnectionId: symbol;
109
122
  transportReady: boolean;
@@ -155,14 +168,20 @@ export class ZLinkChannelSocketRegistry {
155
168
  outstandingProbeId?: bigint;
156
169
  }
157
170
  >();
158
- private readonly ownedMonitors = new Set<ZLinkBackendSocketMonitor>();
171
+ private readonly disposal = new RuntimeDisposal();
172
+ private readonly ownedResources = new Set<
173
+ | ZLinkBackendSocketMonitor
174
+ | ZLinkBackendReadablePoller
175
+ | ZLinkBackendDealerSocket
176
+ | ZLinkBackendSubscriberSocket
177
+ >();
159
178
  private readonly fanoutConnections = new Map<string, FanoutPublisherConnection>();
160
179
  private readonly fanoutPublisherNextBeacon = new Map<string, number>();
161
180
  private clientServerLivenessTimer?: NodeJS.Timeout;
162
181
  private nextClientServerProbeId = 1n;
163
182
  private readonly clientServerMonitorHandlers = new Map<
164
183
  string,
165
- Set<(event: ZLinkBackendSocketMonitorEvent) => void>
184
+ Set<(event?: ZLinkBackendSocketMonitorEvent) => void>
166
185
  >();
167
186
  private readonly fanoutMonitorHandlers = new Map<
168
187
  string,
@@ -170,19 +189,34 @@ export class ZLinkChannelSocketRegistry {
170
189
  >();
171
190
  private readonly fanoutTopologyHandlers = new Map<string, Set<() => void>>();
172
191
 
192
+ private readonly listenerRecords: ZLinkListenerRecords;
193
+
173
194
  constructor(
174
195
  private readonly registration: ZLinkFrameworkRegistration,
175
196
  private readonly adapter: ZLinkChannelBackendAdapter,
176
197
  private readonly context: ZLinkBackendContext,
177
198
  private readonly monitoringAdapter?: ZLinkMonitoringBackendAdapter,
178
199
  private readonly oneWayFailureSink?: (error: unknown) => void,
179
- private readonly applicationJobQueue?: ApplicationJobQueue
180
- ) {}
200
+ private readonly applicationJobQueue?: ApplicationJobQueue,
201
+ listenerRecords?: ZLinkListenerRecords
202
+ ) {
203
+ this.listenerRecords = listenerRecords ?? new ZLinkListenerRecords();
204
+ }
205
+
206
+ dispose(): Promise<void> {
207
+ return this.disposal.run(() => this.disposeCore());
208
+ }
181
209
 
182
- async dispose(): Promise<void> {
210
+ private async disposeCore(): Promise<void> {
211
+ this.clientServerDiscovery.dispose(
212
+ createInternalFrameworkException(
213
+ ZLinkFrameworkInternalErrorKind.RuntimeShutdown,
214
+ 'Channel sockets are shutting down.'
215
+ )
216
+ );
183
217
  const clientServerConnections = [...new Set(this.clientServerConnections.values())];
184
- const clientServerPollers = clientServerConnections.map(
185
- (connection) => connection.readablePoller
218
+ const clientServerPollers = clientServerConnections.flatMap((connection) =>
219
+ connection.readablePoller === undefined ? [] : [connection.readablePoller]
186
220
  );
187
221
  const sockets = [
188
222
  ...this.clientDealers.values(),
@@ -199,8 +233,6 @@ export class ZLinkChannelSocketRegistry {
199
233
  ...this.routeRouters.values()
200
234
  ]))
201
235
  this.unregisterReceiveFlowSocket(socket);
202
- this.clientDealers.clear();
203
- this.clientServerConnections.clear();
204
236
  this.clientServerReadyIdentities.clear();
205
237
  this.clientServerServerDescriptors.clear();
206
238
  this.clientServerPublicWeights.clear();
@@ -210,23 +242,37 @@ export class ZLinkChannelSocketRegistry {
210
242
  this.clientServerMonitorHandlers.clear();
211
243
  this.fanoutMonitorHandlers.clear();
212
244
  this.fanoutTopologyHandlers.clear();
213
- this.fanoutConnections.clear();
214
245
  this.fanoutPublisherNextBeacon.clear();
215
246
  if (this.clientServerLivenessTimer !== undefined) {
216
247
  clearInterval(this.clientServerLivenessTimer);
217
248
  this.clientServerLivenessTimer = undefined;
218
249
  }
219
- this.channelRouters.clear();
220
- this.publishers.clear();
221
- this.routeRouters.clear();
222
250
  this.routeMembers.clear();
223
- const monitors = [...this.ownedMonitors];
224
- this.ownedMonitors.clear();
225
- const cleanup = await Promise.allSettled([
226
- ...clientServerPollers.map((poller) => poller.dispose()),
227
- ...monitors.map((monitor) => monitor.dispose()),
228
- ...sockets.map((socket) => socket.dispose())
229
- ]);
251
+ const cleanup = await Promise.allSettled(
252
+ [...new Set([...clientServerPollers, ...this.ownedResources, ...sockets])].map(
253
+ async (resource) => {
254
+ await resource.dispose();
255
+ this.ownedResources.delete(resource as ZLinkBackendSocketMonitor);
256
+ for (const owners of [
257
+ this.clientDealers,
258
+ this.channelRouters,
259
+ this.publishers,
260
+ this.routeRouters
261
+ ]) {
262
+ for (const [name, owned] of owners) if (owned === resource) owners.delete(name);
263
+ }
264
+ for (const [name, owned] of this.clientServerConnections) {
265
+ if (owned.dealer === resource) this.clientServerConnections.delete(name);
266
+ if (owned.readablePoller === resource) owned.readablePoller = undefined;
267
+ if (owned.monitor === resource) owned.monitor = undefined;
268
+ }
269
+ for (const [name, owned] of this.fanoutConnections) {
270
+ if (owned.subscriber === resource) this.fanoutConnections.delete(name);
271
+ if (owned.monitor === resource) owned.monitor = undefined;
272
+ }
273
+ }
274
+ )
275
+ );
230
276
  const errors = cleanup
231
277
  .filter((result): result is PromiseRejectedResult => result.status === 'rejected')
232
278
  .map((result) => result.reason);
@@ -247,13 +293,16 @@ export class ZLinkChannelSocketRegistry {
247
293
  }
248
294
 
249
295
  const dealer = this.adapter.createDealerSocket(this.context);
296
+ this.clientDealers.set(channelName, dealer);
250
297
  this.registerReceiveFlowSocket(dealer);
251
298
  dealer.setChannelName(channelName);
252
299
  if (channel?.routingId !== undefined && channel.routingId.length > 0) {
253
300
  dealer.setRoutingId(deriveRoutingId(channel.routingId, 'dealer'));
254
301
  }
255
- applySocketConfig(dealer, client);
256
- this.clientDealers.set(channelName, dealer);
302
+ applySocketConfig(dealer, {
303
+ ...client,
304
+ sendTimeoutMs: configuredSendTimeoutMs(client.sendTimeoutMs)
305
+ });
257
306
  return dealer;
258
307
  }
259
308
 
@@ -274,6 +323,7 @@ export class ZLinkChannelSocketRegistry {
274
323
  }
275
324
 
276
325
  const router = this.adapter.createRouterSocket(this.context);
326
+ this.channelRouters.set(channelName, router);
277
327
  this.registerReceiveFlowSocket(router);
278
328
  router.setChannelName(channelName);
279
329
  const identity = this.clientServerIdentities.get(channelName) ?? {
@@ -282,14 +332,14 @@ export class ZLinkChannelSocketRegistry {
282
332
  };
283
333
  this.clientServerIdentities.set(channelName, identity);
284
334
  router.setRoutingId(identity.serverRid);
285
- const publicWeight = channel.server.weight ?? 100;
335
+ const publicWeight = channel.server.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
286
336
  this.clientServerPublicWeights.set(channelName, publicWeight);
287
337
  router.peerWeight = rawAvailabilityWeight(publicWeight);
288
338
  applySocketConfig(router, channel.server);
289
339
  router.bind(channel.server.bind);
290
340
  if (this.monitoringAdapter !== undefined) {
291
341
  const monitor = this.monitoringAdapter.openSocketMonitor(router);
292
- this.ownedMonitors.add(monitor);
342
+ this.ownedResources.add(monitor);
293
343
  monitor.onEvent((event) => {
294
344
  if (event.routingId === undefined) return;
295
345
  if (
@@ -305,15 +355,18 @@ export class ZLinkChannelSocketRegistry {
305
355
  this.clientServerAdmittedClients.get(channelName)?.delete(routingId);
306
356
  });
307
357
  }
308
- this.channelRouters.set(channelName, router);
358
+ const endpoint = advertisedEndpoint(
359
+ router.lastEndpoint ?? channel.server.bind,
360
+ channel.server.advertiseHost
361
+ );
362
+ this.recordListener('clientServer', channelName, endpoint);
309
363
  if (!this.clientServerServerDescriptors.has(channelName)) {
310
- const boundEndpoint = router.lastEndpoint ?? channel.server.bind;
311
364
  this.clientServerServerDescriptors.set(channelName, {
312
365
  channelName,
313
366
  serverRid: identity.serverRid,
314
367
  lifecycleGeneration: identity.lifecycleGeneration,
315
368
  descriptorRevision: 1n,
316
- endpoint: advertisedEndpoint(boundEndpoint, channel.server.advertiseHost),
369
+ endpoint,
317
370
  weight: publicWeight,
318
371
  state: ZLinkFrameworkRuntimeState.Serving,
319
372
  securityIdentity: 'default',
@@ -326,22 +379,21 @@ export class ZLinkChannelSocketRegistry {
326
379
  }
327
380
 
328
381
  clientServerServerIdentity(channelName: string): ZLinkClientServerServerSocketIdentity {
329
- const router = this.channelRouter(channelName);
382
+ this.channelRouter(channelName);
330
383
  const identity = this.clientServerIdentities.get(channelName);
331
- const channel = this.registration.channels.get(channelName);
332
- if (identity === undefined || channel?.server === undefined) {
384
+ const endpoint = this.listenerRecords.endpoint('clientServer', channelName);
385
+ if (identity === undefined || endpoint === undefined) {
333
386
  throw new ZLinkConfigurationException(`Channel server '${channelName}' is not registered.`);
334
387
  }
335
- const boundEndpoint = router.lastEndpoint ?? channel.server.bind;
336
- if (boundEndpoint === undefined || boundEndpoint.length === 0) {
337
- throw new ZLinkConfigurationException(
338
- `Channel server '${channelName}' did not report its bound endpoint.`
339
- );
340
- }
341
- return {
342
- ...identity,
343
- endpoint: advertisedEndpoint(boundEndpoint, channel.server.advertiseHost)
344
- };
388
+ return { ...identity, endpoint };
389
+ }
390
+
391
+ fanoutPublisherEndpoint(channelName: string): string | undefined {
392
+ return this.listenerRecords.endpoint('fanout', channelName);
393
+ }
394
+
395
+ private recordListener(kind: 'clientServer' | 'fanout', name: string, endpoint: string): void {
396
+ this.listenerRecords.record(kind, name, endpoint);
345
397
  }
346
398
 
347
399
  clientServerServerSocket(channelName: string): ZLinkBackendRouterSocket {
@@ -350,7 +402,7 @@ export class ZLinkChannelSocketRegistry {
350
402
 
351
403
  clientServerServerWeight(channelName: string): number {
352
404
  this.channelRouter(channelName);
353
- return this.clientServerPublicWeights.get(channelName) ?? 100;
405
+ return this.clientServerPublicWeights.get(channelName) ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
354
406
  }
355
407
 
356
408
  setClientServerServerWeight(channelName: string, weight: number): void {
@@ -382,47 +434,38 @@ export class ZLinkChannelSocketRegistry {
382
434
  throw new ZLinkConfigurationException(`Channel client '${channelName}' is not registered.`);
383
435
  }
384
436
  const dealer = this.adapter.createDealerSocket(this.context);
385
- this.registerReceiveFlowSocket(dealer);
386
- dealer.setChannelName(channelName);
387
- dealer.setRoutingId(`cs-client-${randomUUID()}`);
388
- applySocketConfig(dealer, client);
389
- const cleanupDealer = (): void => {
390
- this.unregisterReceiveFlowSocket(dealer);
391
- void Promise.allSettled([dealer.dispose()]);
392
- };
393
- let readablePoller: ZLinkBackendReadablePoller;
394
- try {
395
- readablePoller = this.adapter.createReadablePoller(dealer);
396
- } catch (error) {
397
- cleanupDealer();
398
- throw error;
399
- }
400
- let monitor: ZLinkBackendSocketMonitor;
401
- try {
402
- monitor = this.monitoringAdapter.openSocketMonitor(dealer);
403
- } catch (error) {
404
- try {
405
- readablePoller.dispose();
406
- } finally {
407
- cleanupDealer();
408
- }
409
- throw error;
410
- }
411
- this.ownedMonitors.add(monitor);
412
437
  const connection: ClientServerPhysicalConnection = {
413
438
  channelName,
414
439
  endpoint,
415
440
  dealer,
416
- readablePoller,
417
- monitor,
418
441
  aliases: new Set([connectionId]),
419
442
  callbacksByAlias: new Map([[connectionId, callbacks]]),
420
- physicalConnectionId: Symbol(connectionId),
421
- terminationRequested: false
443
+ physicalConnectionId: Symbol(connectionId)
422
444
  };
423
- this.clientServerConnections.set(connectionId, connection);
424
- this.ensureClientServerLivenessTimer();
445
+ this.ownedResources.add(dealer);
446
+ const created: (
447
+ | ZLinkBackendSocketMonitor
448
+ | ZLinkBackendReadablePoller
449
+ | ZLinkBackendDealerSocket
450
+ | ZLinkBackendSubscriberSocket
451
+ )[] = [dealer];
425
452
  try {
453
+ this.clientServerConnections.set(connectionId, connection);
454
+ this.registerReceiveFlowSocket(dealer);
455
+ dealer.setChannelName(channelName);
456
+ dealer.setRoutingId(`cs-client-${randomUUID()}`);
457
+ applySocketConfig(dealer, {
458
+ ...client,
459
+ sendTimeoutMs: configuredSendTimeoutMs(client.sendTimeoutMs)
460
+ });
461
+ connection.readablePoller = this.adapter.createReadablePoller(dealer);
462
+ created.push(connection.readablePoller);
463
+ this.ownedResources.add(connection.readablePoller);
464
+ const monitor = this.monitoringAdapter.openSocketMonitor(dealer);
465
+ connection.monitor = monitor;
466
+ created.push(monitor);
467
+ this.ownedResources.add(monitor);
468
+ this.ensureClientServerLivenessTimer();
426
469
  monitor.onEvent((event) => {
427
470
  if (
428
471
  ![...connection.aliases].some(
@@ -436,7 +479,7 @@ export class ZLinkChannelSocketRegistry {
436
479
  const routingId = event.routingId === undefined ? undefined : String(event.routingId);
437
480
  if (event.nativeEvent === ZLinkSocketNativeEventType.ConnectionReady) {
438
481
  // This single-endpoint DEALER also receives its disconnected ready-count snapshot.
439
- if (event.value === 0n || connection.terminationRequested) return;
482
+ if (event.value === 0n) return;
440
483
  connection.physicalConnectionId = Symbol(connectionId);
441
484
  connection.admissionAttempt = undefined;
442
485
  for (const currentCallbacks of [...connection.callbacksByAlias.values()]) {
@@ -451,47 +494,32 @@ export class ZLinkChannelSocketRegistry {
451
494
  event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedProtocol ||
452
495
  event.nativeEvent === ZLinkSocketNativeEventType.HandshakeFailedAuth
453
496
  ) {
454
- if (
455
- connection.terminationRequested &&
456
- (event.remoteAddr !== connection.endpoint ||
457
- (event.nativeEvent !== ZLinkSocketNativeEventType.Disconnected &&
458
- event.nativeEvent !== ZLinkSocketNativeEventType.Closed))
459
- )
460
- return;
461
- connection.physicalConnectionId = Symbol(connectionId);
462
- connection.admissionAttempt = undefined;
463
- if (connection.readyConnectionId !== undefined) {
464
- this.removeReadyConnection(connection.readyConnectionId);
465
- }
466
- for (const currentCallbacks of [...connection.callbacksByAlias.values()]) {
467
- currentCallbacks.onTerminated(routingId, event.remoteAddr);
468
- }
469
- if (connection.terminationRequested) {
470
- connection.terminationRequested = false;
471
- // Explicit disconnect removes intent; restore it once after this endpoint closes.
472
- connection.dealer.connect(connection.endpoint);
473
- }
497
+ // Core owns the endpoint reconnect (transport liveness §6); the
498
+ // connect intent stays and the next READY starts a new admission.
499
+ this.endClientServerAdmission(connectionId, connection, routingId, event.remoteAddr);
474
500
  }
475
501
  });
476
502
  dealer.connect(endpoint);
503
+ return dealer;
477
504
  } catch (error) {
478
505
  this.clientServerConnections.delete(connectionId);
479
- this.ownedMonitors.delete(monitor);
480
- try {
481
- readablePoller.dispose();
482
- } finally {
483
- cleanupDealer();
484
- void Promise.allSettled([monitor.dispose()]);
485
- }
506
+ this.unregisterReceiveFlowSocket(dealer);
507
+ void Promise.allSettled(
508
+ created.map(async (resource) => {
509
+ await resource.dispose();
510
+ this.ownedResources.delete(resource);
511
+ })
512
+ ).then((results) => {
513
+ for (const result of results)
514
+ if (result.status === 'rejected') this.oneWayFailureSink?.(result.reason);
515
+ });
486
516
  throw error;
487
517
  }
488
- return dealer;
489
518
  }
490
519
 
491
520
  async closeClientServerConnection(connectionId: string): Promise<void> {
492
521
  const current = this.clientServerConnections.get(connectionId);
493
522
  if (current === undefined) return;
494
- this.clientServerConnections.delete(connectionId);
495
523
  current.aliases.delete(connectionId);
496
524
  current.callbacksByAlias.delete(connectionId);
497
525
  const ready = this.clientServerReadyIdentities.get(connectionId);
@@ -517,8 +545,13 @@ export class ZLinkChannelSocketRegistry {
517
545
  });
518
546
  }
519
547
  }
520
- if (current.aliases.size > 0) return;
548
+ this.notifyClientServerTopology(current.channelName);
549
+ if (current.aliases.size > 0) {
550
+ this.clientServerConnections.delete(connectionId);
551
+ return;
552
+ }
521
553
  await this.disposeClientServerPhysical(connectionId, current);
554
+ this.clientServerConnections.delete(connectionId);
522
555
  }
523
556
 
524
557
  private async disposeClientServerPhysical(
@@ -528,12 +561,21 @@ export class ZLinkChannelSocketRegistry {
528
561
  try {
529
562
  current.dealer.disconnect(current.endpoint);
530
563
  } catch {
531
- // Disposal below is the terminal cleanup if the transport already closed.
564
+ // The socket close below releases an endpoint that is already disconnected.
532
565
  }
533
- this.ownedMonitors.delete(current.monitor);
534
566
  this.unregisterReceiveFlowSocket(current.dealer);
535
- current.readablePoller.dispose();
536
- const results = await Promise.allSettled([current.monitor.dispose(), current.dealer.dispose()]);
567
+ if (current.readablePoller !== undefined) {
568
+ current.readablePoller.dispose();
569
+ this.ownedResources.delete(current.readablePoller);
570
+ current.readablePoller = undefined;
571
+ }
572
+ const results = await Promise.allSettled([
573
+ current.monitor?.dispose(),
574
+ (async () => {
575
+ await current.dealer.dispose();
576
+ this.ownedResources.delete(current.dealer);
577
+ })()
578
+ ]);
537
579
  const errors = results
538
580
  .filter((result): result is PromiseRejectedResult => result.status === 'rejected')
539
581
  .map((result) => result.reason);
@@ -541,6 +583,7 @@ export class ZLinkChannelSocketRegistry {
541
583
  if (errors.length > 1) {
542
584
  throw new AggregateError(errors, `ClientServer connection '${connectionId}' cleanup failed.`);
543
585
  }
586
+ if (current.monitor !== undefined) this.ownedResources.delete(current.monitor);
544
587
  }
545
588
 
546
589
  admitClientServerConnection(
@@ -555,6 +598,7 @@ export class ZLinkChannelSocketRegistry {
555
598
  connection.readyConnectionId
556
599
  );
557
600
  if (admitted) connection.admittedDescriptor = descriptor;
601
+ this.notifyClientServerTopology(descriptor.channelName);
558
602
  return admitted;
559
603
  }
560
604
  const duplicateId = [...this.clientServerReadyIdentities].find(
@@ -592,6 +636,7 @@ export class ZLinkChannelSocketRegistry {
592
636
  connection.readyConnectionId = connectionId;
593
637
  connection.admittedDescriptor = descriptor;
594
638
  }
639
+ this.notifyClientServerTopology(descriptor.channelName);
595
640
  return admitted;
596
641
  }
597
642
 
@@ -615,6 +660,7 @@ export class ZLinkChannelSocketRegistry {
615
660
  connection.outstandingProbeId = undefined;
616
661
  }
617
662
  }
663
+ this.notifyClientServerTopology(channelName);
618
664
  return removed;
619
665
  }
620
666
 
@@ -646,52 +692,60 @@ export class ZLinkChannelSocketRegistry {
646
692
  return undefined;
647
693
  }
648
694
 
649
- /**
650
- * Resolves a ClientServer send target, waiting when the ready candidate set is still empty, as
651
- * `framework/doc/framework/common/spec/server/02-channel-transport/02-channel-messaging.ko.md` §3.2 requires: the call waits
652
- * at call time for a bounded period and then fails with no-target. The bound is the shorter of
653
- * the call's remaining deadline and five seconds, mirroring the .NET reference
654
- * `ZLinkClientServerClientRuntime.WaitForReadyAsync`. The wait lives here because this registry
655
- * owns ClientServer connections, admission and weighted selection. Sends have no per-call
656
- * timeout, so they use the Channel's request timeout.
657
- *
658
- * The wait only observes admission that is already in flight: it never opens or reconnects a
659
- * connection, so it cannot trigger the admission it waits for, and Framework startup keeps not
660
- * waiting for local ClientServer admission. It applies whenever nothing is selectable, including
661
- * candidate sets excluded by weight 0 or drain, because `selectClientServerDealer` filters the
662
- * same way the reference `SelectReady()` does.
663
- *
664
- * Every attempt yields to the event loop between polls. ClientServer admission completes on the
665
- * monitor drains that the backend poll timer pumps, so a synchronous wait would starve the
666
- * admission it is waiting for and burn the whole bound before failing anyway. That is this
667
- * execution model's form of the hazard the JVM mirror avoids by not holding the admission
668
- * monitor across its sleep.
669
- */
695
+ /** Observes discovery changes until the client DEALER admission deadline. */
670
696
  async awaitClientDealerForOutbound(
671
697
  channelName: string,
672
- signal?: AbortSignal,
673
- deadlineAtMs?: number
698
+ signal?: AbortSignal
674
699
  ): Promise<ZLinkBackendDealerSocket | undefined> {
675
- const startedAtMs = performance.now();
676
- const deadline = Math.min(
677
- deadlineAtMs ??
678
- startedAtMs +
679
- (this.registration.channels.get(channelName)?.requestTimeoutMs ??
680
- this.registration.requestTimeoutMs ??
681
- DEFAULT_REQUEST_TIMEOUT_MS),
682
- startedAtMs + CLIENT_SERVER_READY_WAIT_CAP_MS
683
- );
684
- for (;;) {
685
- this.drainSocketMonitors();
700
+ throwIfAborted(signal);
701
+ const select = (): ZLinkBackendDealerSocket | undefined => {
686
702
  const dealer = this.clientDealerForOutbound(channelName);
687
703
  if (dealer !== undefined) return dealer;
688
- const remainingMs = deadline - performance.now();
689
- if (remainingMs <= 0) return undefined;
690
- throwIfAborted(signal);
691
- await new Promise<void>((resolve) => {
692
- setTimeout(resolve, Math.min(CLIENT_SERVER_READY_POLL_INTERVAL_MS, remainingMs));
693
- });
694
- }
704
+ if (this.clientServerDiscovery.hasReadyClientServer(channelName)) {
705
+ throw createInternalFrameworkException(
706
+ ZLinkFrameworkInternalErrorKind.RouteNotConnected,
707
+ `Channel '${channelName}' has no eligible ClientServer member.`
708
+ );
709
+ }
710
+ return undefined;
711
+ };
712
+ const dealer = select();
713
+ if (dealer !== undefined) return dealer;
714
+ const sendTimeoutMs = configuredSendTimeoutMs(
715
+ this.registration.channels.get(channelName)?.client?.sendTimeoutMs
716
+ );
717
+ return new Promise((resolve, reject) => {
718
+ const cleanup = (): void => {
719
+ clearTimeout(deadline);
720
+ unsubscribe();
721
+ signal?.removeEventListener('abort', abort);
722
+ };
723
+ const abort = (): void => {
724
+ cleanup();
725
+ reject(createAbortError());
726
+ };
727
+ const changed = (error?: Error): void => {
728
+ try {
729
+ if (error !== undefined) throw error;
730
+ const selected = select();
731
+ if (selected === undefined) return;
732
+ cleanup();
733
+ resolve(selected);
734
+ } catch (error) {
735
+ cleanup();
736
+ reject(error);
737
+ }
738
+ };
739
+ const unsubscribe = this.clientServerDiscovery.onClientServerChanged(changed);
740
+ const deadline = setTimeout(() => {
741
+ cleanup();
742
+ resolve(undefined);
743
+ }, sendTimeoutMs);
744
+ signal?.addEventListener('abort', abort, { once: true });
745
+ // Registration and selection share one event-loop turn; recheck after subscribing.
746
+ changed();
747
+ if (signal?.aborted === true) abort();
748
+ });
695
749
  }
696
750
 
697
751
  startManualClientServerConnections(): void {
@@ -726,26 +780,41 @@ export class ZLinkChannelSocketRegistry {
726
780
  }
727
781
  }
728
782
 
729
- clientServerMonitoringSource(channelName: string): ZLinkBackendSocketMonitor {
730
- if (this.registration.channels.get(channelName)?.client === undefined) {
731
- throw new ZLinkConfigurationException(`Channel client '${channelName}' is not registered.`);
783
+ clientServerMonitoringSource(channelName: string): ZLinkBackendSocketMonitor & {
784
+ onChange(handler: () => void): void;
785
+ } {
786
+ const channel = this.registration.channels.get(channelName);
787
+ if (channel?.client === undefined && channel?.server === undefined) {
788
+ throw new ZLinkConfigurationException(
789
+ `ClientServer channel '${channelName}' is not registered.`
790
+ );
732
791
  }
733
792
  let disposed = false;
734
- let handler: ((event: ZLinkBackendSocketMonitorEvent) => void) | undefined;
793
+ let handler: ((event?: ZLinkBackendSocketMonitorEvent) => void) | undefined;
794
+ const register = (next: (event?: ZLinkBackendSocketMonitorEvent) => void): void => {
795
+ if (disposed) return;
796
+ if (handler !== undefined) {
797
+ this.clientServerMonitorHandlers.get(channelName)?.delete(handler);
798
+ }
799
+ handler = next;
800
+ let handlers = this.clientServerMonitorHandlers.get(channelName);
801
+ if (handlers === undefined) {
802
+ handlers = new Set();
803
+ this.clientServerMonitorHandlers.set(channelName, handlers);
804
+ }
805
+ handlers.add(next);
806
+ };
735
807
  return {
736
808
  nativeInstance: {},
737
809
  onEvent: (next) => {
738
- if (disposed) return;
739
- if (handler !== undefined) {
740
- this.clientServerMonitorHandlers.get(channelName)?.delete(handler);
741
- }
742
- handler = next;
743
- let handlers = this.clientServerMonitorHandlers.get(channelName);
744
- if (handlers === undefined) {
745
- handlers = new Set();
746
- this.clientServerMonitorHandlers.set(channelName, handlers);
747
- }
748
- handlers.add(next);
810
+ register((event) => {
811
+ if (event !== undefined) next(event);
812
+ });
813
+ },
814
+ onChange: (next) => {
815
+ register((event) => {
816
+ if (event === undefined) next();
817
+ });
749
818
  },
750
819
  drain: () => 0,
751
820
  dispose: async () => {
@@ -790,10 +859,6 @@ export class ZLinkChannelSocketRegistry {
790
859
  );
791
860
  }
792
861
 
793
- hasKnownClientServerTargets(channelName: string): boolean {
794
- return this.clientServerDiscovery.clientServerDescriptors(channelName).length > 0;
795
- }
796
-
797
862
  fanoutActiveTargets(channelName: string) {
798
863
  return this.clientServerDiscovery.fanoutEndpoints(channelName);
799
864
  }
@@ -836,6 +901,11 @@ export class ZLinkChannelSocketRegistry {
836
901
  this.clientServerServerDescriptors.set(channelName, descriptor);
837
902
  this.pushClientServerDescriptorUpdate(channelName, descriptor);
838
903
  }
904
+ this.notifyClientServerTopology(channelName);
905
+ }
906
+
907
+ private notifyClientServerTopology(channelName: string): void {
908
+ for (const handler of this.clientServerMonitorHandlers.get(channelName) ?? []) handler();
839
909
  }
840
910
 
841
911
  tryHandleClientServerControl(
@@ -883,7 +953,7 @@ export class ZLinkChannelSocketRegistry {
883
953
  received.parts.length !== 1 ||
884
954
  received.replyToken === null
885
955
  ) {
886
- reply = encodeClientServerReject(1);
956
+ reply = encodeClientServerReject(ClientServerRejectReason.ProtocolVersionUnsupported);
887
957
  } else {
888
958
  const descriptor = this.clientServerServerDescriptors.get(channelName);
889
959
  if (
@@ -891,10 +961,10 @@ export class ZLinkChannelSocketRegistry {
891
961
  record.hello.channelName !== channelName ||
892
962
  record.hello.securityIdentity !== descriptor.securityIdentity
893
963
  ) {
894
- reply = encodeClientServerReject(3);
964
+ reply = encodeClientServerReject(ClientServerRejectReason.AdmissionMismatch);
895
965
  } else {
896
966
  const normalizedEffectiveMaxMessageBytes = Math.min(
897
- normalizedMessageLimit(router.maxMessageSize),
967
+ normalizeClientServerMessageLimit(router.maxMessageSize),
898
968
  record.hello.normalizedEffectiveMaxMessageBytes
899
969
  );
900
970
  reply = encodeClientServerAdmit(descriptor, normalizedEffectiveMaxMessageBytes);
@@ -929,7 +999,7 @@ export class ZLinkChannelSocketRegistry {
929
999
  this.drainClientServerControl(connectionId, connection);
930
1000
  if (connection.deadlineAt === undefined) continue;
931
1001
  if (nowMs >= connection.deadlineAt) {
932
- this.requestClientServerEndpointTermination(connectionId, connection);
1002
+ this.restartClientServerAdmission(connectionId, connection);
933
1003
  continue;
934
1004
  }
935
1005
  if (connection.nextProbeAt === undefined || nowMs < connection.nextProbeAt) continue;
@@ -980,23 +1050,31 @@ export class ZLinkChannelSocketRegistry {
980
1050
  );
981
1051
  }
982
1052
  const subscriber = this.adapter.createSubscriberSocket(this.context);
983
- subscriber.setChannelName(channelName);
984
- setFanoutSubscriptions(subscriber, channel.subscriptions);
985
- const monitor = this.monitoringAdapter.openSocketMonitor(subscriber);
986
1053
  const connection: FanoutPublisherConnection = {
987
1054
  channelName,
988
1055
  endpoint,
989
1056
  subscriber,
990
- monitor,
991
1057
  callbacks,
992
1058
  physicalConnectionId: Symbol(connectionId),
993
1059
  transportReady: false,
994
1060
  ready: false
995
1061
  };
996
- this.fanoutConnections.set(connectionId, connection);
997
- this.ownedMonitors.add(monitor);
998
- this.ensureClientServerLivenessTimer();
1062
+ this.ownedResources.add(subscriber);
1063
+ const created: (
1064
+ | ZLinkBackendSocketMonitor
1065
+ | ZLinkBackendReadablePoller
1066
+ | ZLinkBackendDealerSocket
1067
+ | ZLinkBackendSubscriberSocket
1068
+ )[] = [subscriber];
999
1069
  try {
1070
+ this.fanoutConnections.set(connectionId, connection);
1071
+ subscriber.setChannelName(channelName);
1072
+ setFanoutSubscriptions(subscriber, channel.subscriptions);
1073
+ const monitor = this.monitoringAdapter.openSocketMonitor(subscriber);
1074
+ connection.monitor = monitor;
1075
+ created.push(monitor);
1076
+ this.ownedResources.add(monitor);
1077
+ this.ensureClientServerLivenessTimer();
1000
1078
  monitor.onEvent((event) => {
1001
1079
  if (this.fanoutConnections.get(connectionId) !== connection) return;
1002
1080
  for (const handler of this.fanoutMonitorHandlers.get(channelName) ?? []) {
@@ -1020,28 +1098,36 @@ export class ZLinkChannelSocketRegistry {
1020
1098
  }
1021
1099
  });
1022
1100
  subscriber.connect(endpoint);
1101
+ return subscriber;
1023
1102
  } catch (error) {
1024
1103
  this.fanoutConnections.delete(connectionId);
1025
- this.ownedMonitors.delete(monitor);
1026
- void Promise.allSettled([monitor.dispose(), subscriber.dispose()]);
1104
+ void Promise.allSettled(
1105
+ created.map(async (resource) => {
1106
+ await resource.dispose();
1107
+ this.ownedResources.delete(resource);
1108
+ })
1109
+ ).then((results) => {
1110
+ for (const result of results)
1111
+ if (result.status === 'rejected') this.oneWayFailureSink?.(result.reason);
1112
+ });
1027
1113
  throw error;
1028
1114
  }
1029
- return subscriber;
1030
1115
  }
1031
1116
 
1032
1117
  async closeFanoutSubscriberConnection(connectionId: string): Promise<void> {
1033
1118
  const connection = this.fanoutConnections.get(connectionId);
1034
1119
  if (connection === undefined) return;
1035
- this.fanoutConnections.delete(connectionId);
1036
1120
  try {
1037
1121
  connection.subscriber.disconnect(connection.endpoint);
1038
1122
  } catch {
1039
- // Disposal remains the terminal cleanup path.
1123
+ // The socket close below releases an endpoint that is already disconnected.
1040
1124
  }
1041
- this.ownedMonitors.delete(connection.monitor);
1042
1125
  const results = await Promise.allSettled([
1043
- connection.monitor.dispose(),
1044
- connection.subscriber.dispose()
1126
+ connection.monitor?.dispose(),
1127
+ (async () => {
1128
+ await connection.subscriber.dispose();
1129
+ this.ownedResources.delete(connection.subscriber);
1130
+ })()
1045
1131
  ]);
1046
1132
  const errors = results
1047
1133
  .filter((result): result is PromiseRejectedResult => result.status === 'rejected')
@@ -1050,6 +1136,8 @@ export class ZLinkChannelSocketRegistry {
1050
1136
  if (errors.length > 1) {
1051
1137
  throw new AggregateError(errors, `Fanout connection '${connectionId}' cleanup failed.`);
1052
1138
  }
1139
+ this.fanoutConnections.delete(connectionId);
1140
+ if (connection.monitor !== undefined) this.ownedResources.delete(connection.monitor);
1053
1141
  }
1054
1142
 
1055
1143
  handleFanoutInbound(
@@ -1170,7 +1258,7 @@ export class ZLinkChannelSocketRegistry {
1170
1258
  };
1171
1259
  }
1172
1260
 
1173
- private notifyFanoutTopology(channelName: string): void {
1261
+ notifyFanoutTopology(channelName: string): void {
1174
1262
  for (const handler of this.fanoutTopologyHandlers.get(channelName) ?? []) {
1175
1263
  try {
1176
1264
  handler();
@@ -1298,9 +1386,8 @@ export class ZLinkChannelSocketRegistry {
1298
1386
  connectionId: string,
1299
1387
  connection: ClientServerPhysicalConnection
1300
1388
  ): void {
1301
- if (connection.terminationRequested) return;
1302
1389
  for (;;) {
1303
- if (!connection.readablePoller.wait(0)) return;
1390
+ if (connection.readablePoller === undefined || !connection.readablePoller.wait(0)) return;
1304
1391
  const received = connection.dealer.recv(1);
1305
1392
  if (received === undefined) {
1306
1393
  connection.readablePoller.markDrained();
@@ -1331,7 +1418,7 @@ export class ZLinkChannelSocketRegistry {
1331
1418
  }
1332
1419
  this.applyClientServerDescriptorUpdate(connectionId, connection, record.admission);
1333
1420
  } catch (error) {
1334
- this.requestClientServerEndpointTermination(connectionId, connection);
1421
+ this.restartClientServerAdmission(connectionId, connection);
1335
1422
  this.oneWayFailureSink?.(error);
1336
1423
  return;
1337
1424
  } finally {
@@ -1340,19 +1427,39 @@ export class ZLinkChannelSocketRegistry {
1340
1427
  }
1341
1428
  }
1342
1429
 
1343
- private requestClientServerEndpointTermination(
1430
+ /**
1431
+ * Ends the current logical admission of this connection: later replies of
1432
+ * the fenced attempt no longer apply and its ready target is withdrawn.
1433
+ */
1434
+ private endClientServerAdmission(
1344
1435
  connectionId: string,
1345
- connection: ClientServerPhysicalConnection
1436
+ connection: ClientServerPhysicalConnection,
1437
+ routingId: string | undefined,
1438
+ endpoint: string
1346
1439
  ): void {
1347
- if (connection.terminationRequested) return;
1348
- connection.terminationRequested = true;
1349
1440
  connection.physicalConnectionId = Symbol(connectionId);
1350
1441
  connection.admissionAttempt = undefined;
1351
- this.removeReadyConnection(connectionId);
1352
- try {
1353
- connection.dealer.disconnect(connection.endpoint);
1354
- } catch (error) {
1355
- this.oneWayFailureSink?.(error);
1442
+ if (connection.readyConnectionId !== undefined) {
1443
+ this.removeReadyConnection(connection.readyConnectionId);
1444
+ }
1445
+ for (const callbacks of [...connection.callbacksByAlias.values()]) {
1446
+ callbacks.onTerminated(routingId, endpoint);
1447
+ }
1448
+ }
1449
+
1450
+ /**
1451
+ * A peer deadline or an invalid pushed control ends only the current logical
1452
+ * admission. The connect intent stays with Core, which owns the endpoint
1453
+ * reconnect (transport liveness §6); the service handshake starts again on
1454
+ * the existing admission path.
1455
+ */
1456
+ private restartClientServerAdmission(
1457
+ connectionId: string,
1458
+ connection: ClientServerPhysicalConnection
1459
+ ): void {
1460
+ this.endClientServerAdmission(connectionId, connection, undefined, connection.endpoint);
1461
+ for (const callbacks of [...connection.callbacksByAlias.values()]) {
1462
+ callbacks.onTransportReady('', connection.endpoint);
1356
1463
  }
1357
1464
  }
1358
1465
 
@@ -1412,12 +1519,15 @@ export class ZLinkChannelSocketRegistry {
1412
1519
 
1413
1520
  private ensureClientServerLivenessTimer(): void {
1414
1521
  if (this.clientServerLivenessTimer !== undefined) return;
1415
- this.clientServerLivenessTimer = setInterval(() => this.tickClientServerLiveness(), 100);
1522
+ this.clientServerLivenessTimer = setInterval(
1523
+ () => this.tickClientServerLiveness(),
1524
+ CLIENT_SERVER_LIVENESS_TICK_MS
1525
+ );
1416
1526
  this.clientServerLivenessTimer.unref();
1417
1527
  }
1418
1528
 
1419
1529
  private drainSocketMonitors(): void {
1420
- for (const monitor of this.ownedMonitors) monitor.drain();
1530
+ for (const monitor of this.ownedResources) if ('drain' in monitor) monitor.drain();
1421
1531
  }
1422
1532
 
1423
1533
  private removeReadyConnection(connectionId: string): void {
@@ -1438,6 +1548,7 @@ export class ZLinkChannelSocketRegistry {
1438
1548
  connection.nextProbeAt = undefined;
1439
1549
  connection.outstandingProbeId = undefined;
1440
1550
  }
1551
+ this.notifyClientServerTopology(identity.channelName);
1441
1552
  }
1442
1553
 
1443
1554
  private requestClientServerLiveness(
@@ -1585,7 +1696,7 @@ export class ZLinkChannelSocketRegistry {
1585
1696
 
1586
1697
  private allocateClientServerProbeId(): bigint {
1587
1698
  const result = this.nextClientServerProbeId;
1588
- this.nextClientServerProbeId = result === 0xffff_ffff_ffff_ffffn ? 1n : result + 1n;
1699
+ this.nextClientServerProbeId = result === UINT64_MAX ? 1n : result + 1n;
1589
1700
  return result;
1590
1701
  }
1591
1702
 
@@ -1608,10 +1719,17 @@ export class ZLinkChannelSocketRegistry {
1608
1719
  }
1609
1720
 
1610
1721
  const publisher = this.adapter.createPublisherSocket(this.context);
1722
+ this.publishers.set(channelName, publisher);
1611
1723
  publisher.setChannelName(channelName);
1612
1724
  applyFanoutPublisherSocketOptions(publisher, channel);
1613
1725
  publisher.bind(channel.publisher.bind);
1614
- this.publishers.set(channelName, publisher);
1726
+ const endpoint = buildAdvertisedEndpoint(
1727
+ publisher.lastEndpoint ?? channel.publisher.bind,
1728
+ channel.publisher.advertiseHost
1729
+ );
1730
+ if (endpoint !== undefined && endpoint.length > 0) {
1731
+ this.recordListener('fanout', channelName, endpoint);
1732
+ }
1615
1733
  this.fanoutPublisherNextBeacon.set(
1616
1734
  channelName,
1617
1735
  performance.now() + CLIENT_SERVER_PROBE_INTERVAL_MS
@@ -1620,20 +1738,6 @@ export class ZLinkChannelSocketRegistry {
1620
1738
  return publisher;
1621
1739
  }
1622
1740
 
1623
- fanoutPublisherEndpoint(channelName: string): string | undefined {
1624
- const channel = this.registration.channels.get(channelName);
1625
- const publisher = this.publishers.get(channelName);
1626
- const boundEndpoint = publisher?.lastEndpoint;
1627
- if (
1628
- channel?.publisher === undefined ||
1629
- boundEndpoint === undefined ||
1630
- boundEndpoint.length === 0
1631
- ) {
1632
- return undefined;
1633
- }
1634
- return advertisedEndpoint(boundEndpoint, channel.publisher.advertiseHost);
1635
- }
1636
-
1637
1741
  routeRouter(routerChannelId: string): ZLinkBackendRouterSocket {
1638
1742
  const existing = this.routeRouters.get(routerChannelId);
1639
1743
  if (existing !== undefined) {
@@ -1647,6 +1751,7 @@ export class ZLinkChannelSocketRegistry {
1647
1751
  );
1648
1752
  }
1649
1753
  const router = this.adapter.createRouterSocket(this.context);
1754
+ this.routeRouters.set(routerChannelId, router);
1650
1755
  this.registerReceiveFlowSocket(router);
1651
1756
  router.setChannelName(routerChannelId);
1652
1757
  if (
@@ -1658,7 +1763,7 @@ export class ZLinkChannelSocketRegistry {
1658
1763
  router.setRoutingId(
1659
1764
  routeChannel.routingId ?? `${routeChannel.routingIdPrefix ?? routerChannelId}-${randomUUID()}`
1660
1765
  );
1661
- const publicWeight = routeChannel.weight ?? 100;
1766
+ const publicWeight = routeChannel.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
1662
1767
  this.routeMeshPublicWeights.set(routerChannelId, publicWeight);
1663
1768
  router.peerWeight = rawAvailabilityWeight(publicWeight);
1664
1769
  applySocketConfig(router, routeChannel);
@@ -1672,7 +1777,6 @@ export class ZLinkChannelSocketRegistry {
1672
1777
  if (routeChannel.bind !== undefined && routeChannel.bind.trim().length > 0) {
1673
1778
  router.bind(routeChannel.bind);
1674
1779
  }
1675
- this.routeRouters.set(routerChannelId, router);
1676
1780
  return router;
1677
1781
  }
1678
1782
 
@@ -1682,7 +1786,7 @@ export class ZLinkChannelSocketRegistry {
1682
1786
 
1683
1787
  routeMeshWeight(routerChannelId: string): number {
1684
1788
  this.routeRouter(routerChannelId);
1685
- return this.routeMeshPublicWeights.get(routerChannelId) ?? 100;
1789
+ return this.routeMeshPublicWeights.get(routerChannelId) ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
1686
1790
  }
1687
1791
 
1688
1792
  setRouteMeshWeight(routerChannelId: string, weight: number): void {
@@ -1719,7 +1823,7 @@ export class ZLinkChannelSocketRegistry {
1719
1823
  return;
1720
1824
  }
1721
1825
  const monitor = this.monitoringAdapter.openSocketMonitor(socket);
1722
- this.ownedMonitors.add(monitor);
1826
+ this.ownedResources.add(monitor);
1723
1827
  monitor.onEvent((event) => {
1724
1828
  if (
1725
1829
  event.nativeEvent === ZLinkSocketNativeEventType.Disconnected &&
@@ -1735,7 +1839,7 @@ export class ZLinkChannelSocketRegistry {
1735
1839
  return;
1736
1840
  }
1737
1841
  const monitor = this.monitoringAdapter.openSocketMonitor(router);
1738
- this.ownedMonitors.add(monitor);
1842
+ this.ownedResources.add(monitor);
1739
1843
  monitor.onEvent((event) => {
1740
1844
  const routingId = event.routingId === undefined ? undefined : String(event.routingId);
1741
1845
  if (
@@ -1777,7 +1881,7 @@ async function requestClientServerAdmission(
1777
1881
  encodeClientServerHello({
1778
1882
  channelName,
1779
1883
  securityIdentity,
1780
- normalizedEffectiveMaxMessageBytes: normalizedMessageLimit(dealer.maxMessageSize)
1884
+ normalizedEffectiveMaxMessageBytes: normalizeClientServerMessageLimit(dealer.maxMessageSize)
1781
1885
  })
1782
1886
  );
1783
1887
  try {
@@ -1855,9 +1959,9 @@ function setFanoutSubscriptions(
1855
1959
 
1856
1960
  function deriveRoutingId(baseRoutingId: string, suffix: string): string {
1857
1961
  const derived = `${baseRoutingId}\0${suffix}`;
1858
- if (Buffer.byteLength(derived, 'utf8') > 255) {
1962
+ if (Buffer.byteLength(derived, 'utf8') > ZLINK_MAX_ROUTING_ID_BYTES) {
1859
1963
  throw new ZLinkConfigurationException(
1860
- `Derived routing id with suffix '${suffix}' exceeds the 255 byte limit.`
1964
+ `Derived routing id with suffix '${suffix}' exceeds the ${ZLINK_MAX_ROUTING_ID_BYTES} byte limit.`
1861
1965
  );
1862
1966
  }
1863
1967
  return derived;
@@ -1868,6 +1972,7 @@ function applyFanoutPublisherSocketOptions(
1868
1972
  channel: ZLinkChannelOptions
1869
1973
  ): void {
1870
1974
  publisher.noDrop = channel.noDrop ?? false;
1975
+ publisher.sendTimeoutMs = configuredSendTimeoutMs(channel.publisher?.sendTimeoutMs);
1871
1976
  }
1872
1977
 
1873
1978
  function fanoutDiscoveryConnectionId(connectionId: string): string {
@@ -1891,13 +1996,11 @@ function advertisedEndpoint(boundEndpoint: string, advertiseHost: string | undef
1891
1996
  return result;
1892
1997
  }
1893
1998
 
1894
- function normalizedMessageLimit(value: number): number {
1895
- return Number.isSafeInteger(value) && value > 0 ? Math.min(value, 0xffff_ffff) : 0x7fff_ffff;
1896
- }
1897
-
1898
1999
  function requirePublicWeight(weight: number): void {
1899
- if (!Number.isInteger(weight) || weight < 0 || weight > 10_000) {
1900
- throw new ZLinkConfigurationException('Weight must be an integer in 0..10000.');
2000
+ if (!isValidPublicWeight(weight)) {
2001
+ throw new ZLinkConfigurationException(
2002
+ `Weight must be an integer in 0..${ZLINK_MAX_PUBLIC_WEIGHT}.`
2003
+ );
1901
2004
  }
1902
2005
  }
1903
2006
 
@@ -1933,3 +2036,7 @@ function applySocketConfig(
1933
2036
  socket.maxMessageSize = config.maxMessageSize;
1934
2037
  }
1935
2038
  }
2039
+
2040
+ function configuredSendTimeoutMs(value: number | undefined): number {
2041
+ return value ?? DEFAULT_SEND_TIMEOUT_MS;
2042
+ }