@zlink-systems/framework 0.20.0 → 0.22.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 (487) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Common/ZLinkMessage.js +5 -5
  3. package/dist/contracts/Configuration/CodecContentType.js +5 -7
  4. package/dist/contracts/Configuration/DiagnosticsValidation.js +1 -6
  5. package/dist/contracts/Configuration/EndpointNotation.js +4 -8
  6. package/dist/contracts/Configuration/Registration.js +14 -11
  7. package/dist/contracts/Configuration/RegistrationBuilders.js +32 -25
  8. package/dist/contracts/Configuration/RegistrationNormalizers.js +25 -26
  9. package/dist/contracts/Configuration/RegistrationValidators.js +36 -38
  10. package/dist/contracts/Configuration/SendTimeoutValidation.js +4 -4
  11. package/dist/contracts/Configuration/TimerRegistrationValidator.js +7 -7
  12. package/dist/contracts/Handlers/JsonContract.js +23 -11
  13. package/dist/contracts/Spots/SpotKind.js +16 -8
  14. package/dist/location-store-integration.js +16 -16
  15. package/dist/nest-integration.js +17 -11
  16. package/dist/runtime/abort.js +9 -5
  17. package/dist/runtime/actors/actor-authority-payload-codec.js +12 -16
  18. package/dist/runtime/actors/actor-authority-publication.js +18 -17
  19. package/dist/runtime/actors/actor-client.js +83 -63
  20. package/dist/runtime/actors/actor-context.js +24 -18
  21. package/dist/runtime/actors/actor-creation.js +4 -3
  22. package/dist/runtime/actors/actor-handoff.js +89 -92
  23. package/dist/runtime/actors/actor-local-native-join.js +18 -19
  24. package/dist/runtime/actors/actor-mailbox.js +1 -1
  25. package/dist/runtime/actors/actor-message-follow-context.js +24 -21
  26. package/dist/runtime/actors/actor-packet-relay-wire.js +1 -3
  27. package/dist/runtime/actors/actor-remote-joiner.js +20 -17
  28. package/dist/runtime/actors/actor-remote-wire.js +6 -7
  29. package/dist/runtime/actors/actor-runtime-state.js +87 -81
  30. package/dist/runtime/actors/actor-transfer-registry.js +3 -5
  31. package/dist/runtime/actors/bound-session-wire.js +14 -9
  32. package/dist/runtime/actors/deferred-join-accepted-journal.js +158 -124
  33. package/dist/runtime/actors/index.js +2 -5
  34. package/dist/runtime/actors/post-commit-actor-binder.js +3 -6
  35. package/dist/runtime/actors/post-commit-actor-location.js +1 -1
  36. package/dist/runtime/actors/spot-actor-dispatch.js +5 -5
  37. package/dist/runtime/actors/transferred-actor-rollback.js +4 -4
  38. package/dist/runtime/admission.js +2 -6
  39. package/dist/runtime/application-jobs/application-ingress-record-owner.js +2 -6
  40. package/dist/runtime/application-jobs/receive-flow-controller.js +11 -12
  41. package/dist/runtime/backend/mesh-completion-table.js +1 -3
  42. package/dist/runtime/backend/mesh-dispatch-pump.js +12 -16
  43. package/dist/runtime/backend/node/node-backend-adapter-factory.js +1 -3
  44. package/dist/runtime/backend/node/node-backend-adapter-support.js +26 -17
  45. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +4 -3
  46. package/dist/runtime/backend/node/node-raw-binding-port.js +7 -6
  47. package/dist/runtime/backend/node/node-raw-mesh-backend.js +116 -113
  48. package/dist/runtime/backend/node/node-socket-backend-adapter.js +12 -13
  49. package/dist/runtime/backend/runtime-message.js +3 -3
  50. package/dist/runtime/backend/runtime-values.d.ts +2 -2
  51. package/dist/runtime/backend/runtime-values.js +4 -5
  52. package/dist/runtime/channels/channel-clients.js +27 -24
  53. package/dist/runtime/channels/channel-dispatch-pipeline.js +10 -18
  54. package/dist/runtime/channels/channel-dispatch-services.js +7 -4
  55. package/dist/runtime/channels/channel-dispatchers.js +9 -9
  56. package/dist/runtime/channels/channel-envelope-inspection.js +16 -13
  57. package/dist/runtime/channels/channel-envelope.js +83 -47
  58. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  59. package/dist/runtime/channels/channel-receive-loops.js +20 -22
  60. package/dist/runtime/channels/channel-receive-task-tracker.js +1 -1
  61. package/dist/runtime/channels/channel-runtime-lifecycle.js +61 -56
  62. package/dist/runtime/channels/channel-runtime-manager.js +18 -9
  63. package/dist/runtime/channels/channel-socket-registry.js +126 -123
  64. package/dist/runtime/channels/channel-transports.js +43 -33
  65. package/dist/runtime/channels/client-server-location-runtime.js +32 -40
  66. package/dist/runtime/channels/client-server-service-wire.js +29 -22
  67. package/dist/runtime/channels/dispatch-error-reporter.js +9 -7
  68. package/dist/runtime/channels/fanout-location-runtime.js +34 -47
  69. package/dist/runtime/channels/fanout-service-wire.js +3 -5
  70. package/dist/runtime/channels/local-spot-route-transport.js +7 -1
  71. package/dist/runtime/channels/route-member-snapshot.js +3 -3
  72. package/dist/runtime/channels/source-spot-router.js +6 -2
  73. package/dist/runtime/channels/spot-route-bridge-transport.js +5 -2
  74. package/dist/runtime/channels/spot-route-dispatch-strategy.js +2 -2
  75. package/dist/runtime/channels/spot-route-target-resolver.js +6 -6
  76. package/dist/runtime/diagnostics/index.js +38 -10
  77. package/dist/runtime/diagnostics/message-flow.js +47 -39
  78. package/dist/runtime/diagnostics/runtime-metrics.js +18 -9
  79. package/dist/runtime/diagnostics/runtime-observation-queue.js +8 -10
  80. package/dist/runtime/diagnostics/topology-runtime-projections.js +17 -10
  81. package/dist/runtime/execution/index.js +7 -6
  82. package/dist/runtime/execution/serial-execution-queue.js +12 -18
  83. package/dist/runtime/execution/state-lane.js +2 -2
  84. package/dist/runtime/foundation/actor-join-recovery-codec.js +31 -23
  85. package/dist/runtime/foundation/event-loop-resources.js +4 -4
  86. package/dist/runtime/foundation/message-follow-suppression-registry.js +4 -4
  87. package/dist/runtime/foundation/raw-service-mesh-runtime.js +136 -136
  88. package/dist/runtime/foundation/route-mesh-connection-policy.js +4 -4
  89. package/dist/runtime/foundation/runtime-state-projections.js +22 -11
  90. package/dist/runtime/foundation/service-authority-payload-codec.js +13 -15
  91. package/dist/runtime/foundation/service-discovery-registry.js +35 -33
  92. package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +20 -22
  93. package/dist/runtime/foundation/service-liveness-registry.js +16 -12
  94. package/dist/runtime/foundation/service-maintenance-runtime.js +2 -4
  95. package/dist/runtime/foundation/service-relocation-aggregate-committer.js +24 -24
  96. package/dist/runtime/foundation/service-relocation-object-owner.js +6 -6
  97. package/dist/runtime/foundation/service-relocation-runtime.js +137 -94
  98. package/dist/runtime/foundation/service-runtime-contracts.js +5 -5
  99. package/dist/runtime/foundation/service-stateful-registry.js +24 -23
  100. package/dist/runtime/foundation/service-stateful-runtime.js +416 -438
  101. package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
  102. package/dist/runtime/foundation/service-topology-registry.js +96 -95
  103. package/dist/runtime/foundation/service-weighted-selection.js +6 -11
  104. package/dist/runtime/foundation/service-wire-binary-primitives.js +5 -6
  105. package/dist/runtime/foundation/service-wire-m6a-codec.js +46 -35
  106. package/dist/runtime/framework-errors-internal.js +7 -10
  107. package/dist/runtime/handlers/handler-instance-scope.js +4 -5
  108. package/dist/runtime/handlers/index.js +3 -1
  109. package/dist/runtime/host/actor-packet-relay.js +74 -70
  110. package/dist/runtime/host/actor-placement-coordinator.js +29 -31
  111. package/dist/runtime/host/actor-runtime-options-factory.js +12 -14
  112. package/dist/runtime/host/actor-transfer-authority-runtime.js +7 -9
  113. package/dist/runtime/host/actor-transfer-runtime.js +176 -153
  114. package/dist/runtime/host/application-job-queue.js +18 -22
  115. package/dist/runtime/host/bound-session-relay.js +3 -1
  116. package/dist/runtime/host/channel-runtime-options-factory.js +31 -14
  117. package/dist/runtime/host/host-capacity-status.js +8 -4
  118. package/dist/runtime/host/index.js +244 -227
  119. package/dist/runtime/host/instance-activation-authority.js +93 -96
  120. package/dist/runtime/host/location-runtime-owner.js +16 -14
  121. package/dist/runtime/host/mesh-router-resolver.js +11 -13
  122. package/dist/runtime/host/relocation-direct-transfer.js +10 -9
  123. package/dist/runtime/host/remote-actor-join-receiver.js +20 -15
  124. package/dist/runtime/host/remote-actor-packet-target-store.js +18 -22
  125. package/dist/runtime/host/remote-bound-session-relay.js +97 -73
  126. package/dist/runtime/host/route-mesh-runtime.js +64 -69
  127. package/dist/runtime/host/runtime-shutdown.js +1 -2
  128. package/dist/runtime/host/service-relocation-host-runtime.js +586 -511
  129. package/dist/runtime/host/spot-address-transport.js +69 -71
  130. package/dist/runtime/host/spot-runtime-options-factory.js +30 -29
  131. package/dist/runtime/host/stateful-authority-route-runtime.js +65 -68
  132. package/dist/runtime/host/user-spot-creation-coordinator.js +61 -67
  133. package/dist/runtime/locations/actor-location-claims.js +26 -20
  134. package/dist/runtime/locations/aggregate-inventory-store.js +72 -75
  135. package/dist/runtime/locations/authority-key-codec.js +7 -7
  136. package/dist/runtime/locations/auto-connect-loop.js +3 -3
  137. package/dist/runtime/locations/auto-connect-planner.js +25 -19
  138. package/dist/runtime/locations/auto-connect-reconciler.js +51 -31
  139. package/dist/runtime/locations/in-memory-authority-store.js +128 -118
  140. package/dist/runtime/locations/in-memory-location-store.js +195 -168
  141. package/dist/runtime/locations/in-memory-provider-location-store.js +8 -10
  142. package/dist/runtime/locations/key-codec.js +1 -1
  143. package/dist/runtime/locations/lease-tracker.js +23 -21
  144. package/dist/runtime/locations/lifecycle.js +4 -5
  145. package/dist/runtime/locations/location-store-repository.js +368 -324
  146. package/dist/runtime/locations/opaque-record-key.js +2 -2
  147. package/dist/runtime/locations/resolvers.js +73 -82
  148. package/dist/runtime/locations/runtime.js +68 -63
  149. package/dist/runtime/locations/spot-location-claims.js +39 -35
  150. package/dist/runtime/messaging/framework-json-v1.js +7 -7
  151. package/dist/runtime/messaging/packet-name.js +7 -6
  152. package/dist/runtime/messaging/payload-codec.js +21 -18
  153. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +30 -2
  154. package/dist/runtime/protocol/service_wire_codec.generated.js +1671 -234
  155. package/dist/runtime/routing-id.js +3 -5
  156. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +35 -31
  157. package/dist/runtime/spots/formal-remote-actor-transfer-registry.js +1 -2
  158. package/dist/runtime/spots/index.js +208 -219
  159. package/dist/runtime/spots/spot-activation-registry.js +15 -14
  160. package/dist/runtime/spots/spot-activation-state.js +17 -15
  161. package/dist/runtime/spots/spot-activation.js +33 -16
  162. package/dist/runtime/spots/spot-actor-admission-coordinator.js +18 -15
  163. package/dist/runtime/spots/spot-actor-membership.js +1 -3
  164. package/dist/runtime/spots/spot-actor-packet-dispatch.js +23 -20
  165. package/dist/runtime/spots/spot-actor-packet-drain.js +12 -10
  166. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +10 -6
  167. package/dist/runtime/spots/spot-closing.js +3 -7
  168. package/dist/runtime/spots/spot-context.js +2 -2
  169. package/dist/runtime/spots/spot-entry-activation.js +13 -14
  170. package/dist/runtime/spots/spot-handle.js +6 -3
  171. package/dist/runtime/spots/spot-handler-registry.js +12 -12
  172. package/dist/runtime/spots/spot-manager-public.js +5 -6
  173. package/dist/runtime/spots/spot-native-actor-join-admission.js +4 -3
  174. package/dist/runtime/spots/spot-node-autoconnect.js +15 -18
  175. package/dist/runtime/spots/spot-node-runtime-manager.js +74 -85
  176. package/dist/runtime/spots/spot-outbound.js +10 -14
  177. package/dist/runtime/spots/spot-remote-codec.js +22 -26
  178. package/dist/runtime/spots/spot-remote-route-codec.js +5 -7
  179. package/dist/runtime/spots/spot-route-packet-dispatch.js +16 -14
  180. package/dist/runtime/spots/spot-route-replies.js +4 -6
  181. package/dist/runtime/spots/spot-routed-actor-admission.js +9 -7
  182. package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +1 -2
  183. package/dist/runtime/spots/spot-routed-frame-dispatch.js +5 -5
  184. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +14 -10
  185. package/dist/runtime/spots/spot-serial-executor.js +5 -8
  186. package/dist/runtime/spots/spot-serial-turn-executor.js +4 -6
  187. package/dist/runtime/spots/spot-subscription-dispatch.js +5 -5
  188. package/dist/runtime/spots/spot-timer.js +25 -29
  189. package/dist/runtime/streams/actor-session-binding-registry.js +98 -107
  190. package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
  191. package/dist/runtime/streams/bound-actor-relay-sender.js +18 -16
  192. package/dist/runtime/streams/bound-session-service.js +8 -9
  193. package/dist/runtime/streams/index.js +20 -19
  194. package/dist/runtime/streams/managed-stream.js +32 -30
  195. package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
  196. package/dist/runtime/streams/protocol.js +29 -18
  197. package/dist/runtime/streams/session-actor-coordinator.js +34 -37
  198. package/dist/runtime/streams/session-context.js +30 -28
  199. package/dist/runtime/streams/session-provider.js +2 -2
  200. package/dist/runtime/streams/session-serial-executor.js +1 -2
  201. package/dist/runtime/streams/stream-frame-factory.js +11 -5
  202. package/dist/runtime/streams/stream-session-runtime.js +70 -66
  203. package/dist/runtime/workers/index.js +15 -4
  204. package/package.json +2 -2
  205. package/src/contracts/Channels/RouteCalls.ts +6 -1
  206. package/src/contracts/Common/ZLinkMessage.ts +5 -5
  207. package/src/contracts/Common/ZLinkMessageMetadata.ts +4 -3
  208. package/src/contracts/Configuration/Builders.ts +14 -14
  209. package/src/contracts/Configuration/CodecContentType.ts +8 -10
  210. package/src/contracts/Configuration/DiagnosticsValidation.ts +1 -6
  211. package/src/contracts/Configuration/EndpointNotation.ts +11 -11
  212. package/src/contracts/Configuration/ObjectRoles.ts +1 -3
  213. package/src/contracts/Configuration/Registration.ts +46 -17
  214. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +10 -8
  215. package/src/contracts/Configuration/RegistrationBuilders.ts +107 -96
  216. package/src/contracts/Configuration/RegistrationCodecRegistry.ts +9 -3
  217. package/src/contracts/Configuration/RegistrationNormalizers.ts +116 -84
  218. package/src/contracts/Configuration/RegistrationTypes.ts +21 -25
  219. package/src/contracts/Configuration/RegistrationValidators.ts +122 -73
  220. package/src/contracts/Configuration/RouteChannelInternalState.ts +1 -4
  221. package/src/contracts/Configuration/RuntimeEndpointConnections.ts +4 -1
  222. package/src/contracts/Configuration/SendTimeoutValidation.ts +6 -4
  223. package/src/contracts/Configuration/TimerRegistrationValidator.ts +8 -13
  224. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -6
  225. package/src/contracts/Errors/index.ts +1 -4
  226. package/src/contracts/Handlers/Attributes.ts +15 -9
  227. package/src/contracts/Handlers/IZLinkChannelHandlers.ts +24 -4
  228. package/src/contracts/Handlers/JsonContract.ts +53 -19
  229. package/src/contracts/Locations/ActorTransfer.ts +1 -5
  230. package/src/contracts/Locations/Authority.ts +4 -11
  231. package/src/contracts/Locations/Keys.ts +6 -1
  232. package/src/contracts/Locations/Options.ts +3 -2
  233. package/src/contracts/Locations/RelocationStore.ts +1 -4
  234. package/src/contracts/Locations/Resolvers.ts +5 -5
  235. package/src/contracts/Locations/RuntimeQuery.ts +6 -2
  236. package/src/contracts/Locations/Stores.ts +1 -2
  237. package/src/contracts/Locations/index.ts +2 -8
  238. package/src/contracts/RouteMesh/Contracts.ts +1 -7
  239. package/src/contracts/RouteMesh/RuntimeTopology.ts +1 -4
  240. package/src/contracts/Spots/Contracts.ts +2 -8
  241. package/src/contracts/Spots/SpotKind.ts +16 -8
  242. package/src/contracts/Spots/ZLinkSpot.ts +8 -11
  243. package/src/contracts/Streams/IZLinkSession.ts +0 -1
  244. package/src/contracts/Streams/IZLinkSessionActor.ts +5 -1
  245. package/src/contracts/Streams/IZLinkSessionPacketHandler.ts +5 -1
  246. package/src/internal.ts +5 -4
  247. package/src/location-store-integration.ts +24 -16
  248. package/src/nest-integration.ts +40 -25
  249. package/src/runtime/abort.ts +10 -4
  250. package/src/runtime/actors/actor-authority-payload-codec.ts +20 -29
  251. package/src/runtime/actors/actor-authority-publication.ts +92 -77
  252. package/src/runtime/actors/actor-client.ts +162 -133
  253. package/src/runtime/actors/actor-context.ts +138 -130
  254. package/src/runtime/actors/actor-creation.ts +47 -44
  255. package/src/runtime/actors/actor-execution-context.ts +6 -4
  256. package/src/runtime/actors/actor-handoff.ts +269 -293
  257. package/src/runtime/actors/actor-join-deferred-scope.ts +5 -4
  258. package/src/runtime/actors/actor-lifecycle-snapshot.ts +5 -8
  259. package/src/runtime/actors/actor-local-native-join.ts +131 -159
  260. package/src/runtime/actors/actor-mailbox.ts +16 -19
  261. package/src/runtime/actors/actor-message-follow-context.ts +46 -36
  262. package/src/runtime/actors/actor-packet-relay-wire.ts +32 -21
  263. package/src/runtime/actors/actor-remote-joiner.ts +50 -54
  264. package/src/runtime/actors/actor-remote-wire.ts +9 -13
  265. package/src/runtime/actors/actor-routed-join-transport.ts +10 -2
  266. package/src/runtime/actors/actor-runtime-contracts.ts +2 -5
  267. package/src/runtime/actors/actor-runtime-state.ts +127 -124
  268. package/src/runtime/actors/actor-transfer-registry.ts +9 -14
  269. package/src/runtime/actors/actor-transport-delivery-gate.ts +4 -6
  270. package/src/runtime/actors/bound-session-wire.ts +37 -17
  271. package/src/runtime/actors/deferred-join-accepted-journal.ts +351 -320
  272. package/src/runtime/actors/index.ts +43 -86
  273. package/src/runtime/actors/post-commit-actor-binder.ts +10 -10
  274. package/src/runtime/actors/post-commit-actor-location.ts +30 -23
  275. package/src/runtime/actors/spot-actor-dispatch.ts +78 -53
  276. package/src/runtime/actors/transferred-actor-rollback.ts +18 -13
  277. package/src/runtime/admission.ts +9 -9
  278. package/src/runtime/application-jobs/application-ingress-record-owner.ts +5 -15
  279. package/src/runtime/application-jobs/application-job-queue-handler-start-gate.ts +3 -2
  280. package/src/runtime/application-jobs/receive-flow-controller.ts +17 -14
  281. package/src/runtime/backend/contracts/index.ts +73 -52
  282. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -14
  283. package/src/runtime/backend/mesh-completion-table.ts +6 -9
  284. package/src/runtime/backend/mesh-dispatch-pump.ts +38 -30
  285. package/src/runtime/backend/node/node-backend-adapter-factory.ts +23 -21
  286. package/src/runtime/backend/node/node-backend-adapter-support.ts +36 -22
  287. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +59 -58
  288. package/src/runtime/backend/node/node-event-loop-poller.ts +2 -10
  289. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +12 -5
  290. package/src/runtime/backend/node/node-monitor-backend-adapter.ts +4 -3
  291. package/src/runtime/backend/node/node-raw-binding-port.ts +29 -29
  292. package/src/runtime/backend/node/node-raw-mesh-backend.ts +335 -383
  293. package/src/runtime/backend/node/node-socket-backend-adapter.ts +101 -54
  294. package/src/runtime/backend/runtime-message.ts +5 -3
  295. package/src/runtime/backend/runtime-values.ts +10 -7
  296. package/src/runtime/channels/channel-autoconnect.ts +1 -4
  297. package/src/runtime/channels/channel-clients.ts +93 -73
  298. package/src/runtime/channels/channel-dispatch-pipeline.ts +40 -42
  299. package/src/runtime/channels/channel-dispatch-services.ts +51 -49
  300. package/src/runtime/channels/channel-dispatchers.ts +152 -96
  301. package/src/runtime/channels/channel-envelope-inspection.ts +20 -16
  302. package/src/runtime/channels/channel-envelope.ts +256 -150
  303. package/src/runtime/channels/channel-multipart.ts +13 -5
  304. package/src/runtime/channels/channel-outbound-operations.ts +37 -41
  305. package/src/runtime/channels/channel-receive-loops.ts +102 -98
  306. package/src/runtime/channels/channel-receive-task-tracker.ts +1 -1
  307. package/src/runtime/channels/channel-runtime-lifecycle.ts +248 -190
  308. package/src/runtime/channels/channel-runtime-manager.ts +63 -37
  309. package/src/runtime/channels/channel-socket-options.ts +3 -10
  310. package/src/runtime/channels/channel-socket-registry.ts +331 -273
  311. package/src/runtime/channels/channel-transports.ts +215 -197
  312. package/src/runtime/channels/client-server-location-runtime.ts +116 -100
  313. package/src/runtime/channels/client-server-service-wire.ts +37 -36
  314. package/src/runtime/channels/dispatch-error-reporter.ts +11 -8
  315. package/src/runtime/channels/fanout-location-runtime.ts +91 -94
  316. package/src/runtime/channels/fanout-service-wire.ts +5 -12
  317. package/src/runtime/channels/handler-filter-scope.ts +1 -4
  318. package/src/runtime/channels/index.ts +1 -4
  319. package/src/runtime/channels/local-spot-route-transport.ts +20 -5
  320. package/src/runtime/channels/route-member-snapshot.ts +11 -5
  321. package/src/runtime/channels/router-socket-spot-route-transport.ts +1 -7
  322. package/src/runtime/channels/source-spot-router.ts +26 -22
  323. package/src/runtime/channels/spot-direct-envelope.ts +10 -8
  324. package/src/runtime/channels/spot-node-route-transport.ts +13 -16
  325. package/src/runtime/channels/spot-route-bridge-transport.ts +26 -9
  326. package/src/runtime/channels/spot-route-dispatch-strategy.ts +40 -13
  327. package/src/runtime/channels/spot-route-target-resolver.ts +18 -9
  328. package/src/runtime/codecs/index.ts +3 -2
  329. package/src/runtime/diagnostics/flow-context.ts +12 -3
  330. package/src/runtime/diagnostics/index.ts +96 -61
  331. package/src/runtime/diagnostics/internal-event-contracts.ts +87 -33
  332. package/src/runtime/diagnostics/message-flow.ts +95 -76
  333. package/src/runtime/diagnostics/runtime-metrics.ts +46 -24
  334. package/src/runtime/diagnostics/runtime-observation-queue.ts +17 -28
  335. package/src/runtime/diagnostics/topology-runtime-projections.ts +62 -43
  336. package/src/runtime/execution/index.ts +18 -26
  337. package/src/runtime/execution/serial-execution-queue.ts +31 -40
  338. package/src/runtime/execution/state-lane.ts +2 -2
  339. package/src/runtime/foundation/actor-join-recovery-codec.ts +69 -51
  340. package/src/runtime/foundation/event-loop-resources.ts +8 -4
  341. package/src/runtime/foundation/message-follow-suppression-registry.ts +7 -14
  342. package/src/runtime/foundation/operation-identity.ts +1 -2
  343. package/src/runtime/foundation/operation-registry.ts +8 -2
  344. package/src/runtime/foundation/raw-service-mesh-runtime.ts +312 -385
  345. package/src/runtime/foundation/route-mesh-connection-policy.ts +7 -8
  346. package/src/runtime/foundation/runtime-state-projections.ts +24 -23
  347. package/src/runtime/foundation/service-authority-payload-codec.ts +54 -57
  348. package/src/runtime/foundation/service-discovery-registry.ts +67 -59
  349. package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +28 -29
  350. package/src/runtime/foundation/service-liveness-registry.ts +18 -13
  351. package/src/runtime/foundation/service-mailbox.ts +14 -14
  352. package/src/runtime/foundation/service-maintenance-runtime.ts +22 -21
  353. package/src/runtime/foundation/service-metadata-codec.ts +2 -9
  354. package/src/runtime/foundation/service-relocation-aggregate-committer.ts +39 -36
  355. package/src/runtime/foundation/service-relocation-coordinator.ts +1 -4
  356. package/src/runtime/foundation/service-relocation-object-owner.ts +40 -58
  357. package/src/runtime/foundation/service-relocation-runtime.ts +292 -216
  358. package/src/runtime/foundation/service-runtime-contracts.ts +8 -8
  359. package/src/runtime/foundation/service-session-binding-ingress-port.ts +1 -4
  360. package/src/runtime/foundation/service-stateful-registry.ts +69 -59
  361. package/src/runtime/foundation/service-stateful-runtime.ts +1174 -1112
  362. package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
  363. package/src/runtime/foundation/service-topology-registry.ts +157 -159
  364. package/src/runtime/foundation/service-weighted-selection.ts +9 -15
  365. package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -12
  366. package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -47
  367. package/src/runtime/framework-errors-internal.ts +31 -30
  368. package/src/runtime/handlers/handler-instance-scope.ts +18 -29
  369. package/src/runtime/handlers/index.ts +18 -8
  370. package/src/runtime/host/actor-packet-relay.ts +290 -261
  371. package/src/runtime/host/actor-placement-coordinator.ts +165 -150
  372. package/src/runtime/host/actor-runtime-options-factory.ts +89 -87
  373. package/src/runtime/host/actor-transfer-authority-runtime.ts +46 -38
  374. package/src/runtime/host/actor-transfer-runtime.ts +391 -395
  375. package/src/runtime/host/application-job-queue.ts +32 -48
  376. package/src/runtime/host/bound-session-relay.ts +7 -9
  377. package/src/runtime/host/channel-runtime-options-factory.ts +75 -35
  378. package/src/runtime/host/host-capacity-status.ts +10 -9
  379. package/src/runtime/host/index.ts +861 -789
  380. package/src/runtime/host/instance-activation-authority.ts +125 -143
  381. package/src/runtime/host/location-runtime-owner.ts +38 -26
  382. package/src/runtime/host/mesh-router-resolver.ts +30 -23
  383. package/src/runtime/host/relocation-direct-transfer.ts +15 -15
  384. package/src/runtime/host/relocation-integrity-fault-gate.ts +3 -2
  385. package/src/runtime/host/remote-actor-join-receiver.ts +43 -34
  386. package/src/runtime/host/remote-actor-packet-target-store.ts +54 -52
  387. package/src/runtime/host/remote-bound-session-relay.ts +274 -247
  388. package/src/runtime/host/route-mesh-runtime-options.ts +1 -3
  389. package/src/runtime/host/route-mesh-runtime.ts +227 -181
  390. package/src/runtime/host/runtime-shutdown.ts +4 -3
  391. package/src/runtime/host/service-relocation-control.ts +14 -5
  392. package/src/runtime/host/service-relocation-host-runtime.ts +1388 -1165
  393. package/src/runtime/host/spot-address-transport.ts +284 -237
  394. package/src/runtime/host/spot-node-runtime-options-factory.ts +14 -8
  395. package/src/runtime/host/spot-runtime-options-factory.ts +71 -62
  396. package/src/runtime/host/stateful-authority-route-runtime.ts +117 -116
  397. package/src/runtime/host/user-spot-creation-coordinator.ts +225 -220
  398. package/src/runtime/locations/actor-location-claims.ts +61 -49
  399. package/src/runtime/locations/actor-session-route-claims.ts +1 -4
  400. package/src/runtime/locations/aggregate-inventory-store.ts +105 -134
  401. package/src/runtime/locations/authority-key-codec.ts +13 -10
  402. package/src/runtime/locations/auto-connect-loop.ts +14 -11
  403. package/src/runtime/locations/auto-connect-planner.ts +42 -31
  404. package/src/runtime/locations/auto-connect-reconciler.ts +106 -63
  405. package/src/runtime/locations/canonical-codec.ts +3 -1
  406. package/src/runtime/locations/creation-operation-id.ts +4 -3
  407. package/src/runtime/locations/domain-store-contract.ts +13 -7
  408. package/src/runtime/locations/in-memory-authority-store.ts +232 -199
  409. package/src/runtime/locations/in-memory-location-store.ts +432 -250
  410. package/src/runtime/locations/in-memory-provider-location-store.ts +16 -17
  411. package/src/runtime/locations/internal-store-contracts.ts +95 -38
  412. package/src/runtime/locations/key-codec.ts +3 -4
  413. package/src/runtime/locations/lease-tracker.ts +36 -27
  414. package/src/runtime/locations/lifecycle-runtime.ts +15 -3
  415. package/src/runtime/locations/lifecycle.ts +33 -28
  416. package/src/runtime/locations/location-store-repository.ts +1329 -1185
  417. package/src/runtime/locations/opaque-record-key.ts +4 -9
  418. package/src/runtime/locations/resolvers.ts +201 -178
  419. package/src/runtime/locations/runtime.ts +251 -159
  420. package/src/runtime/locations/spot-location-claims.ts +110 -112
  421. package/src/runtime/messaging/creation-payload-codec.ts +4 -1
  422. package/src/runtime/messaging/framework-json-v1.ts +34 -15
  423. package/src/runtime/messaging/packet-name.ts +8 -6
  424. package/src/runtime/messaging/payload-codec.ts +70 -50
  425. package/src/runtime/messaging/submission-result.ts +6 -9
  426. package/src/runtime/protocol/service_wire_codec.generated.ts +1376 -159
  427. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
  428. package/src/runtime/routing-id.ts +10 -7
  429. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +56 -62
  430. package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +23 -20
  431. package/src/runtime/spots/index.ts +593 -563
  432. package/src/runtime/spots/spot-activation-registry.ts +38 -34
  433. package/src/runtime/spots/spot-activation-state.ts +43 -51
  434. package/src/runtime/spots/spot-activation.ts +179 -116
  435. package/src/runtime/spots/spot-actor-admission-coordinator.ts +110 -78
  436. package/src/runtime/spots/spot-actor-join-dispatch.ts +57 -41
  437. package/src/runtime/spots/spot-actor-lifecycle-drain.ts +5 -7
  438. package/src/runtime/spots/spot-actor-membership.ts +25 -27
  439. package/src/runtime/spots/spot-actor-packet-dispatch.ts +184 -153
  440. package/src/runtime/spots/spot-actor-packet-drain.ts +54 -42
  441. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +37 -39
  442. package/src/runtime/spots/spot-closing.ts +11 -12
  443. package/src/runtime/spots/spot-context.ts +46 -26
  444. package/src/runtime/spots/spot-entry-activation.ts +84 -65
  445. package/src/runtime/spots/spot-handle.ts +17 -15
  446. package/src/runtime/spots/spot-handler-registry.ts +44 -31
  447. package/src/runtime/spots/spot-location-claim.ts +5 -4
  448. package/src/runtime/spots/spot-manager-public.ts +62 -82
  449. package/src/runtime/spots/spot-native-actor-join-admission.ts +20 -16
  450. package/src/runtime/spots/spot-node-autoconnect.ts +54 -61
  451. package/src/runtime/spots/spot-node-runtime-manager.ts +230 -221
  452. package/src/runtime/spots/spot-outbound.ts +47 -59
  453. package/src/runtime/spots/spot-publisher-transport.ts +5 -4
  454. package/src/runtime/spots/spot-remote-codec.ts +66 -65
  455. package/src/runtime/spots/spot-remote-route-codec.ts +61 -41
  456. package/src/runtime/spots/spot-route-packet-dispatch.ts +128 -95
  457. package/src/runtime/spots/spot-route-replies.ts +23 -24
  458. package/src/runtime/spots/spot-route-reply-wire.ts +3 -2
  459. package/src/runtime/spots/spot-routed-actor-admission.ts +37 -27
  460. package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +11 -17
  461. package/src/runtime/spots/spot-routed-frame-dispatch.ts +18 -15
  462. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +35 -26
  463. package/src/runtime/spots/spot-routing-internal.ts +1 -4
  464. package/src/runtime/spots/spot-runtime-ports.ts +5 -5
  465. package/src/runtime/spots/spot-serial-executor.ts +5 -9
  466. package/src/runtime/spots/spot-serial-turn-executor.ts +19 -26
  467. package/src/runtime/spots/spot-subscription-dispatch.ts +56 -46
  468. package/src/runtime/spots/spot-timer.ts +98 -91
  469. package/src/runtime/streams/actor-session-binding-registry.ts +277 -235
  470. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +7 -4
  471. package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
  472. package/src/runtime/streams/bound-actor-relay-sender.ts +53 -51
  473. package/src/runtime/streams/bound-session-response-target.ts +29 -8
  474. package/src/runtime/streams/bound-session-service.ts +39 -39
  475. package/src/runtime/streams/index.ts +176 -100
  476. package/src/runtime/streams/managed-stream.ts +98 -87
  477. package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
  478. package/src/runtime/streams/protocol.ts +73 -43
  479. package/src/runtime/streams/session-actor-coordinator.ts +97 -89
  480. package/src/runtime/streams/session-calls.ts +2 -8
  481. package/src/runtime/streams/session-context.ts +66 -48
  482. package/src/runtime/streams/session-provider.ts +5 -7
  483. package/src/runtime/streams/session-serial-executor.ts +7 -6
  484. package/src/runtime/streams/stream-binding-runtime-ports.ts +79 -29
  485. package/src/runtime/streams/stream-frame-factory.ts +55 -38
  486. package/src/runtime/streams/stream-session-runtime.ts +268 -210
  487. package/src/runtime/workers/index.ts +68 -29
