@zlink-systems/framework 0.29.1 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/LICENSE +150 -68
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
  4. package/dist/contracts/Channels/Calls.d.ts +2 -1
  5. package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  7. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  8. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  9. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  10. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  11. package/dist/contracts/Configuration/index.d.ts +1 -1
  12. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  13. package/dist/contracts/Handlers/Attributes.js +7 -11
  14. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  15. package/dist/contracts/Handlers/JsonContract.js +4 -153
  16. package/dist/contracts/Spots/Contracts.d.ts +2 -1
  17. package/dist/internal.d.ts +1 -0
  18. package/dist/internal.js +3 -1
  19. package/dist/nest-integration.d.ts +1 -1
  20. package/dist/nest-integration.js +2 -1
  21. package/dist/runtime/actors/actor-client.d.ts +1 -1
  22. package/dist/runtime/actors/actor-client.js +14 -12
  23. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  24. package/dist/runtime/actors/actor-handoff.js +15 -7
  25. package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
  26. package/dist/runtime/actors/actor-local-native-join.js +9 -12
  27. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  28. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  29. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  30. package/dist/runtime/actors/index.d.ts +2 -1
  31. package/dist/runtime/actors/index.js +18 -6
  32. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  33. package/dist/runtime/admission.d.ts +1 -1
  34. package/dist/runtime/admission.js +15 -5
  35. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +9 -9
  36. package/dist/runtime/application-jobs/application-ingress-record-owner.js +45 -23
  37. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +5 -2
  38. package/dist/runtime/application-jobs/application-job-queue-scope.js +41 -21
  39. package/dist/runtime/application-jobs/contracts.d.ts +15 -2
  40. package/dist/runtime/backend/contracts/index.d.ts +27 -27
  41. package/dist/runtime/backend/mesh-completion-table.d.ts +15 -5
  42. package/dist/runtime/backend/mesh-completion-table.js +160 -50
  43. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
  44. package/dist/runtime/backend/mesh-dispatch-pump.js +53 -36
  45. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  46. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  47. package/dist/runtime/backend/node/node-backend-adapter-support.js +33 -31
  48. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  49. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  50. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  51. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  52. package/dist/runtime/backend/node/node-raw-binding-port.js +50 -25
  53. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +22 -16
  54. package/dist/runtime/backend/node/node-raw-mesh-backend.js +133 -149
  55. package/dist/runtime/backend/node/node-socket-backend-adapter.js +15 -10
  56. package/dist/runtime/backend/raw-binding-port.d.ts +10 -3
  57. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  58. package/dist/runtime/backend/runtime-message.js +5 -0
  59. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  60. package/dist/runtime/backend/runtime-values.js +2 -1
  61. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  62. package/dist/runtime/channels/channel-clients.js +58 -21
  63. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
  64. package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
  65. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  66. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  67. package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
  68. package/dist/runtime/channels/channel-dispatchers.js +27 -26
  69. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  70. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  71. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  72. package/dist/runtime/channels/channel-envelope.js +83 -8
  73. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  74. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  75. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  76. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  77. package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
  78. package/dist/runtime/channels/channel-runtime-manager.js +12 -12
  79. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  80. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  81. package/dist/runtime/channels/channel-transports.d.ts +18 -15
  82. package/dist/runtime/channels/channel-transports.js +48 -31
  83. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  84. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  85. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  86. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  87. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  88. package/dist/runtime/channels/source-spot-router.js +4 -4
  89. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  90. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  91. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  92. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  93. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  94. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  95. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  96. package/dist/runtime/diagnostics/message-flow.js +3 -3
  97. package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
  98. package/dist/runtime/execution/serial-execution-queue.js +1 -0
  99. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  100. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  101. package/dist/runtime/foundation/durable-service-request.js +98 -0
  102. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  103. package/dist/runtime/foundation/operation-identity.js +5 -1
  104. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +37 -6
  105. package/dist/runtime/foundation/raw-service-mesh-runtime.js +473 -220
  106. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  107. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  108. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  109. package/dist/runtime/foundation/service-mailbox.js +2 -1
  110. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
  111. package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
  112. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  113. package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
  114. package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
  115. package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -9
  116. package/dist/runtime/foundation/service-stateful-runtime.js +78 -126
  117. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -7
  118. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  119. package/dist/runtime/foundation/service-topology-registry.d.ts +16 -4
  120. package/dist/runtime/foundation/service-topology-registry.js +69 -30
  121. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
  122. package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
  123. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  124. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  125. package/dist/runtime/host/actor-packet-relay.js +7 -7
  126. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  127. package/dist/runtime/host/application-job-queue.d.ts +28 -9
  128. package/dist/runtime/host/application-job-queue.js +214 -50
  129. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  130. package/dist/runtime/host/entry-actor-runtime.js +4 -1
  131. package/dist/runtime/host/index.d.ts +7 -1
  132. package/dist/runtime/host/index.js +154 -126
  133. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  134. package/dist/runtime/host/instance-activation-authority.js +89 -25
  135. package/dist/runtime/host/remote-bound-session-relay.js +2 -18
  136. package/dist/runtime/host/route-mesh-runtime.js +1 -1
  137. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  138. package/dist/runtime/host/service-relocation-control.js +10 -4
  139. package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
  140. package/dist/runtime/host/service-relocation-host-runtime.js +215 -243
  141. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  142. package/dist/runtime/host/spot-address-transport.js +28 -14
  143. package/dist/runtime/host/spot-runtime-options-factory.js +3 -2
  144. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  145. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  146. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  147. package/dist/runtime/locations/actor-location-claims.js +34 -19
  148. package/dist/runtime/locations/domain-store-contract.d.ts +2 -2
  149. package/dist/runtime/locations/in-memory-authority-store.d.ts +4 -2
  150. package/dist/runtime/locations/in-memory-authority-store.js +80 -8
  151. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  152. package/dist/runtime/locations/in-memory-location-store.js +19 -3
  153. package/dist/runtime/locations/internal-location-contracts.d.ts +3 -0
  154. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  155. package/dist/runtime/locations/lifecycle.js +2 -5
  156. package/dist/runtime/locations/location-store-repository.d.ts +3 -2
  157. package/dist/runtime/locations/location-store-repository.js +165 -22
  158. package/dist/runtime/locations/resolvers.d.ts +2 -1
  159. package/dist/runtime/locations/resolvers.js +10 -1
  160. package/dist/runtime/locations/runtime.d.ts +1 -1
  161. package/dist/runtime/locations/runtime.js +24 -23
  162. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  163. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  164. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  165. package/dist/runtime/messaging/packet-name.js +8 -24
  166. package/dist/runtime/messaging/request-result.d.ts +2 -0
  167. package/dist/runtime/messaging/request-result.js +54 -0
  168. package/dist/runtime/messaging/submission-result.d.ts +2 -1
  169. package/dist/runtime/messaging/submission-result.js +7 -4
  170. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
  171. package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
  172. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
  173. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
  174. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +9 -2
  175. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
  176. package/dist/runtime/spots/index.d.ts +7 -3
  177. package/dist/runtime/spots/index.js +23 -16
  178. package/dist/runtime/spots/spot-activation.d.ts +3 -1
  179. package/dist/runtime/spots/spot-activation.js +21 -12
  180. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  181. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  182. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  183. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  184. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  185. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  186. package/dist/runtime/spots/spot-entry-activation.js +9 -3
  187. package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
  188. package/dist/runtime/spots/spot-handler-registry.js +18 -8
  189. package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
  190. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +2 -1
  191. package/dist/runtime/spots/spot-node-runtime-manager.js +4 -11
  192. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  193. package/dist/runtime/spots/spot-outbound.js +24 -15
  194. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  195. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  196. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  197. package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -1
  198. package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
  199. package/dist/runtime/spots/spot-timer.js +1 -0
  200. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  201. package/dist/runtime/streams/stream-session-runtime.js +14 -28
  202. package/package.json +3 -3
  203. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  204. package/src/contracts/Channels/Calls.ts +2 -1
  205. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  206. package/src/contracts/Configuration/Builders.ts +1 -2
  207. package/src/contracts/Configuration/Configs.ts +0 -6
  208. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  209. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  210. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  211. package/src/contracts/Configuration/index.ts +1 -6
  212. package/src/contracts/Handlers/Attributes.ts +14 -21
  213. package/src/contracts/Handlers/JsonContract.ts +8 -216
  214. package/src/contracts/Spots/Contracts.ts +2 -1
  215. package/src/internal.ts +1 -0
  216. package/src/nest-integration.ts +1 -0
  217. package/src/runtime/actors/actor-client.ts +40 -16
  218. package/src/runtime/actors/actor-handoff.ts +22 -8
  219. package/src/runtime/actors/actor-join-relocation.ts +1 -0
  220. package/src/runtime/actors/actor-local-native-join.ts +17 -26
  221. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  222. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  223. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  224. package/src/runtime/actors/index.ts +19 -5
  225. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  226. package/src/runtime/admission.ts +18 -5
  227. package/src/runtime/application-jobs/application-ingress-record-owner.ts +53 -27
  228. package/src/runtime/application-jobs/application-job-queue-scope.ts +56 -22
  229. package/src/runtime/application-jobs/contracts.ts +28 -2
  230. package/src/runtime/backend/contracts/index.ts +63 -32
  231. package/src/runtime/backend/mesh-completion-table.ts +175 -59
  232. package/src/runtime/backend/mesh-dispatch-pump.ts +59 -32
  233. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  234. package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -31
  235. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  236. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  237. package/src/runtime/backend/node/node-raw-binding-port.ts +73 -37
  238. package/src/runtime/backend/node/node-raw-mesh-backend.ts +209 -176
  239. package/src/runtime/backend/node/node-socket-backend-adapter.ts +32 -13
  240. package/src/runtime/backend/raw-binding-port.ts +18 -3
  241. package/src/runtime/backend/runtime-message.ts +6 -0
  242. package/src/runtime/backend/runtime-values.ts +1 -0
  243. package/src/runtime/channels/channel-clients.ts +90 -41
  244. package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
  245. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  246. package/src/runtime/channels/channel-dispatchers.ts +29 -27
  247. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  248. package/src/runtime/channels/channel-envelope.ts +133 -8
  249. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  250. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  251. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  252. package/src/runtime/channels/channel-runtime-manager.ts +29 -12
  253. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  254. package/src/runtime/channels/channel-transports.ts +128 -60
  255. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  256. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  257. package/src/runtime/channels/source-spot-router.ts +8 -4
  258. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  259. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  260. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  261. package/src/runtime/diagnostics/message-flow.ts +1 -1
  262. package/src/runtime/execution/serial-execution-queue.ts +2 -0
  263. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  264. package/src/runtime/foundation/durable-service-request.ts +137 -0
  265. package/src/runtime/foundation/operation-identity.ts +5 -1
  266. package/src/runtime/foundation/raw-service-mesh-runtime.ts +642 -253
  267. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  268. package/src/runtime/foundation/service-mailbox.ts +7 -1
  269. package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
  270. package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
  271. package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
  272. package/src/runtime/foundation/service-stateful-runtime.ts +128 -160
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -84
  274. package/src/runtime/foundation/service-topology-registry.ts +103 -42
  275. package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
  276. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  277. package/src/runtime/host/actor-packet-relay.ts +7 -0
  278. package/src/runtime/host/actor-runtime-options-factory.ts +14 -2
  279. package/src/runtime/host/application-job-queue.ts +249 -48
  280. package/src/runtime/host/entry-actor-runtime.ts +5 -0
  281. package/src/runtime/host/index.ts +224 -160
  282. package/src/runtime/host/instance-activation-authority.ts +132 -27
  283. package/src/runtime/host/remote-bound-session-relay.ts +2 -23
  284. package/src/runtime/host/route-mesh-runtime.ts +1 -1
  285. package/src/runtime/host/service-relocation-control.ts +11 -5
  286. package/src/runtime/host/service-relocation-host-runtime.ts +317 -291
  287. package/src/runtime/host/spot-address-transport.ts +49 -24
  288. package/src/runtime/host/spot-runtime-options-factory.ts +4 -0
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  290. package/src/runtime/locations/actor-location-claims.ts +52 -30
  291. package/src/runtime/locations/domain-store-contract.ts +6 -2
  292. package/src/runtime/locations/in-memory-authority-store.ts +113 -9
  293. package/src/runtime/locations/in-memory-location-store.ts +25 -3
  294. package/src/runtime/locations/internal-location-contracts.ts +4 -0
  295. package/src/runtime/locations/lifecycle.ts +8 -26
  296. package/src/runtime/locations/location-store-repository.ts +220 -15
  297. package/src/runtime/locations/resolvers.ts +25 -2
  298. package/src/runtime/locations/runtime.ts +28 -24
  299. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  300. package/src/runtime/messaging/packet-name.ts +5 -25
  301. package/src/runtime/messaging/request-result.ts +58 -0
  302. package/src/runtime/messaging/submission-result.ts +7 -3
  303. package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
  304. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  305. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +45 -23
  306. package/src/runtime/spots/index.ts +30 -2
  307. package/src/runtime/spots/spot-activation.ts +33 -10
  308. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  309. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  310. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  311. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  312. package/src/runtime/spots/spot-entry-activation.ts +12 -2
  313. package/src/runtime/spots/spot-handler-registry.ts +41 -8
  314. package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
  315. package/src/runtime/spots/spot-node-runtime-manager.ts +7 -12
  316. package/src/runtime/spots/spot-outbound.ts +36 -16
  317. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  318. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  319. package/src/runtime/spots/spot-runtime-ports.ts +3 -0
  320. package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
  321. package/src/runtime/spots/spot-timer.ts +5 -1
  322. package/src/runtime/streams/stream-session-runtime.ts +13 -30
