@zlink-systems/framework 0.26.0 → 0.28.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 (561) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Actors/ZLinkActorClient.d.ts +1 -1
  3. package/dist/contracts/Channels/Calls.d.ts +1 -1
  4. package/dist/contracts/Common/CoreTypes.d.ts +6 -0
  5. package/dist/contracts/Common/CoreTypes.js +7 -0
  6. package/dist/contracts/Common/index.d.ts +1 -1
  7. package/dist/contracts/Common/index.js +0 -1
  8. package/dist/contracts/Configuration/Builders.d.ts +0 -1
  9. package/dist/contracts/Configuration/Configs.d.ts +0 -1
  10. package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
  11. package/dist/contracts/Configuration/InternalDefaults.js +9 -1
  12. package/dist/contracts/Configuration/Registration.d.ts +13 -2
  13. package/dist/contracts/Configuration/Registration.js +58 -36
  14. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
  15. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
  16. package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
  17. package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
  18. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -5
  19. package/dist/contracts/Configuration/RegistrationValidators.js +15 -14
  20. package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
  21. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
  22. package/dist/contracts/Handlers/JsonContract.js +10 -4
  23. package/dist/contracts/Locations/Authority.d.ts +1 -1
  24. package/dist/contracts/Locations/Authority.js +3 -2
  25. package/dist/contracts/Locations/Options.js +1 -1
  26. package/dist/contracts/Locations/Stores.d.ts +12 -0
  27. package/dist/contracts/Locations/Stores.js +9 -0
  28. package/dist/contracts/Spots/Contracts.d.ts +2 -2
  29. package/dist/contracts/Streams/BoundSessionContracts.d.ts +1 -1
  30. package/dist/contracts/Streams/IZLinkSession.d.ts +2 -3
  31. package/dist/contracts/Streams/IZLinkSessionActor.d.ts +2 -2
  32. package/dist/internal.d.ts +4 -0
  33. package/dist/internal.js +15 -1
  34. package/dist/nest-integration.d.ts +4 -2
  35. package/dist/nest-integration.js +14 -4
  36. package/dist/runtime/abort.d.ts +1 -0
  37. package/dist/runtime/abort.js +8 -5
  38. package/dist/runtime/activation-admission.d.ts +1 -2
  39. package/dist/runtime/activation-admission.js +2 -6
  40. package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
  41. package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
  42. package/dist/runtime/actors/actor-client.d.ts +2 -2
  43. package/dist/runtime/actors/actor-client.js +49 -153
  44. package/dist/runtime/actors/actor-context.d.ts +3 -5
  45. package/dist/runtime/actors/actor-context.js +13 -11
  46. package/dist/runtime/actors/actor-handoff.d.ts +4 -4
  47. package/dist/runtime/actors/actor-handoff.js +8 -8
  48. package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
  49. package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
  50. package/dist/runtime/actors/actor-local-native-join.js +83 -105
  51. package/dist/runtime/actors/actor-native-lookup.js +2 -8
  52. package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
  53. package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
  54. package/dist/runtime/actors/actor-remote-joiner.d.ts +1 -1
  55. package/dist/runtime/actors/actor-remote-joiner.js +5 -9
  56. package/dist/runtime/actors/actor-remote-wire.js +5 -3
  57. package/dist/runtime/actors/actor-request-deadline.d.ts +1 -0
  58. package/dist/runtime/actors/actor-request-deadline.js +6 -0
  59. package/dist/runtime/actors/actor-retry-delay.js +2 -1
  60. package/dist/runtime/actors/actor-routed-join-transport.d.ts +2 -3
  61. package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
  62. package/dist/runtime/actors/actor-runtime-state.js +70 -187
  63. package/dist/runtime/actors/bound-session-wire.js +2 -7
  64. package/dist/runtime/actors/deferred-join-completion.d.ts +11 -6
  65. package/dist/runtime/actors/deferred-join-completion.js +1 -0
  66. package/dist/runtime/actors/index.d.ts +9 -7
  67. package/dist/runtime/actors/index.js +87 -69
  68. package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
  69. package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
  70. package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
  71. package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
  72. package/dist/runtime/admission.d.ts +2 -0
  73. package/dist/runtime/admission.js +7 -1
  74. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
  75. package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
  76. package/dist/runtime/backend/contracts/index.d.ts +7 -27
  77. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +1 -17
  78. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
  79. package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
  80. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -1
  81. package/dist/runtime/backend/node/node-backend-adapter-support.js +51 -10
  82. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  83. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +1 -2
  84. package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
  85. package/dist/runtime/backend/node/node-event-loop-poller.js +6 -7
  86. package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
  87. package/dist/runtime/backend/node/node-raw-binding-port.js +41 -34
  88. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +14 -15
  89. package/dist/runtime/backend/node/node-raw-mesh-backend.js +146 -118
  90. package/dist/runtime/backend/node/node-socket-backend-adapter.js +4 -3
  91. package/dist/runtime/backend/raw-binding-port.d.ts +1 -1
  92. package/dist/runtime/backend/runtime-values.d.ts +4 -1
  93. package/dist/runtime/backend/runtime-values.js +2 -0
  94. package/dist/runtime/channels/channel-clients.d.ts +20 -8
  95. package/dist/runtime/channels/channel-clients.js +73 -59
  96. package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
  97. package/dist/runtime/channels/channel-envelope.d.ts +1 -1
  98. package/dist/runtime/channels/channel-envelope.js +51 -39
  99. package/dist/runtime/channels/channel-outbound-operations.d.ts +5 -2
  100. package/dist/runtime/channels/channel-outbound-operations.js +25 -42
  101. package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
  102. package/dist/runtime/channels/channel-receive-loops.js +27 -6
  103. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
  104. package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
  105. package/dist/runtime/channels/channel-runtime-manager.d.ts +4 -4
  106. package/dist/runtime/channels/channel-runtime-manager.js +13 -10
  107. package/dist/runtime/channels/channel-socket-options.js +3 -12
  108. package/dist/runtime/channels/channel-socket-registry.d.ts +14 -29
  109. package/dist/runtime/channels/channel-socket-registry.js +240 -177
  110. package/dist/runtime/channels/channel-transports.d.ts +21 -31
  111. package/dist/runtime/channels/channel-transports.js +80 -62
  112. package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
  113. package/dist/runtime/channels/client-server-location-runtime.js +10 -11
  114. package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
  115. package/dist/runtime/channels/client-server-service-wire.js +32 -11
  116. package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
  117. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  118. package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
  119. package/dist/runtime/channels/fanout-location-runtime.js +130 -72
  120. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  121. package/dist/runtime/channels/local-spot-route-transport.js +1 -3
  122. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +1 -1
  123. package/dist/runtime/channels/router-socket-spot-route-transport.js +2 -2
  124. package/dist/runtime/channels/source-spot-router.d.ts +1 -1
  125. package/dist/runtime/channels/source-spot-router.js +2 -4
  126. package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
  127. package/dist/runtime/channels/spot-direct-envelope.js +4 -3
  128. package/dist/runtime/channels/spot-node-route-transport.d.ts +1 -1
  129. package/dist/runtime/channels/spot-node-route-transport.js +5 -5
  130. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +1 -1
  131. package/dist/runtime/channels/spot-route-bridge-transport.js +2 -2
  132. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +2 -4
  133. package/dist/runtime/channels/spot-route-dispatch-strategy.js +11 -12
  134. package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
  135. package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
  136. package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
  137. package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
  138. package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
  139. package/dist/runtime/diagnostics/flow-context.js +16 -2
  140. package/dist/runtime/diagnostics/index.d.ts +4 -2
  141. package/dist/runtime/diagnostics/index.js +14 -4
  142. package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
  143. package/dist/runtime/diagnostics/message-flow.js +10 -19
  144. package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
  145. package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
  146. package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
  147. package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
  148. package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
  149. package/dist/runtime/disposal.d.ts +5 -0
  150. package/dist/runtime/disposal.js +22 -0
  151. package/dist/runtime/execution/index.d.ts +12 -9
  152. package/dist/runtime/execution/index.js +58 -14
  153. package/dist/runtime/execution/serial-execution-queue.d.ts +8 -2
  154. package/dist/runtime/execution/serial-execution-queue.js +54 -15
  155. package/dist/runtime/execution/state-lane.d.ts +8 -1
  156. package/dist/runtime/execution/state-lane.js +118 -3
  157. package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
  158. package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
  159. package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
  160. package/dist/runtime/foundation/event-loop-resources.js +6 -119
  161. package/dist/runtime/foundation/operation-identity.d.ts +2 -0
  162. package/dist/runtime/foundation/operation-identity.js +9 -5
  163. package/dist/runtime/foundation/operation-registry.d.ts +5 -7
  164. package/dist/runtime/foundation/operation-registry.js +34 -44
  165. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +8 -5
  166. package/dist/runtime/foundation/raw-service-mesh-runtime.js +79 -94
  167. package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
  168. package/dist/runtime/foundation/runtime-state-projections.js +8 -0
  169. package/dist/runtime/foundation/service-authority-payload-codec.js +22 -12
  170. package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
  171. package/dist/runtime/foundation/service-discovery-registry.js +22 -3
  172. package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
  173. package/dist/runtime/foundation/service-liveness-registry.js +2 -1
  174. package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
  175. package/dist/runtime/foundation/service-maintenance-runtime.js +0 -6
  176. package/dist/runtime/foundation/service-metadata-codec.js +3 -3
  177. package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
  178. package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
  179. package/dist/runtime/foundation/service-relocation-object-owner.js +3 -2
  180. package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
  181. package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
  182. package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
  183. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -12
  184. package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
  185. package/dist/runtime/foundation/service-stateful-registry.js +10 -2
  186. package/dist/runtime/foundation/service-stateful-runtime.d.ts +26 -25
  187. package/dist/runtime/foundation/service-stateful-runtime.js +217 -204
  188. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -3
  189. package/dist/runtime/foundation/service-stateful-wire-codec.js +89 -55
  190. package/dist/runtime/foundation/service-topology-registry.d.ts +0 -1
  191. package/dist/runtime/foundation/service-topology-registry.js +17 -32
  192. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
  193. package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
  194. package/dist/runtime/foundation/service-wire-codec.js +10 -8
  195. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  196. package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
  197. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
  198. package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
  199. package/dist/runtime/framework-errors-internal.d.ts +2 -1
  200. package/dist/runtime/framework-errors-internal.js +343 -122
  201. package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
  202. package/dist/runtime/handlers/handler-instance-scope.js +61 -74
  203. package/dist/runtime/host/actor-packet-relay.d.ts +11 -8
  204. package/dist/runtime/host/actor-packet-relay.js +54 -99
  205. package/dist/runtime/host/actor-placement-coordinator.js +7 -5
  206. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
  207. package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
  208. package/dist/runtime/host/actor-transfer-runtime.d.ts +16 -18
  209. package/dist/runtime/host/actor-transfer-runtime.js +143 -176
  210. package/dist/runtime/host/application-job-queue.js +16 -33
  211. package/dist/runtime/host/bound-session-relay.js +1 -1
  212. package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
  213. package/dist/runtime/host/index.d.ts +14 -13
  214. package/dist/runtime/host/index.js +190 -171
  215. package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
  216. package/dist/runtime/host/instance-activation-authority.js +17 -45
  217. package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
  218. package/dist/runtime/host/location-runtime-owner.js +2 -2
  219. package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
  220. package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
  221. package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
  222. package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
  223. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
  224. package/dist/runtime/host/remote-bound-session-relay.js +15 -28
  225. package/dist/runtime/host/route-mesh-runtime.d.ts +13 -11
  226. package/dist/runtime/host/route-mesh-runtime.js +171 -252
  227. package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
  228. package/dist/runtime/host/runtime-shutdown.js +18 -21
  229. package/dist/runtime/host/service-relocation-control.js +6 -1
  230. package/dist/runtime/host/service-relocation-host-runtime.d.ts +21 -30
  231. package/dist/runtime/host/service-relocation-host-runtime.js +508 -416
  232. package/dist/runtime/host/spot-address-transport.d.ts +3 -12
  233. package/dist/runtime/host/spot-address-transport.js +78 -220
  234. package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
  235. package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
  236. package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -10
  237. package/dist/runtime/host/spot-runtime-options-factory.js +50 -14
  238. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -3
  239. package/dist/runtime/host/user-spot-creation-coordinator.js +11 -8
  240. package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
  241. package/dist/runtime/locations/authority-key-codec.js +4 -3
  242. package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
  243. package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
  244. package/dist/runtime/locations/creation-operation-id.js +6 -4
  245. package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
  246. package/dist/runtime/locations/in-memory-authority-store.js +31 -15
  247. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  248. package/dist/runtime/locations/in-memory-location-store.js +17 -14
  249. package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
  250. package/dist/runtime/locations/in-memory-provider-location-store.js +72 -22
  251. package/dist/runtime/locations/key-codec.js +3 -2
  252. package/dist/runtime/locations/lease-tracker.d.ts +3 -5
  253. package/dist/runtime/locations/lease-tracker.js +7 -11
  254. package/dist/runtime/locations/lifecycle.d.ts +4 -9
  255. package/dist/runtime/locations/lifecycle.js +2 -31
  256. package/dist/runtime/locations/location-store-failure.d.ts +2 -0
  257. package/dist/runtime/locations/location-store-failure.js +7 -0
  258. package/dist/runtime/locations/location-store-pages.d.ts +3 -0
  259. package/dist/runtime/locations/location-store-pages.js +13 -0
  260. package/dist/runtime/locations/location-store-repository.d.ts +5 -7
  261. package/dist/runtime/locations/location-store-repository.js +309 -336
  262. package/dist/runtime/locations/relocation-blob.js +18 -5
  263. package/dist/runtime/locations/resolvers.d.ts +5 -5
  264. package/dist/runtime/locations/resolvers.js +37 -28
  265. package/dist/runtime/locations/runtime.d.ts +5 -4
  266. package/dist/runtime/locations/runtime.js +123 -92
  267. package/dist/runtime/locations/spot-location-claims.d.ts +6 -0
  268. package/dist/runtime/locations/spot-location-claims.js +42 -1
  269. package/dist/runtime/messaging/payload-codec.js +26 -20
  270. package/dist/runtime/messaging/request-deadline.d.ts +3 -0
  271. package/dist/runtime/messaging/request-deadline.js +39 -0
  272. package/dist/runtime/messaging/submission-result.d.ts +4 -0
  273. package/dist/runtime/messaging/submission-result.js +56 -1
  274. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
  275. package/dist/runtime/protocol/service_wire_codec.generated.js +12 -7
  276. package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +4 -1
  277. package/dist/runtime/spots/index.d.ts +14 -20
  278. package/dist/runtime/spots/index.js +302 -176
  279. package/dist/runtime/spots/spot-activation-registry.d.ts +3 -5
  280. package/dist/runtime/spots/spot-activation-registry.js +14 -50
  281. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  282. package/dist/runtime/spots/spot-activation-state.js +2 -2
  283. package/dist/runtime/spots/spot-activation.d.ts +3 -4
  284. package/dist/runtime/spots/spot-activation.js +49 -32
  285. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
  286. package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
  287. package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
  288. package/dist/runtime/spots/spot-actor-join-dispatch.js +4 -52
  289. package/dist/runtime/spots/spot-actor-membership.d.ts +4 -6
  290. package/dist/runtime/spots/spot-actor-membership.js +22 -45
  291. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
  292. package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
  293. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
  294. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
  295. package/dist/runtime/spots/spot-context.d.ts +2 -2
  296. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -2
  297. package/dist/runtime/spots/spot-entry-activation.js +9 -20
  298. package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
  299. package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
  300. package/dist/runtime/spots/spot-manager-public.js +5 -4
  301. package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
  302. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -18
  303. package/dist/runtime/spots/spot-node-runtime-manager.js +67 -72
  304. package/dist/runtime/spots/spot-outbound.d.ts +7 -8
  305. package/dist/runtime/spots/spot-outbound.js +21 -23
  306. package/dist/runtime/spots/spot-remote-codec.js +5 -3
  307. package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
  308. package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
  309. package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
  310. package/dist/runtime/spots/spot-route-replies.js +3 -1
  311. package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -3
  312. package/dist/runtime/spots/spot-routed-actor-admission.js +3 -12
  313. package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +1 -2
  314. package/dist/runtime/spots/spot-routed-frame-dispatch.js +0 -1
  315. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
  316. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
  317. package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -16
  318. package/dist/runtime/spots/spot-serial-executor.js +2 -2
  319. package/dist/runtime/spots/spot-serial-turn-executor.d.ts +27 -7
  320. package/dist/runtime/spots/spot-serial-turn-executor.js +83 -11
  321. package/dist/runtime/spots/spot-timer.d.ts +3 -2
  322. package/dist/runtime/streams/actor-session-binding-registry.d.ts +16 -29
  323. package/dist/runtime/streams/actor-session-binding-registry.js +142 -212
  324. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -4
  325. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +8 -4
  326. package/dist/runtime/streams/bound-actor-relay-sender.js +65 -41
  327. package/dist/runtime/streams/bound-session-service.d.ts +7 -0
  328. package/dist/runtime/streams/bound-session-service.js +12 -2
  329. package/dist/runtime/streams/index.d.ts +16 -17
  330. package/dist/runtime/streams/index.js +22 -23
  331. package/dist/runtime/streams/managed-stream.d.ts +5 -2
  332. package/dist/runtime/streams/managed-stream.js +20 -13
  333. package/dist/runtime/streams/native-fallback-bound-session.js +14 -19
  334. package/dist/runtime/streams/protocol.d.ts +6 -33
  335. package/dist/runtime/streams/protocol.js +38 -110
  336. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
  337. package/dist/runtime/streams/session-actor-coordinator.js +12 -4
  338. package/dist/runtime/streams/session-calls.d.ts +6 -8
  339. package/dist/runtime/streams/session-calls.js +6 -22
  340. package/dist/runtime/streams/session-context.d.ts +10 -10
  341. package/dist/runtime/streams/session-context.js +25 -10
  342. package/dist/runtime/streams/session-requests.js +2 -1
  343. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
  344. package/dist/runtime/streams/stream-frame-factory.js +2 -2
  345. package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
  346. package/dist/runtime/streams/stream-session-runtime.js +25 -33
  347. package/dist/runtime/workers/index.d.ts +2 -2
  348. package/dist/runtime/workers/index.js +5 -4
  349. package/package.json +3 -3
  350. package/src/contracts/Actors/ZLinkActorClient.ts +1 -1
  351. package/src/contracts/Channels/Calls.ts +1 -1
  352. package/src/contracts/Common/CoreTypes.ts +7 -0
  353. package/src/contracts/Common/index.ts +1 -1
  354. package/src/contracts/Configuration/Builders.ts +0 -1
  355. package/src/contracts/Configuration/Configs.ts +0 -1
  356. package/src/contracts/Configuration/InternalDefaults.ts +12 -0
  357. package/src/contracts/Configuration/Registration.ts +92 -48
  358. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
  359. package/src/contracts/Configuration/RegistrationBuilders.ts +77 -71
  360. package/src/contracts/Configuration/RegistrationTypes.ts +1 -5
  361. package/src/contracts/Configuration/RegistrationValidators.ts +19 -17
  362. package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
  363. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
  364. package/src/contracts/Handlers/JsonContract.ts +14 -4
  365. package/src/contracts/Locations/Authority.ts +7 -3
  366. package/src/contracts/Locations/Options.ts +1 -1
  367. package/src/contracts/Locations/Stores.ts +14 -0
  368. package/src/contracts/Spots/Contracts.ts +2 -2
  369. package/src/contracts/Streams/BoundSessionContracts.ts +1 -1
  370. package/src/contracts/Streams/IZLinkSession.ts +2 -3
  371. package/src/contracts/Streams/IZLinkSessionActor.ts +2 -6
  372. package/src/internal.ts +14 -0
  373. package/src/nest-integration.ts +28 -10
  374. package/src/runtime/abort.ts +6 -5
  375. package/src/runtime/activation-admission.ts +2 -8
  376. package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
  377. package/src/runtime/actors/actor-client.ts +85 -218
  378. package/src/runtime/actors/actor-context.ts +39 -33
  379. package/src/runtime/actors/actor-handoff.ts +24 -22
  380. package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
  381. package/src/runtime/actors/actor-local-native-join.ts +172 -174
  382. package/src/runtime/actors/actor-native-lookup.ts +2 -9
  383. package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
  384. package/src/runtime/actors/actor-remote-joiner.ts +9 -11
  385. package/src/runtime/actors/actor-remote-wire.ts +5 -3
  386. package/src/runtime/actors/actor-request-deadline.ts +4 -0
  387. package/src/runtime/actors/actor-retry-delay.ts +2 -1
  388. package/src/runtime/actors/actor-routed-join-transport.ts +3 -5
  389. package/src/runtime/actors/actor-runtime-state.ts +85 -247
  390. package/src/runtime/actors/bound-session-wire.ts +2 -8
  391. package/src/runtime/actors/deferred-join-completion.ts +10 -6
  392. package/src/runtime/actors/index.ts +100 -79
  393. package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
  394. package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
  395. package/src/runtime/admission.ts +8 -1
  396. package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
  397. package/src/runtime/backend/contracts/index.ts +14 -37
  398. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -18
  399. package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
  400. package/src/runtime/backend/node/node-backend-adapter-support.ts +67 -10
  401. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +0 -2
  402. package/src/runtime/backend/node/node-event-loop-poller.ts +8 -12
  403. package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
  404. package/src/runtime/backend/node/node-raw-binding-port.ts +44 -49
  405. package/src/runtime/backend/node/node-raw-mesh-backend.ts +227 -170
  406. package/src/runtime/backend/node/node-socket-backend-adapter.ts +4 -3
  407. package/src/runtime/backend/raw-binding-port.ts +1 -1
  408. package/src/runtime/backend/runtime-values.ts +4 -1
  409. package/src/runtime/channels/channel-clients.ts +139 -102
  410. package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
  411. package/src/runtime/channels/channel-envelope.ts +74 -57
  412. package/src/runtime/channels/channel-outbound-operations.ts +40 -55
  413. package/src/runtime/channels/channel-receive-loops.ts +39 -7
  414. package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
  415. package/src/runtime/channels/channel-runtime-manager.ts +12 -30
  416. package/src/runtime/channels/channel-socket-options.ts +8 -15
  417. package/src/runtime/channels/channel-socket-registry.ts +291 -196
  418. package/src/runtime/channels/channel-transports.ts +168 -145
  419. package/src/runtime/channels/client-server-location-runtime.ts +17 -17
  420. package/src/runtime/channels/client-server-service-wire.ts +40 -12
  421. package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
  422. package/src/runtime/channels/fanout-location-runtime.ts +172 -91
  423. package/src/runtime/channels/local-spot-route-transport.ts +1 -5
  424. package/src/runtime/channels/router-socket-spot-route-transport.ts +2 -6
  425. package/src/runtime/channels/source-spot-router.ts +2 -9
  426. package/src/runtime/channels/spot-direct-envelope.ts +1 -1
  427. package/src/runtime/channels/spot-node-route-transport.ts +7 -9
  428. package/src/runtime/channels/spot-route-bridge-transport.ts +5 -12
  429. package/src/runtime/channels/spot-route-dispatch-strategy.ts +11 -30
  430. package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
  431. package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
  432. package/src/runtime/diagnostics/flow-context.ts +16 -2
  433. package/src/runtime/diagnostics/index.ts +27 -17
  434. package/src/runtime/diagnostics/message-flow.ts +15 -25
  435. package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
  436. package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
  437. package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
  438. package/src/runtime/disposal.ts +19 -0
  439. package/src/runtime/execution/index.ts +60 -20
  440. package/src/runtime/execution/serial-execution-queue.ts +131 -18
  441. package/src/runtime/execution/state-lane.ts +142 -4
  442. package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
  443. package/src/runtime/foundation/event-loop-resources.ts +5 -122
  444. package/src/runtime/foundation/operation-identity.ts +11 -5
  445. package/src/runtime/foundation/operation-registry.ts +33 -50
  446. package/src/runtime/foundation/raw-service-mesh-runtime.ts +127 -125
  447. package/src/runtime/foundation/runtime-state-projections.ts +9 -1
  448. package/src/runtime/foundation/service-authority-payload-codec.ts +31 -13
  449. package/src/runtime/foundation/service-discovery-registry.ts +32 -3
  450. package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
  451. package/src/runtime/foundation/service-liveness-registry.ts +2 -1
  452. package/src/runtime/foundation/service-maintenance-runtime.ts +0 -10
  453. package/src/runtime/foundation/service-metadata-codec.ts +2 -2
  454. package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
  455. package/src/runtime/foundation/service-relocation-object-owner.ts +5 -2
  456. package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
  457. package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
  458. package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -17
  459. package/src/runtime/foundation/service-stateful-registry.ts +14 -2
  460. package/src/runtime/foundation/service-stateful-runtime.ts +322 -276
  461. package/src/runtime/foundation/service-stateful-wire-codec.ts +128 -80
  462. package/src/runtime/foundation/service-topology-registry.ts +23 -32
  463. package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
  464. package/src/runtime/foundation/service-wire-codec.ts +15 -8
  465. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  466. package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
  467. package/src/runtime/framework-errors-internal.ts +380 -134
  468. package/src/runtime/handlers/handler-instance-scope.ts +68 -95
  469. package/src/runtime/host/actor-packet-relay.ts +63 -160
  470. package/src/runtime/host/actor-placement-coordinator.ts +8 -5
  471. package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
  472. package/src/runtime/host/actor-transfer-runtime.ts +180 -260
  473. package/src/runtime/host/application-job-queue.ts +28 -34
  474. package/src/runtime/host/bound-session-relay.ts +1 -2
  475. package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
  476. package/src/runtime/host/index.ts +327 -320
  477. package/src/runtime/host/instance-activation-authority.ts +89 -109
  478. package/src/runtime/host/location-runtime-owner.ts +4 -2
  479. package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
  480. package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
  481. package/src/runtime/host/remote-bound-session-relay.ts +16 -57
  482. package/src/runtime/host/route-mesh-runtime.ts +228 -271
  483. package/src/runtime/host/runtime-shutdown.ts +17 -21
  484. package/src/runtime/host/service-relocation-control.ts +14 -1
  485. package/src/runtime/host/service-relocation-host-runtime.ts +699 -561
  486. package/src/runtime/host/spot-address-transport.ts +175 -356
  487. package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
  488. package/src/runtime/host/spot-runtime-options-factory.ts +73 -22
  489. package/src/runtime/host/user-spot-creation-coordinator.ts +36 -22
  490. package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
  491. package/src/runtime/locations/authority-key-codec.ts +7 -3
  492. package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
  493. package/src/runtime/locations/creation-operation-id.ts +6 -3
  494. package/src/runtime/locations/domain-store-contract.ts +12 -3
  495. package/src/runtime/locations/in-memory-authority-store.ts +44 -15
  496. package/src/runtime/locations/in-memory-location-store.ts +50 -39
  497. package/src/runtime/locations/in-memory-provider-location-store.ts +100 -25
  498. package/src/runtime/locations/key-codec.ts +3 -2
  499. package/src/runtime/locations/lease-tracker.ts +8 -14
  500. package/src/runtime/locations/lifecycle.ts +13 -43
  501. package/src/runtime/locations/location-store-failure.ts +4 -0
  502. package/src/runtime/locations/location-store-pages.ts +18 -0
  503. package/src/runtime/locations/location-store-repository.ts +457 -482
  504. package/src/runtime/locations/relocation-blob.ts +17 -6
  505. package/src/runtime/locations/resolvers.ts +75 -49
  506. package/src/runtime/locations/runtime.ts +220 -110
  507. package/src/runtime/locations/spot-location-claims.ts +58 -1
  508. package/src/runtime/messaging/payload-codec.ts +35 -24
  509. package/src/runtime/messaging/request-deadline.ts +58 -0
  510. package/src/runtime/messaging/submission-result.ts +72 -2
  511. package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
  512. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
  513. package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +4 -1
  514. package/src/runtime/spots/index.ts +433 -229
  515. package/src/runtime/spots/spot-activation-registry.ts +30 -69
  516. package/src/runtime/spots/spot-activation-state.ts +2 -2
  517. package/src/runtime/spots/spot-activation.ts +67 -37
  518. package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
  519. package/src/runtime/spots/spot-actor-join-dispatch.ts +24 -77
  520. package/src/runtime/spots/spot-actor-membership.ts +40 -72
  521. package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
  522. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
  523. package/src/runtime/spots/spot-context.ts +3 -3
  524. package/src/runtime/spots/spot-entry-activation.ts +13 -30
  525. package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
  526. package/src/runtime/spots/spot-manager-public.ts +21 -17
  527. package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
  528. package/src/runtime/spots/spot-node-runtime-manager.ts +136 -125
  529. package/src/runtime/spots/spot-outbound.ts +59 -47
  530. package/src/runtime/spots/spot-remote-codec.ts +7 -3
  531. package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
  532. package/src/runtime/spots/spot-route-replies.ts +6 -4
  533. package/src/runtime/spots/spot-routed-actor-admission.ts +13 -26
  534. package/src/runtime/spots/spot-routed-frame-dispatch.ts +2 -3
  535. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
  536. package/src/runtime/spots/spot-runtime-ports.ts +5 -27
  537. package/src/runtime/spots/spot-serial-executor.ts +2 -2
  538. package/src/runtime/spots/spot-serial-turn-executor.ts +112 -11
  539. package/src/runtime/spots/spot-timer.ts +3 -2
  540. package/src/runtime/streams/actor-session-binding-registry.ts +179 -269
  541. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +0 -8
  542. package/src/runtime/streams/bound-actor-relay-sender.ts +98 -66
  543. package/src/runtime/streams/bound-session-service.ts +22 -2
  544. package/src/runtime/streams/index.ts +78 -68
  545. package/src/runtime/streams/managed-stream.ts +32 -23
  546. package/src/runtime/streams/native-fallback-bound-session.ts +14 -28
  547. package/src/runtime/streams/protocol.ts +34 -88
  548. package/src/runtime/streams/session-actor-coordinator.ts +17 -5
  549. package/src/runtime/streams/session-calls.ts +11 -36
  550. package/src/runtime/streams/session-context.ts +60 -25
  551. package/src/runtime/streams/session-requests.ts +2 -1
  552. package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
  553. package/src/runtime/streams/stream-frame-factory.ts +2 -3
  554. package/src/runtime/streams/stream-session-runtime.ts +57 -59
  555. package/src/runtime/workers/index.ts +13 -12
  556. package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
  557. package/dist/runtime/actors/post-commit-actor-location.js +0 -72
  558. package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
  559. package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
  560. package/src/runtime/actors/post-commit-actor-location.ts +0 -121
  561. package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
