@zlink-systems/framework 0.26.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (561) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Actors/ZLinkActorClient.d.ts +1 -1
  3. package/dist/contracts/Channels/Calls.d.ts +1 -1
  4. package/dist/contracts/Common/CoreTypes.d.ts +6 -0
  5. package/dist/contracts/Common/CoreTypes.js +7 -0
  6. package/dist/contracts/Common/index.d.ts +1 -1
  7. package/dist/contracts/Common/index.js +0 -1
  8. package/dist/contracts/Configuration/Builders.d.ts +0 -1
  9. package/dist/contracts/Configuration/Configs.d.ts +0 -1
  10. package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
  11. package/dist/contracts/Configuration/InternalDefaults.js +9 -1
  12. package/dist/contracts/Configuration/Registration.d.ts +13 -2
  13. package/dist/contracts/Configuration/Registration.js +58 -36
  14. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
  15. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
  16. package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
  17. package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
  18. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -5
  19. package/dist/contracts/Configuration/RegistrationValidators.js +15 -14
  20. package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
  21. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
  22. package/dist/contracts/Handlers/JsonContract.js +10 -4
  23. package/dist/contracts/Locations/Authority.d.ts +1 -1
  24. package/dist/contracts/Locations/Authority.js +3 -2
  25. package/dist/contracts/Locations/Options.js +1 -1
  26. package/dist/contracts/Locations/Stores.d.ts +12 -0
  27. package/dist/contracts/Locations/Stores.js +9 -0
  28. package/dist/contracts/Spots/Contracts.d.ts +2 -2
  29. package/dist/contracts/Streams/BoundSessionContracts.d.ts +1 -1
  30. package/dist/contracts/Streams/IZLinkSession.d.ts +2 -3
  31. package/dist/contracts/Streams/IZLinkSessionActor.d.ts +2 -2
  32. package/dist/internal.d.ts +4 -0
  33. package/dist/internal.js +15 -1
  34. package/dist/nest-integration.d.ts +4 -2
  35. package/dist/nest-integration.js +14 -4
  36. package/dist/runtime/abort.d.ts +1 -0
  37. package/dist/runtime/abort.js +8 -5
  38. package/dist/runtime/activation-admission.d.ts +1 -2
  39. package/dist/runtime/activation-admission.js +2 -6
  40. package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
  41. package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
  42. package/dist/runtime/actors/actor-client.d.ts +2 -2
  43. package/dist/runtime/actors/actor-client.js +49 -153
  44. package/dist/runtime/actors/actor-context.d.ts +3 -5
  45. package/dist/runtime/actors/actor-context.js +13 -11
  46. package/dist/runtime/actors/actor-handoff.d.ts +4 -4
  47. package/dist/runtime/actors/actor-handoff.js +8 -8
  48. package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
  49. package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
  50. package/dist/runtime/actors/actor-local-native-join.js +83 -105
  51. package/dist/runtime/actors/actor-native-lookup.js +2 -8
  52. package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
  53. package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
  54. package/dist/runtime/actors/actor-remote-joiner.d.ts +1 -1
  55. package/dist/runtime/actors/actor-remote-joiner.js +5 -9
  56. package/dist/runtime/actors/actor-remote-wire.js +5 -3
  57. package/dist/runtime/actors/actor-request-deadline.d.ts +1 -0
  58. package/dist/runtime/actors/actor-request-deadline.js +6 -0
  59. package/dist/runtime/actors/actor-retry-delay.js +2 -1
  60. package/dist/runtime/actors/actor-routed-join-transport.d.ts +2 -3
  61. package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
  62. package/dist/runtime/actors/actor-runtime-state.js +70 -187
  63. package/dist/runtime/actors/bound-session-wire.js +2 -7
  64. package/dist/runtime/actors/deferred-join-completion.d.ts +11 -6
  65. package/dist/runtime/actors/deferred-join-completion.js +1 -0
  66. package/dist/runtime/actors/index.d.ts +9 -7
  67. package/dist/runtime/actors/index.js +87 -69
  68. package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
  69. package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
  70. package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
  71. package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
  72. package/dist/runtime/admission.d.ts +2 -0
  73. package/dist/runtime/admission.js +7 -1
  74. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
  75. package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
  76. package/dist/runtime/backend/contracts/index.d.ts +7 -27
  77. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +1 -17
  78. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
  79. package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
  80. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -1
  81. package/dist/runtime/backend/node/node-backend-adapter-support.js +51 -10
  82. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  83. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +1 -2
  84. package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
  85. package/dist/runtime/backend/node/node-event-loop-poller.js +6 -7
  86. package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
  87. package/dist/runtime/backend/node/node-raw-binding-port.js +41 -34
  88. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +14 -15
  89. package/dist/runtime/backend/node/node-raw-mesh-backend.js +146 -118
  90. package/dist/runtime/backend/node/node-socket-backend-adapter.js +4 -3
  91. package/dist/runtime/backend/raw-binding-port.d.ts +1 -1
  92. package/dist/runtime/backend/runtime-values.d.ts +4 -1
  93. package/dist/runtime/backend/runtime-values.js +2 -0
  94. package/dist/runtime/channels/channel-clients.d.ts +20 -8
  95. package/dist/runtime/channels/channel-clients.js +73 -59
  96. package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
  97. package/dist/runtime/channels/channel-envelope.d.ts +1 -1
  98. package/dist/runtime/channels/channel-envelope.js +51 -39
  99. package/dist/runtime/channels/channel-outbound-operations.d.ts +5 -2
  100. package/dist/runtime/channels/channel-outbound-operations.js +25 -42
  101. package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
  102. package/dist/runtime/channels/channel-receive-loops.js +27 -6
  103. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
  104. package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
  105. package/dist/runtime/channels/channel-runtime-manager.d.ts +4 -4
  106. package/dist/runtime/channels/channel-runtime-manager.js +13 -10
  107. package/dist/runtime/channels/channel-socket-options.js +3 -12
  108. package/dist/runtime/channels/channel-socket-registry.d.ts +14 -29
  109. package/dist/runtime/channels/channel-socket-registry.js +240 -177
  110. package/dist/runtime/channels/channel-transports.d.ts +21 -31
  111. package/dist/runtime/channels/channel-transports.js +80 -62
  112. package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
  113. package/dist/runtime/channels/client-server-location-runtime.js +10 -11
  114. package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
  115. package/dist/runtime/channels/client-server-service-wire.js +32 -11
  116. package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
  117. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  118. package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
  119. package/dist/runtime/channels/fanout-location-runtime.js +130 -72
  120. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  121. package/dist/runtime/channels/local-spot-route-transport.js +1 -3
  122. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +1 -1
  123. package/dist/runtime/channels/router-socket-spot-route-transport.js +2 -2
  124. package/dist/runtime/channels/source-spot-router.d.ts +1 -1
  125. package/dist/runtime/channels/source-spot-router.js +2 -4
  126. package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
  127. package/dist/runtime/channels/spot-direct-envelope.js +4 -3
  128. package/dist/runtime/channels/spot-node-route-transport.d.ts +1 -1
  129. package/dist/runtime/channels/spot-node-route-transport.js +5 -5
  130. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +1 -1
  131. package/dist/runtime/channels/spot-route-bridge-transport.js +2 -2
  132. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +2 -4
  133. package/dist/runtime/channels/spot-route-dispatch-strategy.js +11 -12
  134. package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
  135. package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
  136. package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
  137. package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
  138. package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
  139. package/dist/runtime/diagnostics/flow-context.js +16 -2
  140. package/dist/runtime/diagnostics/index.d.ts +4 -2
  141. package/dist/runtime/diagnostics/index.js +14 -4
  142. package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
  143. package/dist/runtime/diagnostics/message-flow.js +10 -19
  144. package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
  145. package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
  146. package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
  147. package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
  148. package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
  149. package/dist/runtime/disposal.d.ts +5 -0
  150. package/dist/runtime/disposal.js +22 -0
  151. package/dist/runtime/execution/index.d.ts +12 -9
  152. package/dist/runtime/execution/index.js +58 -14
  153. package/dist/runtime/execution/serial-execution-queue.d.ts +8 -2
  154. package/dist/runtime/execution/serial-execution-queue.js +54 -15
  155. package/dist/runtime/execution/state-lane.d.ts +8 -1
  156. package/dist/runtime/execution/state-lane.js +118 -3
  157. package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
  158. package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
  159. package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
  160. package/dist/runtime/foundation/event-loop-resources.js +6 -119
  161. package/dist/runtime/foundation/operation-identity.d.ts +2 -0
  162. package/dist/runtime/foundation/operation-identity.js +9 -5
  163. package/dist/runtime/foundation/operation-registry.d.ts +5 -7
  164. package/dist/runtime/foundation/operation-registry.js +34 -44
  165. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +8 -5
  166. package/dist/runtime/foundation/raw-service-mesh-runtime.js +79 -94
  167. package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
  168. package/dist/runtime/foundation/runtime-state-projections.js +8 -0
  169. package/dist/runtime/foundation/service-authority-payload-codec.js +22 -12
  170. package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
  171. package/dist/runtime/foundation/service-discovery-registry.js +22 -3
  172. package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
  173. package/dist/runtime/foundation/service-liveness-registry.js +2 -1
  174. package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
  175. package/dist/runtime/foundation/service-maintenance-runtime.js +0 -6
  176. package/dist/runtime/foundation/service-metadata-codec.js +3 -3
  177. package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
  178. package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
  179. package/dist/runtime/foundation/service-relocation-object-owner.js +3 -2
  180. package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
  181. package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
  182. package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
  183. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -12
  184. package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
  185. package/dist/runtime/foundation/service-stateful-registry.js +10 -2
  186. package/dist/runtime/foundation/service-stateful-runtime.d.ts +26 -25
  187. package/dist/runtime/foundation/service-stateful-runtime.js +217 -204
  188. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -3
  189. package/dist/runtime/foundation/service-stateful-wire-codec.js +89 -55
  190. package/dist/runtime/foundation/service-topology-registry.d.ts +0 -1
  191. package/dist/runtime/foundation/service-topology-registry.js +17 -32
  192. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
  193. package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
  194. package/dist/runtime/foundation/service-wire-codec.js +10 -8
  195. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  196. package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
  197. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
  198. package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
  199. package/dist/runtime/framework-errors-internal.d.ts +2 -1
  200. package/dist/runtime/framework-errors-internal.js +343 -122
  201. package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
  202. package/dist/runtime/handlers/handler-instance-scope.js +61 -74
  203. package/dist/runtime/host/actor-packet-relay.d.ts +11 -8
  204. package/dist/runtime/host/actor-packet-relay.js +54 -99
  205. package/dist/runtime/host/actor-placement-coordinator.js +7 -5
  206. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
  207. package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
  208. package/dist/runtime/host/actor-transfer-runtime.d.ts +16 -18
  209. package/dist/runtime/host/actor-transfer-runtime.js +143 -176
  210. package/dist/runtime/host/application-job-queue.js +16 -33
  211. package/dist/runtime/host/bound-session-relay.js +1 -1
  212. package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
  213. package/dist/runtime/host/index.d.ts +14 -13
  214. package/dist/runtime/host/index.js +190 -171
  215. package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
  216. package/dist/runtime/host/instance-activation-authority.js +17 -45
  217. package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
  218. package/dist/runtime/host/location-runtime-owner.js +2 -2
  219. package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
  220. package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
  221. package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
  222. package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
  223. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
  224. package/dist/runtime/host/remote-bound-session-relay.js +15 -28
  225. package/dist/runtime/host/route-mesh-runtime.d.ts +13 -11
  226. package/dist/runtime/host/route-mesh-runtime.js +171 -252
  227. package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
  228. package/dist/runtime/host/runtime-shutdown.js +18 -21
  229. package/dist/runtime/host/service-relocation-control.js +6 -1
  230. package/dist/runtime/host/service-relocation-host-runtime.d.ts +21 -30
  231. package/dist/runtime/host/service-relocation-host-runtime.js +508 -416
  232. package/dist/runtime/host/spot-address-transport.d.ts +3 -12
  233. package/dist/runtime/host/spot-address-transport.js +78 -220
  234. package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
  235. package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
  236. package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -10
  237. package/dist/runtime/host/spot-runtime-options-factory.js +50 -14
  238. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -3
  239. package/dist/runtime/host/user-spot-creation-coordinator.js +11 -8
  240. package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
  241. package/dist/runtime/locations/authority-key-codec.js +4 -3
  242. package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
  243. package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
  244. package/dist/runtime/locations/creation-operation-id.js +6 -4
  245. package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
  246. package/dist/runtime/locations/in-memory-authority-store.js +31 -15
  247. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  248. package/dist/runtime/locations/in-memory-location-store.js +17 -14
  249. package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
  250. package/dist/runtime/locations/in-memory-provider-location-store.js +72 -22
  251. package/dist/runtime/locations/key-codec.js +3 -2
  252. package/dist/runtime/locations/lease-tracker.d.ts +3 -5
  253. package/dist/runtime/locations/lease-tracker.js +7 -11
  254. package/dist/runtime/locations/lifecycle.d.ts +4 -9
  255. package/dist/runtime/locations/lifecycle.js +2 -31
  256. package/dist/runtime/locations/location-store-failure.d.ts +2 -0
  257. package/dist/runtime/locations/location-store-failure.js +7 -0
  258. package/dist/runtime/locations/location-store-pages.d.ts +3 -0
  259. package/dist/runtime/locations/location-store-pages.js +13 -0
  260. package/dist/runtime/locations/location-store-repository.d.ts +5 -7
  261. package/dist/runtime/locations/location-store-repository.js +309 -336
  262. package/dist/runtime/locations/relocation-blob.js +18 -5
  263. package/dist/runtime/locations/resolvers.d.ts +5 -5
  264. package/dist/runtime/locations/resolvers.js +37 -28
  265. package/dist/runtime/locations/runtime.d.ts +5 -4
  266. package/dist/runtime/locations/runtime.js +123 -92
  267. package/dist/runtime/locations/spot-location-claims.d.ts +6 -0
  268. package/dist/runtime/locations/spot-location-claims.js +42 -1
  269. package/dist/runtime/messaging/payload-codec.js +26 -20
  270. package/dist/runtime/messaging/request-deadline.d.ts +3 -0
  271. package/dist/runtime/messaging/request-deadline.js +39 -0
  272. package/dist/runtime/messaging/submission-result.d.ts +4 -0
  273. package/dist/runtime/messaging/submission-result.js +56 -1
  274. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
  275. package/dist/runtime/protocol/service_wire_codec.generated.js +12 -7
  276. package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +4 -1
  277. package/dist/runtime/spots/index.d.ts +14 -20
  278. package/dist/runtime/spots/index.js +302 -176
  279. package/dist/runtime/spots/spot-activation-registry.d.ts +3 -5
  280. package/dist/runtime/spots/spot-activation-registry.js +14 -50
  281. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  282. package/dist/runtime/spots/spot-activation-state.js +2 -2
  283. package/dist/runtime/spots/spot-activation.d.ts +3 -4
  284. package/dist/runtime/spots/spot-activation.js +49 -32
  285. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
  286. package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
  287. package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
  288. package/dist/runtime/spots/spot-actor-join-dispatch.js +4 -52
  289. package/dist/runtime/spots/spot-actor-membership.d.ts +4 -6
  290. package/dist/runtime/spots/spot-actor-membership.js +22 -45
  291. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
  292. package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
  293. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
  294. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
  295. package/dist/runtime/spots/spot-context.d.ts +2 -2
  296. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -2
  297. package/dist/runtime/spots/spot-entry-activation.js +9 -20
  298. package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
  299. package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
  300. package/dist/runtime/spots/spot-manager-public.js +5 -4
  301. package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
  302. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -18
  303. package/dist/runtime/spots/spot-node-runtime-manager.js +67 -72
  304. package/dist/runtime/spots/spot-outbound.d.ts +7 -8
  305. package/dist/runtime/spots/spot-outbound.js +21 -23
  306. package/dist/runtime/spots/spot-remote-codec.js +5 -3
  307. package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
  308. package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
  309. package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
  310. package/dist/runtime/spots/spot-route-replies.js +3 -1
  311. package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -3
  312. package/dist/runtime/spots/spot-routed-actor-admission.js +3 -12
  313. package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +1 -2
  314. package/dist/runtime/spots/spot-routed-frame-dispatch.js +0 -1
  315. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
  316. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
  317. package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -16
  318. package/dist/runtime/spots/spot-serial-executor.js +2 -2
  319. package/dist/runtime/spots/spot-serial-turn-executor.d.ts +27 -7
  320. package/dist/runtime/spots/spot-serial-turn-executor.js +83 -11
  321. package/dist/runtime/spots/spot-timer.d.ts +3 -2
  322. package/dist/runtime/streams/actor-session-binding-registry.d.ts +16 -29
  323. package/dist/runtime/streams/actor-session-binding-registry.js +142 -212
  324. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -4
  325. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +8 -4
  326. package/dist/runtime/streams/bound-actor-relay-sender.js +65 -41
  327. package/dist/runtime/streams/bound-session-service.d.ts +7 -0
  328. package/dist/runtime/streams/bound-session-service.js +12 -2
  329. package/dist/runtime/streams/index.d.ts +16 -17
  330. package/dist/runtime/streams/index.js +22 -23
  331. package/dist/runtime/streams/managed-stream.d.ts +5 -2
  332. package/dist/runtime/streams/managed-stream.js +20 -13
  333. package/dist/runtime/streams/native-fallback-bound-session.js +14 -19
  334. package/dist/runtime/streams/protocol.d.ts +6 -33
  335. package/dist/runtime/streams/protocol.js +38 -110
  336. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
  337. package/dist/runtime/streams/session-actor-coordinator.js +12 -4
  338. package/dist/runtime/streams/session-calls.d.ts +6 -8
  339. package/dist/runtime/streams/session-calls.js +6 -22
  340. package/dist/runtime/streams/session-context.d.ts +10 -10
  341. package/dist/runtime/streams/session-context.js +25 -10
  342. package/dist/runtime/streams/session-requests.js +2 -1
  343. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
  344. package/dist/runtime/streams/stream-frame-factory.js +2 -2
  345. package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
  346. package/dist/runtime/streams/stream-session-runtime.js +25 -33
  347. package/dist/runtime/workers/index.d.ts +2 -2
  348. package/dist/runtime/workers/index.js +5 -4
  349. package/package.json +3 -3
  350. package/src/contracts/Actors/ZLinkActorClient.ts +1 -1
  351. package/src/contracts/Channels/Calls.ts +1 -1
  352. package/src/contracts/Common/CoreTypes.ts +7 -0
  353. package/src/contracts/Common/index.ts +1 -1
  354. package/src/contracts/Configuration/Builders.ts +0 -1
  355. package/src/contracts/Configuration/Configs.ts +0 -1
  356. package/src/contracts/Configuration/InternalDefaults.ts +12 -0
  357. package/src/contracts/Configuration/Registration.ts +92 -48
  358. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
  359. package/src/contracts/Configuration/RegistrationBuilders.ts +77 -71
  360. package/src/contracts/Configuration/RegistrationTypes.ts +1 -5
  361. package/src/contracts/Configuration/RegistrationValidators.ts +19 -17
  362. package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
  363. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
  364. package/src/contracts/Handlers/JsonContract.ts +14 -4
  365. package/src/contracts/Locations/Authority.ts +7 -3
  366. package/src/contracts/Locations/Options.ts +1 -1
  367. package/src/contracts/Locations/Stores.ts +14 -0
  368. package/src/contracts/Spots/Contracts.ts +2 -2
  369. package/src/contracts/Streams/BoundSessionContracts.ts +1 -1
  370. package/src/contracts/Streams/IZLinkSession.ts +2 -3
  371. package/src/contracts/Streams/IZLinkSessionActor.ts +2 -6
  372. package/src/internal.ts +14 -0
  373. package/src/nest-integration.ts +28 -10
  374. package/src/runtime/abort.ts +6 -5
  375. package/src/runtime/activation-admission.ts +2 -8
  376. package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
  377. package/src/runtime/actors/actor-client.ts +85 -218
  378. package/src/runtime/actors/actor-context.ts +39 -33
  379. package/src/runtime/actors/actor-handoff.ts +24 -22
  380. package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
  381. package/src/runtime/actors/actor-local-native-join.ts +172 -174
  382. package/src/runtime/actors/actor-native-lookup.ts +2 -9
  383. package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
  384. package/src/runtime/actors/actor-remote-joiner.ts +9 -11
  385. package/src/runtime/actors/actor-remote-wire.ts +5 -3
  386. package/src/runtime/actors/actor-request-deadline.ts +4 -0
  387. package/src/runtime/actors/actor-retry-delay.ts +2 -1
  388. package/src/runtime/actors/actor-routed-join-transport.ts +3 -5
  389. package/src/runtime/actors/actor-runtime-state.ts +85 -247
  390. package/src/runtime/actors/bound-session-wire.ts +2 -8
  391. package/src/runtime/actors/deferred-join-completion.ts +10 -6
  392. package/src/runtime/actors/index.ts +100 -79
  393. package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
  394. package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
  395. package/src/runtime/admission.ts +8 -1
  396. package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
  397. package/src/runtime/backend/contracts/index.ts +14 -37
  398. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -18
  399. package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
  400. package/src/runtime/backend/node/node-backend-adapter-support.ts +67 -10
  401. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +0 -2
  402. package/src/runtime/backend/node/node-event-loop-poller.ts +8 -12
  403. package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
  404. package/src/runtime/backend/node/node-raw-binding-port.ts +44 -49
  405. package/src/runtime/backend/node/node-raw-mesh-backend.ts +227 -170
  406. package/src/runtime/backend/node/node-socket-backend-adapter.ts +4 -3
  407. package/src/runtime/backend/raw-binding-port.ts +1 -1
  408. package/src/runtime/backend/runtime-values.ts +4 -1
  409. package/src/runtime/channels/channel-clients.ts +139 -102
  410. package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
  411. package/src/runtime/channels/channel-envelope.ts +74 -57
  412. package/src/runtime/channels/channel-outbound-operations.ts +40 -55
  413. package/src/runtime/channels/channel-receive-loops.ts +39 -7
  414. package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
  415. package/src/runtime/channels/channel-runtime-manager.ts +12 -30
  416. package/src/runtime/channels/channel-socket-options.ts +8 -15
  417. package/src/runtime/channels/channel-socket-registry.ts +291 -196
  418. package/src/runtime/channels/channel-transports.ts +168 -145
  419. package/src/runtime/channels/client-server-location-runtime.ts +17 -17
  420. package/src/runtime/channels/client-server-service-wire.ts +40 -12
  421. package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
  422. package/src/runtime/channels/fanout-location-runtime.ts +172 -91
  423. package/src/runtime/channels/local-spot-route-transport.ts +1 -5
  424. package/src/runtime/channels/router-socket-spot-route-transport.ts +2 -6
  425. package/src/runtime/channels/source-spot-router.ts +2 -9
  426. package/src/runtime/channels/spot-direct-envelope.ts +1 -1
  427. package/src/runtime/channels/spot-node-route-transport.ts +7 -9
  428. package/src/runtime/channels/spot-route-bridge-transport.ts +5 -12
  429. package/src/runtime/channels/spot-route-dispatch-strategy.ts +11 -30
  430. package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
  431. package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
  432. package/src/runtime/diagnostics/flow-context.ts +16 -2
  433. package/src/runtime/diagnostics/index.ts +27 -17
  434. package/src/runtime/diagnostics/message-flow.ts +15 -25
  435. package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
  436. package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
  437. package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
  438. package/src/runtime/disposal.ts +19 -0
  439. package/src/runtime/execution/index.ts +60 -20
  440. package/src/runtime/execution/serial-execution-queue.ts +131 -18
  441. package/src/runtime/execution/state-lane.ts +142 -4
  442. package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
  443. package/src/runtime/foundation/event-loop-resources.ts +5 -122
  444. package/src/runtime/foundation/operation-identity.ts +11 -5
  445. package/src/runtime/foundation/operation-registry.ts +33 -50
  446. package/src/runtime/foundation/raw-service-mesh-runtime.ts +127 -125
  447. package/src/runtime/foundation/runtime-state-projections.ts +9 -1
  448. package/src/runtime/foundation/service-authority-payload-codec.ts +31 -13
  449. package/src/runtime/foundation/service-discovery-registry.ts +32 -3
  450. package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
  451. package/src/runtime/foundation/service-liveness-registry.ts +2 -1
  452. package/src/runtime/foundation/service-maintenance-runtime.ts +0 -10
  453. package/src/runtime/foundation/service-metadata-codec.ts +2 -2
  454. package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
  455. package/src/runtime/foundation/service-relocation-object-owner.ts +5 -2
  456. package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
  457. package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
  458. package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -17
  459. package/src/runtime/foundation/service-stateful-registry.ts +14 -2
  460. package/src/runtime/foundation/service-stateful-runtime.ts +322 -276
  461. package/src/runtime/foundation/service-stateful-wire-codec.ts +128 -80
  462. package/src/runtime/foundation/service-topology-registry.ts +23 -32
  463. package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
  464. package/src/runtime/foundation/service-wire-codec.ts +15 -8
  465. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  466. package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
  467. package/src/runtime/framework-errors-internal.ts +380 -134
  468. package/src/runtime/handlers/handler-instance-scope.ts +68 -95
  469. package/src/runtime/host/actor-packet-relay.ts +63 -160
  470. package/src/runtime/host/actor-placement-coordinator.ts +8 -5
  471. package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
  472. package/src/runtime/host/actor-transfer-runtime.ts +180 -260
  473. package/src/runtime/host/application-job-queue.ts +28 -34
  474. package/src/runtime/host/bound-session-relay.ts +1 -2
  475. package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
  476. package/src/runtime/host/index.ts +327 -320
  477. package/src/runtime/host/instance-activation-authority.ts +89 -109
  478. package/src/runtime/host/location-runtime-owner.ts +4 -2
  479. package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
  480. package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
  481. package/src/runtime/host/remote-bound-session-relay.ts +16 -57
  482. package/src/runtime/host/route-mesh-runtime.ts +228 -271
  483. package/src/runtime/host/runtime-shutdown.ts +17 -21
  484. package/src/runtime/host/service-relocation-control.ts +14 -1
  485. package/src/runtime/host/service-relocation-host-runtime.ts +699 -561
  486. package/src/runtime/host/spot-address-transport.ts +175 -356
  487. package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
  488. package/src/runtime/host/spot-runtime-options-factory.ts +73 -22
  489. package/src/runtime/host/user-spot-creation-coordinator.ts +36 -22
  490. package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
  491. package/src/runtime/locations/authority-key-codec.ts +7 -3
  492. package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
  493. package/src/runtime/locations/creation-operation-id.ts +6 -3
  494. package/src/runtime/locations/domain-store-contract.ts +12 -3
  495. package/src/runtime/locations/in-memory-authority-store.ts +44 -15
  496. package/src/runtime/locations/in-memory-location-store.ts +50 -39
  497. package/src/runtime/locations/in-memory-provider-location-store.ts +100 -25
  498. package/src/runtime/locations/key-codec.ts +3 -2
  499. package/src/runtime/locations/lease-tracker.ts +8 -14
  500. package/src/runtime/locations/lifecycle.ts +13 -43
  501. package/src/runtime/locations/location-store-failure.ts +4 -0
  502. package/src/runtime/locations/location-store-pages.ts +18 -0
  503. package/src/runtime/locations/location-store-repository.ts +457 -482
  504. package/src/runtime/locations/relocation-blob.ts +17 -6
  505. package/src/runtime/locations/resolvers.ts +75 -49
  506. package/src/runtime/locations/runtime.ts +220 -110
  507. package/src/runtime/locations/spot-location-claims.ts +58 -1
  508. package/src/runtime/messaging/payload-codec.ts +35 -24
  509. package/src/runtime/messaging/request-deadline.ts +58 -0
  510. package/src/runtime/messaging/submission-result.ts +72 -2
  511. package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
  512. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
  513. package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +4 -1
  514. package/src/runtime/spots/index.ts +433 -229
  515. package/src/runtime/spots/spot-activation-registry.ts +30 -69
  516. package/src/runtime/spots/spot-activation-state.ts +2 -2
  517. package/src/runtime/spots/spot-activation.ts +67 -37
  518. package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
  519. package/src/runtime/spots/spot-actor-join-dispatch.ts +24 -77
  520. package/src/runtime/spots/spot-actor-membership.ts +40 -72
  521. package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
  522. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
  523. package/src/runtime/spots/spot-context.ts +3 -3
  524. package/src/runtime/spots/spot-entry-activation.ts +13 -30
  525. package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
  526. package/src/runtime/spots/spot-manager-public.ts +21 -17
  527. package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
  528. package/src/runtime/spots/spot-node-runtime-manager.ts +136 -125
  529. package/src/runtime/spots/spot-outbound.ts +59 -47
  530. package/src/runtime/spots/spot-remote-codec.ts +7 -3
  531. package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
  532. package/src/runtime/spots/spot-route-replies.ts +6 -4
  533. package/src/runtime/spots/spot-routed-actor-admission.ts +13 -26
  534. package/src/runtime/spots/spot-routed-frame-dispatch.ts +2 -3
  535. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
  536. package/src/runtime/spots/spot-runtime-ports.ts +5 -27
  537. package/src/runtime/spots/spot-serial-executor.ts +2 -2
  538. package/src/runtime/spots/spot-serial-turn-executor.ts +112 -11
  539. package/src/runtime/spots/spot-timer.ts +3 -2
  540. package/src/runtime/streams/actor-session-binding-registry.ts +179 -269
  541. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +0 -8
  542. package/src/runtime/streams/bound-actor-relay-sender.ts +98 -66
  543. package/src/runtime/streams/bound-session-service.ts +22 -2
  544. package/src/runtime/streams/index.ts +78 -68
  545. package/src/runtime/streams/managed-stream.ts +32 -23
  546. package/src/runtime/streams/native-fallback-bound-session.ts +14 -28
  547. package/src/runtime/streams/protocol.ts +34 -88
  548. package/src/runtime/streams/session-actor-coordinator.ts +17 -5
  549. package/src/runtime/streams/session-calls.ts +11 -36
  550. package/src/runtime/streams/session-context.ts +60 -25
  551. package/src/runtime/streams/session-requests.ts +2 -1
  552. package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
  553. package/src/runtime/streams/stream-frame-factory.ts +2 -3
  554. package/src/runtime/streams/stream-session-runtime.ts +57 -59
  555. package/src/runtime/workers/index.ts +13 -12
  556. package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
  557. package/dist/runtime/actors/post-commit-actor-location.js +0 -72
  558. package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
  559. package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
  560. package/src/runtime/actors/post-commit-actor-location.ts +0 -121
  561. package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