@@ -4,6 +4,7 @@ exports.ZLinkChannelSocketRegistry = void 0;
4
4
  const disposal_1 = require("../disposal");
5
5
  const stream_wire_1 = require("@zlink-systems/stream-wire");
6
6
  const node_crypto_1 = require("node:crypto");
7
+ const zlink_1 = require("@zlink-systems/zlink");
7
8
  const contracts_1 = require("../../contracts");
8
9
  const CoreTypes_1 = require("../../contracts/Common/CoreTypes");
9
10
  const RegistrationBuilderPolicy_1 = require("../../contracts/Configuration/RegistrationBuilderPolicy");
@@ -46,7 +47,6 @@ class ZLinkChannelSocketRegistry {
46
47
  clientServerServerDescriptors = new Map();
47
48
  clientServerPublicWeights = new Map();
48
49
  routeMeshPublicWeights = new Map();
49
- clientServerAdmittedClients = new Map();
50
50
  clientServerServerPeers = new Map();
51
51
  disposal = new disposal_1.RuntimeDisposal();
52
52
  ownedResources = new Set();
@@ -83,8 +83,6 @@ class ZLinkChannelSocketRegistry {
83
83
  ...this.routeRouters.values()
84
84
  ];
85
85
  for (const socket of new Set([
86
- ...this.clientDealers.values(),
87
- ...clientServerConnections.map((value) => value.dealer),
88
86
  ...this.channelRouters.values(),
89
87
  ...this.routeRouters.values()
90
88
  ]))
@@ -93,7 +91,8 @@ class ZLinkChannelSocketRegistry {
93
91
  this.clientServerServerDescriptors.clear();
94
92
  this.clientServerPublicWeights.clear();
95
93
  this.routeMeshPublicWeights.clear();
96
- this.clientServerAdmittedClients.clear();
94
+ for (const peers of this.clientServerServerPeers.values())
95
+ peers.clear();
97
96
  this.clientServerServerPeers.clear();
98
97
  this.clientServerMonitorHandlers.clear();
99
98
  this.fanoutMonitorHandlers.clear();
@@ -152,7 +151,6 @@ class ZLinkChannelSocketRegistry {
152
151
  }
153
152
  const dealer = this.adapter.createDealerSocket(this.context);
154
153
  this.clientDealers.set(channelName, dealer);
155
- this.registerReceiveFlowSocket(dealer);
156
154
  dealer.setChannelName(channelName);
157
155
  if (channel?.routingId !== undefined && channel.routingId.length > 0) {
158
156
  dealer.setRoutingId(deriveRoutingId(channel.routingId, 'dealer'));
@@ -202,8 +200,7 @@ class ZLinkChannelSocketRegistry {
202
200
  event.nativeEvent !== internal_event_contracts_1.ZLinkSocketNativeEventType.HandshakeFailedAuth)
203
201
  return;
204
202
  const routingId = String(event.routingId);
205
- this.clientServerServerPeers.delete(clientServerServerPeerKey(channelName, routingId));
206
- this.clientServerAdmittedClients.get(channelName)?.delete(routingId);
203
+ this.clientServerServerPeers.get(channelName)?.delete(routingId);
207
204
  });
208
205
  }