@@ -12,9 +12,7 @@ import type {
12
12
  ApplicationJobPermitPort,
13
13
  ApplicationJobQueuePort
14
14
  } from '../application-jobs/contracts';
15
- import {
16
- ApplicationIngressRecordOwner
17
- } from '../application-jobs/application-ingress-record-owner';
15
+ import { ApplicationIngressRecordOwner } from '../application-jobs/application-ingress-record-owner';
18
16
  import { OperationRegistry, type PendingOperation } from './operation-registry';
19
17
  import { ServiceLivenessRegistry, type ServiceLivenessTick } from './service-liveness-registry';
20
18
  import { ServiceMailbox, type ServiceMailboxRecord } from './service-mailbox';
@@ -55,16 +53,9 @@ import {
55
53
  } from './service-wire-constants.generated';
56
54
 
57
55
  export type RawServicePumpResult =
58
- | 'noData'
59
- | 'infrastructure'
60
- | 'application'
61
- | 'dropped'
62
- | 'protocolError';
56
+ 'noData' | 'infrastructure' | 'application' | 'dropped' | 'protocolError';
63
57
 
64
- export type RawServicePumpObserver = (
65
- sourceRoutingId: string,
66
- byteCount: number
67
- ) => void;
58
+ export type RawServicePumpObserver = (sourceRoutingId: string, byteCount: number) => void;
68
59
 