@@ -1,43 +1,58 @@
1
- import { ZLinkListenerRecords } from '../foundation/listener-records';
1
+ import { RuntimeDisposal } from '../disposal';
2
+ import { UINT64_MAX } from '@zlink-systems/stream-wire';
3
+ import { randomBytes, randomUUID } from 'node:crypto';
2
4
  import {
3
5
  ZLinkFrameworkRuntimeState,
4
6
  type RoutingId,
5
7
  type ZLinkClientServerServerDescriptor,
6
8
  type ZLinkFanoutPublisherDescriptor
7
9
  } from '../../contracts';
8
- import type { ZLinkChannelOptions } from '../../contracts/Configuration/RegistrationTypes';
9
- 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';
10
12
  import {
11
- buildAdvertisedEndpoint,
12
- ZLinkConfigurationException,
13
- type ZLinkFrameworkRegistration
14
- } 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';
15
20
  import type {
16
21
  ZLinkBackendContext,
17
22
  ZLinkBackendDealerSocket,
18
23
  ZLinkBackendPublisherSocket,
19
- ZLinkBackendRouterSocket,
20
24
  ZLinkBackendReadablePoller,
25
+ ZLinkBackendRouterSocket,
21
26
  ZLinkBackendSocketMonitor,
22
27
  ZLinkBackendSocketMonitorEvent,
23
28
  ZLinkBackendSubscriberSocket,
24
29
  ZLinkChannelBackendAdapter,
25
30
  ZLinkMonitoringBackendAdapter
26
31
  } from '../backend/contracts';