209
206
  const endpoint = advertisedEndpoint(router.lastEndpoint ?? channel.server.bind, channel.server.advertiseHost);
@@ -278,7 +275,6 @@ class ZLinkChannelSocketRegistry {
278
275
  const created = [dealer];
279
276
  try {
280
277
  this.clientServerConnections.set(connectionId, connection);
281
- this.registerReceiveFlowSocket(dealer);
282
278
  dealer.setChannelName(channelName);
283
279
  dealer.setRoutingId(`cs-client-${(0, node_crypto_1.randomUUID)()}`);
284
280
  applySocketConfig(dealer, {
@@ -325,7 +321,6 @@ class ZLinkChannelSocketRegistry {
325
321
  }
326
322
  catch (error) {
327
323
  this.clientServerConnections.delete(connectionId);
328
- this.unregisterReceiveFlowSocket(dealer);
329
324
  void Promise.allSettled(created.map(async (resource) => {
330
325
  await resource.dispose();
331
326
  this.ownedResources.delete(resource);
@@ -375,7 +370,6 @@ class ZLinkChannelSocketRegistry {
375
370
  catch {
376
371
  // The socket close below releases an endpoint that is already disconnected.
377
372
  }
378
- this.unregisterReceiveFlowSocket(current.dealer);
379
373
  if (current.readablePoller !== undefined) {
380
374
  current.readablePoller.dispose();
381
375
  this.ownedResources.delete(current.readablePoller);
@@ -430,9 +424,8 @@ class ZLinkChannelSocketRegistry {
430
424
  const admitted = this.clientServerDiscovery.admitClientServer(descriptor, connectionId);
431
425
  if (admitted) {
432
426
  const now = performance.now();
433
- connection.nextProbeAt = now + CLIENT_SERVER_PROBE_INTERVAL_MS;
434
- connection.deadlineAt = now + CLIENT_SERVER_PEER_DEADLINE_MS;
435
- connection.outstandingProbeId = undefined;
427
+ connection.liveness = new service_liveness_registry_1.ServiceLivenessConnection(connectionId, now);
428
+ connection.dealer.receiveAdmission = connection.liveness;
436
429
  this.clientServerReadyIdentities.set(connectionId, {
437
430
  channelName: descriptor.channelName,
438
431
  serverRoutingId: descriptor.serverRoutingId,
@@ -451,9 +444,8 @@ class ZLinkChannelSocketRegistry {
451
444
  const connection = this.clientServerConnections.get(connectionId);
452
445
  if (connection?.readyConnectionId === connectionId) {
453
446
  connection.readyConnectionId = undefined;
454
- connection.deadlineAt = undefined;
455
- connection.nextProbeAt = undefined;
456
- connection.outstandingProbeId = undefined;
447
+ connection.liveness = undefined;
448
+ connection.dealer.receiveAdmission = undefined;
457
449
  }
458
450
  }
459
451
  this.notifyClientServerTopology(channelName);
@@ -657,7 +649,18 @@ class ZLinkChannelSocketRegistry {
657
649
  for (const handler of this.clientServerMonitorHandlers.get(channelName) ?? [])
658
650
  handler();
659
651
  }
660
- tryHandleClientServerControl(channelName, received, router) {
652
+ clientServerServerPeersForChannel(channelName) {
653
+ let peers = this.clientServerServerPeers.get(channelName);
654
+ if (peers === undefined) {
655
+ peers = new Map();
656
+ this.clientServerServerPeers.set(channelName, peers);
657
+ }
658
+ return peers;
659
+ }
660
+ tryHandleClientServerControl(channelName, received, router, peers = this.clientServerServerPeersForChannel(channelName)) {
661
+ const routingId = String(received.routingId);
662
+ const peer = peers.get(routingId);
663
+ peer?.liveness.recordReceived();
661
664
  if (received.parts.length === 0)
662
665
  return false;
663
666
  const first = received.parts[0];
@@ -674,8 +677,8 @@ class ZLinkChannelSocketRegistry {
674
677
  else if (record.kind === 'livenessAck' &&
675
678
  received.parts.length === 1 &&
676
679
  received.replyToken === null) {
677
- if (!this.acceptClientServerServerLivenessAck(channelName, String(received.routingId), record.probeId)) {
678
- this.reportStaleClientServerLivenessAck(channelName, String(received.routingId), record.probeId);
680
+ if (!this.acceptClientServerServerLivenessAck(peer, record.probeId)) {
681
+ this.reportStaleClientServerLivenessAck(channelName, routingId, record.probeId);
679
682
  }
680
683
  return true;
681
684
  }
@@ -694,7 +697,7 @@ class ZLinkChannelSocketRegistry {
694
697
  else {
695
698
  const normalizedEffectiveMaxMessageBytes = Math.min((0, client_server_service_wire_1.normalizeClientServerMessageLimit)(router.maxMessageSize), record.hello.normalizedEffectiveMaxMessageBytes);
696
699
  reply = (0, client_server_service_wire_1.encodeClientServerAdmit)(descriptor, normalizedEffectiveMaxMessageBytes);
697
- this.admitClientServerServerPeer(channelName, String(received.routingId), normalizedEffectiveMaxMessageBytes);
700
+ this.admitClientServerServerPeer(channelName, routingId, normalizedEffectiveMaxMessageBytes);
698
701
  }
699
702
  }
700
703
  }
@@ -704,7 +707,7 @@ class ZLinkChannelSocketRegistry {
704
707
  if (received.replyToken !== null) {
705
708
  const message = runtime_message_1.ZLinkBufferMessage.from(reply);
706
709
  try {
707
- router.reply(received.routingId, received.replyToken, message);
710
+ router.reply(routingId, received.replyToken, message);
708
711
  }
709
712
  finally {
710
713
  message.close();
@@ -720,37 +723,33 @@ class ZLinkChannelSocketRegistry {
720
723
  if (connectionId === undefined)
721
724
  continue;
722
725
  this.drainClientServerControl(connectionId, connection);
723
- if (connection.deadlineAt === undefined)
726
+ if (connection.liveness === undefined)
724
727
  continue;
725
- if (nowMs >= connection.deadlineAt) {
728
+ if (connection.liveness.isExpired(nowMs)) {
726
729
  this.restartClientServerAdmission(connectionId, connection);
727
730
  continue;
728
731
  }
729
- if (connection.nextProbeAt === undefined || nowMs < connection.nextProbeAt)
732
+ const probeId = connection.liveness.tryGetProbe(nowMs, () => this.allocateClientServerProbeId());
733
+ if (probeId === undefined)
730
734
  continue;
731
- connection.nextProbeAt = nowMs + CLIENT_SERVER_PROBE_INTERVAL_MS;
732
- const probeId = connection.outstandingProbeId ?? this.allocateClientServerProbeId();
733
- connection.outstandingProbeId = probeId;
734
735
  this.requestClientServerLiveness(connectionId, connection, probeId);
735
736
  }
736
- for (const [key, peer] of [...this.clientServerServerPeers]) {
737
- if (nowMs >= peer.deadlineAt) {
738
- this.clientServerServerPeers.delete(key);
739
- this.clientServerAdmittedClients.get(peer.channelName)?.delete(peer.routingId);
740
- try {
741
- this.channelRouters.get(peer.channelName)?.disconnectPeer(peer.routingId);
742
- }
743
- catch (error) {
744
- this.oneWayFailureSink?.(error);
737
+ for (const peers of this.clientServerServerPeers.values()) {
738
+ for (const [routingId, peer] of peers) {
739
+ if (peer.liveness.isExpired(nowMs)) {
740
+ peers.delete(routingId);
741
+ try {
742
+ this.channelRouters.get(peer.channelName)?.disconnectPeer(peer.routingId);
743
+ }
744
+ catch (error) {
745
+ this.oneWayFailureSink?.(error);
746
+ }
747
+ continue;
745
748
  }
746
- continue;
749
+ const probeId = peer.liveness.tryGetProbe(nowMs, () => this.allocateClientServerProbeId());
750
+ if (probeId !== undefined)
751
+ this.requestClientServerServerLiveness(peer, probeId);
747
752
  }
748
- if (nowMs < peer.nextProbeAt)
749
- continue;
750
- peer.nextProbeAt = nowMs + CLIENT_SERVER_PROBE_INTERVAL_MS;
751
- const probeId = peer.outstandingProbeId ?? this.allocateClientServerProbeId();
752
- peer.outstandingProbeId = probeId;
753
- this.requestClientServerServerLiveness(peer, probeId);
754
753
  }
755
754
  this.tickFanoutLiveness(nowMs);
756
755
  }
@@ -1040,6 +1039,7 @@ class ZLinkChannelSocketRegistry {
1040
1039
  }
1041
1040
  }
1042
1041
  drainClientServerControl(connectionId, connection) {
1042
+ const admission = connection.liveness;
1043
1043
  for (;;) {
1044
1044
  if (connection.readablePoller === undefined || !connection.readablePoller.wait(0))
1045
1045
  return;
@@ -1048,6 +1048,7 @@ class ZLinkChannelSocketRegistry {
1048
1048
  connection.readablePoller.markDrained();
1049
1049
  return;
1050
1050
  }
1051
+ admission?.recordReceived();
1051
1052
  try {
1052
1053
  if (received.parts.length !== 1 || !(0, client_server_service_wire_1.isClientServerControlFrame)(received.parts[0].data())) {
1053
1054
  throw new configuration_1.ZLinkConfigurationException(`ClientServer '${connection.channelName}' received an unsolicited application frame.`);
@@ -1164,13 +1165,13 @@ class ZLinkChannelSocketRegistry {
1164
1165
  if (connection.readyConnectionId === connectionId) {
1165
1166
  connection.readyConnectionId = undefined;
1166
1167
  }
1167
- connection.deadlineAt = undefined;
1168
- connection.nextProbeAt = undefined;
1169
- connection.outstandingProbeId = undefined;
1168
+ connection.liveness = undefined;
1169
+ connection.dealer.receiveAdmission = undefined;
1170
1170
  }
1171
1171
  this.notifyClientServerTopology(identity.channelName);
1172
1172
  }
1173
1173
  requestClientServerLiveness(connectionId, connection, probeId) {
1174
+ const admission = connection.liveness;
1174
1175
  const message = runtime_message_1.ZLinkBufferMessage.from((0, client_server_service_wire_1.encodeClientServerLivenessProbe)(probeId));
1175
1176
  void connection.dealer
1176
1177
  .request(message, CLIENT_SERVER_PEER_DEADLINE_MS)
@@ -1179,17 +1180,17 @@ class ZLinkChannelSocketRegistry {
1179
1180
  const current = this.clientServerConnections.get(connectionId);
1180
1181
  if (current === undefined ||
1181
1182
  current.physicalConnectionId !== connection.physicalConnectionId ||
1183
+ current.liveness !== admission ||
1182
1184
  parts.length !== 1)
1183
1185
  return;
1184
1186
  const record = (0, client_server_service_wire_1.decodeClientServerControl)(parts[0].data());
1185
1187
  if (record.kind !== 'livenessAck')
1186
1188
  return;
1187
- if (current.outstandingProbeId !== probeId || record.probeId !== probeId) {
1189
+ if (admission === undefined ||
1190
+ !admission.acknowledge(record.probeId, performance.now())) {
1188
1191
  this.reportStaleClientServerLivenessAck(connection.channelName, connectionId, record.probeId);
1189
1192
  return;
1190
1193
  }
1191
- current.outstandingProbeId = undefined;
1192
- current.deadlineAt = performance.now() + CLIENT_SERVER_PEER_DEADLINE_MS;
1193
1194
  }
1194
1195
  finally {
1195
1196
  closeMessages(parts);
@@ -1199,23 +1200,13 @@ class ZLinkChannelSocketRegistry {
1199
1200
  .finally(() => message.close());
1200
1201
  }
1201
1202
  admitClientServerServerPeer(channelName, routingId, normalizedEffectiveMaxMessageBytes) {
1202
- const key = clientServerServerPeerKey(channelName, routingId);
1203
- const now = performance.now();
1204
1203
  const peer = {
1205
1204
  channelName,
1206
1205
  routingId,
1207
- physicalConnectionId: Symbol(key),
1208
1206
  normalizedEffectiveMaxMessageBytes,
1209
- nextProbeAt: now + CLIENT_SERVER_PROBE_INTERVAL_MS,
1210
- deadlineAt: now + CLIENT_SERVER_PEER_DEADLINE_MS
1207
+ liveness: new service_liveness_registry_1.ServiceLivenessConnection(clientServerServerPeerKey(channelName, routingId), performance.now())
1211
1208
  };
1212
- this.clientServerServerPeers.set(key, peer);
1213
- let clients = this.clientServerAdmittedClients.get(channelName);
1214
- if (clients === undefined) {
1215
- clients = new Set();
1216
- this.clientServerAdmittedClients.set(channelName, clients);
1217
- }
1218
- clients.add(routingId);
1209
+ this.clientServerServerPeersForChannel(channelName).set(routingId, peer);
1219
1210
  this.ensureClientServerLivenessTimer();
1220
1211
  }
1221
1212
  requestClientServerServerLiveness(peer, probeId) {
@@ -1228,33 +1219,22 @@ class ZLinkChannelSocketRegistry {
1228
1219
  .catch((error) => this.oneWayFailureSink?.(error))
1229
1220
  .finally(() => message.close());
1230
1221
  }
1231
- acceptClientServerServerLivenessAck(channelName, routingId, probeId) {
1232
- const peer = this.clientServerServerPeers.get(clientServerServerPeerKey(channelName, routingId));
1233
- if (peer === undefined || peer.outstandingProbeId !== probeId)
1234
- return false;
1235
- peer.outstandingProbeId = undefined;
1236
- peer.deadlineAt = performance.now() + CLIENT_SERVER_PEER_DEADLINE_MS;
1237
- return true;
1222
+ acceptClientServerServerLivenessAck(peer, probeId) {
1223
+ return peer?.liveness.acknowledge(probeId, performance.now()) ?? false;
1238
1224
  }
1239
1225
  reportStaleClientServerLivenessAck(channelName, peer, probeId) {
1240
1226
  this.oneWayFailureSink?.((0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestProtocolError, `ClientServer '${channelName}' ignored stale or duplicate liveness ACK '${probeId}' from '${peer}'.`, false));
1241
1227
  }
1242
1228
  pushClientServerDescriptorUpdate(channelName, descriptor) {
1243
1229
  const router = this.channelRouters.get(channelName);
1244
- const clients = this.clientServerAdmittedClients.get(channelName);
1245
- if (router === undefined || clients === undefined)
1230
+ const peers = this.clientServerServerPeers.get(channelName);
1231
+ if (router === undefined || peers === undefined)
1246
1232
  return;
1247
- for (const routingId of [...clients]) {
1248
- const peer = this.clientServerServerPeers.get(clientServerServerPeerKey(channelName, routingId));
1249
- if (peer === undefined) {
1250
- clients.delete(routingId);
1251
- continue;
1252
- }
1233
+ for (const [routingId, peer] of peers) {
1253
1234
  const message = runtime_message_1.ZLinkBufferMessage.from((0, client_server_service_wire_1.encodeClientServerUpdate)(descriptor, peer.normalizedEffectiveMaxMessageBytes));
1254
1235
  void router
1255
1236
  .send(routingId, message)
1256
1237
  .catch((error) => {
1257
- clients.delete(routingId);
1258
1238
  this.oneWayFailureSink?.(error);
1259
1239
  })
1260
1240
  .finally(() => message.close());
@@ -1338,7 +1318,7 @@ class ZLinkChannelSocketRegistry {
1338
1318
  router.peerWeight = rawAvailabilityWeight(weight);
1339
1319
  }
1340
1320
  registerReceiveFlowSocket(socket) {
1341
- this.applicationJobQueue?.registerReceiveFlowTarget(socket, (state) => socket.setReceiveFlowState(state === 'paused' ? 1 : 0), this.oneWayFailureSink);
1321
+ this.applicationJobQueue?.registerReceiveFlowTarget(socket, (state) => socket.setReceiveFlowState(state === 'paused' ? zlink_1.ReceiveFlowState.PAUSED : zlink_1.ReceiveFlowState.RUNNING), this.oneWayFailureSink);
1342
1322
  }
1343
1323
  unregisterReceiveFlowSocket(socket) {
1344
1324
  this.applicationJobQueue?.unregisterReceiveFlowTarget(socket);
@@ -1463,7 +1443,7 @@ function deriveRoutingId(baseRoutingId, suffix) {
1463
1443
  }
1464
1444
  function applyFanoutPublisherSocketOptions(publisher, channel) {
1465
1445
  publisher.noDrop = channel.noDrop ?? false;
1466
- publisher.sendTimeoutMs = configuredSendTimeoutMs(channel.publisher?.sendTimeoutMs);
1446
+ publisher.sendTimeoutMs = channel.sendTimeoutMs ?? DEFAULT_SEND_TIMEOUT_MS;
1467
1447
  }
1468
1448
  function fanoutDiscoveryConnectionId(connectionId) {
1469
1449
  return `fanout:${connectionId.replaceAll('\0', '/')}`;
@@ -1506,6 +1486,3 @@ function applySocketConfig(socket, config) {
1506
1486
  socket.maxMessageSize = config.maxMessageSize;
1507
1487
  }
1508
1488
  }
1509
- function configuredSendTimeoutMs(value) {
1510
- return value ?? DEFAULT_SEND_TIMEOUT_MS;
1511
- }
@@ -11,7 +11,7 @@ import type { ZLinkSpotRoutedSendOptions, ZLinkSpotRoutedRequestOptions } from '
11
11
  import { type ZLinkChannelEnvelopeCodecRegistry } from './channel-envelope';
12
12
  export interface ZLinkChannelClientTransport {
13
13
  send(channelName: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): void | ZLinkSubmitResult | Promise<void | ZLinkSubmitResult>;
14
- request<TReply>(channelName: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<TReply>;
14
+ request<TReply>(channelName: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>, onAdmitted?: () => void): Promise<TReply>;
15
15
  tryPublish?(channelName: string, topic: string, packetName: string | undefined, event: unknown, metadata?: ReadonlyMap<string, string>): ZLinkSubmitResult;
16
16
  publish(channelName: string, topic: string, packetName: string | undefined, event: unknown, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): ZLinkSubmitResult | Promise<ZLinkSubmitResult>;
17
17
  }
@@ -22,9 +22,9 @@ export interface ZLinkSpotPublisherClientTransport {
22
22
  }
23
23
  export interface ZLinkRouteClientTransport {
24
24
  submit(routerChannelId: string, targetNodeRid: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): void | ZLinkSubmitResult | Promise<void | ZLinkSubmitResult>;
25
- request<TReply>(routerChannelId: string, targetNodeRid: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<TReply>;
25
+ request<TReply>(routerChannelId: string, targetNodeRid: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>, onAdmitted?: () => void): Promise<TReply>;
26
26
  submitToChannel(meshName: string, channelName: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): void | ZLinkSubmitResult | Promise<void | ZLinkSubmitResult>;
27
- requestToChannel<TReply>(meshName: string, channelName: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<TReply>;
27
+ requestToChannel<TReply>(meshName: string, channelName: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>, onAdmitted?: () => void): Promise<TReply>;
28
28
  sendToSpot?(spotRouteTarget: ZLinkSpotRouteTarget, message: unknown, options: {
29
29
  readonly packetName?: string;
30
30
  readonly metadata?: ReadonlyMap<string, string>;
@@ -33,24 +33,25 @@ export interface ZLinkRouteClientTransport {
33
33
  readonly packetName?: string;
34
34
  readonly timeoutMs?: number;
35
35
  readonly signal?: AbortSignal;
36
+ readonly onAdmitted?: () => void;
36
37
  readonly metadata?: ReadonlyMap<string, string>;
37
38
  }): Promise<TReply>;
38
39
  }
39
40
  interface ZLinkChannelTransportRuntime {
40
41
  send(channelName: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): Promise<ZLinkSubmitResult>;
41
- request<TReply>(channelName: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<TReply>;
42
+ request<TReply>(channelName: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>, onAdmitted?: () => void): Promise<TReply>;
42
43
  tryPublish(channelName: string, topic: string, packetName: string | undefined, event: unknown, metadata?: ReadonlyMap<string, string>): ZLinkSubmitResult;
43
44
  publish(channelName: string, topic: string, packetName: string | undefined, event: unknown, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<ZLinkSubmitResult>;
44
45
  canRouteChannel(routerChannelId: string): boolean;
45
46
  canRoutePacketChannel(routerChannelId: string): boolean;
46
47
  routeSubmit(routerChannelId: string, targetNodeRid: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): Promise<ZLinkSubmitResult>;
47
- routeRequest<TReply>(routerChannelId: string, targetNodeRid: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<TReply>;
48
+ routeRequest<TReply>(routerChannelId: string, targetNodeRid: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>, onAdmitted?: () => void): Promise<TReply>;
48
49
  routeSendToSpot(spotRouteTarget: ZLinkSpotRouteTarget, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): Promise<void>;
49
50
  routeSendFromSpotToSpot(sourceSpot: ZLinkBackendSpot, spotRouteTarget: ZLinkSpotRouteTarget, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): Promise<void>;
50
- routeRequestToSpot<TReply>(spotRouteTarget: ZLinkSpotRouteTarget, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<TReply>;
51
- routeRequestFromSpotToSpot<TReply>(sourceSpot: ZLinkBackendSpot, spotRouteTarget: ZLinkSpotRouteTarget, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal): Promise<TReply>;
52
- routeRequestRawFromSpotToSpot(sourceSpot: ZLinkBackendSpot, spotRouteTarget: ZLinkSpotRouteTarget, request: Message, timeoutMs: number | undefined, signal?: AbortSignal): Promise<readonly Message[]>;
53
- routeRequestRawToSpot(spotRouteTarget: ZLinkSpotRouteTarget, request: Message, timeoutMs: number | undefined, signal?: AbortSignal): Promise<readonly Message[]>;
51
+ routeRequestToSpot<TReply>(spotRouteTarget: ZLinkSpotRouteTarget, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>, onAdmitted?: () => void): Promise<TReply>;
52
+ routeRequestFromSpotToSpot<TReply>(sourceSpot: ZLinkBackendSpot, spotRouteTarget: ZLinkSpotRouteTarget, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, onAdmitted?: () => void): Promise<TReply>;
53
+ routeRequestRawFromSpotToSpot(sourceSpot: ZLinkBackendSpot, spotRouteTarget: ZLinkSpotRouteTarget, request: Message, timeoutMs: number | undefined, signal?: AbortSignal, onAdmitted?: () => void): Promise<readonly Message[]>;
54
+ routeRequestRawToSpot(spotRouteTarget: ZLinkSpotRouteTarget, request: Message, timeoutMs: number | undefined, signal?: AbortSignal, onAdmitted?: () => void): Promise<readonly Message[]>;
54
55
  }
55
56
  export declare class ZLinkRuntimeRouteTransport implements ZLinkRouteClientTransport {
56
57
  private readonly manager;
@@ -63,20 +64,20 @@ export declare class ZLinkRuntimeRouteTransport implements ZLinkRouteClientTrans
63
64
  private readonly flowCreationEnabled;
64
65
  private readonly outboundFlow;
65
66
  constructor(manager: () => ZLinkChannelTransportRuntime | undefined, routeChannelPredicate?: ((routerChannelId: string) => boolean) | undefined, meshRuntime?: (() => {
66
- readonly meshNode: (meshName: string) => ZLinkBackendMeshNode | undefined;
67
+ readonly meshNode?: (meshName: string) => ZLinkBackendMeshNode | undefined;
67
68
  readonly meshCompletionTable: (meshName: string) => ZLinkMeshCompletionTable | undefined;
68
69
  } | undefined) | undefined, codecs?: ZLinkChannelEnvelopeCodecRegistry | undefined, manualNodeTarget?: ((meshName: string, targetNodeRid: string) => boolean | undefined) | undefined, localNodeSubmit?: ((meshName: string, sourceNodeRid: string, parts: readonly MessageLike[]) => ZLinkSubmitResult) | undefined, metrics?: ZLinkRuntimeMetrics | undefined, flowCreationEnabled?: () => boolean, outboundFlow?: () => ZLinkMessageFlowTracer | undefined);
69
70
  canRouteChannel(routerChannelId: string): boolean;
70
71
  canRoutePacketChannel(routerChannelId: string): boolean;
71
- submit(meshName: string, targetNodeRid: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): Promise<ZLinkSubmitResult>;
72
- submitInfrastructure(meshName: string, targetNodeRid: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): Promise<ZLinkSubmitResult>;
72
+ submit(meshName: string, targetNodeRid: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): ZLinkSubmitResult | Promise<ZLinkSubmitResult>;
73
+ submitInfrastructure(meshName: string, targetNodeRid: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): ZLinkSubmitResult | Promise<ZLinkSubmitResult>;
73
74
  private submitNode;
74
- request<TReply>(meshName: string, targetNodeRid: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<TReply>;
75
+ request<TReply>(meshName: string, targetNodeRid: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>, onAdmitted?: () => void): Promise<TReply>;
75
76
  private requestScoped;
76
77
  private traceNodeRequest;
77
78
  submitToChannel(meshName: string, channelName: string, packetName: string | undefined, message: unknown, metadata?: ReadonlyMap<string, string>): Promise<ZLinkSubmitResult>;
78
79
  private submitToChannelScoped;
79
- requestToChannel<TReply>(meshName: string, channelName: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<TReply>;
80
+ requestToChannel<TReply>(meshName: string, channelName: string, packetName: string | undefined, request: unknown, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>, onAdmitted?: () => void): Promise<TReply>;
80
81
  private requestToChannelScoped;
81
82
  private submitRequestOperation;
82
83
  sendToSpot(spotRouteTarget: ZLinkSpotRouteTarget, message: unknown, options: ZLinkSpotRoutedSendOptions): Promise<ZLinkSubmitResult>;
@@ -91,19 +92,21 @@ export declare class ZLinkRuntimeRouteTransport implements ZLinkRouteClientTrans
91
92
  readonly packetName?: string;
92
93
  readonly timeoutMs?: number;
93
94
  readonly signal?: AbortSignal;
95
+ readonly onAdmitted?: () => void;
94
96
  }): Promise<TReply>;
95
97
  requestRawFromSpotToSpot(sourceSpot: ZLinkBackendSpot, spotRouteTarget: ZLinkSpotRouteTarget, request: Message, options: {
96
98
  readonly timeoutMs?: number;
97
99
  readonly signal?: AbortSignal;
100
+ readonly onAdmitted?: () => void;
98
101
  }): Promise<readonly Message[]>;
99
102
  requestRawToSpot(spotRouteTarget: ZLinkSpotRouteTarget, request: Message, options: {
100
103
  readonly timeoutMs?: number;
101
104
  readonly signal?: AbortSignal;
105
+ readonly onAdmitted?: () => void;
102
106
  }): Promise<readonly Message[]>;
103
107
  private requestRawToSpotScoped;
104
108
  private requireManager;
105
109
  private meshNode;
106
- private isSelfNode;
107
110
  private isKnownBackendPeer;
108
111
  private submitLocalNode;
109
112
  private requireMeshNode;
@@ -19,6 +19,7 @@ const framework_errors_internal_1 = require("../framework-errors-internal");
19
19
  const submission_result_1 = require("../messaging/submission-result");
20
20
  const routing_id_1 = require("../routing-id");
21
21
  const channel_envelope_1 = require("./channel-envelope");
22
+ const NON_BLOCKING_SEND_OPTIONS = Object.freeze({ flags: runtime_values_1.ZLINK_BACKEND_SEND_DONT_WAIT });
22
23
  class ZLinkRuntimeRouteTransport {
23
24
  manager;
24
25
  routeChannelPredicate;
@@ -52,15 +53,19 @@ class ZLinkRuntimeRouteTransport {
52
53
  this.routeChannelPredicate?.(routerChannelId) ??
53
54
  false);
54
55
  }
55
- async submit(meshName, targetNodeRid, packetName, message, metadata) {
56
+ submit(meshName, targetNodeRid, packetName, message, metadata) {
56
57
  // Call-scoped flow (spec 27 §4): the envelope flow pair lives only for
57
58
  // the duration of this outbound call, never in the caller's context.
58
- return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.submitNode(meshName, targetNodeRid, packetName, message, metadata, false));
59
+ if (!this.flowCreationEnabled())
60
+ return this.submitNode(meshName, targetNodeRid, packetName, message, metadata, false);
61
+ return (0, flow_context_1.runWithOutboundFlow)(true, () => this.submitNode(meshName, targetNodeRid, packetName, message, metadata, false));
59
62
  }
60
- async submitInfrastructure(meshName, targetNodeRid, packetName, message, metadata) {
61
- return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.submitNode(meshName, targetNodeRid, packetName, message, metadata, true));
63
+ submitInfrastructure(meshName, targetNodeRid, packetName, message, metadata) {
64
+ if (!this.flowCreationEnabled())
65
+ return this.submitNode(meshName, targetNodeRid, packetName, message, metadata, true);
66
+ return (0, flow_context_1.runWithOutboundFlow)(true, () => this.submitNode(meshName, targetNodeRid, packetName, message, metadata, true));
62
67
  }
63
- async submitNode(meshName, targetNodeRid, packetName, message, metadata, allowObjectClientTarget) {
68
+ submitNode(meshName, targetNodeRid, packetName, message, metadata, allowObjectClientTarget) {
64
69
  const node = this.meshNode(meshName);
65
70
  if (node === undefined) {
66
71
  return this.requireManager().routeSubmit(meshName, targetNodeRid, packetName, message, metadata);
@@ -70,28 +75,35 @@ class ZLinkRuntimeRouteTransport {
70
75
  return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
71
76
  }
72
77
  const parts = this.encodeMessage(3 /* ZLinkChannelMessageKind.Command */, meshName, packetName, message, undefined, metadata);
73
- const operation = `MeshNode '${meshName}' send to node '${targetNodeRid}'`;
74
- if (this.isSelfNode(node, targetNodeRid)) {
75
- return this.submitLocalNode(meshName, String(node.status().routingId), parts);
78
+ const sourceNodeRid = node.routingId ?? node.status().routingId;
79
+ if ((0, routing_id_1.routingIdsEqual)(sourceNodeRid, targetNodeRid)) {
80
+ return this.submitLocalNode(meshName, String(sourceNodeRid), parts);
76
81
  }
77
- if (!this.isKnownBackendPeer(node, targetNodeRid) &&
78
- this.manualNodeTarget?.(meshName, targetNodeRid) === false) {
82
+ if (this.manualNodeTarget?.(meshName, targetNodeRid) === false &&
83
+ !this.isKnownBackendPeer(node, targetNodeRid)) {
79
84
  return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
80
85
  }
81
86
  try {
82
- return mapMeshSubmitResult(await node.sendToNode((0, routing_id_1.toBackendRoutingId)(targetNodeRid), parts, { flags: 1 }));
87
+ const submitted = node.sendToNode((0, routing_id_1.toBackendRoutingId)(targetNodeRid), parts, NON_BLOCKING_SEND_OPTIONS);
88
+ return submitted instanceof Promise
89
+ ? submitted.then(mapMeshSubmitResult, (error) => {
90
+ throw mapMeshSubmissionError(error, `MeshNode '${meshName}' send to node '${targetNodeRid}'`);
91
+ })
92
+ : mapMeshSubmitResult(submitted);
83
93
  }
84
94
  catch (error) {
85
- throw mapMeshSubmissionError(error, operation);
95
+ throw mapMeshSubmissionError(error, `MeshNode '${meshName}' send to node '${targetNodeRid}'`);
86
96
  }
87
97
  }
88
- request(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata) {
89
- return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.requestScoped(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata));
98
+ request(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata, onAdmitted) {
99
+ if (!this.flowCreationEnabled())
100
+ return this.requestScoped(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata, onAdmitted);
101
+ return (0, flow_context_1.runWithOutboundFlow)(true, () => this.requestScoped(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata, onAdmitted));
90
102
  }
91
- async requestScoped(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata) {
103
+ async requestScoped(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata, onAdmitted) {
92
104
  const node = this.meshNode(meshName);
93
105
  if (node === undefined) {
94
- return this.requireManager().routeRequest(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata);
106
+ return this.requireManager().routeRequest(meshName, targetNodeRid, packetName, request, timeoutMs, signal, metadata, onAdmitted);
95
107
  }
96
108
  const correlationId = (0, channel_envelope_1.newChannelCorrelationId)();
97
109
  try {
@@ -103,6 +115,7 @@ class ZLinkRuntimeRouteTransport {
103
115
  const completion = await this.submitRequestOperation(meshName, timeoutMs, signal, `MeshNode '${meshName}' request to node '${targetNodeRid}'`, (remainingTimeoutMs) => {
104
116
  const operationId = node.requestToNode((0, routing_id_1.toBackendRoutingId)(targetNodeRid), parts, {
105
117
  flags: 1,
118
+ onAdmitted,
106
119
  timeoutMs: remainingTimeoutMs
107
120
  });
108
121
  this.traceNodeRequest(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Sent, undefined, meshName, targetNodeRid, packetName, correlationId);
@@ -142,7 +155,7 @@ class ZLinkRuntimeRouteTransport {
142
155
  const parts = this.encodeMessage(3 /* ZLinkChannelMessageKind.Command */, channelName, packetName, message, undefined, metadata);
143
156
  const operation = `MeshNode '${meshName}' send to channel '${channelName}'`;
144
157
  try {
145
- const result = mapMeshSubmitResult(await node.sendToChannel(channelName, parts, { flags: 1 }));
158
+ const result = mapMeshSubmitResult(await node.sendToChannel(channelName, parts, NON_BLOCKING_SEND_OPTIONS));
146
159
  if (result.status === submission_result_1.ZLinkSubmitStatus.TargetNotFound) {
147
160
  this.metrics?.recordChannelSelectionFailure(meshName, channelName, 'no_ready_target');
148
161
  }
@@ -152,16 +165,22 @@ class ZLinkRuntimeRouteTransport {
152
165
  throw mapMeshSubmissionError(error, operation);
153
166
  }
154
167
  }
155
- requestToChannel(meshName, channelName, packetName, request, timeoutMs, signal, metadata) {
156
- return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.requestToChannelScoped(meshName, channelName, packetName, request, timeoutMs, signal, metadata));
168
+ requestToChannel(meshName, channelName, packetName, request, timeoutMs, signal, metadata, onAdmitted) {
169
+ if (!this.flowCreationEnabled())
170
+ return this.requestToChannelScoped(meshName, channelName, packetName, request, timeoutMs, signal, metadata, onAdmitted);
171
+ return (0, flow_context_1.runWithOutboundFlow)(true, () => this.requestToChannelScoped(meshName, channelName, packetName, request, timeoutMs, signal, metadata, onAdmitted));
157
172
  }
158
- async requestToChannelScoped(meshName, channelName, packetName, request, timeoutMs, signal, metadata) {
173
+ async requestToChannelScoped(meshName, channelName, packetName, request, timeoutMs, signal, metadata, onAdmitted) {
159
174
  (0, abort_1.throwIfAborted)(signal);
160
175
  const node = this.requireMeshNode(meshName);
161
176
  const parts = this.encodeMessage(1 /* ZLinkChannelMessageKind.Request */, channelName, packetName, request, timeoutMs ?? Registration_1.DEFAULT_REQUEST_TIMEOUT_MS, metadata);
162
177
  const metric = this.metrics?.startRequest(meshName, 'channel');
163
178
  try {
164
- const completion = await this.submitRequestOperation(meshName, timeoutMs, signal, `MeshNode '${meshName}' request to channel '${channelName}'`, (remainingTimeoutMs) => node.requestToChannel(channelName, parts, { flags: 1, timeoutMs: remainingTimeoutMs }));
179
+ const completion = await this.submitRequestOperation(meshName, timeoutMs, signal, `MeshNode '${meshName}' request to channel '${channelName}'`, (remainingTimeoutMs) => node.requestToChannel(channelName, parts, {
180
+ flags: 1,
181
+ timeoutMs: remainingTimeoutMs,
182
+ onAdmitted
183
+ }));
165
184
  const reply = this.decodeMeshReply(meshName, completion);
166
185
  metric?.complete('completed');
167
186
  return reply;
@@ -232,18 +251,19 @@ class ZLinkRuntimeRouteTransport {
232
251
  if (spotRouteTarget.spotKind === Spots_1.ZLinkSpotKind.Instance) {
233
252
  throw new configuration_1.ZLinkConfigurationException('Instance Spot routes require the MeshNode command 39 transport.');
234
253
  }
235
- return this.requireManager().routeRequestToSpot(spotRouteTarget, options.packetName, request, options.timeoutMs, options.signal, options.metadata);
254
+ return this.requireManager().routeRequestToSpot(spotRouteTarget, options.packetName, request, options.timeoutMs, options.signal, options.metadata, options.onAdmitted);
236
255
  }
237
256
  (0, abort_1.throwIfAborted)(options.signal);
238
257
  let completionPromise;
239
258
  try {
240
259
  const encoded = this.encodeMessage(1 /* ZLinkChannelMessageKind.Request */, meshName, options.packetName, request, options.timeoutMs, options.metadata);
241
260
  completionPromise = this.completionTable(meshName).submit(() => spotRouteTarget.spotKind === Spots_1.ZLinkSpotKind.Instance
242
- ? node.requestInstanceSpot(instanceSpotRouteFence(spotRouteTarget), encoded, options.timeoutMs, undefined, options.metadata, options.instanceSpot)
261
+ ? node.requestInstanceSpot(instanceSpotRouteFence(spotRouteTarget), encoded, options.timeoutMs, undefined, options.metadata, options.instanceSpot, options.onAdmitted)
243
262
  : node
244
263
  .entrySpot()
245
264
  .requestToSpot((0, routing_id_1.toBackendRoutingId)(spotRouteTarget.targetNodeRid), (0, routing_id_1.toBackendRoutingId)(spotRouteTarget.spotId), spotRouteTarget.targetSpotGeneration ?? 0n, encoded, {
246
265
  flags: 1,
266
+ onAdmitted: options.onAdmitted,
247
267
  timeoutMs: options.timeoutMs,
248
268
  routeFence: directSpotRouteFence(spotRouteTarget),
249
269
  entrySpot: spotRouteTarget.spotKind === Spots_1.ZLinkSpotKind.Entry
@@ -255,10 +275,10 @@ class ZLinkRuntimeRouteTransport {
255
275
  return this.waitForMeshReply(meshName, completionPromise);
256
276
  }
257
277
  async requestFromSpotToSpot(sourceSpot, spotRouteTarget, request, options) {
258
- return this.requireManager().routeRequestFromSpotToSpot(sourceSpot, spotRouteTarget, options.packetName, request, options.timeoutMs, options.signal);
278
+ return this.requireManager().routeRequestFromSpotToSpot(sourceSpot, spotRouteTarget, options.packetName, request, options.timeoutMs, options.signal, options.onAdmitted);
259
279
  }
260
280
  async requestRawFromSpotToSpot(sourceSpot, spotRouteTarget, request, options) {
261
- return this.requireManager().routeRequestRawFromSpotToSpot(sourceSpot, spotRouteTarget, request, options.timeoutMs, options.signal);
281
+ return this.requireManager().routeRequestRawFromSpotToSpot(sourceSpot, spotRouteTarget, request, options.timeoutMs, options.signal, options.onAdmitted);
262
282
  }
263
283
  requestRawToSpot(spotRouteTarget, request, options) {
264
284
  return (0, flow_context_1.runWithOutboundFlow)(this.flowCreationEnabled(), () => this.requestRawToSpotScoped(spotRouteTarget, request, options));
@@ -277,6 +297,7 @@ class ZLinkRuntimeRouteTransport {
277
297
  .entrySpot()
278
298
  .requestToSpot((0, routing_id_1.toBackendRoutingId)(spotRouteTarget.targetNodeRid), (0, routing_id_1.toBackendRoutingId)(spotRouteTarget.spotId), spotRouteTarget.targetSpotGeneration ?? 0n, parts, {
279
299
  flags: 1,
300
+ onAdmitted: options.onAdmitted,
280
301
  timeoutMs: options.timeoutMs,
281
302
  routeFence: directSpotRouteFence(spotRouteTarget),
282
303
  entrySpot: spotRouteTarget.spotKind === Spots_1.ZLinkSpotKind.Entry
@@ -302,7 +323,7 @@ class ZLinkRuntimeRouteTransport {
302
323
  (0, mesh_completion_table_1.closeMeshCompletion)(completion);
303
324
  }
304
325
  }
305
- return this.requireManager().routeRequestRawToSpot(spotRouteTarget, request, options.timeoutMs, options.signal);
326
+ return this.requireManager().routeRequestRawToSpot(spotRouteTarget, request, options.timeoutMs, options.signal, options.onAdmitted);
306
327
  }
307
328
  requireManager() {
308
329
  const manager = this.manager();
@@ -312,11 +333,7 @@ class ZLinkRuntimeRouteTransport {
312
333
  return manager;
313
334
  }
314
335
  meshNode(meshName) {
315
- const runtime = this.meshRuntime?.();
316
- return runtime?.meshNode?.(meshName);
317
- }
318
- isSelfNode(node, targetNodeRid) {
319
- return (0, routing_id_1.routingIdsEqual)(node.status().routingId, targetNodeRid);
336
+ return this.meshRuntime?.()?.meshNode?.(meshName);
320
337
  }
321
338
  isKnownBackendPeer(node, targetNodeRid) {
322
339
  return node