@@ -1,6 +1,5 @@
1
1
  export interface OperationClock {
2
- setTimeout(callback: () => void, delayMs: number): unknown;
3
- clearTimeout(handle: unknown): void;
2
+ now(): number;
4
3
  }
5
4
 
6
5
  export class OperationTimeoutError extends Error {
@@ -26,32 +25,26 @@ export interface PendingOperation<T> {
26
25
  }
27
26
 
28
27
  interface Entry<T> {
29
- readonly generation: bigint;
28
+ readonly deadlineMs?: number;
30
29
  readonly resolve: (value: T | PromiseLike<T>) => void;
31
30
  readonly reject: (reason: unknown) => void;
32
- timer?: unknown;
33
31
  }
34
32
 
35
33
  const systemClock: OperationClock = {
36
- setTimeout(callback, delayMs) {
37
- // A request promise is live work. Raw RouteMesh polling deliberately
38
- // uses unref'ed timers, so this deadline is the handle that keeps a
39
- // submit() caller alive until a reply, cancellation, or deadline settles.
40
- return setTimeout(callback, delayMs);
41
- },
42
- clearTimeout(handle) {
43
- clearTimeout(handle as NodeJS.Timeout);
44
- }
34
+ now: () => performance.now()
45
35
  };
46
36
 
47
37
  /** Owns request completion so reply, timeout, cancellation, and shutdown race safely. */
48
38
  export class OperationRegistry<T> {
49
39
  private readonly entries = new Map<bigint, Entry<T>>();
50
40
  private nextId = 1n;
51
- private generation = 1n;
41
+ private deadlineCursor?: MapIterator<[bigint, Entry<T>]>;
52
42
  private closed = false;
53
43
 
54
- constructor(private readonly clock: OperationClock = systemClock) {}
44
+ constructor(
45
+ private readonly clock: OperationClock = systemClock,
46
+ private readonly onPendingChanged?: () => void
47
+ ) {}
55
48
 
56
49
  register(
57
50
  timeoutMs: number,
@@ -62,23 +55,19 @@ export class OperationRegistry<T> {
62
55
  throw new RangeError('timeoutMs must be a non-negative finite number.');
63
56
  }
64
57
  const id = this.nextId++;
65
- const generation = this.generation;
66
58
  let resolve!: Entry<T>['resolve'];
67
59
  let reject!: Entry<T>['reject'];
68
60
  const promise = new Promise<T>((onResolve, onReject) => {
69
61
  resolve = onResolve;
70
62
  reject = onReject;
71
63
  });
72
- const entry: Entry<T> = { generation, resolve, reject };
64
+ const entry: Entry<T> = {
65
+ deadlineMs: timeoutOwner === 'registry' ? this.clock.now() + timeoutMs : undefined,
66
+ resolve,
67
+ reject
68
+ };
73
69
  this.entries.set(id, entry);
74
- // Durable senders classify exhaustion from admission history. Keep their
75
- // identity and cancellation here without racing that decision with a timer.
76
- if (timeoutOwner === 'registry') {
77
- entry.timer = this.clock.setTimeout(
78
- () => this.rejectIfCurrent(id, generation, new OperationTimeoutError(id)),
79
- timeoutMs
80
- );
81
- }
70
+ if (this.entries.size === 1) this.onPendingChanged?.();
82
71
  return { id, promise };
83
72
  }
84
73
 
@@ -90,10 +79,6 @@ export class OperationRegistry<T> {
90
79
  }
91
80
 
92
81
  fail(id: bigint, reason: unknown): boolean {
93
- return this.failCore(id, reason);
94
- }
95
-
96
- private failCore(id: bigint, reason: unknown): boolean {
97
82
  const entry = this.take(id);
98
83
  if (entry === undefined) return false;
99
84
  entry.reject(reason);
@@ -101,7 +86,7 @@ export class OperationRegistry<T> {
101
86
  }
102
87
 
103
88
  cancel(id: bigint, message?: string): boolean {
104
- return this.failCore(id, new OperationCancelledError(id, message));
89
+ return this.fail(id, new OperationCancelledError(id, message));
105
90
  }
106
91
 
107
92
  isPending(id: bigint): boolean {
@@ -111,38 +96,36 @@ export class OperationRegistry<T> {
111
96
  close(reason = 'Operation registry closed.'): void {
112
97
  if (this.closed) return;
113
98
  this.closed = true;
114
- this.generation++;
115
- const pending = [...this.entries.entries()];
116
- this.entries.clear();
117
- for (const [, entry] of pending) this.clearTimer(entry);
118
- for (const [id, entry] of pending) {
119
- entry.reject(new OperationCancelledError(id, reason));
120
- }
99
+ for (const id of this.entries.keys()) this.cancel(id, reason);
100
+ this.deadlineCursor = undefined;
121
101
  }
122
102
 
123
103
  get size(): number {
124
104
  return this.entries.size;
125
105
  }
126
106
 
127
- private rejectIfCurrent(id: bigint, generation: bigint, reason: unknown): void {
128
- const entry = this.entries.get(id);
129
- if (entry === undefined || entry.generation !== generation) return;
130
- this.entries.delete(id);
131
- this.clearTimer(entry);
132
- entry.reject(reason);
107
+ expire(nowMs: number, turnDeadlineMs: number): number {
108
+ let expired = 0;
109
+ while (this.clock.now() < turnDeadlineMs) {
110
+ this.deadlineCursor ??= this.entries.entries();
111
+ const current = this.deadlineCursor.next();
112
+ if (current.done === true) {
113
+ this.deadlineCursor = undefined;
114
+ break;
115
+ }
116
+ const [id, entry] = current.value;
117
+ if (entry.deadlineMs !== undefined && entry.deadlineMs <= nowMs) {
118
+ if (this.fail(id, new OperationTimeoutError(id))) expired++;
119
+ }
120
+ }
121
+ return expired;
133
122
  }
134
123
 
135
124
  private take(id: bigint): Entry<T> | undefined {
136
125
  const entry = this.entries.get(id);
137
126
  if (entry === undefined) return undefined;
138
127
  this.entries.delete(id);
139
- this.clearTimer(entry);
128
+ if (this.entries.size === 0) this.onPendingChanged?.();
140
129
  return entry;
141
130
  }
142
-
143
- private clearTimer(entry: Entry<T>): void {
144
- if (entry.timer === undefined) return;
145
- this.clock.clearTimeout(entry.timer);
146
- entry.timer = undefined;
147
- }
148
131
  }
@@ -1,27 +1,37 @@
1
+ import { constants as osConstants } from 'node:os';
2
+ import { ApplicationIngressRecordOwner } from '../application-jobs/application-ingress-record-owner';
3
+ import type {
4
+ ApplicationJobPermitPort,
5
+ ApplicationJobQueuePort
6
+ } from '../application-jobs/contracts';
1
7
  import type {
2
8
  ZLinkRawBindingPort,
3
9
  ZLinkRawHostPort,
4
10
  ZLinkRawReceivedRecord,
5
11
  ZLinkRawRouterPort
6
12
  } from '../backend/raw-binding-port';
7
- import { RequestResult, SubmitResult } from '../backend/runtime-values';
8
- import type {
9
- ApplicationJobPermitPort,
10
- ApplicationJobQueuePort
11
- } from '../application-jobs/contracts';
12
- import { ApplicationIngressRecordOwner } from '../application-jobs/application-ingress-record-owner';
13
+ import { submitToRequestResult } from '../messaging/submission-result';
14
+ import { RequestResult, SubmitResult, isZLinkBackendResultError } from '../backend/runtime-values';
15
+ import { enumWireRejectReason } from '../protocol/service_wire_codec.generated';
13
16
  import { OperationRegistry, type PendingOperation } from './operation-registry';
14
17
  import { ServiceLivenessRegistry, type ServiceLivenessTick } from './service-liveness-registry';
15
18
  import { ServiceMailbox, type ServiceMailboxRecord } from './service-mailbox';
16
19
  import {
17
- ServiceTopologyRegistry,
18
20
  sameServiceNodeDescriptor,
21
+ ServiceTopologyRegistry,
19
22
  validateDescriptor,
20
23
  type AdmittedServicePeer,
21
24
  type PeerAdmissionResult,
22
- type ServicePeerAdmissionExpectation,
23
- type ServiceNodeDescriptor
25
+ type ServiceNodeDescriptor,
26
+ type ServicePeerAdmissionExpectation
24
27
  } from './service-topology-registry';
28
+ import { createServiceWireCodec } from './service-wire-codec';
29
+ import {
30
+ SERVICE_WIRE_MAGIC,
31
+ SERVICE_WIRE_MAJOR,
32
+ ServiceWireCommand,
33
+ ServiceWireFrameworkErrorCode
34
+ } from './service-wire-constants.generated';
25
35
  import {
26
36
  decodeApplicationPayloadView,
27
37
  decodeChannelRequestHeader,
@@ -40,14 +50,11 @@ import {
40
50
  encodeReplyHeader,
41
51
  encodeRouteMeshAdmission,
42
52
  M6aServiceWireCommand,
43
- type ServiceApplicationPayload,
44
- ServiceWireProtocolError
53
+ ServiceWireProtocolError,
54
+ type ServiceApplicationPayload
45
55
  } from './service-wire-m6a-codec';
46
- import { createServiceWireCodec } from './service-wire-codec';
47
- import {
48
- ServiceWireCommand,
49
- ServiceWireFrameworkErrorCode
50
- } from './service-wire-constants.generated';
56
+
57
+ const nativeErrnoValues = osConstants.errno;
51
58
 
52
59
  export type RawServicePumpResult =
53
60
  'noData' | 'infrastructure' | 'application' | 'dropped' | 'protocolError';
@@ -93,6 +100,7 @@ export type RawServiceIngressHandler = (
93
100
  ) => RawServicePumpResult | undefined | Promise<RawServicePumpResult | undefined>;
94
101
 
95
102
  export interface RawServiceMeshRuntimeOptions {
103
+ readonly onPendingOperationsChanged?: () => void;
96
104
  readonly descriptor: ServiceNodeDescriptor;
97
105
  readonly resolveAdvertisedEndpoint?: (boundEndpoint: string) => string;
98
106
  readonly probeIntervalMs?: number;
@@ -118,11 +126,15 @@ export interface RawServiceMeshRuntimeOptions {
118
126
 
119
127
  // Framework error code 13 (RequestTargetNotFound) is encoded as 14 on a
120
128
  // RequestResult.NotFound reply. Boundary transport results keep failureCode 0.
121
- const REQUEST_TARGET_NOT_FOUND_FAILURE_CODE = 14;
129
+ const RAW_MESH_RECEIVE_RECORD_BUDGET = 64;
130
+ const RAW_MESH_RECEIVE_BYTE_BUDGET = 4 * 1024 * 1024;
131
+ export const RAW_MESH_RECEIVE_TIME_BUDGET_MS = 2;
132
+
133
+ const REQUEST_TARGET_NOT_FOUND_FAILURE_CODE = ServiceWireFrameworkErrorCode.requestTargetNotFound;
122
134
 
123
135
  const livenessCodec = createServiceWireCodec({
124
- magic: [0x5a, 0x4d],
125
- major: 1,
136
+ magic: SERVICE_WIRE_MAGIC,
137
+ major: SERVICE_WIRE_MAJOR,
126
138
  commands: M6aServiceWireCommand
127
139
  });
128
140
 
@@ -135,7 +147,7 @@ export class RawServiceMeshRuntime {
135
147
  readonly mailbox: ServiceMailbox;
136
148
  readonly liveness: ServiceLivenessRegistry;
137
149
 
138
- private readonly operations = new OperationRegistry<RawServiceRequestResult>();
150
+ private readonly operations: OperationRegistry<RawServiceRequestResult>;
139
151
  private readonly expectedPeers = new Map<
140
152
  string,
141
153
  {
@@ -144,6 +156,7 @@ export class RawServiceMeshRuntime {
144
156
  readonly endpoint?: string;
145
157
  readonly securityIdentity?: string;
146
158
  readonly lifecycleGeneration?: bigint;
159
+ helloSubmittedGeneration?: bigint;
147
160
  }
148
161
  >();
149
162
  private readonly endpointOnlyPeers = new Set<string>();
@@ -170,6 +183,7 @@ export class RawServiceMeshRuntime {
170
183
  private closed = false;
171
184
 
172
185
  constructor(options: RawServiceMeshRuntimeOptions) {
186
+ this.operations = new OperationRegistry(undefined, options.onPendingOperationsChanged);
173
187
  this.descriptor = options.descriptor;
174
188
  this.topology = new ServiceTopologyRegistry(options.descriptor);
175
189
  this.mailbox = new ServiceMailbox(options.onMailboxReady);
@@ -224,13 +238,16 @@ export class RawServiceMeshRuntime {
224
238
 
225
239
  connectPeer(endpoint: string, expected: ServiceNodeDescriptor): void {
226
240
  this.requireStarted().connectToRoutingId(expected.nodeRoutingId, endpoint);
227
- this.expectedPeers.set(expected.nodeRoutingId, {
228
- meshName: expected.meshName,
229
- nodeRoutingId: expected.nodeRoutingId,
230
- endpoint,
231
- securityIdentity: expected.securityIdentity,
232
- lifecycleGeneration: expected.lifecycleGeneration
233
- });
241
+ this.expectedPeers.set(
242
+ expected.nodeRoutingId,
243
+ Object.assign(this.expectedPeers.get(expected.nodeRoutingId) ?? {}, {
244
+ meshName: expected.meshName,
245
+ nodeRoutingId: expected.nodeRoutingId,
246
+ endpoint,
247
+ securityIdentity: expected.securityIdentity,
248
+ lifecycleGeneration: expected.lifecycleGeneration
249
+ })
250
+ );
234
251
  }
235
252
 
236
253
  connectPeerByRoutingId(
@@ -240,13 +257,16 @@ export class RawServiceMeshRuntime {
240
257
  lifecycleGeneration?: bigint
241
258
  ): void {
242
259
  this.requireStarted().connectToRoutingId(nodeRoutingId, endpoint);
243
- this.expectedPeers.set(nodeRoutingId, {
244
- meshName: this.topology.localDescriptor().meshName,
260
+ this.expectedPeers.set(
245
261
  nodeRoutingId,
246
- endpoint,
247
- securityIdentity,
248
- lifecycleGeneration
249
- });
262
+ Object.assign(this.expectedPeers.get(nodeRoutingId) ?? {}, {
263
+ meshName: this.topology.localDescriptor().meshName,
264
+ nodeRoutingId,
265
+ endpoint,
266
+ securityIdentity,
267
+ lifecycleGeneration
268
+ })
269
+ );
250
270
  }
251
271
 
252
272
  expectPeerByRoutingId(
@@ -255,13 +275,16 @@ export class RawServiceMeshRuntime {
255
275
  securityIdentity?: string,
256
276
  lifecycleGeneration?: bigint
257
277
  ): void {
258
- this.expectedPeers.set(nodeRoutingId, {
259
- meshName: this.topology.localDescriptor().meshName,
278
+ this.expectedPeers.set(
260
279
  nodeRoutingId,
261
- endpoint,
262
- securityIdentity,
263
- lifecycleGeneration
264
- });
280
+ Object.assign(this.expectedPeers.get(nodeRoutingId) ?? {}, {
281
+ meshName: this.topology.localDescriptor().meshName,
282
+ nodeRoutingId,
283
+ endpoint,
284
+ securityIdentity,
285
+ lifecycleGeneration
286
+ })
287
+ );
265
288
  }
266
289
 
267
290
  connectPeerEndpoint(endpoint: string): void {
@@ -349,11 +372,25 @@ export class RawServiceMeshRuntime {
349
372
  }
350
373
 
351
374
  async announcePeer(nodeRoutingId: string): Promise<boolean> {
352
- if (!this.expectedPeers.has(nodeRoutingId) || this.peerAdmissionSealed?.() === true)
375
+ const expected = this.expectedPeers.get(nodeRoutingId);
376
+ const generation = this.selectedRoutes.get(nodeRoutingId);
377
+ if (
378
+ expected === undefined ||
379
+ generation === undefined ||
380
+ expected.helloSubmittedGeneration === generation ||
381
+ this.peerAdmissionSealed?.() === true
382
+ )
353
383
  return false;
354
- return this.send(nodeRoutingId, [
384
+ const accepted = await this.send(nodeRoutingId, [
355
385
  encodeRouteMeshAdmission(M6aServiceWireCommand.hello, this.topology.localDescriptor())
356
386
  ]);
387
+ if (
388
+ accepted &&
389
+ this.expectedPeers.get(nodeRoutingId) === expected &&
390
+ this.selectedRoutes.get(nodeRoutingId) === generation
391
+ )
392
+ expected.helloSubmittedGeneration = generation;
393
+ return accepted;
357
394
  }
358
395
 
359
396
  isPeerRouteReady(nodeRoutingId: string, lifecycleGeneration?: bigint): boolean {
@@ -371,11 +408,6 @@ export class RawServiceMeshRuntime {
371
408
  async announceExpectedPeers(): Promise<number> {
372
409
  let accepted = 0;
373
410
  for (const nodeRoutingId of this.expectedPeers.keys()) {
374
- // Admission is a one-time fence for the current selected route.
375
- // Re-sending Hello after the peer is admitted would re-run admission on
376
- // every poll and reset the liveness record before application traffic
377
- // can use the route. A peer whose selected route ended is removed by the
378
- // route observer and remains eligible for the next admission attempt.
379
411
  if (this.topology.peer(nodeRoutingId) !== undefined) continue;
380
412
  if (await this.announcePeer(nodeRoutingId)) accepted++;
381
413
  }
@@ -419,7 +451,6 @@ export class RawServiceMeshRuntime {
419
451
  for (const peer of this.topology.peers()) {
420
452
  await this.send(peer.descriptor.nodeRoutingId, [update]);
421
453
  }
422
- await this.announceExpectedPeers();
423
454
  }
424
455
 
425
456
  replaceDiscoveredNotRequired(descriptors: readonly ServiceNodeDescriptor[]): void {
@@ -449,23 +480,6 @@ export class RawServiceMeshRuntime {
449
480
  if (selection.kind !== 'selected') return selection.submitResult;
450
481
  const selected = selection.peer;
451
482
  const applicationFrame = this.applicationFrame(payload);
452
- if (selected.descriptor.nodeRoutingId === this.descriptor.nodeRoutingId) {
453
- const applicationJobOwner = await this.reserveLocalIngress();
454
- try {
455
- const applicationJob = await applicationJobOwner.acquire('application');
456
- const accepted = this.mailbox.tryEnqueue({
457
- owner: `channel:${channelName}`,
458
- domain: 'application',
459
- parts: [encodeChannelSendHeader(channelName), applicationFrame],
460
- sourceRoutingId: this.descriptor.nodeRoutingId,
461
- applicationJob
462
- });
463
- if (!accepted) applicationJob.close();
464
- return accepted ? SubmitResult.Ok : SubmitResult.NotAdmitted;
465
- } finally {
466
- applicationJobOwner.close();
467
- }
468
- }
469
483
  return (await this.send(selected.descriptor.nodeRoutingId, [
470
484
  encodeChannelSendHeader(channelName),
471
485
  applicationFrame
@@ -503,7 +517,7 @@ export class RawServiceMeshRuntime {
503
517
 
504
518
  private selectChannelTarget(channelName: string): RawServiceChannelTargetSelection {
505
519
  const selected = this.topology.selectChannel(channelName, (peer) =>
506
- this.isLocalOrReadyPeer(peer.descriptor.nodeRoutingId)
520
+ this.isPeerRouteReady(peer.descriptor.nodeRoutingId)
507
521
  );
508
522
  if (selected !== undefined) return { kind: 'selected', peer: selected };
509
523
  return this.topology.hasKnownChannelTarget(channelName)
@@ -522,10 +536,6 @@ export class RawServiceMeshRuntime {
522
536
  };
523
537
  }
524
538
 
525
- private isLocalOrReadyPeer(nodeRoutingId: string): boolean {
526
- return nodeRoutingId === this.descriptor.nodeRoutingId || this.isPeerRouteReady(nodeRoutingId);
527
- }
528
-
529
539
  setServiceIngress(handler: RawServiceIngressHandler): void {
530
540
  if (this.serviceIngress !== undefined && this.serviceIngress !== handler) {
531
541
  throw new Error('Raw service ingress is already registered.');
@@ -600,20 +610,20 @@ export class RawServiceMeshRuntime {
600
610
  return this.receiveOne(nowMs, observe);
601
611
  }
602
612
 
603
- setReadableHandler(handler: () => void): void {
613
+ setReadableHandler(handler: (receiveReady: boolean, routeReady: boolean) => void): void {
604
614
  this.requireStarted().setReadableHandler(handler);
605
615
  }
606
616
 
607
617
  /** Returns whether a receive budget ended before no-data; idle ticks only maintain peers. */
608
- async pumpBatch(receiveReady = true): Promise<boolean> {
609
- await this.observeSelectedRoutes();
618
+ async pumpBatch(receiveReady = true, routeReady = false): Promise<boolean> {
619
+ if (routeReady) await this.observeSelectedRoutes();
610
620
  const startedAtMs = performance.now();
611
621
  let messages = 0;
612
622
  let bytes = 0;
613
623
  const observe: RawServicePumpObserver = (_source, byteCount) => {
614
624
  bytes += byteCount;
615
625
  };
616
- while (receiveReady && messages < 64 && !this.closed) {
626
+ while (receiveReady && messages < RAW_MESH_RECEIVE_RECORD_BUDGET && !this.closed) {
617
627
  const result = await this.receiveOne(performance.now(), observe);
618
628
  if (result === 'noData') {
619
629
  receiveReady = false;
@@ -622,7 +632,11 @@ export class RawServiceMeshRuntime {
622
632
  messages += 1;
623
633
  // Core owns the per-peer fair-queue cursor. The Framework limit bounds
624
634
  // the entire round, so changing peers does not renew its byte/count budget.
625
- if (bytes >= 4 * 1024 * 1024 || performance.now() - startedAtMs >= 2) break;
635
+ if (
636
+ bytes >= RAW_MESH_RECEIVE_BYTE_BUDGET ||
637
+ performance.now() - startedAtMs >= RAW_MESH_RECEIVE_TIME_BUDGET_MS
638
+ )
639
+ break;
626
640
  }
627
641
  if (!this.closed) {
628
642
  await this.announceExpectedPeers();
@@ -758,7 +772,9 @@ export class RawServiceMeshRuntime {
758
772
  (expected.meshName !== descriptor.meshName ||
759
773
  expected.nodeRoutingId !== descriptor.nodeRoutingId)
760
774
  ) {
761
- await this.send(received.sourceRid, [encodeReject(3)]);
775
+ await this.send(received.sourceRid, [
776
+ encodeReject(enumWireRejectReason('identityMismatch'))
777
+ ]);
762
778
  return 'infrastructure';
763
779
  }
764
780
  const result = this.admitPeer(
@@ -798,23 +814,7 @@ export class RawServiceMeshRuntime {
798
814
  }
799
815
  if (header.command === M6aServiceWireCommand.reject) {
800
816
  if (received.parts.length !== 1) return 'protocolError';
801
- const reason = decodeReject(received.parts[0]!);
802
- // Keep an already admitted peer: a reject of an earlier Hello on the
803
- // same selected route does not end the admission that succeeded.
804
- if (reason === 4 && this.topology.peer(received.sourceRid) === undefined) {
805
- const expected = this.expectedPeers.get(received.sourceRid);
806
- const local = this.topology.localDescriptor();
807
- this.topology.markNotRequired({
808
- ...local,
809
- nodeRoutingId: received.sourceRid,
810
- lifecycleGeneration: 1n,
811
- descriptorRevision: 1n,
812
- advertisedEndpoint: expected?.endpoint ?? local.advertisedEndpoint,
813
- channels: [],
814
- objectRole: 'client'
815
- });
816
- this.retireNotRequiredExpectedPeer(received.sourceRid);
817
- }
817
+ decodeReject(received.parts[0]!);
818
818
  return 'infrastructure';
819
819
  }
820
820
  const peer = this.topology.peer(received.sourceRid);
@@ -831,17 +831,14 @@ export class RawServiceMeshRuntime {
831
831
  peer.connectionId,
832
832
  record.probeId
833
833
  );
834
- const sent =
835
- ack !== undefined &&
836
- (await this.send(received.sourceRid, [
837
- livenessCodec.encodeLivenessRecord({
838
- command: M6aServiceWireCommand.livenessAck,
839
- probeId: record.probeId
840
- })
841
- ]));
842
- if (!sent) {
843
- return 'protocolError';
844
- }
834
+ if (ack === undefined) return 'protocolError';
835
+ const sent = await this.send(received.sourceRid, [
836
+ livenessCodec.encodeLivenessRecord({
837
+ command: M6aServiceWireCommand.livenessAck,
838
+ probeId: record.probeId
839
+ })
840
+ ]);
841
+ if (!sent) return 'dropped';
845
842
  } else {
846
843
  this.liveness.acknowledge(received.sourceRid, peer.connectionId, record.probeId, nowMs);
847
844
  }
@@ -945,6 +942,14 @@ export class RawServiceMeshRuntime {
945
942
  }
946
943
  }
947
944
 
945
+ expireOperations(nowMs: number, turnDeadlineMs: number): number {
946
+ return this.operations.expire(nowMs, turnDeadlineMs);
947
+ }
948
+
949
+ get pendingOperationCount(): number {
950
+ return this.operations.size;
951
+ }
952
+
948
953
  async tickLiveness(nowMs = performance.now()): Promise<ServiceLivenessTick> {
949
954
  const result = this.liveness.tick(nowMs);
950
955
  this.requireStarted();
@@ -982,6 +987,8 @@ export class RawServiceMeshRuntime {
982
987
  for (const [nodeRoutingId, generation] of this.selectedRoutes) {
983
988
  if (observed.get(nodeRoutingId) === generation) continue;
984
989
  changes++;
990
+ const expected = this.expectedPeers.get(nodeRoutingId);
991
+ if (expected !== undefined) delete expected.helloSubmittedGeneration;
985
992
  const peer = this.topology.peer(nodeRoutingId);
986
993
  if (peer !== undefined && peer.connectionId === routeConnectionId(generation)) {
987
994
  this.removePeer(peer);
@@ -1001,7 +1008,6 @@ export class RawServiceMeshRuntime {
1001
1008
 
1002
1009
  close(): void {
1003
1010
  if (this.closed) return;
1004
- this.closed = true;
1005
1011
  this.applicationJobStop.abort(
1006
1012
  new Error('Raw service runtime application job admission stopped.')
1007
1013
  );
@@ -1013,9 +1019,10 @@ export class RawServiceMeshRuntime {
1013
1019
  this.applicationJobQueue.unregisterReceiveFlowTarget?.(router);
1014
1020
  }
1015
1021
  const host = this.host;
1022
+ if (host !== undefined) host.close();
1016
1023
  this.router = undefined;
1017
1024
  this.host = undefined;
1018
- if (host !== undefined) host.close();
1025
+ this.closed = true;
1019
1026
  }
1020
1027
 
1021
1028
  private requestToTarget(
@@ -1046,14 +1053,11 @@ export class RawServiceMeshRuntime {
1046
1053
  for (;;) {
1047
1054
  const alternate = this.topology.selectChannel(channelName, (peer) => {
1048
1055
  const candidate = peer.descriptor.nodeRoutingId;
1049
- return !excludedTargets.has(candidate) && this.isLocalOrReadyPeer(candidate);
1056
+ return !excludedTargets.has(candidate) && this.isPeerRouteReady(candidate);
1050
1057
  });
1051
1058
  if (alternate === undefined) break;
1052
1059
  selectedTargetNodeRoutingId = alternate.descriptor.nodeRoutingId;
1053
- if (
1054
- selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId ||
1055
- this.isPeerRouteReady(selectedTargetNodeRoutingId)
1056
- ) {
1060
+ if (this.isPeerRouteReady(selectedTargetNodeRoutingId)) {
1057
1061
  break;
1058
1062
  }
1059
1063
  excludedTargets.add(selectedTargetNodeRoutingId);
@@ -1077,10 +1081,7 @@ export class RawServiceMeshRuntime {
1077
1081
  return;
1078
1082
  }
1079
1083
  const accepted = this.mailbox.tryEnqueue({
1080
- owner:
1081
- channelName === undefined
1082
- ? `node:${this.descriptor.nodeRoutingId}`
1083
- : `channel:${channelName}`,
1084
+ owner: `node:${this.descriptor.nodeRoutingId}`,
1084
1085
  domain: 'application',
1085
1086
  parts,
1086
1087
  sourceRoutingId: this.descriptor.nodeRoutingId,
@@ -1260,8 +1261,13 @@ export class RawServiceMeshRuntime {
1260
1261
  try {
1261
1262
  await this.requireStarted().send(targetNodeRoutingId, parts);
1262
1263
  return true;
1263
- } catch {
1264
- return false;
1264
+ } catch (error) {
1265
+ if (isZLinkBackendResultError(error) && error.operation === 'submit') {
1266
+ const terminal = submitToRequestResult(error.result, error.phase);
1267
+ if (terminal === RequestResult.NotConnected || terminal === RequestResult.NotFound)
1268
+ return false;
1269
+ }
1270
+ throw error;
1265
1271
  }
1266
1272
  }
1267
1273
  }
@@ -1300,7 +1306,7 @@ function isAlreadyDisconnectedError(error: unknown): boolean {
1300
1306
  if (typeof error !== 'object' || error === null || !('nativeErrno' in error)) {
1301
1307
  return false;
1302
1308
  }
1303
- return (error as { readonly nativeErrno?: unknown }).nativeErrno === 2;
1309
+ return (error as { readonly nativeErrno?: unknown }).nativeErrno === nativeErrnoValues.ENOENT;
1304
1310
  }
1305
1311
 
1306
1312
  /**
@@ -1378,17 +1384,13 @@ function immutableDescriptorMismatch(
1378
1384
  return undefined;
1379
1385
  }
1380
1386
 
1381
- function admissionReason(result: PeerAdmissionResult): number {
1387
+ function admissionReason(result: Exclude<PeerAdmissionResult, 'admitted' | 'notRequired'>): number {
1382
1388
  switch (result) {
1383
1389
  case 'meshMismatch':
1384
- return 2;
1390
+ return enumWireRejectReason('topologyMismatch');
1385
1391
  case 'staleDescriptor':
1386
- return 7;
1392
+ return enumWireRejectReason('descriptorRevisionStale');
1387
1393
  case 'invalidDescriptor':
1388
- return 11;
1389
- case 'notRequired':
1390
- return 4;
1391
- case 'admitted':
1392
- return 1;
1394
+ return enumWireRejectReason('invalidDescriptor');
1393
1395
  }
1394
1396
  }
@@ -1,4 +1,12 @@
1
- import { ZLinkFrameworkRuntimeState } from '../../contracts';
1
+ import { ZLinkFrameworkRuntimeState, ZLinkTopologyState } from '../../contracts';
2
+
3
+ export function runtimeObservationIsTerminal(state: ZLinkFrameworkRuntimeState): boolean {
4
+ return state === ZLinkFrameworkRuntimeState.Stopped;
5
+ }
6
+
7
+ export function topologyObservationIsTerminal(state: ZLinkTopologyState): boolean {
8
+ return state === ZLinkTopologyState.Stopped || state === ZLinkTopologyState.Failed;
9
+ }
2
10
 
3
11
  export type MaintenanceAdmissionState =
4
12
  'preparing' | 'serving' | 'retiring' | 'draining' | 'stopped' | 'error';