27
- import { throwIfAborted } from '../abort';
28
- import { attachEndpointConnections } from '../../contracts/Configuration/RuntimeEndpointConnections';
29
- import { ZLinkRouteMemberSnapshot } from './route-member-snapshot';
30
- import {
31
- ZLinkFrameworkInternalErrorKind,
32
- createInternalFrameworkException
33
- } from '../framework-errors-internal';
34
- import { randomBytes, randomUUID } from 'node:crypto';
35
32
  import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
36
- import type { Message } from '../../contracts/Common/Message';
37
- 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';
38
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';
39
47
  import { ServiceWireProtocolError } from '../foundation/service-wire-m6a-codec';
40
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,
41
56
  decodeClientServerControl,
42
57
  encodeClientServerAdmit,
43
58
  encodeClientServerHello,
@@ -46,6 +61,7 @@ import {
46
61
  encodeClientServerReject,
47
62
  encodeClientServerUpdate,
48
63
  isClientServerControlFrame,
64
+ normalizeClientServerMessageLimit,
49
65
  type ZLinkClientServerAdmission
50
66
  } from './client-server-service-wire';
51
67
  import {
@@ -53,16 +69,13 @@ import {
53
69
  FANOUT_LIVENESS_TOPIC,
54
70
  inspectFanoutInbound
55
71
  } from './fanout-service-wire';
56
- import type { ZLinkChannelEnvelopeHeader } from './channel-envelope';
57
- import type { ApplicationJobQueue } from '../host/application-job-queue';
58
- import { isBackendRequestTimeoutError } from '../backend/runtime-values';
72
+ import { ZLinkRouteMemberSnapshot } from './route-member-snapshot';
59
73
 
60
74
  const MAX_LIFECYCLE_GENERATION = 0x7fff_ffff_ffff_ffffn;
61
- const CLIENT_SERVER_PROBE_INTERVAL_MS = 5_000;
62
- const CLIENT_SERVER_PEER_DEADLINE_MS = 15_000;
63
- const CLIENT_SERVER_READY_WAIT_CAP_MS = 5_000;
64
- const CLIENT_SERVER_READY_POLL_INTERVAL_MS = 5;
65
- 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;
66
79
 
67
80
  export interface ZLinkClientServerServerSocketIdentity {
68
81
  readonly serverRid: string;
@@ -81,8 +94,8 @@ interface ClientServerPhysicalConnection {
81
94
  readonly channelName: string;
82
95
  readonly endpoint: string;
83
96
  readonly dealer: ZLinkBackendDealerSocket;
84
- readonly readablePoller: ZLinkBackendReadablePoller;
85
- readonly monitor: ZLinkBackendSocketMonitor;
97
+ readablePoller?: ZLinkBackendReadablePoller;
98
+ monitor?: ZLinkBackendSocketMonitor;
86
99
  readonly aliases: Set<string>;
87
100
  readonly callbacksByAlias: Map<string, ZLinkClientServerConnectionCallbacks>;
88
101
  physicalConnectionId: symbol;
@@ -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,
@@ -184,10 +203,20 @@ export class ZLinkChannelSocketRegistry {
184
203
  this.listenerRecords = listenerRecords ?? new ZLinkListenerRecords();
185
204
  }
186
205
 
187
- async dispose(): Promise<void> {
206
+ dispose(): Promise<void> {
207
+ return this.disposal.run(() => this.disposeCore());
208
+ }
209
+
210
+ private async disposeCore(): Promise<void> {
211
+ this.clientServerDiscovery.dispose(
212
+ createInternalFrameworkException(
213
+ ZLinkFrameworkInternalErrorKind.RuntimeShutdown,
214
+ 'Channel sockets are shutting down.'
215
+ )
216
+ );
188
217
  const clientServerConnections = [...new Set(this.clientServerConnections.values())];
189
- const clientServerPollers = clientServerConnections.map(
190
- (connection) => connection.readablePoller
218
+ const clientServerPollers = clientServerConnections.flatMap((connection) =>
219
+ connection.readablePoller === undefined ? [] : [connection.readablePoller]
191
220
  );
192
221
  const sockets = [
193
222
  ...this.clientDealers.values(),
@@ -204,8 +233,6 @@ export class ZLinkChannelSocketRegistry {
204
233
  ...this.routeRouters.values()
205
234
  ]))
206
235
  this.unregisterReceiveFlowSocket(socket);
207
- this.clientDealers.clear();
208
- this.clientServerConnections.clear();
209
236
  this.clientServerReadyIdentities.clear();
210
237
  this.clientServerServerDescriptors.clear();
211
238
  this.clientServerPublicWeights.clear();
@@ -215,23 +242,37 @@ export class ZLinkChannelSocketRegistry {
215
242
  this.clientServerMonitorHandlers.clear();
216
243
  this.fanoutMonitorHandlers.clear();
217
244
  this.fanoutTopologyHandlers.clear();
218
- this.fanoutConnections.clear();
219
245
  this.fanoutPublisherNextBeacon.clear();
220
246
  if (this.clientServerLivenessTimer !== undefined) {
221
247
  clearInterval(this.clientServerLivenessTimer);
222
248
  this.clientServerLivenessTimer = undefined;
223
249
  }
224
- this.channelRouters.clear();
225
- this.publishers.clear();
226
- this.routeRouters.clear();
227
250
  this.routeMembers.clear();
228
- const monitors = [...this.ownedMonitors];
229
- this.ownedMonitors.clear();
230
- const cleanup = await Promise.allSettled([
231
- ...clientServerPollers.map((poller) => poller.dispose()),
232
- ...monitors.map((monitor) => monitor.dispose()),
233
- ...sockets.map((socket) => socket.dispose())
234
- ]);
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
+ );
235
276
  const errors = cleanup
236
277
  .filter((result): result is PromiseRejectedResult => result.status === 'rejected')
237
278
  .map((result) => result.reason);
@@ -252,13 +293,15 @@ export class ZLinkChannelSocketRegistry {
252
293
  }
253
294
 
254
295
  const dealer = this.adapter.createDealerSocket(this.context);
296
+ this.clientDealers.set(channelName, dealer);
255
297
  this.registerReceiveFlowSocket(dealer);
256
298
  dealer.setChannelName(channelName);
257
299
  if (channel?.routingId !== undefined && channel.routingId.length > 0) {
258
300
  dealer.setRoutingId(deriveRoutingId(channel.routingId, 'dealer'));
259
301
  }
260
- applySocketConfig(dealer, client);
261
- this.clientDealers.set(channelName, dealer);
302
+ applySocketConfig(dealer, {
303
+ ...client
304
+ });
262
305
  return dealer;
263
306
  }
264
307
 
@@ -279,6 +322,7 @@ export class ZLinkChannelSocketRegistry {
279
322
  }
280
323
 
281
324
  const router = this.adapter.createRouterSocket(this.context);
325
+ this.channelRouters.set(channelName, router);
282
326
  this.registerReceiveFlowSocket(router);
283
327
  router.setChannelName(channelName);
284
328
  const identity = this.clientServerIdentities.get(channelName) ?? {
@@ -287,14 +331,14 @@ export class ZLinkChannelSocketRegistry {
287
331
  };
288
332
  this.clientServerIdentities.set(channelName, identity);
289
333
  router.setRoutingId(identity.serverRid);
290
- const publicWeight = channel.server.weight ?? 100;
334
+ const publicWeight = channel.server.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
291
335
  this.clientServerPublicWeights.set(channelName, publicWeight);
292
336
  router.peerWeight = rawAvailabilityWeight(publicWeight);
293
337
  applySocketConfig(router, channel.server);
294
338
  router.bind(channel.server.bind);
295
339
  if (this.monitoringAdapter !== undefined) {
296
340
  const monitor = this.monitoringAdapter.openSocketMonitor(router);
297
- this.ownedMonitors.add(monitor);
341
+ this.ownedResources.add(monitor);
298
342
  monitor.onEvent((event) => {
299
343
  if (event.routingId === undefined) return;
300
344
  if (
@@ -310,7 +354,6 @@ export class ZLinkChannelSocketRegistry {
310
354
  this.clientServerAdmittedClients.get(channelName)?.delete(routingId);
311
355
  });
312
356
  }
313
- this.channelRouters.set(channelName, router);
314
357
  const endpoint = advertisedEndpoint(
315
358
  router.lastEndpoint ?? channel.server.bind,
316
359
  channel.server.advertiseHost
@@ -358,7 +401,7 @@ export class ZLinkChannelSocketRegistry {
358
401
 
359
402
  clientServerServerWeight(channelName: string): number {
360
403
  this.channelRouter(channelName);
361
- return this.clientServerPublicWeights.get(channelName) ?? 100;
404
+ return this.clientServerPublicWeights.get(channelName) ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
362
405
  }
363
406
 
364
407
  setClientServerServerWeight(channelName: string, weight: number): void {
@@ -390,46 +433,37 @@ export class ZLinkChannelSocketRegistry {
390
433
  throw new ZLinkConfigurationException(`Channel client '${channelName}' is not registered.`);
391
434
  }
392
435
  const dealer = this.adapter.createDealerSocket(this.context);
393
- this.registerReceiveFlowSocket(dealer);
394
- dealer.setChannelName(channelName);
395
- dealer.setRoutingId(`cs-client-${randomUUID()}`);
396
- applySocketConfig(dealer, client);
397
- const cleanupDealer = (): void => {
398
- this.unregisterReceiveFlowSocket(dealer);
399
- void Promise.allSettled([dealer.dispose()]);
400
- };
401
- let readablePoller: ZLinkBackendReadablePoller;
402
- try {
403
- readablePoller = this.adapter.createReadablePoller(dealer);
404
- } catch (error) {
405
- cleanupDealer();
406
- throw error;
407
- }
408
- let monitor: ZLinkBackendSocketMonitor;
409
- try {
410
- monitor = this.monitoringAdapter.openSocketMonitor(dealer);
411
- } catch (error) {
412
- try {
413
- readablePoller.dispose();
414
- } finally {
415
- cleanupDealer();
416
- }
417
- throw error;
418
- }
419
- this.ownedMonitors.add(monitor);
420
436
  const connection: ClientServerPhysicalConnection = {
421
437
  channelName,
422
438
  endpoint,
423
439
  dealer,
424
- readablePoller,
425
- monitor,
426
440
  aliases: new Set([connectionId]),
427
441
  callbacksByAlias: new Map([[connectionId, callbacks]]),
428
442
  physicalConnectionId: Symbol(connectionId)
429
443
  };
430
- this.clientServerConnections.set(connectionId, connection);
431
- this.ensureClientServerLivenessTimer();
444
+ this.ownedResources.add(dealer);
445
+ const created: (
446
+ | ZLinkBackendSocketMonitor
447
+ | ZLinkBackendReadablePoller
448
+ | ZLinkBackendDealerSocket
449
+ | ZLinkBackendSubscriberSocket
450
+ )[] = [dealer];
432
451
  try {
452
+ this.clientServerConnections.set(connectionId, connection);
453
+ this.registerReceiveFlowSocket(dealer);
454
+ dealer.setChannelName(channelName);
455
+ dealer.setRoutingId(`cs-client-${randomUUID()}`);
456
+ applySocketConfig(dealer, {
457
+ ...client
458
+ });
459
+ connection.readablePoller = this.adapter.createReadablePoller(dealer);
460
+ created.push(connection.readablePoller);
461
+ this.ownedResources.add(connection.readablePoller);
462
+ const monitor = this.monitoringAdapter.openSocketMonitor(dealer);
463
+ connection.monitor = monitor;
464
+ created.push(monitor);
465
+ this.ownedResources.add(monitor);
466
+ this.ensureClientServerLivenessTimer();
433
467
  monitor.onEvent((event) => {
434
468
  if (
435
469
  ![...connection.aliases].some(
@@ -464,24 +498,26 @@ export class ZLinkChannelSocketRegistry {
464
498
  }
465
499
  });
466
500
  dealer.connect(endpoint);
501
+ return dealer;
467
502
  } catch (error) {
468
503
  this.clientServerConnections.delete(connectionId);
469
- this.ownedMonitors.delete(monitor);
470
- try {
471
- readablePoller.dispose();
472
- } finally {
473
- cleanupDealer();
474
- void Promise.allSettled([monitor.dispose()]);
475
- }
504
+ this.unregisterReceiveFlowSocket(dealer);
505
+ void Promise.allSettled(
506
+ created.map(async (resource) => {
507
+ await resource.dispose();
508
+ this.ownedResources.delete(resource);
509
+ })
510
+ ).then((results) => {
511
+ for (const result of results)
512
+ if (result.status === 'rejected') this.oneWayFailureSink?.(result.reason);
513
+ });
476
514
  throw error;
477
515
  }
478
- return dealer;
479
516
  }
480
517
 
481
518
  async closeClientServerConnection(connectionId: string): Promise<void> {
482
519
  const current = this.clientServerConnections.get(connectionId);
483
520
  if (current === undefined) return;
484
- this.clientServerConnections.delete(connectionId);
485
521
  current.aliases.delete(connectionId);
486
522
  current.callbacksByAlias.delete(connectionId);
487
523
  const ready = this.clientServerReadyIdentities.get(connectionId);
@@ -507,8 +543,13 @@ export class ZLinkChannelSocketRegistry {
507
543
  });
508
544
  }
509
545
  }
510
- if (current.aliases.size > 0) return;
546
+ this.notifyClientServerTopology(current.channelName);
547
+ if (current.aliases.size > 0) {
548
+ this.clientServerConnections.delete(connectionId);
549
+ return;
550
+ }
511
551
  await this.disposeClientServerPhysical(connectionId, current);
552
+ this.clientServerConnections.delete(connectionId);
512
553
  }
513
554
 
514
555
  private async disposeClientServerPhysical(
@@ -518,12 +559,21 @@ export class ZLinkChannelSocketRegistry {
518
559
  try {
519
560
  current.dealer.disconnect(current.endpoint);
520
561
  } catch {
521
- // Disposal below is the terminal cleanup if the transport already closed.
562
+ // The socket close below releases an endpoint that is already disconnected.
522
563
  }
523
- this.ownedMonitors.delete(current.monitor);
524
564
  this.unregisterReceiveFlowSocket(current.dealer);
525
- current.readablePoller.dispose();
526
- const results = await Promise.allSettled([current.monitor.dispose(), current.dealer.dispose()]);
565
+ if (current.readablePoller !== undefined) {
566
+ current.readablePoller.dispose();
567
+ this.ownedResources.delete(current.readablePoller);
568
+ current.readablePoller = undefined;
569
+ }
570
+ const results = await Promise.allSettled([
571
+ current.monitor?.dispose(),
572
+ (async () => {
573
+ await current.dealer.dispose();
574
+ this.ownedResources.delete(current.dealer);
575
+ })()
576
+ ]);
527
577
  const errors = results
528
578
  .filter((result): result is PromiseRejectedResult => result.status === 'rejected')
529
579
  .map((result) => result.reason);
@@ -531,6 +581,7 @@ export class ZLinkChannelSocketRegistry {
531
581
  if (errors.length > 1) {
532
582
  throw new AggregateError(errors, `ClientServer connection '${connectionId}' cleanup failed.`);
533
583
  }
584
+ if (current.monitor !== undefined) this.ownedResources.delete(current.monitor);
534
585
  }
535
586
 
536
587
  admitClientServerConnection(
@@ -545,6 +596,7 @@ export class ZLinkChannelSocketRegistry {
545
596
  connection.readyConnectionId
546
597
  );
547
598
  if (admitted) connection.admittedDescriptor = descriptor;
599
+ this.notifyClientServerTopology(descriptor.channelName);
548
600
  return admitted;
549
601
  }
550
602
  const duplicateId = [...this.clientServerReadyIdentities].find(
@@ -582,6 +634,7 @@ export class ZLinkChannelSocketRegistry {
582
634
  connection.readyConnectionId = connectionId;
583
635
  connection.admittedDescriptor = descriptor;
584
636
  }
637
+ this.notifyClientServerTopology(descriptor.channelName);
585
638
  return admitted;
586
639
  }
587
640
 
@@ -605,6 +658,7 @@ export class ZLinkChannelSocketRegistry {
605
658
  connection.outstandingProbeId = undefined;
606
659
  }
607
660
  }
661
+ this.notifyClientServerTopology(channelName);
608
662
  return removed;
609
663
  }
610
664
 
@@ -636,52 +690,52 @@ export class ZLinkChannelSocketRegistry {
636
690
  return undefined;
637
691
  }
638
692
 
639
- /**
640
- * Resolves a ClientServer send target, waiting when the ready candidate set is still empty, as
641
- * `framework/doc/framework/common/spec/server/02-channel-transport/02-channel-messaging.ko.md` §3.2 requires: the call waits
642
- * at call time for a bounded period and then fails with no-target. The bound is the shorter of
643
- * the call's remaining deadline and five seconds, mirroring the .NET reference
644
- * `ZLinkClientServerClientRuntime.WaitForReadyAsync`. The wait lives here because this registry
645
- * owns ClientServer connections, admission and weighted selection. Sends have no per-call
646
- * timeout, so they use the Channel's request timeout.
647
- *
648
- * The wait only observes admission that is already in flight: it never opens or reconnects a
649
- * connection, so it cannot trigger the admission it waits for, and Framework startup keeps not
650
- * waiting for local ClientServer admission. It applies whenever nothing is selectable, including
651
- * candidate sets excluded by weight 0 or drain, because `selectClientServerDealer` filters the
652
- * same way the reference `SelectReady()` does.
653
- *
654
- * Every attempt yields to the event loop between polls. ClientServer admission completes on the
655
- * monitor drains that the backend poll timer pumps, so a synchronous wait would starve the
656
- * admission it is waiting for and burn the whole bound before failing anyway. That is this
657
- * execution model's form of the hazard the JVM mirror avoids by not holding the admission
658
- * monitor across its sleep.
659
- */
693
+ /** Observes discovery changes until a server is ready or the runtime closes. */
660
694
  async awaitClientDealerForOutbound(
661
695
  channelName: string,
662
- signal?: AbortSignal,
663
- deadlineAtMs?: number
696
+ signal?: AbortSignal
664
697
  ): Promise<ZLinkBackendDealerSocket | undefined> {
665
- const startedAtMs = performance.now();
666
- const deadline = Math.min(
667
- deadlineAtMs ??
668
- startedAtMs +
669
- (this.registration.channels.get(channelName)?.requestTimeoutMs ??
670
- this.registration.requestTimeoutMs ??
671
- DEFAULT_REQUEST_TIMEOUT_MS),
672
- startedAtMs + CLIENT_SERVER_READY_WAIT_CAP_MS
673
- );
674
- for (;;) {
675
- this.drainSocketMonitors();
698
+ throwIfAborted(signal);
699
+ const select = (): ZLinkBackendDealerSocket | undefined => {
676
700
  const dealer = this.clientDealerForOutbound(channelName);
677
701
  if (dealer !== undefined) return dealer;
678
- const remainingMs = deadline - performance.now();
679
- if (remainingMs <= 0) return undefined;
680
- throwIfAborted(signal);
681
- await new Promise<void>((resolve) => {
682
- setTimeout(resolve, Math.min(CLIENT_SERVER_READY_POLL_INTERVAL_MS, remainingMs));
683
- });
684
- }
702
+ if (this.clientServerDiscovery.hasReadyClientServer(channelName)) {
703
+ throw createInternalFrameworkException(
704
+ ZLinkFrameworkInternalErrorKind.RouteNotConnected,
705
+ `Channel '${channelName}' has no eligible ClientServer member.`
706
+ );
707
+ }
708
+ return undefined;
709
+ };
710
+ const dealer = select();
711
+ if (dealer !== undefined) return dealer;
712
+ return new Promise((resolve, reject) => {
713
+ const cleanup = (): void => {
714
+ unsubscribe();
715
+ signal?.removeEventListener('abort', abort);
716
+ };
717
+ const abort = (): void => {
718
+ cleanup();
719
+ reject(createAbortError());
720
+ };
721
+ const changed = (error?: Error): void => {
722
+ try {
723
+ if (error !== undefined) throw error;
724
+ const selected = select();
725
+ if (selected === undefined) return;
726
+ cleanup();
727
+ resolve(selected);
728
+ } catch (error) {
729
+ cleanup();
730
+ reject(error);
731
+ }
732
+ };
733
+ const unsubscribe = this.clientServerDiscovery.onClientServerChanged(changed);
734
+ signal?.addEventListener('abort', abort, { once: true });
735
+ // Registration and selection share one event-loop turn; recheck after subscribing.
736
+ changed();
737
+ if (signal?.aborted === true) abort();
738
+ });
685
739
  }
686
740
 
687
741
  startManualClientServerConnections(): void {
@@ -716,26 +770,41 @@ export class ZLinkChannelSocketRegistry {
716
770
  }
717
771
  }
718
772
 
719
- clientServerMonitoringSource(channelName: string): ZLinkBackendSocketMonitor {
720
- if (this.registration.channels.get(channelName)?.client === undefined) {
721
- throw new ZLinkConfigurationException(`Channel client '${channelName}' is not registered.`);
773
+ clientServerMonitoringSource(channelName: string): ZLinkBackendSocketMonitor & {
774
+ onChange(handler: () => void): void;
775
+ } {
776
+ const channel = this.registration.channels.get(channelName);
777
+ if (channel?.client === undefined && channel?.server === undefined) {
778
+ throw new ZLinkConfigurationException(
779
+ `ClientServer channel '${channelName}' is not registered.`
780
+ );
722
781
  }
723
782
  let disposed = false;
724
- let handler: ((event: ZLinkBackendSocketMonitorEvent) => void) | undefined;
783
+ let handler: ((event?: ZLinkBackendSocketMonitorEvent) => void) | undefined;
784
+ const register = (next: (event?: ZLinkBackendSocketMonitorEvent) => void): void => {
785
+ if (disposed) return;
786
+ if (handler !== undefined) {
787
+ this.clientServerMonitorHandlers.get(channelName)?.delete(handler);
788
+ }
789
+ handler = next;
790
+ let handlers = this.clientServerMonitorHandlers.get(channelName);
791
+ if (handlers === undefined) {
792
+ handlers = new Set();
793
+ this.clientServerMonitorHandlers.set(channelName, handlers);
794
+ }
795
+ handlers.add(next);
796
+ };
725
797
  return {
726
798
  nativeInstance: {},
727
799
  onEvent: (next) => {
728
- if (disposed) return;
729
- if (handler !== undefined) {
730
- this.clientServerMonitorHandlers.get(channelName)?.delete(handler);
731
- }
732
- handler = next;
733
- let handlers = this.clientServerMonitorHandlers.get(channelName);
734
- if (handlers === undefined) {
735
- handlers = new Set();
736
- this.clientServerMonitorHandlers.set(channelName, handlers);
737
- }
738
- handlers.add(next);
800
+ register((event) => {
801
+ if (event !== undefined) next(event);
802
+ });
803
+ },
804
+ onChange: (next) => {
805
+ register((event) => {
806
+ if (event === undefined) next();
807
+ });
739
808
  },
740
809
  drain: () => 0,
741
810
  dispose: async () => {
@@ -822,6 +891,11 @@ export class ZLinkChannelSocketRegistry {
822
891
  this.clientServerServerDescriptors.set(channelName, descriptor);
823
892
  this.pushClientServerDescriptorUpdate(channelName, descriptor);
824
893
  }
894
+ this.notifyClientServerTopology(channelName);
895
+ }
896
+
897
+ private notifyClientServerTopology(channelName: string): void {
898
+ for (const handler of this.clientServerMonitorHandlers.get(channelName) ?? []) handler();
825
899
  }
826
900
 
827
901
  tryHandleClientServerControl(
@@ -869,7 +943,7 @@ export class ZLinkChannelSocketRegistry {
869
943
  received.parts.length !== 1 ||
870
944
  received.replyToken === null
871
945
  ) {
872
- reply = encodeClientServerReject(1);
946
+ reply = encodeClientServerReject(ClientServerRejectReason.ProtocolVersionUnsupported);
873
947
  } else {
874
948
  const descriptor = this.clientServerServerDescriptors.get(channelName);
875
949
  if (
@@ -877,10 +951,10 @@ export class ZLinkChannelSocketRegistry {
877
951
  record.hello.channelName !== channelName ||
878
952
  record.hello.securityIdentity !== descriptor.securityIdentity
879
953
  ) {
880
- reply = encodeClientServerReject(3);
954
+ reply = encodeClientServerReject(ClientServerRejectReason.AdmissionMismatch);
881
955
  } else {
882
956
  const normalizedEffectiveMaxMessageBytes = Math.min(
883
- normalizedMessageLimit(router.maxMessageSize),
957
+ normalizeClientServerMessageLimit(router.maxMessageSize),
884
958
  record.hello.normalizedEffectiveMaxMessageBytes
885
959
  );
886
960
  reply = encodeClientServerAdmit(descriptor, normalizedEffectiveMaxMessageBytes);
@@ -966,23 +1040,31 @@ export class ZLinkChannelSocketRegistry {
966
1040
  );
967
1041
  }
968
1042
  const subscriber = this.adapter.createSubscriberSocket(this.context);
969
- subscriber.setChannelName(channelName);
970
- setFanoutSubscriptions(subscriber, channel.subscriptions);
971
- const monitor = this.monitoringAdapter.openSocketMonitor(subscriber);
972
1043
  const connection: FanoutPublisherConnection = {
973
1044
  channelName,
974
1045
  endpoint,
975
1046
  subscriber,
976
- monitor,
977
1047
  callbacks,
978
1048
  physicalConnectionId: Symbol(connectionId),
979
1049
  transportReady: false,
980
1050
  ready: false
981
1051
  };
982
- this.fanoutConnections.set(connectionId, connection);
983
- this.ownedMonitors.add(monitor);
984
- this.ensureClientServerLivenessTimer();
1052
+ this.ownedResources.add(subscriber);
1053
+ const created: (
1054
+ | ZLinkBackendSocketMonitor
1055
+ | ZLinkBackendReadablePoller
1056
+ | ZLinkBackendDealerSocket
1057
+ | ZLinkBackendSubscriberSocket
1058
+ )[] = [subscriber];
985
1059
  try {
1060
+ this.fanoutConnections.set(connectionId, connection);
1061
+ subscriber.setChannelName(channelName);
1062
+ setFanoutSubscriptions(subscriber, channel.subscriptions);
1063
+ const monitor = this.monitoringAdapter.openSocketMonitor(subscriber);
1064
+ connection.monitor = monitor;
1065
+ created.push(monitor);
1066
+ this.ownedResources.add(monitor);
1067
+ this.ensureClientServerLivenessTimer();
986
1068
  monitor.onEvent((event) => {
987
1069
  if (this.fanoutConnections.get(connectionId) !== connection) return;
988
1070
  for (const handler of this.fanoutMonitorHandlers.get(channelName) ?? []) {
@@ -1006,28 +1088,36 @@ export class ZLinkChannelSocketRegistry {
1006
1088
  }
1007
1089
  });
1008
1090
  subscriber.connect(endpoint);
1091
+ return subscriber;
1009
1092
  } catch (error) {
1010
1093
  this.fanoutConnections.delete(connectionId);
1011
- this.ownedMonitors.delete(monitor);
1012
- void Promise.allSettled([monitor.dispose(), subscriber.dispose()]);
1094
+ void Promise.allSettled(
1095
+ created.map(async (resource) => {
1096
+ await resource.dispose();
1097
+ this.ownedResources.delete(resource);
1098
+ })
1099
+ ).then((results) => {
1100
+ for (const result of results)
1101
+ if (result.status === 'rejected') this.oneWayFailureSink?.(result.reason);
1102
+ });
1013
1103
  throw error;
1014
1104
  }
1015
- return subscriber;
1016
1105
  }
1017
1106
 
1018
1107
  async closeFanoutSubscriberConnection(connectionId: string): Promise<void> {
1019
1108
  const connection = this.fanoutConnections.get(connectionId);
1020
1109
  if (connection === undefined) return;
1021
- this.fanoutConnections.delete(connectionId);
1022
1110
  try {
1023
1111
  connection.subscriber.disconnect(connection.endpoint);
1024
1112
  } catch {
1025
- // Disposal remains the terminal cleanup path.
1113
+ // The socket close below releases an endpoint that is already disconnected.
1026
1114
  }
1027
- this.ownedMonitors.delete(connection.monitor);
1028
1115
  const results = await Promise.allSettled([
1029
- connection.monitor.dispose(),
1030
- connection.subscriber.dispose()
1116
+ connection.monitor?.dispose(),
1117
+ (async () => {
1118
+ await connection.subscriber.dispose();
1119
+ this.ownedResources.delete(connection.subscriber);
1120
+ })()
1031
1121
  ]);
1032
1122
  const errors = results
1033
1123
  .filter((result): result is PromiseRejectedResult => result.status === 'rejected')
@@ -1036,6 +1126,8 @@ export class ZLinkChannelSocketRegistry {
1036
1126
  if (errors.length > 1) {
1037
1127
  throw new AggregateError(errors, `Fanout connection '${connectionId}' cleanup failed.`);
1038
1128
  }
1129
+ this.fanoutConnections.delete(connectionId);
1130
+ if (connection.monitor !== undefined) this.ownedResources.delete(connection.monitor);
1039
1131
  }
1040
1132
 
1041
1133
  handleFanoutInbound(
@@ -1156,7 +1248,7 @@ export class ZLinkChannelSocketRegistry {
1156
1248
  };
1157
1249
  }
1158
1250
 
1159
- private notifyFanoutTopology(channelName: string): void {
1251
+ notifyFanoutTopology(channelName: string): void {
1160
1252
  for (const handler of this.fanoutTopologyHandlers.get(channelName) ?? []) {
1161
1253
  try {
1162
1254
  handler();
@@ -1285,7 +1377,7 @@ export class ZLinkChannelSocketRegistry {
1285
1377
  connection: ClientServerPhysicalConnection
1286
1378
  ): void {
1287
1379
  for (;;) {
1288
- if (!connection.readablePoller.wait(0)) return;
1380
+ if (connection.readablePoller === undefined || !connection.readablePoller.wait(0)) return;
1289
1381
  const received = connection.dealer.recv(1);
1290
1382
  if (received === undefined) {
1291
1383
  connection.readablePoller.markDrained();
@@ -1417,12 +1509,15 @@ export class ZLinkChannelSocketRegistry {
1417
1509
 
1418
1510
  private ensureClientServerLivenessTimer(): void {
1419
1511
  if (this.clientServerLivenessTimer !== undefined) return;
1420
- this.clientServerLivenessTimer = setInterval(() => this.tickClientServerLiveness(), 100);
1512
+ this.clientServerLivenessTimer = setInterval(
1513
+ () => this.tickClientServerLiveness(),
1514
+ CLIENT_SERVER_LIVENESS_TICK_MS
1515
+ );
1421
1516
  this.clientServerLivenessTimer.unref();
1422
1517
  }
1423
1518
 
1424
1519
  private drainSocketMonitors(): void {
1425
- for (const monitor of this.ownedMonitors) monitor.drain();
1520
+ for (const monitor of this.ownedResources) if ('drain' in monitor) monitor.drain();
1426
1521
  }
1427
1522
 
1428
1523
  private removeReadyConnection(connectionId: string): void {
@@ -1443,6 +1538,7 @@ export class ZLinkChannelSocketRegistry {
1443
1538
  connection.nextProbeAt = undefined;
1444
1539
  connection.outstandingProbeId = undefined;
1445
1540
  }
1541
+ this.notifyClientServerTopology(identity.channelName);
1446
1542
  }
1447
1543
 
1448
1544
  private requestClientServerLiveness(
@@ -1590,7 +1686,7 @@ export class ZLinkChannelSocketRegistry {
1590
1686
 
1591
1687
  private allocateClientServerProbeId(): bigint {
1592
1688
  const result = this.nextClientServerProbeId;
1593
- this.nextClientServerProbeId = result === 0xffff_ffff_ffff_ffffn ? 1n : result + 1n;
1689
+ this.nextClientServerProbeId = result === UINT64_MAX ? 1n : result + 1n;
1594
1690
  return result;
1595
1691
  }
1596
1692
 
@@ -1613,10 +1709,10 @@ export class ZLinkChannelSocketRegistry {
1613
1709
  }
1614
1710
 
1615
1711
  const publisher = this.adapter.createPublisherSocket(this.context);
1712
+ this.publishers.set(channelName, publisher);
1616
1713
  publisher.setChannelName(channelName);
1617
1714
  applyFanoutPublisherSocketOptions(publisher, channel);
1618
1715
  publisher.bind(channel.publisher.bind);
1619
- this.publishers.set(channelName, publisher);
1620
1716
  const endpoint = buildAdvertisedEndpoint(
1621
1717
  publisher.lastEndpoint ?? channel.publisher.bind,
1622
1718
  channel.publisher.advertiseHost
@@ -1645,6 +1741,7 @@ export class ZLinkChannelSocketRegistry {
1645
1741
  );
1646
1742
  }
1647
1743
  const router = this.adapter.createRouterSocket(this.context);
1744
+ this.routeRouters.set(routerChannelId, router);
1648
1745
  this.registerReceiveFlowSocket(router);
1649
1746
  router.setChannelName(routerChannelId);
1650
1747
  if (
@@ -1656,7 +1753,7 @@ export class ZLinkChannelSocketRegistry {
1656
1753
  router.setRoutingId(
1657
1754
  routeChannel.routingId ?? `${routeChannel.routingIdPrefix ?? routerChannelId}-${randomUUID()}`
1658
1755
  );
1659
- const publicWeight = routeChannel.weight ?? 100;
1756
+ const publicWeight = routeChannel.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
1660
1757
  this.routeMeshPublicWeights.set(routerChannelId, publicWeight);
1661
1758
  router.peerWeight = rawAvailabilityWeight(publicWeight);
1662
1759
  applySocketConfig(router, routeChannel);
@@ -1670,7 +1767,6 @@ export class ZLinkChannelSocketRegistry {
1670
1767
  if (routeChannel.bind !== undefined && routeChannel.bind.trim().length > 0) {
1671
1768
  router.bind(routeChannel.bind);
1672
1769
  }
1673
- this.routeRouters.set(routerChannelId, router);
1674
1770
  return router;
1675
1771
  }
1676
1772
 
@@ -1680,7 +1776,7 @@ export class ZLinkChannelSocketRegistry {
1680
1776
 
1681
1777
  routeMeshWeight(routerChannelId: string): number {
1682
1778
  this.routeRouter(routerChannelId);
1683
- return this.routeMeshPublicWeights.get(routerChannelId) ?? 100;
1779
+ return this.routeMeshPublicWeights.get(routerChannelId) ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
1684
1780
  }
1685
1781
 
1686
1782
  setRouteMeshWeight(routerChannelId: string, weight: number): void {
@@ -1717,7 +1813,7 @@ export class ZLinkChannelSocketRegistry {
1717
1813
  return;
1718
1814
  }
1719
1815
  const monitor = this.monitoringAdapter.openSocketMonitor(socket);
1720
- this.ownedMonitors.add(monitor);
1816
+ this.ownedResources.add(monitor);
1721
1817
  monitor.onEvent((event) => {
1722
1818
  if (
1723
1819
  event.nativeEvent === ZLinkSocketNativeEventType.Disconnected &&
@@ -1733,7 +1829,7 @@ export class ZLinkChannelSocketRegistry {
1733
1829
  return;
1734
1830
  }
1735
1831
  const monitor = this.monitoringAdapter.openSocketMonitor(router);
1736
- this.ownedMonitors.add(monitor);
1832
+ this.ownedResources.add(monitor);
1737
1833
  monitor.onEvent((event) => {
1738
1834
  const routingId = event.routingId === undefined ? undefined : String(event.routingId);
1739
1835
  if (
@@ -1775,7 +1871,7 @@ async function requestClientServerAdmission(
1775
1871
  encodeClientServerHello({
1776
1872
  channelName,
1777
1873
  securityIdentity,
1778
- normalizedEffectiveMaxMessageBytes: normalizedMessageLimit(dealer.maxMessageSize)
1874
+ normalizedEffectiveMaxMessageBytes: normalizeClientServerMessageLimit(dealer.maxMessageSize)
1779
1875
  })
1780
1876
  );
1781
1877
  try {
@@ -1853,9 +1949,9 @@ function setFanoutSubscriptions(
1853
1949
 
1854
1950
  function deriveRoutingId(baseRoutingId: string, suffix: string): string {
1855
1951
  const derived = `${baseRoutingId}\0${suffix}`;
1856
- if (Buffer.byteLength(derived, 'utf8') > 255) {
1952
+ if (Buffer.byteLength(derived, 'utf8') > ZLINK_MAX_ROUTING_ID_BYTES) {
1857
1953
  throw new ZLinkConfigurationException(
1858
- `Derived routing id with suffix '${suffix}' exceeds the 255 byte limit.`
1954
+ `Derived routing id with suffix '${suffix}' exceeds the ${ZLINK_MAX_ROUTING_ID_BYTES} byte limit.`
1859
1955
  );
1860
1956
  }
1861
1957
  return derived;
@@ -1866,6 +1962,7 @@ function applyFanoutPublisherSocketOptions(
1866
1962
  channel: ZLinkChannelOptions
1867
1963
  ): void {
1868
1964
  publisher.noDrop = channel.noDrop ?? false;
1965
+ publisher.sendTimeoutMs = configuredSendTimeoutMs(channel.publisher?.sendTimeoutMs);
1869
1966
  }
1870
1967
 
1871
1968
  function fanoutDiscoveryConnectionId(connectionId: string): string {
@@ -1889,13 +1986,11 @@ function advertisedEndpoint(boundEndpoint: string, advertiseHost: string | undef
1889
1986
  return result;
1890
1987
  }
1891
1988
 
1892
- function normalizedMessageLimit(value: number): number {
1893
- return Number.isSafeInteger(value) && value > 0 ? Math.min(value, 0xffff_ffff) : 0x7fff_ffff;
1894
- }
1895
-
1896
1989
  function requirePublicWeight(weight: number): void {
1897
- if (!Number.isInteger(weight) || weight < 0 || weight > 10_000) {
1898
- throw new ZLinkConfigurationException('Weight must be an integer in 0..10000.');
1990
+ if (!isValidPublicWeight(weight)) {
1991
+ throw new ZLinkConfigurationException(
1992
+ `Weight must be an integer in 0..${ZLINK_MAX_PUBLIC_WEIGHT}.`
1993
+ );
1899
1994
  }
1900
1995
  }
1901
1996
 
@@ -1911,7 +2006,6 @@ function applySocketConfig(
1911
2006
  readonly sendHighWaterMark?: number;
1912
2007
  readonly receiveHighWaterMark?: number;
1913
2008
  readonly receiveTimeoutMs?: number;
1914
- readonly sendTimeoutMs?: number;
1915
2009
  readonly maxMessageSize?: number;
1916
2010
  }
1917
2011
  ): void {
@@ -1924,10 +2018,11 @@ function applySocketConfig(
1924
2018
  if (config.receiveTimeoutMs !== undefined) {
1925
2019
  socket.receiveTimeoutMs = config.receiveTimeoutMs;
1926
2020
  }
1927
- if (config.sendTimeoutMs !== undefined) {
1928
- socket.sendTimeoutMs = config.sendTimeoutMs;
1929
- }
1930
2021
  if (config.maxMessageSize !== undefined) {
1931
2022
  socket.maxMessageSize = config.maxMessageSize;
1932
2023
  }
1933
2024
  }
2025
+
2026
+ function configuredSendTimeoutMs(value: number | undefined): number {
2027
+ return value ?? DEFAULT_SEND_TIMEOUT_MS;
2028
+ }