@zlink-systems/framework 0.30.0 → 0.30.2

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 (456) 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/ZLinkEncodedPayload.d.ts +6 -0
  6. package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
  7. package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
  8. package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
  9. package/dist/contracts/Common/encoded-payload-storage.js +5 -2
  10. package/dist/contracts/Configuration/Builders.d.ts +1 -1
  11. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
  12. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
  13. package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
  14. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  15. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
  16. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  17. package/dist/contracts/Handlers/Attributes.js +7 -11
  18. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  19. package/dist/contracts/Handlers/JsonContract.js +4 -153
  20. package/dist/contracts/Locations/Rows.d.ts +2 -0
  21. package/dist/contracts/Spots/Contracts.d.ts +6 -1
  22. package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
  23. package/dist/nest-integration.d.ts +1 -1
  24. package/dist/nest-integration.js +2 -1
  25. package/dist/runtime/abort.d.ts +5 -0
  26. package/dist/runtime/abort.js +10 -0
  27. package/dist/runtime/actors/actor-authority-publication.js +3 -2
  28. package/dist/runtime/actors/actor-client.d.ts +1 -2
  29. package/dist/runtime/actors/actor-client.js +52 -57
  30. package/dist/runtime/actors/actor-context.d.ts +2 -0
  31. package/dist/runtime/actors/actor-context.js +46 -9
  32. package/dist/runtime/actors/actor-handoff.d.ts +8 -4
  33. package/dist/runtime/actors/actor-handoff.js +219 -92
  34. package/dist/runtime/actors/actor-join-relocation.d.ts +3 -0
  35. package/dist/runtime/actors/actor-local-native-join.js +13 -12
  36. package/dist/runtime/actors/actor-mailbox.js +27 -1
  37. package/dist/runtime/actors/actor-remote-joiner.js +3 -1
  38. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  39. package/dist/runtime/actors/actor-reply.d.ts +4 -0
  40. package/dist/runtime/actors/actor-reply.js +29 -0
  41. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  42. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  43. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
  44. package/dist/runtime/actors/actor-runtime-state.js +2 -20
  45. package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
  46. package/dist/runtime/actors/index.d.ts +8 -3
  47. package/dist/runtime/actors/index.js +55 -27
  48. package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
  49. package/dist/runtime/actors/session-disconnected-wire.js +48 -0
  50. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  51. package/dist/runtime/admission.d.ts +9 -1
  52. package/dist/runtime/admission.js +56 -23
  53. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
  54. package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
  55. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +15 -1
  56. package/dist/runtime/application-jobs/application-job-queue-scope.js +61 -20
  57. package/dist/runtime/application-jobs/contracts.d.ts +12 -1
  58. package/dist/runtime/backend/contracts/index.d.ts +37 -12
  59. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
  60. package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
  61. package/dist/runtime/backend/mesh-completion-table.js +154 -49
  62. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +28 -1
  63. package/dist/runtime/backend/mesh-dispatch-pump.js +208 -101
  64. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
  65. package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
  66. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  67. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  68. package/dist/runtime/backend/node/node-raw-binding-port.js +124 -72
  69. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +46 -13
  70. package/dist/runtime/backend/node/node-raw-mesh-backend.js +181 -164
  71. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
  72. package/dist/runtime/backend/node/node-socket-backend-adapter.js +11 -11
  73. package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
  74. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  75. package/dist/runtime/backend/runtime-message.js +5 -0
  76. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  77. package/dist/runtime/backend/runtime-values.js +2 -1
  78. package/dist/runtime/channels/channel-clients.d.ts +2 -0
  79. package/dist/runtime/channels/channel-clients.js +75 -23
  80. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +25 -5
  81. package/dist/runtime/channels/channel-dispatch-pipeline.js +111 -56
  82. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  83. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  84. package/dist/runtime/channels/channel-dispatchers.d.ts +4 -3
  85. package/dist/runtime/channels/channel-dispatchers.js +62 -54
  86. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  87. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  88. package/dist/runtime/channels/channel-envelope.d.ts +2 -0
  89. package/dist/runtime/channels/channel-envelope.js +146 -28
  90. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  91. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  92. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
  93. package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
  94. package/dist/runtime/channels/channel-runtime-manager.d.ts +9 -8
  95. package/dist/runtime/channels/channel-runtime-manager.js +16 -16
  96. package/dist/runtime/channels/channel-transports.d.ts +18 -16
  97. package/dist/runtime/channels/channel-transports.js +77 -58
  98. package/dist/runtime/channels/client-server-location-runtime.js +5 -4
  99. package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
  100. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  101. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  102. package/dist/runtime/channels/fanout-location-runtime.js +3 -3
  103. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  104. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  105. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  106. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  107. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  108. package/dist/runtime/channels/source-spot-router.js +4 -4
  109. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  110. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  111. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  112. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  113. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  114. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  115. package/dist/runtime/diagnostics/flow-context.js +19 -7
  116. package/dist/runtime/diagnostics/index.js +4 -9
  117. package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
  118. package/dist/runtime/diagnostics/message-flow.js +35 -5
  119. package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
  120. package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
  121. package/dist/runtime/execution/index.d.ts +4 -2
  122. package/dist/runtime/execution/index.js +33 -10
  123. package/dist/runtime/execution/serial-execution-queue.d.ts +5 -0
  124. package/dist/runtime/execution/serial-execution-queue.js +22 -2
  125. package/dist/runtime/execution/state-lane.d.ts +2 -0
  126. package/dist/runtime/execution/state-lane.js +5 -0
  127. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  128. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  129. package/dist/runtime/foundation/durable-service-request.js +98 -0
  130. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  131. package/dist/runtime/foundation/operation-identity.js +5 -1
  132. package/dist/runtime/foundation/operation-registry.d.ts +25 -1
  133. package/dist/runtime/foundation/operation-registry.js +86 -18
  134. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +61 -8
  135. package/dist/runtime/foundation/raw-service-mesh-runtime.js +486 -266
  136. package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
  137. package/dist/runtime/foundation/service-liveness-registry.js +38 -0
  138. package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
  139. package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
  140. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +3 -3
  141. package/dist/runtime/foundation/service-relocation-object-owner.js +48 -34
  142. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  143. package/dist/runtime/foundation/service-relocation-runtime.js +20 -4
  144. package/dist/runtime/foundation/service-runtime-contracts.d.ts +10 -1
  145. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
  146. package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
  147. package/dist/runtime/foundation/service-stateful-registry.js +24 -26
  148. package/dist/runtime/foundation/service-stateful-runtime.d.ts +75 -9
  149. package/dist/runtime/foundation/service-stateful-runtime.js +486 -218
  150. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -6
  151. package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
  152. package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
  153. package/dist/runtime/foundation/service-topology-registry.js +61 -27
  154. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
  155. package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
  156. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  157. package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
  158. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +13 -3
  159. package/dist/runtime/foundation/service-wire-m6a-codec.js +189 -78
  160. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  161. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  162. package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
  163. package/dist/runtime/host/actor-packet-relay.js +59 -72
  164. package/dist/runtime/host/actor-placement-coordinator.js +25 -8
  165. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  166. package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
  167. package/dist/runtime/host/actor-transfer-runtime.js +85 -331
  168. package/dist/runtime/host/application-job-queue.d.ts +40 -7
  169. package/dist/runtime/host/application-job-queue.js +137 -42
  170. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  171. package/dist/runtime/host/entry-actor-runtime.js +3 -0
  172. package/dist/runtime/host/index.d.ts +12 -2
  173. package/dist/runtime/host/index.js +300 -202
  174. package/dist/runtime/host/location-runtime-owner.js +2 -6
  175. package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
  176. package/dist/runtime/host/mesh-router-resolver.js +14 -6
  177. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
  178. package/dist/runtime/host/remote-bound-session-relay.js +73 -208
  179. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
  180. package/dist/runtime/host/route-mesh-runtime.js +6 -4
  181. package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
  182. package/dist/runtime/host/runtime-shutdown.js +3 -2
  183. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  184. package/dist/runtime/host/service-relocation-control.js +10 -4
  185. package/dist/runtime/host/service-relocation-host-runtime.d.ts +22 -14
  186. package/dist/runtime/host/service-relocation-host-runtime.js +754 -599
  187. package/dist/runtime/host/spot-address-transport.js +3 -2
  188. package/dist/runtime/host/spot-runtime-options-factory.js +16 -7
  189. package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
  190. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  191. package/dist/runtime/locations/actor-location-claims.js +34 -19
  192. package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
  193. package/dist/runtime/locations/auto-connect-loop.js +22 -14
  194. package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
  195. package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
  196. package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
  197. package/dist/runtime/locations/descriptor-publication.js +11 -0
  198. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  199. package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
  200. package/dist/runtime/locations/in-memory-authority-store.js +56 -19
  201. package/dist/runtime/locations/in-memory-location-store.js +1 -10
  202. package/dist/runtime/locations/index.d.ts +1 -0
  203. package/dist/runtime/locations/index.js +1 -0
  204. package/dist/runtime/locations/lease-tracker.js +1 -6
  205. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  206. package/dist/runtime/locations/lifecycle.js +2 -5
  207. package/dist/runtime/locations/location-store-repository.d.ts +51 -1
  208. package/dist/runtime/locations/location-store-repository.js +363 -139
  209. package/dist/runtime/locations/relocation-blob.d.ts +18 -1
  210. package/dist/runtime/locations/relocation-blob.js +52 -1
  211. package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
  212. package/dist/runtime/locations/request-source-resolver.js +80 -0
  213. package/dist/runtime/locations/resolvers.js +1 -1
  214. package/dist/runtime/locations/runtime.d.ts +7 -3
  215. package/dist/runtime/locations/runtime.js +61 -53
  216. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  217. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  218. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  219. package/dist/runtime/messaging/packet-name.js +8 -24
  220. package/dist/runtime/messaging/payload-codec.d.ts +7 -1
  221. package/dist/runtime/messaging/payload-codec.js +7 -6
  222. package/dist/runtime/messaging/request-result.d.ts +2 -0
  223. package/dist/runtime/messaging/request-result.js +57 -0
  224. package/dist/runtime/messaging/submission-result.d.ts +1 -0
  225. package/dist/runtime/messaging/submission-result.js +5 -2
  226. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +34 -1
  227. package/dist/runtime/protocol/service_wire_codec.generated.js +229 -0
  228. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +16 -1
  229. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +37 -8
  230. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
  231. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +36 -21
  232. package/dist/runtime/spots/index.d.ts +21 -11
  233. package/dist/runtime/spots/index.js +243 -178
  234. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  235. package/dist/runtime/spots/spot-activation-registry.js +21 -11
  236. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  237. package/dist/runtime/spots/spot-activation-state.js +7 -7
  238. package/dist/runtime/spots/spot-activation.d.ts +7 -3
  239. package/dist/runtime/spots/spot-activation.js +140 -52
  240. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
  241. package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
  242. package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
  243. package/dist/runtime/spots/spot-actor-membership.js +0 -8
  244. package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
  245. package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
  246. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
  247. package/dist/runtime/spots/spot-entry-activation.js +20 -11
  248. package/dist/runtime/spots/spot-handler-registry.d.ts +7 -4
  249. package/dist/runtime/spots/spot-handler-registry.js +24 -10
  250. package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
  251. package/dist/runtime/spots/spot-manager-public.js +2 -2
  252. package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
  253. package/dist/runtime/spots/spot-node-autoconnect.js +22 -42
  254. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
  255. package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
  256. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  257. package/dist/runtime/spots/spot-outbound.js +27 -18
  258. package/dist/runtime/spots/spot-remote-codec.js +5 -1
  259. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  260. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  261. package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -1
  262. package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
  263. package/dist/runtime/spots/spot-serial-executor.js +61 -8
  264. package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
  265. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -4
  266. package/dist/runtime/spots/spot-timer.d.ts +57 -5
  267. package/dist/runtime/spots/spot-timer.js +288 -103
  268. package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
  269. package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
  270. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
  271. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
  272. package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
  273. package/dist/runtime/streams/bound-session-service.d.ts +1 -1
  274. package/dist/runtime/streams/bound-session-service.js +6 -11
  275. package/dist/runtime/streams/index.d.ts +3 -2
  276. package/dist/runtime/streams/index.js +6 -4
  277. package/dist/runtime/streams/managed-stream.js +3 -2
  278. package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
  279. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
  280. package/dist/runtime/streams/session-actor-coordinator.js +15 -32
  281. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
  282. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  283. package/dist/runtime/streams/stream-session-runtime.js +14 -31
  284. package/dist/runtime/workers/index.js +1 -1
  285. package/package.json +3 -3
  286. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  287. package/src/contracts/Channels/Calls.ts +2 -1
  288. package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
  289. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  290. package/src/contracts/Common/encoded-payload-storage.ts +6 -3
  291. package/src/contracts/Configuration/Builders.ts +4 -1
  292. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
  293. package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
  294. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  295. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
  296. package/src/contracts/Handlers/Attributes.ts +14 -21
  297. package/src/contracts/Handlers/JsonContract.ts +8 -216
  298. package/src/contracts/Locations/Rows.ts +2 -0
  299. package/src/contracts/Spots/Contracts.ts +10 -1
  300. package/src/contracts/Spots/ZLinkSpot.ts +3 -3
  301. package/src/nest-integration.ts +1 -0
  302. package/src/runtime/abort.ts +12 -0
  303. package/src/runtime/actors/actor-authority-publication.ts +3 -2
  304. package/src/runtime/actors/actor-client.ts +100 -85
  305. package/src/runtime/actors/actor-context.ts +49 -9
  306. package/src/runtime/actors/actor-handoff.ts +291 -110
  307. package/src/runtime/actors/actor-join-relocation.ts +3 -0
  308. package/src/runtime/actors/actor-local-native-join.ts +21 -26
  309. package/src/runtime/actors/actor-mailbox.ts +40 -2
  310. package/src/runtime/actors/actor-remote-joiner.ts +6 -1
  311. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  312. package/src/runtime/actors/actor-reply.ts +42 -0
  313. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  314. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  315. package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
  316. package/src/runtime/actors/actor-runtime-state.ts +2 -20
  317. package/src/runtime/actors/actor-source-transfer.ts +1 -34
  318. package/src/runtime/actors/index.ts +60 -32
  319. package/src/runtime/actors/session-disconnected-wire.ts +66 -0
  320. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  321. package/src/runtime/admission.ts +69 -21
  322. package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
  323. package/src/runtime/application-jobs/application-job-queue-scope.ts +83 -22
  324. package/src/runtime/application-jobs/contracts.ts +16 -1
  325. package/src/runtime/backend/contracts/index.ts +92 -18
  326. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
  327. package/src/runtime/backend/mesh-completion-table.ts +160 -57
  328. package/src/runtime/backend/mesh-dispatch-pump.ts +237 -108
  329. package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
  330. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  331. package/src/runtime/backend/node/node-raw-binding-port.ts +148 -85
  332. package/src/runtime/backend/node/node-raw-mesh-backend.ts +315 -201
  333. package/src/runtime/backend/node/node-socket-backend-adapter.ts +26 -11
  334. package/src/runtime/backend/raw-binding-port.ts +7 -2
  335. package/src/runtime/backend/runtime-message.ts +6 -0
  336. package/src/runtime/backend/runtime-values.ts +1 -0
  337. package/src/runtime/channels/channel-clients.ts +132 -58
  338. package/src/runtime/channels/channel-dispatch-pipeline.ts +198 -114
  339. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  340. package/src/runtime/channels/channel-dispatchers.ts +136 -90
  341. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  342. package/src/runtime/channels/channel-envelope.ts +225 -31
  343. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  344. package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
  345. package/src/runtime/channels/channel-runtime-manager.ts +41 -17
  346. package/src/runtime/channels/channel-transports.ts +171 -112
  347. package/src/runtime/channels/client-server-location-runtime.ts +11 -10
  348. package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
  349. package/src/runtime/channels/fanout-location-runtime.ts +17 -9
  350. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  351. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  352. package/src/runtime/channels/source-spot-router.ts +8 -4
  353. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  354. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  355. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  356. package/src/runtime/diagnostics/flow-context.ts +20 -7
  357. package/src/runtime/diagnostics/index.ts +1 -7
  358. package/src/runtime/diagnostics/message-flow.ts +47 -9
  359. package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
  360. package/src/runtime/execution/index.ts +40 -14
  361. package/src/runtime/execution/serial-execution-queue.ts +33 -4
  362. package/src/runtime/execution/state-lane.ts +7 -0
  363. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  364. package/src/runtime/foundation/durable-service-request.ts +137 -0
  365. package/src/runtime/foundation/operation-identity.ts +5 -1
  366. package/src/runtime/foundation/operation-registry.ts +98 -20
  367. package/src/runtime/foundation/raw-service-mesh-runtime.ts +704 -336
  368. package/src/runtime/foundation/service-liveness-registry.ts +39 -0
  369. package/src/runtime/foundation/service-mailbox.ts +8 -0
  370. package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
  371. package/src/runtime/foundation/service-relocation-object-owner.ts +55 -36
  372. package/src/runtime/foundation/service-relocation-runtime.ts +25 -4
  373. package/src/runtime/foundation/service-runtime-contracts.ts +19 -2
  374. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
  375. package/src/runtime/foundation/service-stateful-registry.ts +38 -35
  376. package/src/runtime/foundation/service-stateful-runtime.ts +732 -275
  377. package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -16
  378. package/src/runtime/foundation/service-topology-registry.ts +91 -36
  379. package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
  380. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  381. package/src/runtime/foundation/service-wire-m6a-codec.ts +231 -76
  382. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  383. package/src/runtime/host/actor-packet-relay.ts +113 -94
  384. package/src/runtime/host/actor-placement-coordinator.ts +31 -8
  385. package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
  386. package/src/runtime/host/actor-transfer-runtime.ts +104 -430
  387. package/src/runtime/host/application-job-queue.ts +160 -41
  388. package/src/runtime/host/entry-actor-runtime.ts +4 -0
  389. package/src/runtime/host/index.ts +473 -271
  390. package/src/runtime/host/location-runtime-owner.ts +2 -6
  391. package/src/runtime/host/mesh-router-resolver.ts +13 -5
  392. package/src/runtime/host/remote-bound-session-relay.ts +88 -271
  393. package/src/runtime/host/route-mesh-runtime.ts +12 -6
  394. package/src/runtime/host/runtime-shutdown.ts +15 -4
  395. package/src/runtime/host/service-relocation-control.ts +11 -5
  396. package/src/runtime/host/service-relocation-host-runtime.ts +1092 -759
  397. package/src/runtime/host/spot-address-transport.ts +4 -2
  398. package/src/runtime/host/spot-runtime-options-factory.ts +20 -7
  399. package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
  400. package/src/runtime/locations/actor-location-claims.ts +52 -30
  401. package/src/runtime/locations/auto-connect-loop.ts +22 -14
  402. package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
  403. package/src/runtime/locations/auto-connect-types.ts +0 -1
  404. package/src/runtime/locations/descriptor-publication.ts +7 -0
  405. package/src/runtime/locations/domain-store-contract.ts +5 -0
  406. package/src/runtime/locations/in-memory-authority-store.ts +85 -23
  407. package/src/runtime/locations/in-memory-location-store.ts +1 -12
  408. package/src/runtime/locations/index.ts +1 -0
  409. package/src/runtime/locations/lease-tracker.ts +2 -9
  410. package/src/runtime/locations/lifecycle.ts +8 -26
  411. package/src/runtime/locations/location-store-repository.ts +628 -152
  412. package/src/runtime/locations/relocation-blob.ts +75 -1
  413. package/src/runtime/locations/request-source-resolver.ts +138 -0
  414. package/src/runtime/locations/resolvers.ts +2 -2
  415. package/src/runtime/locations/runtime.ts +98 -64
  416. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  417. package/src/runtime/messaging/packet-name.ts +5 -25
  418. package/src/runtime/messaging/payload-codec.ts +8 -11
  419. package/src/runtime/messaging/request-result.ts +62 -0
  420. package/src/runtime/messaging/submission-result.ts +5 -1
  421. package/src/runtime/protocol/service_wire_codec.generated.ts +218 -5
  422. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +16 -13
  423. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +46 -25
  424. package/src/runtime/spots/index.ts +389 -283
  425. package/src/runtime/spots/spot-activation-registry.ts +25 -13
  426. package/src/runtime/spots/spot-activation-state.ts +12 -19
  427. package/src/runtime/spots/spot-activation.ts +198 -96
  428. package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
  429. package/src/runtime/spots/spot-actor-membership.ts +0 -15
  430. package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
  431. package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
  432. package/src/runtime/spots/spot-entry-activation.ts +33 -21
  433. package/src/runtime/spots/spot-handler-registry.ts +56 -12
  434. package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
  435. package/src/runtime/spots/spot-manager-public.ts +2 -2
  436. package/src/runtime/spots/spot-node-autoconnect.ts +28 -47
  437. package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
  438. package/src/runtime/spots/spot-outbound.ts +39 -19
  439. package/src/runtime/spots/spot-remote-codec.ts +9 -2
  440. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  441. package/src/runtime/spots/spot-runtime-ports.ts +1 -1
  442. package/src/runtime/spots/spot-serial-executor.ts +97 -25
  443. package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
  444. package/src/runtime/spots/spot-subscription-dispatch.ts +1 -4
  445. package/src/runtime/spots/spot-timer.ts +418 -158
  446. package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
  447. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
  448. package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
  449. package/src/runtime/streams/bound-session-service.ts +7 -10
  450. package/src/runtime/streams/index.ts +12 -6
  451. package/src/runtime/streams/managed-stream.ts +4 -2
  452. package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
  453. package/src/runtime/streams/session-actor-coordinator.ts +39 -88
  454. package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
  455. package/src/runtime/streams/stream-session-runtime.ts +13 -34
  456. package/src/runtime/workers/index.ts +1 -1