69
60
  export interface RawServiceRequestResult {
70
61
  readonly terminalResult: number;
@@ -101,10 +92,7 @@ export interface RawServiceMeshRuntimeOptions {
101
92
  readonly peerAdmissionSealed?: () => boolean;
102
93
  readonly onReceiveFlowConfigFailure?: (error: unknown) => void;
103
94
  readonly onMailboxReady?: (domain: 'application' | 'infrastructure') => void;
104
- readonly onPeerNotRequired?: (
105
- nodeRoutingId: string,
106
- endpoint: string
107
- ) => void;
95
+ readonly onPeerNotRequired?: (nodeRoutingId: string, endpoint: string) => void;
108
96
  readonly onPeerDisconnected?: (
109
97
  nodeRoutingId: string,
110
98
  endpoint: string,
@@ -153,13 +141,16 @@ export class RawServiceMeshRuntime {
153
141
  readonly liveness: ServiceLivenessRegistry;
154
142
 
155
143
  private readonly operations = new OperationRegistry<RawServiceRequestResult>();
156
- private readonly expectedPeers = new Map<string, {
157
- readonly meshName: string;
158
- readonly nodeRoutingId: string;
159
- readonly endpoint?: string;
160
- readonly securityIdentity?: string;
161
- readonly lifecycleGeneration?: bigint;
162
- }>();
144
+ private readonly expectedPeers = new Map<
145
+ string,
146
+ {
147
+ readonly meshName: string;
148
+ readonly nodeRoutingId: string;
149
+ readonly endpoint?: string;
150
+ readonly securityIdentity?: string;
151
+ readonly lifecycleGeneration?: bigint;
152
+ }
153
+ >();
163
154
  private readonly endpointOnlyPeers = new Set<string>();
164
155
  private readonly peerConnectionIntentRemoved = new Set<(nodeRoutingId: string) => void>();
165
156
  private readonly connectionCandidates = new Map<
@@ -183,8 +174,7 @@ export class RawServiceMeshRuntime {
183
174
  private readonly onPeerNotRequired?: RawServiceMeshRuntimeOptions['onPeerNotRequired'];
184
175
  private readonly onPeerDisconnected?: RawServiceMeshRuntimeOptions['onPeerDisconnected'];
185
176
  private readonly onProtocolError?: RawServiceMeshRuntimeOptions['onProtocolError'];
186
- private readonly onReceiveFlowConfigFailure?:
187
- RawServiceMeshRuntimeOptions['onReceiveFlowConfigFailure'];
177
+ private readonly onReceiveFlowConfigFailure?: RawServiceMeshRuntimeOptions['onReceiveFlowConfigFailure'];
188
178
  private readonly resolveAdvertisedEndpoint?: RawServiceMeshRuntimeOptions['resolveAdvertisedEndpoint'];
189
179
  private descriptor: ServiceNodeDescriptor;
190
180
  private host?: ZLinkRawHostPort;
@@ -223,15 +213,14 @@ export class RawServiceMeshRuntime {
223
213
  router.setRoutingId(this.descriptor.nodeRoutingId);
224
214
  this.applicationJobQueue.registerReceiveFlowTarget?.(
225
215
  router,
226
- state => receiveFlowRouter.setReceiveFlowState(state),
216
+ (state) => receiveFlowRouter.setReceiveFlowState(state),
227
217
  this.onReceiveFlowConfigFailure
228
218
  );
229
219
  router.bind(this.descriptor.advertisedEndpoint);
230
220
  const boundEndpoint = router.localEndpoint();
231
221
  const next = {
232
222
  ...this.descriptor,
233
- advertisedEndpoint: this.resolveAdvertisedEndpoint?.(boundEndpoint)
234
- ?? boundEndpoint,
223
+ advertisedEndpoint: this.resolveAdvertisedEndpoint?.(boundEndpoint) ?? boundEndpoint,
235
224
  descriptorRevision: this.descriptor.descriptorRevision + 1n,
236
225
  state: 'serving' as const
237
226
  };
@@ -297,35 +286,20 @@ export class RawServiceMeshRuntime {
297
286
  this.endpointOnlyPeers.add(endpoint);
298
287
  }
299
288
 
300
- disconnectPeer(
301
- endpoint: string,
302
- nodeRoutingId: string,
303
- lifecycleGeneration?: bigint
304
- ): void {
289
+ disconnectPeer(endpoint: string, nodeRoutingId: string, lifecycleGeneration?: bigint): void {
305
290
  const current = this.topology.peer(nodeRoutingId);
306
291
  const expected = this.expectedPeers.get(nodeRoutingId);
307
292
  if (
308
- lifecycleGeneration !== undefined
309
- && (
310
- // Discovery has already fenced this RID to a replacement process.
311
- // The old auto-connect intent must not use disconnectRid here: that
312
- // is RID-wide and can close the provisional replacement before its
313
- // Hello/admission promotes it. admitPeer owns exact old-pair teardown
314
- // after the replacement descriptor is accepted.
315
- (
316
- expected?.lifecycleGeneration !== undefined
317
- && expected.lifecycleGeneration !== lifecycleGeneration
318
- )
319
- ||
320
- (
321
- current !== undefined
322
- && current.descriptor.lifecycleGeneration !== lifecycleGeneration
323
- )
324
- || (
325
- current === undefined
326
- && expected?.lifecycleGeneration !== lifecycleGeneration
327
- )
328
- )
293
+ lifecycleGeneration !== undefined &&
294
+ // Discovery has already fenced this RID to a replacement process.
295
+ // The old auto-connect intent must not use disconnectRid here: that
296
+ // is RID-wide and can close the provisional replacement before its
297
+ // Hello/admission promotes it. admitPeer owns exact old-pair teardown
298
+ // after the replacement descriptor is accepted.
299
+ ((expected?.lifecycleGeneration !== undefined &&
300
+ expected.lifecycleGeneration !== lifecycleGeneration) ||
301
+ (current !== undefined && current.descriptor.lifecycleGeneration !== lifecycleGeneration) ||
302
+ (current === undefined && expected?.lifecycleGeneration !== lifecycleGeneration))
329
303
  ) {
330
304
  return;
331
305
  }
@@ -342,9 +316,9 @@ export class RawServiceMeshRuntime {
342
316
  if (current !== undefined) this.removePeer(current);
343
317
  this.topology.forgetNotRequired(nodeRoutingId);
344
318
  if (
345
- lifecycleGeneration === undefined
346
- || expected?.lifecycleGeneration === undefined
347
- || expected.lifecycleGeneration === lifecycleGeneration
319
+ lifecycleGeneration === undefined ||
320
+ expected?.lifecycleGeneration === undefined ||
321
+ expected.lifecycleGeneration === lifecycleGeneration
348
322
  ) {
349
323
  this.expectedPeers.delete(nodeRoutingId);
350
324
  }
@@ -378,34 +352,38 @@ export class RawServiceMeshRuntime {
378
352
 
379
353
  observePeerConnectionIntentRemoved(listener: (nodeRoutingId: string) => void): () => void {
380
354
  this.peerConnectionIntentRemoved.add(listener);
381
- return () => { this.peerConnectionIntentRemoved.delete(listener); };
355
+ return () => {
356
+ this.peerConnectionIntentRemoved.delete(listener);
357
+ };
382
358
  }
383
359
 
384
360
  private notifyPeerConnectionIntentRemoved(nodeRoutingId: string): void {
385
361
  // Only the logical owner's removal publishes lifecycle termination.
386
362
  // A physical disconnect alone retains the connection expectation.
387
- if (this.expectedPeers.has(nodeRoutingId) || this.topology.peer(nodeRoutingId) !== undefined) return;
363
+ if (this.expectedPeers.has(nodeRoutingId) || this.topology.peer(nodeRoutingId) !== undefined)
364
+ return;
388
365
  for (const listener of this.peerConnectionIntentRemoved) listener(nodeRoutingId);
389
366
  }
390
367
 
391
368
  async announcePeer(nodeRoutingId: string): Promise<boolean> {
392
- if (!this.expectedPeers.has(nodeRoutingId) || this.peerAdmissionSealed?.() === true) return false;
393
- return this.send(
394
- nodeRoutingId,
395
- [encodeRouteMeshAdmission(M6aServiceWireCommand.hello, this.topology.localDescriptor())]
396
- );
369
+ if (!this.expectedPeers.has(nodeRoutingId) || this.peerAdmissionSealed?.() === true)
370
+ return false;
371
+ return this.send(nodeRoutingId, [
372
+ encodeRouteMeshAdmission(M6aServiceWireCommand.hello, this.topology.localDescriptor())
373
+ ]);
397
374
  }
398
375
 
399
376
  isPeerRouteReady(nodeRoutingId: string, lifecycleGeneration?: bigint): boolean {
400
377
  const peer = this.topology.peer(nodeRoutingId);
401
378
  const monitorConnection = this.monitorConnectionStates.get(nodeRoutingId);
402
- const applicationRouteReady = monitorConnection === undefined
403
- || monitorConnection === peer?.connectionId;
404
- const ready = peer !== undefined
405
- && (lifecycleGeneration === undefined
406
- || peer.descriptor.lifecycleGeneration === lifecycleGeneration)
407
- && applicationRouteReady
408
- && this.liveness.isReady(nodeRoutingId, peer.connectionId);
379
+ const applicationRouteReady =
380
+ monitorConnection === undefined || monitorConnection === peer?.connectionId;
381
+ const ready =
382
+ peer !== undefined &&
383
+ (lifecycleGeneration === undefined ||
384
+ peer.descriptor.lifecycleGeneration === lifecycleGeneration) &&
385
+ applicationRouteReady &&
386
+ this.liveness.isReady(nodeRoutingId, peer.connectionId);
409
387
  return ready;
410
388
  }
411
389
 
@@ -430,14 +408,16 @@ export class RawServiceMeshRuntime {
430
408
  readonly state?: 'draining';
431
409
  }): Promise<void> {
432
410
  const current = this.topology.localDescriptor();
433
- const channels = options.state === 'draining'
434
- ? current.channels.map(channel => ({ ...channel, weight: 0 }))
435
- : options.channelName === undefined
436
- ? current.channels
437
- : current.channels.map(channel =>
438
- channel.name === options.channelName
439
- ? { ...channel, weight: options.channelWeight! }
440
- : channel);
411
+ const channels =
412
+ options.state === 'draining'
413
+ ? current.channels.map((channel) => ({ ...channel, weight: 0 }))
414
+ : options.channelName === undefined
415
+ ? current.channels
416
+ : current.channels.map((channel) =>
417
+ channel.name === options.channelName
418
+ ? { ...channel, weight: options.channelWeight! }
419
+ : channel
420
+ );
441
421
  const next = {
442
422
  ...current,
443
423
  descriptorRevision: current.descriptorRevision + 1n,
@@ -461,16 +441,15 @@ export class RawServiceMeshRuntime {
461
441
  await this.announceExpectedPeers();
462
442
  }
463
443
 
464
- replaceDiscoveredNotRequired(
465
- descriptors: readonly ServiceNodeDescriptor[]
466
- ): void {
444
+ replaceDiscoveredNotRequired(descriptors: readonly ServiceNodeDescriptor[]): void {
467
445
  this.topology.replaceDiscoveredNotRequired(descriptors);
468
446
  }
469
447
 
470
448
  isObjectClientNodeDirectTarget(nodeRoutingId: string): boolean {
471
- const descriptor = nodeRoutingId === this.descriptor.nodeRoutingId
472
- ? this.topology.localDescriptor()
473
- : this.topology.knownDescriptor(nodeRoutingId);
449
+ const descriptor =
450
+ nodeRoutingId === this.descriptor.nodeRoutingId
451
+ ? this.topology.localDescriptor()
452
+ : this.topology.knownDescriptor(nodeRoutingId);
474
453
  return descriptor?.objectRole === 'client';
475
454
  }
476
455
 
@@ -478,19 +457,15 @@ export class RawServiceMeshRuntime {
478
457
  targetNodeRoutingId: string,
479
458
  payload: ServiceApplicationPayloadInput
480
459
  ): Promise<boolean> {
481
- return this.send(
482
- targetNodeRoutingId,
483
- [encodeNodeSendHeader(), this.applicationFrame(payload)]
484
- );
460
+ return this.send(targetNodeRoutingId, [encodeNodeSendHeader(), this.applicationFrame(payload)]);
485
461
  }
486
462
 
487
463
  async sendToChannel(
488
464
  channelName: string,
489
465
  payload: ServiceApplicationPayloadInput
490
466
  ): Promise<boolean> {
491
- const selected = this.topology.selectChannel(
492
- channelName,
493
- peer => this.isLocalOrReadyPeer(peer.descriptor.nodeRoutingId)
467
+ const selected = this.topology.selectChannel(channelName, (peer) =>
468
+ this.isLocalOrReadyPeer(peer.descriptor.nodeRoutingId)
494
469
  );
495
470
  if (selected === undefined) return false;
496
471
  const applicationFrame = this.applicationFrame(payload);
@@ -530,9 +505,8 @@ export class RawServiceMeshRuntime {
530
505
  payload: ServiceApplicationPayloadInput,
531
506
  timeoutMs: number
532
507
  ): PendingOperation<RawServiceRequestResult> | undefined {
533
- const selected = this.topology.selectChannel(
534
- channelName,
535
- peer => this.isLocalOrReadyPeer(peer.descriptor.nodeRoutingId)
508
+ const selected = this.topology.selectChannel(channelName, (peer) =>
509
+ this.isLocalOrReadyPeer(peer.descriptor.nodeRoutingId)
536
510
  );
537
511
  return selected === undefined
538
512
  ? undefined
@@ -540,8 +514,7 @@ export class RawServiceMeshRuntime {
540
514
  }
541
515
 
542
516
  private isLocalOrReadyPeer(nodeRoutingId: string): boolean {
543
- return nodeRoutingId === this.descriptor.nodeRoutingId
544
- || this.isPeerRouteReady(nodeRoutingId);
517
+ return nodeRoutingId === this.descriptor.nodeRoutingId || this.isPeerRouteReady(nodeRoutingId);
545
518
  }
546
519
 
547
520
  setServiceIngress(handler: RawServiceIngressHandler): void {
@@ -551,24 +524,16 @@ export class RawServiceMeshRuntime {
551
524
  this.serviceIngress = handler;
552
525
  }
553
526
 
554
- async reserveLocalIngress(
555
- signal?: AbortSignal
556
- ): Promise<ApplicationIngressRecordOwner> {
557
- const waitSignal = signal === undefined
558
- ? this.applicationJobStop.signal
559
- : AbortSignal.any([this.applicationJobStop.signal, signal]);
527
+ async reserveLocalIngress(signal?: AbortSignal): Promise<ApplicationIngressRecordOwner> {
528
+ const waitSignal =
529
+ signal === undefined
530
+ ? this.applicationJobStop.signal
531
+ : AbortSignal.any([this.applicationJobStop.signal, signal]);
560
532
  const permit = await this.applicationJobQueue.acquire(waitSignal);
561
- return ApplicationIngressRecordOwner.create(
562
- this.applicationJobQueue,
563
- permit,
564
- { close() {} }
565
- );
533
+ return ApplicationIngressRecordOwner.create(this.applicationJobQueue, permit, { close() {} });
566
534
  }
567
535
 
568
- async sendService(
569
- targetNodeRoutingId: string,
570
- parts: readonly Uint8Array[]
571
- ): Promise<boolean> {
536
+ async sendService(targetNodeRoutingId: string, parts: readonly Uint8Array[]): Promise<boolean> {
572
537
  return this.send(targetNodeRoutingId, parts);
573
538
  }
574
539
 
@@ -637,7 +602,9 @@ export class RawServiceMeshRuntime {
637
602
  const startedAtMs = performance.now();
638
603
  let messages = 0;
639
604
  let bytes = 0;
640
- const observe: RawServicePumpObserver = (_source, byteCount) => { bytes += byteCount; };
605
+ const observe: RawServicePumpObserver = (_source, byteCount) => {
606
+ bytes += byteCount;
607
+ };
641
608
  while (receiveReady && messages < 64 && !this.closed) {
642
609
  const result = await this.receiveOne(performance.now(), observe);
643
610
  if (result === 'noData') {
@@ -704,13 +671,13 @@ export class RawServiceMeshRuntime {
704
671
  }
705
672
 
706
673
  private pullMonitorEvents(): void {
707
- this.monitor?.drain(event => {
674
+ this.monitor?.drain((event) => {
708
675
  this.observeMonitorEvent(event);
709
676
  if (this.monitorEvents.length < MAX_PENDING_MONITOR_EVENTS) {
710
677
  this.monitorEvents.push(event);
711
678
  return;
712
679
  }
713
- const existingIndex = this.monitorEvents.findIndex(candidate =>
680
+ const existingIndex = this.monitorEvents.findIndex((candidate) =>
714
681
  sameMonitorConnection(candidate, event)
715
682
  );
716
683
  if (existingIndex >= 0) this.monitorEvents[existingIndex] = event;
@@ -740,17 +707,20 @@ export class RawServiceMeshRuntime {
740
707
  if (received.requestSeq === undefined || received.parts.length === 0) return false;
741
708
  try {
742
709
  const header = decodeHeader(received.parts[0]!);
743
- const correlation = header.command === M6aServiceWireCommand.nodeRequest
744
- ? decodeNodeRequestHeader(received.parts[0]!)
745
- : header.command === M6aServiceWireCommand.channelRequest
746
- ? decodeChannelRequestHeader(received.parts[0]!).correlation
747
- : undefined;
710
+ const correlation =
711
+ header.command === M6aServiceWireCommand.nodeRequest
712
+ ? decodeNodeRequestHeader(received.parts[0]!)
713
+ : header.command === M6aServiceWireCommand.channelRequest
714
+ ? decodeChannelRequestHeader(received.parts[0]!).correlation
715
+ : undefined;
748
716
  if (correlation === undefined) return false;
749
- const reply = [encodeReplyHeader(
750
- correlation,
751
- RequestResult.ProtocolError,
752
- ServiceWireFrameworkErrorCode.requestProtocolError
753
- )];
717
+ const reply = [
718
+ encodeReplyHeader(
719
+ correlation,
720
+ RequestResult.ProtocolError,
721
+ ServiceWireFrameworkErrorCode.requestProtocolError
722
+ )
723
+ ];
754
724
  if (received.reply === undefined) return false;
755
725
  received.reply(reply);
756
726
  return true;
@@ -766,17 +736,13 @@ export class RawServiceMeshRuntime {
766
736
  applicationJobOwner: ApplicationIngressRecordOwner
767
737
  ): Promise<RawServicePumpResult> {
768
738
  if (
769
- received.parts.length === 0
770
- || (
771
- received.parts.length === 1
772
- && received.parts[0]!.byteLength === 0
773
- )
739
+ received.parts.length === 0 ||
740
+ (received.parts.length === 1 && received.parts[0]!.byteLength === 0)
774
741
  ) {
775
742
  if (this.peerAdmissionSealed?.() === true) return 'dropped';
776
- return await this.send(
777
- received.sourceRid,
778
- [encodeRouteMeshAdmission(M6aServiceWireCommand.hello, this.topology.localDescriptor())]
779
- )
743
+ return (await this.send(received.sourceRid, [
744
+ encodeRouteMeshAdmission(M6aServiceWireCommand.hello, this.topology.localDescriptor())
745
+ ]))
780
746
  ? 'infrastructure'
781
747
  : 'dropped';
782
748
  }
@@ -786,9 +752,9 @@ export class RawServiceMeshRuntime {
786
752
  return 'dropped';
787
753
  }
788
754
  if (
789
- header.command === M6aServiceWireCommand.hello
790
- || header.command === M6aServiceWireCommand.admit
791
- || header.command === M6aServiceWireCommand.update
755
+ header.command === M6aServiceWireCommand.hello ||
756
+ header.command === M6aServiceWireCommand.admit ||
757
+ header.command === M6aServiceWireCommand.update
792
758
  ) {
793
759
  if (received.parts.length !== 1) return 'protocolError';
794
760
  const descriptor = decodeRouteMeshAdmission(
@@ -798,11 +764,9 @@ export class RawServiceMeshRuntime {
798
764
  );
799
765
  const expected = this.expectedPeers.get(received.sourceRid);
800
766
  if (
801
- expected !== undefined
802
- && (
803
- expected.meshName !== descriptor.meshName
804
- || expected.nodeRoutingId !== descriptor.nodeRoutingId
805
- )
767
+ expected !== undefined &&
768
+ (expected.meshName !== descriptor.meshName ||
769
+ expected.nodeRoutingId !== descriptor.nodeRoutingId)
806
770
  ) {
807
771
  await this.send(received.sourceRid, [encodeReject(3)]);
808
772
  return 'infrastructure';
@@ -811,23 +775,19 @@ export class RawServiceMeshRuntime {
811
775
  received.sourceRid,
812
776
  descriptor.advertisedEndpoint
813
777
  );
814
- const result = this.admitPeer(
815
- descriptor,
816
- connection,
817
- nowMs,
818
- expected
819
- );
778
+ const result = this.admitPeer(descriptor, connection, nowMs, expected);
820
779
  if (result !== 'admitted' && result !== 'notRequired') {
821
- const detail = result === 'invalidDescriptor'
822
- ? describeInvalidAdmissionDescriptor(
823
- descriptor,
824
- expected,
825
- this.topology.peer(descriptor.nodeRoutingId)?.descriptor
826
- )
827
- : undefined;
780
+ const detail =
781
+ result === 'invalidDescriptor'
782
+ ? describeInvalidAdmissionDescriptor(
783
+ descriptor,
784
+ expected,
785
+ this.topology.peer(descriptor.nodeRoutingId)?.descriptor
786
+ )
787
+ : undefined;
828
788
  console.warn(
829
- `RouteMesh admission rejected peer '${received.sourceRid}' as ${result}`
830
- + (detail === undefined ? '.' : ` (${detail}).`)
789
+ `RouteMesh admission rejected peer '${received.sourceRid}' as ${result}` +
790
+ (detail === undefined ? '.' : ` (${detail}).`)
831
791
  );
832
792
  await this.send(received.sourceRid, [encodeReject(admissionReason(result))]);
833
793
  return 'infrastructure';
@@ -837,15 +797,11 @@ export class RawServiceMeshRuntime {
837
797
  // Hello supplies only the sender's descriptor. Even NotRequired
838
798
  // peers must receive ours before the intent owner closes transport;
839
799
  // submitting a response does not guarantee delivery before close.
840
- await this.send(
841
- received.sourceRid,
842
- [encodeRouteMeshAdmission(M6aServiceWireCommand.admit, this.topology.localDescriptor())]
843
- );
800
+ await this.send(received.sourceRid, [
801
+ encodeRouteMeshAdmission(M6aServiceWireCommand.admit, this.topology.localDescriptor())
802
+ ]);
844
803
  } else if (result === 'notRequired') {
845
- this.retireNotRequiredExpectedPeer(
846
- received.sourceRid,
847
- descriptor.advertisedEndpoint
848
- );
804
+ this.retireNotRequiredExpectedPeer(received.sourceRid, descriptor.advertisedEndpoint);
849
805
  }
850
806
  return 'infrastructure';
851
807
  }
@@ -875,8 +831,8 @@ export class RawServiceMeshRuntime {
875
831
  const peer = this.topology.peer(received.sourceRid);
876
832
  if (peer === undefined) return 'protocolError';
877
833
  if (
878
- header.command === M6aServiceWireCommand.livenessProbe
879
- || header.command === M6aServiceWireCommand.livenessAck
834
+ header.command === M6aServiceWireCommand.livenessProbe ||
835
+ header.command === M6aServiceWireCommand.livenessAck
880
836
  ) {
881
837
  if (received.parts.length !== 1) return 'protocolError';
882
838
  const record = livenessCodec.decodeLivenessRecord(received.parts[0]!);
@@ -886,23 +842,19 @@ export class RawServiceMeshRuntime {
886
842
  peer.connectionId,
887
843
  record.probeId
888
844
  );
889
- const sent = ack !== undefined && await this.send(
890
- received.sourceRid,
891
- [livenessCodec.encodeLivenessRecord({
892
- command: M6aServiceWireCommand.livenessAck,
893
- probeId: record.probeId
894
- })]
895
- );
845
+ const sent =
846
+ ack !== undefined &&
847
+ (await this.send(received.sourceRid, [
848
+ livenessCodec.encodeLivenessRecord({
849
+ command: M6aServiceWireCommand.livenessAck,
850
+ probeId: record.probeId
851
+ })
852
+ ]));
896
853
  if (!sent) {
897
854
  return 'protocolError';
898
855
  }
899
856
  } else {
900
- this.liveness.acknowledge(
901
- received.sourceRid,
902
- peer.connectionId,
903
- record.probeId,
904
- nowMs
905
- );
857
+ this.liveness.acknowledge(received.sourceRid, peer.connectionId, record.probeId, nowMs);
906
858
  }
907
859
  return 'infrastructure';
908
860
  }
@@ -919,7 +871,7 @@ export class RawServiceMeshRuntime {
919
871
  });
920
872
  if (stateful !== undefined) return stateful;
921
873
  if (
922
- header.flags === 0
874
+ header.flags === 0 &&
923
875
  // A bare infrastructure control is normally exactly one frame, but a
924
876
  // relocation Prepare now rides its bound-session journal as
925
877
  // node-internal ZLNI frames trailing the canonical command frame
@@ -931,8 +883,8 @@ export class RawServiceMeshRuntime {
931
883
  // protocolError (surfaced downstream as `invalid_frame`, stalling
932
884
  // the source's Prepare resend loop past the relocation admission
933
885
  // budget).
934
- && received.parts.length >= 1
935
- && isBareInfrastructureControl(header.command)
886
+ received.parts.length >= 1 &&
887
+ isBareInfrastructureControl(header.command)
936
888
  ) {
937
889
  const accepted = this.mailbox.tryEnqueue({
938
890
  owner: `node:${this.descriptor.nodeRoutingId}`,
@@ -946,9 +898,9 @@ export class RawServiceMeshRuntime {
946
898
  return accepted ? 'infrastructure' : 'dropped';
947
899
  }
948
900
  if (
949
- header.flags !== 0
950
- || received.parts.length !== 2
951
- || ![
901
+ header.flags !== 0 ||
902
+ received.parts.length !== 2 ||
903
+ ![
952
904
  M6aServiceWireCommand.nodeSend,
953
905
  M6aServiceWireCommand.nodeRequest,
954
906
  M6aServiceWireCommand.channelSend,
@@ -986,18 +938,15 @@ export class RawServiceMeshRuntime {
986
938
  if (accepted) return 'application';
987
939
  applicationJob.close();
988
940
  if (correlation !== undefined && received.requestSeq !== undefined) {
989
- this.replyService({
990
- sourceRoutingId: received.sourceRid,
991
- sourceRoute: received.sourceRoute,
992
- requestSequence: received.requestSeq,
993
- ...(received.reply === undefined ? {} : { reply: received.reply })
994
- }, [
995
- encodeReplyHeader(
996
- correlation,
997
- RequestResult.NotConnected,
998
- 0
999
- )
1000
- ]);
941
+ this.replyService(
942
+ {
943
+ sourceRoutingId: received.sourceRid,
944
+ sourceRoute: received.sourceRoute,
945
+ requestSequence: received.requestSeq,
946
+ ...(received.reply === undefined ? {} : { reply: received.reply })
947
+ },
948
+ [encodeReplyHeader(correlation, RequestResult.NotConnected, 0)]
949
+ );
1001
950
  return 'infrastructure';
1002
951
  }
1003
952
  return 'dropped';
@@ -1011,10 +960,12 @@ export class RawServiceMeshRuntime {
1011
960
  const result = this.liveness.tick(nowMs);
1012
961
  this.requireStarted();
1013
962
  for (const probe of result.probes) {
1014
- await this.send(probe.nodeRoutingId, [livenessCodec.encodeLivenessRecord({
1015
- command: M6aServiceWireCommand.livenessProbe,
1016
- probeId: probe.probeId
1017
- })]);
963
+ await this.send(probe.nodeRoutingId, [
964
+ livenessCodec.encodeLivenessRecord({
965
+ command: M6aServiceWireCommand.livenessProbe,
966
+ probeId: probe.probeId
967
+ })
968
+ ]);
1018
969
  }
1019
970
  for (const nodeRoutingId of result.timedOutNodes) {
1020
971
  const peer = this.topology.peer(nodeRoutingId);
@@ -1039,15 +990,17 @@ export class RawServiceMeshRuntime {
1039
990
  this.monitorEvents.length = 0;
1040
991
  for (const event of events) {
1041
992
  handled++;
1042
- const nodeRoutingId = event.routingId
1043
- ?? this.expectedPeerRoutingId(event.remoteAddress);
993
+ const nodeRoutingId = event.routingId ?? this.expectedPeerRoutingId(event.remoteAddress);
1044
994
  if (event.event === MONITOR_CONNECTION_READY && isConnectionReadyEdge(event)) {
1045
995
  if (nodeRoutingId === undefined) {
1046
996
  const candidate = this.createUnresolvedConnectionCandidate(event);
1047
997
  const alreadyQueued = this.unresolvedConnectionCandidates.some(
1048
- value => value.connectionId === candidate.connectionId
998
+ (value) => value.connectionId === candidate.connectionId
1049
999
  );
1050
- if (!alreadyQueued && this.unresolvedConnectionCandidates.length < MAX_UNRESOLVED_CONNECTION_CANDIDATES) {
1000
+ if (
1001
+ !alreadyQueued &&
1002
+ this.unresolvedConnectionCandidates.length < MAX_UNRESOLVED_CONNECTION_CANDIDATES
1003
+ ) {
1051
1004
  this.unresolvedConnectionCandidates.push(candidate);
1052
1005
  }
1053
1006
  continue;
@@ -1064,7 +1017,8 @@ export class RawServiceMeshRuntime {
1064
1017
  if (existingPeer !== undefined) {
1065
1018
  if (this.liveness.isReady(nodeRoutingId, existingPeer.connectionId)) {
1066
1019
  const existingCandidate = this.connectionCandidates
1067
- .get(nodeRoutingId)?.get(existingPeer.connectionId);
1020
+ .get(nodeRoutingId)
1021
+ ?.get(existingPeer.connectionId);
1068
1022
  if (this.isDiscoveredLifecycleReplacement(existingPeer, nodeRoutingId)) {
1069
1023
  // A current discovery descriptor with the same RID but a
1070
1024
  // different lifecycle token denotes a replacement process.
@@ -1117,22 +1071,17 @@ export class RawServiceMeshRuntime {
1117
1071
  // route evidence available to the admission message.
1118
1072
  this.connectionIds.set(nodeRoutingId, candidate.connectionId);
1119
1073
  await this.announcePeer(nodeRoutingId);
1120
- } else if (
1121
- event.event === MONITOR_DISCONNECTED
1122
- && nodeRoutingId !== undefined
1123
- ) {
1074
+ } else if (event.event === MONITOR_DISCONNECTED && nodeRoutingId !== undefined) {
1124
1075
  const peer = this.topology.peer(nodeRoutingId);
1125
1076
  const disconnectedId = monitorConnectionId(event, nodeRoutingId);
1126
1077
  this.removeConnectionCandidate(nodeRoutingId, disconnectedId);
1127
1078
  if (peer !== undefined && peer.connectionId === disconnectedId) {
1128
1079
  this.removePeer(peer);
1129
1080
  }
1130
- } else if (
1131
- event.event === MONITOR_DISCONNECTED
1132
- ) {
1081
+ } else if (event.event === MONITOR_DISCONNECTED) {
1133
1082
  const disconnectedId = monitorConnectionId(event);
1134
1083
  const index = this.unresolvedConnectionCandidates.findIndex(
1135
- candidate => candidate.connectionId === disconnectedId
1084
+ (candidate) => candidate.connectionId === disconnectedId
1136
1085
  );
1137
1086
  if (index >= 0) this.unresolvedConnectionCandidates.splice(index, 1);
1138
1087
  }
@@ -1170,15 +1119,16 @@ export class RawServiceMeshRuntime {
1170
1119
  channelName?: string
1171
1120
  ): PendingOperation<RawServiceRequestResult> {
1172
1121
  const correlation = this.nextCorrelation++;
1173
- const header = channelName === undefined
1174
- ? encodeNodeRequestHeader(correlation)
1175
- : encodeChannelRequestHeader(correlation, channelName);
1122
+ const header =
1123
+ channelName === undefined
1124
+ ? encodeNodeRequestHeader(correlation)
1125
+ : encodeChannelRequestHeader(correlation, channelName);
1176
1126
  const encodedPayload = this.applicationFrame(payload);
1177
1127
  const pending = this.operations.register(timeoutMs);
1178
1128
  let selectedTargetNodeRoutingId = targetNodeRoutingId;
1179
1129
  if (
1180
- selectedTargetNodeRoutingId !== this.descriptor.nodeRoutingId
1181
- && !this.isPeerRouteReady(selectedTargetNodeRoutingId)
1130
+ selectedTargetNodeRoutingId !== this.descriptor.nodeRoutingId &&
1131
+ !this.isPeerRouteReady(selectedTargetNodeRoutingId)
1182
1132
  ) {
1183
1133
  // Channel selection happens before native admission. If that selection
1184
1134
  // becomes stale during a peer drain, choose another ready channel peer
@@ -1188,19 +1138,15 @@ export class RawServiceMeshRuntime {
1188
1138
  if (channelName !== undefined) {
1189
1139
  const excludedTargets = new Set([selectedTargetNodeRoutingId]);
1190
1140
  for (;;) {
1191
- const alternate = this.topology.selectChannel(
1192
- channelName,
1193
- peer => {
1194
- const candidate = peer.descriptor.nodeRoutingId;
1195
- return !excludedTargets.has(candidate)
1196
- && this.isLocalOrReadyPeer(candidate);
1197
- }
1198
- );
1141
+ const alternate = this.topology.selectChannel(channelName, (peer) => {
1142
+ const candidate = peer.descriptor.nodeRoutingId;
1143
+ return !excludedTargets.has(candidate) && this.isLocalOrReadyPeer(candidate);
1144
+ });
1199
1145
  if (alternate === undefined) break;
1200
1146
  selectedTargetNodeRoutingId = alternate.descriptor.nodeRoutingId;
1201
1147
  if (
1202
- selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId
1203
- || this.isPeerRouteReady(selectedTargetNodeRoutingId)
1148
+ selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId ||
1149
+ this.isPeerRouteReady(selectedTargetNodeRoutingId)
1204
1150
  ) {
1205
1151
  break;
1206
1152
  }
@@ -1225,9 +1171,10 @@ export class RawServiceMeshRuntime {
1225
1171
  return;
1226
1172
  }
1227
1173
  const accepted = this.mailbox.tryEnqueue({
1228
- owner: channelName === undefined
1229
- ? `node:${this.descriptor.nodeRoutingId}`
1230
- : `channel:${channelName}`,
1174
+ owner:
1175
+ channelName === undefined
1176
+ ? `node:${this.descriptor.nodeRoutingId}`
1177
+ : `channel:${channelName}`,
1231
1178
  domain: 'application',
1232
1179
  parts,
1233
1180
  sourceRoutingId: this.descriptor.nodeRoutingId,
@@ -1250,7 +1197,7 @@ export class RawServiceMeshRuntime {
1250
1197
  } finally {
1251
1198
  applicationJobOwner.close();
1252
1199
  }
1253
- })().catch(error => this.operations.fail(pending.id, error));
1200
+ })().catch((error) => this.operations.fail(pending.id, error));
1254
1201
  return pending;
1255
1202
  }
1256
1203
  if (!this.isPeerRouteReady(selectedTargetNodeRoutingId)) {
@@ -1258,12 +1205,11 @@ export class RawServiceMeshRuntime {
1258
1205
  // topology has never observed. A known peer without a usable route is
1259
1206
  // a Framework NotConnected result; an unknown RID is completed locally
1260
1207
  // as RequestTargetNotFound without submitting an application frame.
1261
- const knownTarget = this.topology.peer(selectedTargetNodeRoutingId) !== undefined
1262
- || this.topology.knownDescriptor(selectedTargetNodeRoutingId) !== undefined;
1208
+ const knownTarget =
1209
+ this.topology.peer(selectedTargetNodeRoutingId) !== undefined ||
1210
+ this.topology.knownDescriptor(selectedTargetNodeRoutingId) !== undefined;
1263
1211
  this.operations.complete(pending.id, {
1264
- terminalResult: knownTarget
1265
- ? RequestResult.NotConnected
1266
- : RequestResult.NotFound,
1212
+ terminalResult: knownTarget ? RequestResult.NotConnected : RequestResult.NotFound,
1267
1213
  failureCode: knownTarget ? 0 : REQUEST_TARGET_NOT_FOUND_FAILURE_CODE
1268
1214
  });
1269
1215
  return pending;
@@ -1273,25 +1219,24 @@ export class RawServiceMeshRuntime {
1273
1219
  let request: Promise<readonly Uint8Array[]>;
1274
1220
  try {
1275
1221
  router = this.requireStarted();
1276
- request = router.request(
1277
- selectedTargetNodeRoutingId,
1278
- parts,
1279
- timeoutMs
1280
- );
1222
+ request = router.request(selectedTargetNodeRoutingId, parts, timeoutMs);
1281
1223
  } catch (error) {
1282
1224
  this.operations.fail(pending.id, error);
1283
1225
  return pending;
1284
1226
  }
1285
1227
  void request.then(
1286
- replyParts => {
1228
+ (replyParts) => {
1287
1229
  try {
1288
1230
  if (replyParts.length < 1 || replyParts.length > 2) {
1289
1231
  throw new ServiceWireProtocolError('Invalid reply parts.');
1290
1232
  }
1291
1233
  const reply = decodeReplyHeader(replyParts[0]!);
1292
- if (reply.correlation !== correlation) throw new ServiceWireProtocolError('Reply correlation mismatch.');
1234
+ if (reply.correlation !== correlation)
1235
+ throw new ServiceWireProtocolError('Reply correlation mismatch.');
1293
1236
  if (reply.tail.byteLength !== 0) {
1294
- throw new ServiceWireProtocolError('Generic node/channel reply carries an operation-specific tail.');
1237
+ throw new ServiceWireProtocolError(
1238
+ 'Generic node/channel reply carries an operation-specific tail.'
1239
+ );
1295
1240
  }
1296
1241
  if (reply.terminalResult === 0 && replyParts.length !== 2) {
1297
1242
  throw new ServiceWireProtocolError('Successful reply omits its payload.');
@@ -1313,7 +1258,7 @@ export class RawServiceMeshRuntime {
1313
1258
  this.operations.fail(pending.id, error);
1314
1259
  }
1315
1260
  },
1316
- error => {
1261
+ (error) => {
1317
1262
  this.operations.fail(pending.id, error);
1318
1263
  }
1319
1264
  );
@@ -1344,15 +1289,11 @@ export class RawServiceMeshRuntime {
1344
1289
  ): PeerAdmissionResult {
1345
1290
  const previous = this.topology.peer(descriptor.nodeRoutingId);
1346
1291
  if (
1347
- previous !== undefined
1348
- && previous.descriptor.lifecycleGeneration === descriptor.lifecycleGeneration
1349
- && (
1350
- descriptor.descriptorRevision < previous.descriptor.descriptorRevision
1351
- || (
1352
- descriptor.descriptorRevision === previous.descriptor.descriptorRevision
1353
- && !sameServiceNodeDescriptor(previous.descriptor, descriptor)
1354
- )
1355
- )
1292
+ previous !== undefined &&
1293
+ previous.descriptor.lifecycleGeneration === descriptor.lifecycleGeneration &&
1294
+ (descriptor.descriptorRevision < previous.descriptor.descriptorRevision ||
1295
+ (descriptor.descriptorRevision === previous.descriptor.descriptorRevision &&
1296
+ !sameServiceNodeDescriptor(previous.descriptor, descriptor)))
1356
1297
  ) {
1357
1298
  throw new ServiceWireProtocolError(
1358
1299
  `RouteMesh peer '${descriptor.nodeRoutingId}' descriptor revision is stale or conflicting.`
@@ -1365,45 +1306,24 @@ export class RawServiceMeshRuntime {
1365
1306
  connection.discriminator
1366
1307
  );
1367
1308
  if (result === 'admitted') {
1368
- this.connectionIds.set(
1369
- descriptor.nodeRoutingId,
1370
- connection.connectionId
1371
- );
1309
+ this.connectionIds.set(descriptor.nodeRoutingId, connection.connectionId);
1372
1310
  this.liveness.admit(descriptor.nodeRoutingId, connection.connectionId, nowMs);
1373
- this.liveness.requestProbe(
1374
- descriptor.nodeRoutingId,
1375
- connection.connectionId,
1376
- nowMs
1377
- );
1378
- this.monitorConnectionStates.set(
1379
- descriptor.nodeRoutingId,
1380
- connection.connectionId
1381
- );
1311
+ this.liveness.requestProbe(descriptor.nodeRoutingId, connection.connectionId, nowMs);
1312
+ this.monitorConnectionStates.set(descriptor.nodeRoutingId, connection.connectionId);
1382
1313
  if (previous !== undefined && previous.connectionId !== connection.connectionId) {
1383
1314
  const previousCandidate = this.connectionCandidates
1384
- .get(descriptor.nodeRoutingId)?.get(previous.connectionId);
1315
+ .get(descriptor.nodeRoutingId)
1316
+ ?.get(previous.connectionId);
1385
1317
  if (previousCandidate !== undefined) {
1386
- this.removeConnectionCandidate(
1387
- descriptor.nodeRoutingId,
1388
- previousCandidate.connectionId
1389
- );
1318
+ this.removeConnectionCandidate(descriptor.nodeRoutingId, previousCandidate.connectionId);
1390
1319
  }
1391
1320
  }
1392
1321
  } else if (result === 'notRequired' && previous !== undefined) {
1393
- this.liveness.disconnect(
1394
- descriptor.nodeRoutingId,
1395
- previous.connectionId
1396
- );
1322
+ this.liveness.disconnect(descriptor.nodeRoutingId, previous.connectionId);
1397
1323
  } else if (previous !== undefined) {
1398
- this.connectionIds.set(
1399
- descriptor.nodeRoutingId,
1400
- previous.connectionId
1401
- );
1324
+ this.connectionIds.set(descriptor.nodeRoutingId, previous.connectionId);
1402
1325
  if (connection.connectionId !== previous.connectionId) {
1403
- this.removeConnectionCandidate(
1404
- descriptor.nodeRoutingId,
1405
- connection.connectionId
1406
- );
1326
+ this.removeConnectionCandidate(descriptor.nodeRoutingId, connection.connectionId);
1407
1327
  }
1408
1328
  }
1409
1329
  return result;
@@ -1414,32 +1334,30 @@ export class RawServiceMeshRuntime {
1414
1334
  advertisedEndpoint: string
1415
1335
  ): PhysicalConnectionCandidate {
1416
1336
  let connectionId = this.connectionIds.get(nodeRoutingId);
1417
- let candidate = connectionId === undefined
1418
- ? undefined
1419
- : this.connectionCandidates.get(nodeRoutingId)?.get(connectionId);
1337
+ let candidate =
1338
+ connectionId === undefined
1339
+ ? undefined
1340
+ : this.connectionCandidates.get(nodeRoutingId)?.get(connectionId);
1420
1341
  if (candidate === undefined) {
1421
- candidate = this.promoteUnresolvedConnectionCandidate(
1422
- nodeRoutingId,
1423
- advertisedEndpoint
1424
- );
1342
+ candidate = this.promoteUnresolvedConnectionCandidate(nodeRoutingId, advertisedEndpoint);
1425
1343
  connectionId = candidate?.connectionId;
1426
1344
  }
1427
1345
  if (candidate === undefined) {
1428
1346
  const localRid = this.topology.localDescriptor().nodeRoutingId;
1429
1347
  const endpointOnly = this.endpointOnlyPeers.has(advertisedEndpoint);
1430
- const direction: PhysicalConnectionDirection =
1431
- this.expectedPeers.has(nodeRoutingId)
1432
- ? 'outbound'
1433
- : endpointOnly
1434
- ? localRid.localeCompare(nodeRoutingId) <= 0
1435
- ? 'outbound'
1436
- : 'inbound'
1437
- : 'inbound';
1438
- const initiator = endpointOnly && localRid.localeCompare(nodeRoutingId) > 0
1439
- ? nodeRoutingId
1440
- : direction === 'outbound'
1441
- ? localRid
1442
- : nodeRoutingId;
1348
+ const direction: PhysicalConnectionDirection = this.expectedPeers.has(nodeRoutingId)
1349
+ ? 'outbound'
1350
+ : endpointOnly
1351
+ ? localRid.localeCompare(nodeRoutingId) <= 0
1352
+ ? 'outbound'
1353
+ : 'inbound'
1354
+ : 'inbound';
1355
+ const initiator =
1356
+ endpointOnly && localRid.localeCompare(nodeRoutingId) > 0
1357
+ ? nodeRoutingId
1358
+ : direction === 'outbound'
1359
+ ? localRid
1360
+ : nodeRoutingId;
1443
1361
  connectionId = `unmonitored:${direction}:${randomUUID()}`;
1444
1362
  candidate = {
1445
1363
  connectionId,
@@ -1473,17 +1391,19 @@ export class RawServiceMeshRuntime {
1473
1391
  : this.endpointOnlyPeers.has(event.remoteAddress)
1474
1392
  ? 'outbound'
1475
1393
  : 'unknown';
1476
- const initiator = direction === 'outbound'
1477
- ? local.nodeRoutingId
1478
- : direction === 'inbound'
1479
- ? nodeRoutingId
1480
- : undefined;
1394
+ const initiator =
1395
+ direction === 'outbound'
1396
+ ? local.nodeRoutingId
1397
+ : direction === 'inbound'
1398
+ ? nodeRoutingId
1399
+ : undefined;
1481
1400
  return {
1482
1401
  connectionId: monitorConnectionId(event, nodeRoutingId),
1483
1402
  direction,
1484
- discriminator: initiator === undefined
1485
- ? `unknown:${monitorConnectionId(event, nodeRoutingId)}`
1486
- : `initiator:${initiator}`,
1403
+ discriminator:
1404
+ initiator === undefined
1405
+ ? `unknown:${monitorConnectionId(event, nodeRoutingId)}`
1406
+ : `initiator:${initiator}`,
1487
1407
  localAddress: event.localAddress,
1488
1408
  remoteAddress: event.remoteAddress
1489
1409
  };
@@ -1495,8 +1415,8 @@ export class RawServiceMeshRuntime {
1495
1415
  const connectionId = monitorConnectionId(event);
1496
1416
  const local = this.topology.localDescriptor();
1497
1417
  const direction: PhysicalConnectionDirection =
1498
- this.endpointOnlyPeers.has(event.remoteAddress)
1499
- || this.expectedPeerRoutingId(event.remoteAddress) !== undefined
1418
+ this.endpointOnlyPeers.has(event.remoteAddress) ||
1419
+ this.expectedPeerRoutingId(event.remoteAddress) !== undefined
1500
1420
  ? 'outbound'
1501
1421
  : event.localAddress === local.advertisedEndpoint
1502
1422
  ? 'inbound'
@@ -1516,11 +1436,12 @@ export class RawServiceMeshRuntime {
1516
1436
  ): PhysicalConnectionCandidate | undefined {
1517
1437
  const relevant = this.unresolvedConnectionCandidates
1518
1438
  .map((candidate, index) => ({ candidate, index }))
1519
- .filter(({ candidate }) =>
1520
- candidate.remoteAddress === advertisedEndpoint
1521
- || candidate.direction === 'inbound');
1439
+ .filter(
1440
+ ({ candidate }) =>
1441
+ candidate.remoteAddress === advertisedEndpoint || candidate.direction === 'inbound'
1442
+ );
1522
1443
  if (relevant.length === 0) return undefined;
1523
- const directions = new Set(relevant.map(value => value.candidate.direction));
1444
+ const directions = new Set(relevant.map((value) => value.candidate.direction));
1524
1445
  const localRid = this.topology.localDescriptor().nodeRoutingId;
1525
1446
  const preferredDirection: PhysicalConnectionDirection =
1526
1447
  directions.has('inbound') && directions.has('outbound')
@@ -1528,21 +1449,22 @@ export class RawServiceMeshRuntime {
1528
1449
  ? 'outbound'
1529
1450
  : 'inbound'
1530
1451
  : relevant.at(-1)!.candidate.direction;
1531
- const selected = [...relevant]
1532
- .reverse()
1533
- .find(value => value.candidate.direction === preferredDirection)
1534
- ?? relevant.at(-1)!;
1452
+ const selected =
1453
+ [...relevant].reverse().find((value) => value.candidate.direction === preferredDirection) ??
1454
+ relevant.at(-1)!;
1535
1455
  this.unresolvedConnectionCandidates.splice(selected.index, 1);
1536
- const initiator = selected.candidate.direction === 'outbound'
1537
- ? localRid
1538
- : selected.candidate.direction === 'inbound'
1539
- ? nodeRoutingId
1540
- : undefined;
1456
+ const initiator =
1457
+ selected.candidate.direction === 'outbound'
1458
+ ? localRid
1459
+ : selected.candidate.direction === 'inbound'
1460
+ ? nodeRoutingId
1461
+ : undefined;
1541
1462
  const candidate: PhysicalConnectionCandidate = {
1542
1463
  ...selected.candidate,
1543
- discriminator: initiator === undefined
1544
- ? `unknown:${selected.candidate.connectionId}`
1545
- : `initiator:${initiator}`
1464
+ discriminator:
1465
+ initiator === undefined
1466
+ ? `unknown:${selected.candidate.connectionId}`
1467
+ : `initiator:${initiator}`
1546
1468
  };
1547
1469
  let candidates = this.connectionCandidates.get(nodeRoutingId);
1548
1470
  if (candidates === undefined) {
@@ -1571,10 +1493,12 @@ export class RawServiceMeshRuntime {
1571
1493
  // A same-RID replacement is permitted only from a complete discovery
1572
1494
  // fence. Manual/endpoint-only intent has no authority to replace a ready
1573
1495
  // peer, and lifecycle generations are opaque equality tokens.
1574
- return expected?.endpoint !== undefined
1575
- && expected.securityIdentity !== undefined
1576
- && expected.lifecycleGeneration !== undefined
1577
- && admitted.descriptor.lifecycleGeneration !== expected.lifecycleGeneration;
1496
+ return (
1497
+ expected?.endpoint !== undefined &&
1498
+ expected.securityIdentity !== undefined &&
1499
+ expected.lifecycleGeneration !== undefined &&
1500
+ admitted.descriptor.lifecycleGeneration !== expected.lifecycleGeneration
1501
+ );
1578
1502
  }
1579
1503
 
1580
1504
  private expectedPeerRoutingId(endpoint: string): string | undefined {
@@ -1594,22 +1518,20 @@ export class RawServiceMeshRuntime {
1594
1518
  // discovery advertised endpoint would reject valid READY events.
1595
1519
  if (event.routingId === nodeRoutingId) return true;
1596
1520
  const expected = this.expectedPeers.get(nodeRoutingId);
1597
- return expected === undefined || expected.endpoint === undefined
1598
- || expected.endpoint === event.remoteAddress;
1521
+ return (
1522
+ expected === undefined ||
1523
+ expected.endpoint === undefined ||
1524
+ expected.endpoint === event.remoteAddress
1525
+ );
1599
1526
  }
1600
1527
 
1601
- private retireNotRequiredExpectedPeer(
1602
- nodeRoutingId: string,
1603
- advertisedEndpoint?: string
1604
- ): void {
1528
+ private retireNotRequiredExpectedPeer(nodeRoutingId: string, advertisedEndpoint?: string): void {
1605
1529
  const expected = this.expectedPeers.get(nodeRoutingId);
1606
- const endpoint = expected?.endpoint
1607
- ?? (
1608
- advertisedEndpoint !== undefined
1609
- && this.endpointOnlyPeers.has(advertisedEndpoint)
1610
- ? advertisedEndpoint
1611
- : undefined
1612
- );
1530
+ const endpoint =
1531
+ expected?.endpoint ??
1532
+ (advertisedEndpoint !== undefined && this.endpointOnlyPeers.has(advertisedEndpoint)
1533
+ ? advertisedEndpoint
1534
+ : undefined);
1613
1535
  if (endpoint !== undefined) {
1614
1536
  this.requireStarted().disconnect(endpoint);
1615
1537
  this.endpointOnlyPeers.delete(endpoint);
@@ -1647,8 +1569,7 @@ export class RawServiceMeshRuntime {
1647
1569
  }
1648
1570
 
1649
1571
  private observeMonitorEvent(event: ZLinkRawMonitorRecord): void {
1650
- const nodeRoutingId = event.routingId
1651
- ?? this.expectedPeerRoutingId(event.remoteAddress);
1572
+ const nodeRoutingId = event.routingId ?? this.expectedPeerRoutingId(event.remoteAddress);
1652
1573
  if (nodeRoutingId === undefined) return;
1653
1574
  const connectionId = monitorConnectionId(event, nodeRoutingId);
1654
1575
  if (event.event === MONITOR_CONNECTION_READY && isConnectionReadyEdge(event)) {
@@ -1657,9 +1578,11 @@ export class RawServiceMeshRuntime {
1657
1578
  // allow a late stale READY to overwrite the admitted replacement.
1658
1579
  return;
1659
1580
  }
1660
- if (event.event === MONITOR_DISCONNECTED
1661
- && this.monitorConnectionStates.get(nodeRoutingId) === connectionId
1662
- && this.topology.peer(nodeRoutingId)?.connectionId === connectionId) {
1581
+ if (
1582
+ event.event === MONITOR_DISCONNECTED &&
1583
+ this.monitorConnectionStates.get(nodeRoutingId) === connectionId &&
1584
+ this.topology.peer(nodeRoutingId)?.connectionId === connectionId
1585
+ ) {
1663
1586
  this.monitorConnectionStates.set(nodeRoutingId, null);
1664
1587
  }
1665
1588
  }
@@ -1669,10 +1592,7 @@ export class RawServiceMeshRuntime {
1669
1592
  return this.router;
1670
1593
  }
1671
1594
 
1672
- private async send(
1673
- targetNodeRoutingId: string,
1674
- parts: readonly Uint8Array[]
1675
- ): Promise<boolean> {
1595
+ private async send(targetNodeRoutingId: string, parts: readonly Uint8Array[]): Promise<boolean> {
1676
1596
  try {
1677
1597
  await this.requireStarted().send(targetNodeRoutingId, parts);
1678
1598
  return true;
@@ -1680,7 +1600,6 @@ export class RawServiceMeshRuntime {
1680
1600
  return false;
1681
1601
  }
1682
1602
  }
1683
-
1684
1603
  }
1685
1604
 
1686
1605
  /**
@@ -1725,11 +1644,7 @@ function monitorConnectionId(
1725
1644
  resolvedNodeRoutingId = event.routingId ?? ''
1726
1645
  ): string {
1727
1646
  if (event.connectionId !== undefined && event.connectionId !== 0n) {
1728
- return JSON.stringify([
1729
- resolvedNodeRoutingId,
1730
- 'connection',
1731
- event.connectionId.toString()
1732
- ]);
1647
+ return JSON.stringify([resolvedNodeRoutingId, 'connection', event.connectionId.toString()]);
1733
1648
  }
1734
1649
  return JSON.stringify([
1735
1650
  // Monitor `value` is event-specific: CONNECTION_READY reports the
@@ -1742,12 +1657,11 @@ function monitorConnectionId(
1742
1657
  ]);
1743
1658
  }
1744
1659
 
1745
- function sameMonitorConnection(
1746
- left: ZLinkRawMonitorRecord,
1747
- right: ZLinkRawMonitorRecord
1748
- ): boolean {
1749
- return monitorConnectionId(left) === monitorConnectionId(right)
1750
- && left.remoteAddress === right.remoteAddress;
1660
+ function sameMonitorConnection(left: ZLinkRawMonitorRecord, right: ZLinkRawMonitorRecord): boolean {
1661
+ return (
1662
+ monitorConnectionId(left) === monitorConnectionId(right) &&
1663
+ left.remoteAddress === right.remoteAddress
1664
+ );
1751
1665
  }
1752
1666
 
1753
1667
  function isConnectionReadyEdge(event: ZLinkRawMonitorRecord): boolean {
@@ -1766,21 +1680,26 @@ function describeInvalidAdmissionDescriptor(
1766
1680
  } catch (error) {
1767
1681
  return `descriptor validation: ${error instanceof Error ? error.message : String(error)}`;
1768
1682
  }
1769
- if (expected?.endpoint !== undefined
1770
- && descriptor.advertisedEndpoint !== expected.endpoint) {
1683
+ if (expected?.endpoint !== undefined && descriptor.advertisedEndpoint !== expected.endpoint) {
1771
1684
  return `advertisedEndpoint expected='${expected.endpoint}' actual='${descriptor.advertisedEndpoint}'`;
1772
1685
  }
1773
- if (expected?.securityIdentity !== undefined
1774
- && descriptor.securityIdentity !== expected.securityIdentity) {
1686
+ if (
1687
+ expected?.securityIdentity !== undefined &&
1688
+ descriptor.securityIdentity !== expected.securityIdentity
1689
+ ) {
1775
1690
  return `securityIdentity expected='${expected.securityIdentity}' actual='${descriptor.securityIdentity}'`;
1776
1691
  }
1777
- if (expected?.lifecycleGeneration !== undefined
1778
- && descriptor.lifecycleGeneration !== expected.lifecycleGeneration) {
1692
+ if (
1693
+ expected?.lifecycleGeneration !== undefined &&
1694
+ descriptor.lifecycleGeneration !== expected.lifecycleGeneration
1695
+ ) {
1779
1696
  return `lifecycleGeneration expected=${expected.lifecycleGeneration} actual=${descriptor.lifecycleGeneration}`;
1780
1697
  }
1781
- if (current !== undefined
1782
- && current.lifecycleGeneration === descriptor.lifecycleGeneration
1783
- && descriptor.descriptorRevision > current.descriptorRevision) {
1698
+ if (
1699
+ current !== undefined &&
1700
+ current.lifecycleGeneration === descriptor.lifecycleGeneration &&
1701
+ descriptor.descriptorRevision > current.descriptorRevision
1702
+ ) {
1784
1703
  const immutableField = immutableDescriptorMismatch(current, descriptor);
1785
1704
  if (immutableField !== undefined) return immutableField;
1786
1705
  }
@@ -1792,19 +1711,27 @@ function immutableDescriptorMismatch(
1792
1711
  descriptor: ServiceNodeDescriptor
1793
1712
  ): string | undefined {
1794
1713
  const fields: ReadonlyArray<keyof ServiceNodeDescriptor> = [
1795
- 'advertisedEndpoint', 'securityIdentity', 'applicationVersion', 'objectRole',
1796
- 'activeCapacityLimit', 'pendingCapacityLimit'
1714
+ 'advertisedEndpoint',
1715
+ 'securityIdentity',
1716
+ 'applicationVersion',
1717
+ 'objectRole',
1718
+ 'activeCapacityLimit',
1719
+ 'pendingCapacityLimit'
1797
1720
  ];
1798
1721
  for (const field of fields) {
1799
1722
  if (current[field] !== descriptor[field]) {
1800
1723
  return `${field} changed within lifecycle expected=${String(current[field])} actual=${String(descriptor[field])}`;
1801
1724
  }
1802
1725
  }
1803
- if (JSON.stringify(current.protocolCapabilities) !== JSON.stringify(descriptor.protocolCapabilities)) {
1726
+ if (
1727
+ JSON.stringify(current.protocolCapabilities) !== JSON.stringify(descriptor.protocolCapabilities)
1728
+ ) {
1804
1729
  return `protocolCapabilities changed within lifecycle expected=${JSON.stringify(current.protocolCapabilities)} actual=${JSON.stringify(descriptor.protocolCapabilities)}`;
1805
1730
  }
1806
- if (JSON.stringify(current.channels.map(channel => channel.name))
1807
- !== JSON.stringify(descriptor.channels.map(channel => channel.name))) {
1731
+ if (
1732
+ JSON.stringify(current.channels.map((channel) => channel.name)) !==
1733
+ JSON.stringify(descriptor.channels.map((channel) => channel.name))
1734
+ ) {
1808
1735
  return 'channels changed within lifecycle';
1809
1736
  }
1810
1737
  return undefined;