@@ -1,3 +1,5 @@
1
+ import { decodeRoutingId } from '../routing-id';
2
+ import { decodeBoundSessionCloseCommand } from '../protocol/service_wire_codec.generated';
1
3
  import { UINT64_MAX, ZlinkStreamContentType } from '@zlink-systems/stream-wire';
2
4
  import { RELOCATION_STATE_CHUNK_DATA_MAX_BYTES } from '../../contracts/Configuration/InternalDefaults';
3
5
  import { isCanonicalWireReplyTerminal } from '../framework-errors-internal';
@@ -177,6 +179,7 @@ interface ServiceWireRelocationBase {
177
179
 
178
180
  export interface ServiceMaintenanceRelocationPrepare extends ServiceWireRelocationBase {
179
181
  readonly kind: 'prepare';
182
+ readonly deadlineUnixMs: bigint;
180
183
  readonly target: ServiceWireRelocationTarget;
181
184
  readonly initiatorRole: ServiceWireRelocationRole;
182
185
  readonly object: ServiceWireRelocationObject;
@@ -189,11 +192,6 @@ export interface ServiceMaintenanceRelocationPrepare extends ServiceWireRelocati
189
192
  /** CRC-32C (Castagnoli) over the fully assembled payload bytes. */
190
193
  readonly payloadChecksumCrc32c: number;
191
194
  readonly applicationVersion: bigint;
192
- /** NODE-INTERNAL; serialized as extra frames after canonical command 40. */
193
- readonly nodeInternalBoundSessions?: readonly {
194
- readonly participantKey: string;
195
- readonly payload: Uint8Array;
196
- }[];
197
195
  }
198
196
 
199
197
  export interface ServiceMaintenanceRelocationReady extends ServiceWireRelocationBase {
@@ -329,6 +327,8 @@ export interface ServiceSessionRelocationOwnerFence {
329
327
  }
330
328
 
331
329
  export interface ServiceSessionRelocationSeal {
330
+ readonly targetNodeRid: string;
331
+ readonly targetNodeGeneration: bigint;
332
332
  readonly relocation: ServiceWireOperationId;
333
333
  readonly coordinator: ServiceWireRelocationCoordinatorFence;
334
334
  readonly senderRole: 'source' | 'coordinator';
@@ -337,6 +337,7 @@ export interface ServiceSessionRelocationSeal {
337
337
  }
338
338
 
339
339
  export interface ServiceSessionRelocationSealed {
340
+ readonly sealResult: 'sealed' | 'bindingAbsent';
340
341
  readonly relocation: ServiceWireOperationId;
341
342
  readonly coordinator: ServiceWireRelocationCoordinatorFence;
342
343
  readonly actor: ServiceBoundSessionActorAuthority;
@@ -376,17 +377,13 @@ export function serviceSessionRelocationIdentityKey(
376
377
  ServiceSessionRelocationSeal | ServiceSessionRelocationSealed | ServiceSessionRelocationRoute
377
378
  ): string {
378
379
  const actor = 'targetNodeGeneration' in value.actor ? value.actor.actor : value.actor;
379
- // Session owner가 seal을 대조할 때 쓰는 값만 넣는다 — Session과 Actor binding
380
- // §8.1 "Session owner는 다음 값만 검증한다". coordinator identity는 transport가
381
- // 검증하는 wire fence이므로 여기서 다시 대조하지 않는다.
382
- return [
380
+ // Session–Actor binding §8.3: all original fields are checked against the
381
+ // recorded request; only relocation identity and ActorId select the record.
382
+ return JSON.stringify([
383
383
  value.relocation.high.toString(),
384
384
  value.relocation.low.toString(),
385
- actor.actorId,
386
- actor.generation.toString(),
387
- value.session.sessionRid,
388
- value.session.bindingGeneration.toString()
389
- ].join(':');
385
+ actor.actorId
386
+ ]);
390
387
  }
391
388
 
392
389
  function toGeneratedRoutingId(value: string, field: string): Uint8Array {
@@ -668,6 +665,8 @@ function toGeneratedSessionRelocationSeal(
668
665
  value: ServiceSessionRelocationSeal
669
666
  ): GeneratedSessionRelocationSeal42 {
670
667
  return {
668
+ targetNodeRid: toGeneratedRoutingId(value.targetNodeRid, 'targetNodeRid'),
669
+ targetNodeGeneration: value.targetNodeGeneration,
671
670
  relocation: value.relocation,
672
671
  coordinator: toGeneratedCoordinatorFence(value.coordinator),
673
672
  senderRole: value.senderRole,
@@ -680,6 +679,8 @@ function fromGeneratedSessionRelocationSeal(
680
679
  value: GeneratedSessionRelocationSeal42
681
680
  ): ServiceSessionRelocationSeal {
682
681
  return {
682
+ targetNodeRid: fromGeneratedRoutingId(value.targetNodeRid, 'targetNodeRid'),
683
+ targetNodeGeneration: value.targetNodeGeneration,
683
684
  relocation: value.relocation,
684
685
  coordinator: fromGeneratedCoordinatorFence(value.coordinator),
685
686
  senderRole: value.senderRole as ServiceSessionRelocationSeal['senderRole'],
@@ -695,7 +696,8 @@ function toGeneratedSessionRelocationSealed(
695
696
  relocation: value.relocation,
696
697
  coordinator: toGeneratedCoordinatorFence(value.coordinator),
697
698
  actor: toGeneratedRouteFence(value.actor),
698
- ...toGeneratedSessionOwnerFence(value.session)
699
+ ...toGeneratedSessionOwnerFence(value.session),
700
+ sealResult: value.sealResult
699
701
  };
700
702
  }
701
703
 
@@ -703,6 +705,7 @@ function fromGeneratedSessionRelocationSealed(
703
705
  value: GeneratedSessionRelocationSealed43
704
706
  ): ServiceSessionRelocationSealed {
705
707
  return {
708
+ sealResult: value.sealResult,
706
709
  relocation: value.relocation,
707
710
  coordinator: fromGeneratedCoordinatorFence(value.coordinator),
708
711
  actor: fromGeneratedRouteFence(value.actor),
@@ -783,6 +786,7 @@ function fromGeneratedRelocationPrepare(
783
786
  ): ServiceMaintenanceRelocationPrepare {
784
787
  return {
785
788
  kind: 'prepare',
789
+ deadlineUnixMs: value.deadlineUnixMs,
786
790
  ...fromGeneratedRelocationBase(value),
787
791
  target: fromGeneratedTargetFence(value.target),
788
792
  initiatorRole: value.initiatorRole,
@@ -1088,6 +1092,12 @@ export type ServiceStatefulWireRecord =
1088
1092
  readonly sessionRid: string;
1089
1093
  readonly binding: ServiceBoundSessionTransition;
1090
1094
  }
1095
+ | {
1096
+ readonly kind: 'boundSessionClose';
1097
+ readonly correlation: bigint;
1098
+ readonly actor: { readonly actorId: string; readonly generation: bigint };
1099
+ readonly session: ServiceRetiredBoundSessionRouteFence;
1100
+ }
1091
1101
  | {
1092
1102
  readonly kind: 'boundSessionReplaced';
1093
1103
  readonly actorAuthority: ServiceBoundSessionActorAuthority;
@@ -1719,6 +1729,25 @@ export function decodeStatefulHeader(
1719
1729
  : { state: 'tombstone', retiredGeneration: generation }
1720
1730
  };
1721
1731
  }
1732
+ case M6bServiceWireCommand.boundSessionClose: {
1733
+ const decoded = decodeBoundSessionCloseCommand([frame], {});
1734
+ return {
1735
+ kind: 'boundSessionClose',
1736
+ correlation: decoded.correlation,
1737
+ actor: { actorId: decoded.actor.actorId, generation: decoded.actor.objectGeneration },
1738
+ session: {
1739
+ ...decoded.session,
1740
+ sessionOwnerNodeRid: decodeRoutingId(
1741
+ Buffer.from(decoded.session.sessionOwnerNodeRid).toString('utf8'),
1742
+ Buffer.from(decoded.session.sessionOwnerNodeRid).toString('hex')
1743
+ ),
1744
+ sessionRid: decodeRoutingId(
1745
+ Buffer.from(decoded.session.sessionRid).toString('utf8'),
1746
+ Buffer.from(decoded.session.sessionRid).toString('hex')
1747
+ )
1748
+ }
1749
+ };
1750
+ }
1722
1751
  case M6bServiceWireCommand.boundSessionReplaced: {
1723
1752
  requireFlags(command.flags, 0);
1724
1753
  const actor = reader.actorRef('actorAuthority.actor');
@@ -1887,7 +1916,8 @@ export function encodeMaintenanceRelocationControl(
1887
1916
  payloadTotalLength: value.payloadTotalLength,
1888
1917
  payloadChunkCount: value.payloadChunkCount,
1889
1918
  payloadChecksumCrc32c: value.payloadChecksumCrc32c,
1890
- applicationVersion: value.applicationVersion
1919
+ applicationVersion: value.applicationVersion,
1920
+ deadlineUnixMs: value.deadlineUnixMs
1891
1921
  })
1892
1922
  );
1893
1923
  case 'ready':
@@ -2015,6 +2045,7 @@ export function decodeStatefulReply(
2015
2045
  | 'actorJoin'
2016
2046
  | 'streamBind'
2017
2047
  | 'streamUnbind'
2048
+ | 'boundSessionClose'
2018
2049
  | 'instanceSpotRequest'
2019
2050
  | 'userSpotCreate'
2020
2051
  | 'userSpotClose'
@@ -2029,6 +2060,8 @@ export function decodeStatefulReply(
2029
2060
  const terminalResult = reader.u32('terminalResult');
2030
2061
  const failureCode = reader.u32('failureCode');
2031
2062
  validateReplyTerminal(terminalResult, failureCode, hasPayload);
2063
+ if (operationKind === 'boundSessionClose' && hasPayload)
2064
+ fail('A bound Session close reply cannot carry application payload.');
2032
2065
  let tail: ServiceStatefulReplyTail | undefined;
2033
2066
  if (terminalResult === 0) {
2034
2067
  if (operationKind === 'actorLookup') {
@@ -8,7 +8,10 @@ import {
8
8
  } from '../../contracts/Configuration/RegistrationBuilderPolicy';
9
9
  import { descriptorConnectionNotRequired } from './route-mesh-connection-policy';
10
10
  import { SmoothWeightedSelection } from './service-weighted-selection';
11
- import { SERVICE_WIRE_REQUIRED_CAPABILITY } from './service-wire-constants.generated';
11
+ import {
12
+ SERVICE_WIRE_REQUIRED_CAPABILITY,
13
+ ServiceWireCommand
14
+ } from './service-wire-constants.generated';
12
15
 
13
16
  export type ServiceNodeState =
14
17
  'preparing' | 'serving' | 'retiring' | 'draining' | 'stopped' | 'error';
@@ -40,8 +43,14 @@ export interface ServiceNodeDescriptor {
40
43
  readonly pendingCapacityUsed: number;
41
44
  }
42
45
 
43
- export interface AdmittedServicePeer {
46
+ interface ServiceRouteAdmission {
44
47
  readonly descriptor: ServiceNodeDescriptor;
48
+ readonly descriptorBytes?: Uint8Array;
49
+ readonly connectionId?: string | bigint;
50
+ readonly remoteAdmitReceived?: boolean;
51
+ }
52
+
53
+ export interface AdmittedServicePeer extends ServiceRouteAdmission {
45
54
  // The Core selected-route generation this admission belongs to (Core ROUTER
46
55
  // §10.1), as an opaque token compared only for equality.
47
56
  readonly connectionId: string | bigint;
@@ -69,7 +78,7 @@ interface ServiceSelectionCacheEntry {
69
78
  export class ServiceTopologyRegistry {
70
79
  private local: ServiceNodeDescriptor;
71
80
  private readonly peersByRid = new Map<string, AdmittedServicePeer>();
72
- private readonly notRequiredByRid = new Map<string, ServiceNodeDescriptor>();
81
+ private readonly notRequiredByRid = new Map<string, ServiceRouteAdmission>();
73
82
  private readonly knownByRid = new Map<string, ServiceNodeDescriptor>();
74
83
  private readonly selections = new Map<string, ServiceSelectionCacheEntry>();
75
84
 
@@ -96,7 +105,7 @@ export class ServiceTopologyRegistry {
96
105
  }
97
106
  this.local = cloneDescriptor(descriptor);
98
107
  for (const [nodeRoutingId, remote] of this.notRequiredByRid) {
99
- if (!descriptorConnectionNotRequired(this.local, remote)) {
108
+ if (!descriptorConnectionNotRequired(this.local, remote.descriptor)) {
100
109
  this.notRequiredByRid.delete(nodeRoutingId);
101
110
  }
102
111
  }
@@ -107,7 +116,9 @@ export class ServiceTopologyRegistry {
107
116
  descriptor: ServiceNodeDescriptor,
108
117
  connectionId: string | bigint,
109
118
  expected?: ServicePeerAdmissionExpectation,
110
- admitLiveness?: () => ServiceLivenessConnection
119
+ admitLiveness?: () => ServiceLivenessConnection,
120
+ command: number = ServiceWireCommand.hello,
121
+ descriptorBytes?: Uint8Array
111
122
  ): PeerAdmissionResult {
112
123
  try {
113
124
  validateDescriptor(descriptor);
@@ -127,37 +138,53 @@ export class ServiceTopologyRegistry {
127
138
  ) {
128
139
  return 'invalidDescriptor';
129
140
  }
141
+ const current = this.peersByRid.get(descriptor.nodeRoutingId);
142
+ const previous = current ?? this.notRequiredByRid.get(descriptor.nodeRoutingId);
143
+ const receivedAdmit =
144
+ command === ServiceWireCommand.admit ||
145
+ (previous?.connectionId === connectionId && previous.remoteAdmitReceived === true);
146
+ if (
147
+ previous !== undefined &&
148
+ previous.descriptor.lifecycleGeneration === descriptor.lifecycleGeneration
149
+ ) {
150
+ const existing = previous.descriptor;
151
+ if (
152
+ descriptor.descriptorRevision < existing.descriptorRevision ||
153
+ (descriptor.descriptorRevision === existing.descriptorRevision &&
154
+ !(previous.descriptorBytes !== undefined && descriptorBytes !== undefined
155
+ ? Buffer.compare(previous.descriptorBytes, descriptorBytes) === 0
156
+ : sameServiceNodeDescriptor(existing, descriptor))) ||
157
+ (descriptor.descriptorRevision > existing.descriptorRevision &&
158
+ command !== ServiceWireCommand.update)
159
+ )
160
+ return 'staleDescriptor';
161
+ if (
162
+ descriptor.descriptorRevision > existing.descriptorRevision &&
163
+ !sameImmutableDescriptor(existing, descriptor)
164
+ )
165
+ return 'invalidDescriptor';
166
+ } else if (command === ServiceWireCommand.update) {
167
+ return 'staleDescriptor';
168
+ }
169
+ const admission: ServiceRouteAdmission = {
170
+ descriptor: cloneDescriptor(descriptor),
171
+ ...(descriptorBytes === undefined ? {} : { descriptorBytes: Buffer.from(descriptorBytes) }),
172
+ connectionId,
173
+ remoteAdmitReceived: receivedAdmit
174
+ };
130
175
  if (descriptorConnectionNotRequired(this.local, descriptor)) {
131
176
  this.peersByRid.delete(descriptor.nodeRoutingId);
132
177
  this.remember(descriptor);
133
- this.notRequiredByRid.set(descriptor.nodeRoutingId, cloneDescriptor(descriptor));
178
+ this.notRequiredByRid.set(descriptor.nodeRoutingId, admission);
134
179
  this.rebuildSelections();
135
180
  return 'notRequired';
136
181
  }
137
182
  this.notRequiredByRid.delete(descriptor.nodeRoutingId);
138
183
 
139
- const current = this.peersByRid.get(descriptor.nodeRoutingId);
140
- if (
141
- current !== undefined &&
142
- current.descriptor.lifecycleGeneration === descriptor.lifecycleGeneration &&
143
- descriptor.descriptorRevision > current.descriptor.descriptorRevision &&
144
- !sameImmutableDescriptor(current.descriptor, descriptor)
145
- ) {
146
- return 'invalidDescriptor';
147
- }
148
- if (
149
- current !== undefined &&
150
- current.descriptor.lifecycleGeneration === descriptor.lifecycleGeneration &&
151
- (current.descriptor.descriptorRevision > descriptor.descriptorRevision ||
152
- (current.descriptor.descriptorRevision === descriptor.descriptorRevision &&
153
- !sameServiceNodeDescriptor(current.descriptor, descriptor)))
154
- ) {
155
- return 'staleDescriptor';
156
- }
157
184
  // Core selects the one route per RID (Core ROUTER §10.1); an admission on
158
185
  // that route replaces the admission of a route it replaced.
159
186
  this.peersByRid.set(descriptor.nodeRoutingId, {
160
- descriptor: cloneDescriptor(descriptor),
187
+ ...admission,
161
188
  connectionId,
162
189
  liveness: admitLiveness?.() ?? current?.liveness
163
190
  });
@@ -175,10 +202,18 @@ export class ServiceTopologyRegistry {
175
202
  }
176
203
 
177
204
  peer(nodeRoutingId: string): AdmittedServicePeer | undefined {
178
- const peer = this.peersByRid.get(nodeRoutingId);
205
+ const peer = this.admittedPeer(nodeRoutingId);
179
206
  return peer === undefined ? undefined : clonePeer(peer);
180
207
  }
181
208
 
209
+ routeAdmission(nodeRoutingId: string): ServiceRouteAdmission | undefined {
210
+ return this.peersByRid.get(nodeRoutingId) ?? this.notRequiredByRid.get(nodeRoutingId);
211
+ }
212
+
213
+ admittedPeer(nodeRoutingId: string): AdmittedServicePeer | undefined {
214
+ return this.peersByRid.get(nodeRoutingId);
215
+ }
216
+
182
217
  peers(): readonly AdmittedServicePeer[] {
183
218
  return this.peersCore();
184
219
  }
@@ -193,12 +228,14 @@ export class ServiceTopologyRegistry {
193
228
 
194
229
  notRequiredPeers(): readonly ServiceNodeDescriptor[] {
195
230
  return [...this.notRequiredByRid.values()]
196
- .sort((left, right) => compareOrdinal(left.nodeRoutingId, right.nodeRoutingId))
197
- .map(cloneDescriptor);
231
+ .sort((left, right) =>
232
+ compareOrdinal(left.descriptor.nodeRoutingId, right.descriptor.nodeRoutingId)
233
+ )
234
+ .map((peer) => cloneDescriptor(peer.descriptor));
198
235
  }
199
236
 
200
237
  replaceDiscoveredNotRequired(descriptors: readonly ServiceNodeDescriptor[]): void {
201
- const next = new Map<string, ServiceNodeDescriptor>();
238
+ const next = new Map<string, ServiceRouteAdmission>();
202
239
  for (const descriptor of descriptors) {
203
240
  validateDescriptor(descriptor);
204
241
  if (
@@ -206,13 +243,16 @@ export class ServiceTopologyRegistry {
206
243
  descriptor.nodeRoutingId !== this.local.nodeRoutingId &&
207
244
  descriptorConnectionNotRequired(this.local, descriptor)
208
245
  ) {
209
- next.set(descriptor.nodeRoutingId, cloneDescriptor(descriptor));
246
+ next.set(descriptor.nodeRoutingId, {
247
+ ...this.notRequiredByRid.get(descriptor.nodeRoutingId),
248
+ descriptor: cloneDescriptor(descriptor)
249
+ });
210
250
  }
211
251
  }
212
252
  this.notRequiredByRid.clear();
213
- for (const [nodeRoutingId, descriptor] of next) {
214
- this.notRequiredByRid.set(nodeRoutingId, descriptor);
215
- this.remember(descriptor);
253
+ for (const [nodeRoutingId, admission] of next) {
254
+ this.notRequiredByRid.set(nodeRoutingId, admission);
255
+ this.remember(admission.descriptor);
216
256
  }
217
257
  this.rebuildSelections();
218
258
  }
@@ -222,12 +262,27 @@ export class ServiceTopologyRegistry {
222
262
  }
223
263
 
224
264
  knownDescriptor(nodeRoutingId: string): ServiceNodeDescriptor | undefined {
225
- const admitted = this.peersByRid.get(nodeRoutingId)?.descriptor;
226
- const descriptor =
227
- admitted ?? this.notRequiredByRid.get(nodeRoutingId) ?? this.knownByRid.get(nodeRoutingId);
265
+ const descriptor = this.knownPeerDescriptor(nodeRoutingId);
228
266
  return descriptor === undefined ? undefined : cloneDescriptor(descriptor);
229
267
  }
230
268
 
269
+ isObjectClientNodeDirectTarget(nodeRoutingId: string): boolean {
270
+ const descriptor =
271
+ nodeRoutingId === this.local.nodeRoutingId
272
+ ? this.local
273
+ : this.knownPeerDescriptor(nodeRoutingId);
274
+ return descriptor?.objectRole === 'client';
275
+ }
276
+
277
+ private knownPeerDescriptor(nodeRoutingId: string): ServiceNodeDescriptor | undefined {
278
+ const admitted = this.peersByRid.get(nodeRoutingId)?.descriptor;
279
+ return (
280
+ admitted ??
281
+ this.notRequiredByRid.get(nodeRoutingId)?.descriptor ??
282
+ this.knownByRid.get(nodeRoutingId)
283
+ );
284
+ }
285
+
231
286
  hasKnownChannelTarget(channelName: string): boolean {
232
287
  requireText(channelName, 'channelName');
233
288
  return [...this.knownByRid.values()].some(
@@ -7,38 +7,61 @@ export const SERVICE_WIRE_PREFIX_SIZE = SERVICE_WIRE_FLAGS_OFFSET + 1;
7
7
 
8
8
  export const SERVICE_WIRE_TEXT8_MAX_BYTES = 255;
9
9
 
10
+ // Fatal decoding accepts exactly the canonical UTF-8 encodings; a leading
11
+ // U+FEFF stays part of the value.
12
+ const CANONICAL_UTF8 = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
13
+
10
14
  export type ServiceWireInvalid = (message: string) => never;
11
15
 
12
- /** Encodes text without silently replacing an unpaired UTF-16 surrogate. */
13
- export function encodeCanonicalServiceWireText(
16
+ /** String.prototype.isWellFormed (ES2024) exists on every supported Node (20 and later). */
17
+ type ServiceWireText = string & { isWellFormed(): boolean };
18
+
19
+ /**
20
+ * Validates text for the service wire and returns its UTF-8 byte length. An
21
+ * unpaired UTF-16 surrogate is rejected instead of being replaced.
22
+ */
23
+ export function canonicalServiceWireTextLength(
14
24
  value: string,
15
25
  field: string,
16
26
  maximumBytes: number,
17
27
  invalid: ServiceWireInvalid
18
- ): Buffer {
19
- const bytes = Buffer.from(value, 'utf8');
28
+ ): number {
29
+ const length = Buffer.byteLength(value, 'utf8');
20
30
  if (
21
- bytes.byteLength < 1 ||
22
- bytes.byteLength > maximumBytes ||
31
+ length < 1 ||
32
+ length > maximumBytes ||
23
33
  value.includes('\0') ||
24
- bytes.toString('utf8') !== value
34
+ !(value as ServiceWireText).isWellFormed()
25
35
  ) {
26
36
  invalid(`${field} must be 1..${maximumBytes} canonical UTF-8 bytes without NUL.`);
27
37
  }
28
- return bytes;
38
+ return length;
29
39
  }
30
40
 
31
- /** Decodes schema text and rejects Node's replacement-character fallback. */
41
+ /** Encodes text without silently replacing an unpaired UTF-16 surrogate. */
42
+ export function encodeCanonicalServiceWireText(
43
+ value: string,
44
+ field: string,
45
+ maximumBytes: number,
46
+ invalid: ServiceWireInvalid
47
+ ): Buffer {
48
+ canonicalServiceWireTextLength(value, field, maximumBytes, invalid);
49
+ return Buffer.from(value, 'utf8');
50
+ }
51
+
52
+ /** Decodes schema text in place and rejects non-canonical UTF-8 and NUL. */
32
53
  export function decodeCanonicalServiceWireText(
33
54
  bytes: Uint8Array,
34
55
  field: string,
35
56
  invalid: ServiceWireInvalid
36
57
  ): string {
37
- const encoded = Buffer.from(bytes);
38
- const value = encoded.toString('utf8');
39
- if (value.includes('\0') || !Buffer.from(value, 'utf8').equals(encoded)) {
58
+ let value: string;
59
+ try {
60
+ value = CANONICAL_UTF8.decode(bytes);
61
+ } catch {
40
62
  invalid(`${field} is not canonical UTF-8 without NUL.`);
41
63
  }
64
+ if (value.includes('\0')) invalid(`${field} is not canonical UTF-8 without NUL.`);
42
65
  return value;
43
66
  }
44
67
 
@@ -46,6 +46,7 @@ export const ServiceWireCommand = {
46
46
  boundSessionReplaced: 51,
47
47
  relocationState: 52,
48
48
  relocationFailed: 53,
49
+ boundSessionClose: 54,
49
50
  } as const;
50
51
  export const ServiceWireFlag = {
51
52
  metadata: 1,