@zlink-systems/framework 0.29.1 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/LICENSE +150 -68
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
  4. package/dist/contracts/Channels/Calls.d.ts +2 -1
  5. package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  7. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  8. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  9. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  10. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  11. package/dist/contracts/Configuration/index.d.ts +1 -1
  12. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  13. package/dist/contracts/Handlers/Attributes.js +7 -11
  14. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  15. package/dist/contracts/Handlers/JsonContract.js +4 -153
  16. package/dist/contracts/Spots/Contracts.d.ts +2 -1
  17. package/dist/internal.d.ts +1 -0
  18. package/dist/internal.js +3 -1
  19. package/dist/nest-integration.d.ts +1 -1
  20. package/dist/nest-integration.js +2 -1
  21. package/dist/runtime/actors/actor-client.d.ts +1 -1
  22. package/dist/runtime/actors/actor-client.js +14 -12
  23. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  24. package/dist/runtime/actors/actor-handoff.js +15 -7
  25. package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
  26. package/dist/runtime/actors/actor-local-native-join.js +9 -12
  27. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  28. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  29. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  30. package/dist/runtime/actors/index.d.ts +2 -1
  31. package/dist/runtime/actors/index.js +18 -6
  32. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  33. package/dist/runtime/admission.d.ts +1 -1
  34. package/dist/runtime/admission.js +15 -5
  35. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +9 -9
  36. package/dist/runtime/application-jobs/application-ingress-record-owner.js +45 -23
  37. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +5 -2
  38. package/dist/runtime/application-jobs/application-job-queue-scope.js +41 -21
  39. package/dist/runtime/application-jobs/contracts.d.ts +15 -2
  40. package/dist/runtime/backend/contracts/index.d.ts +27 -27
  41. package/dist/runtime/backend/mesh-completion-table.d.ts +15 -5
  42. package/dist/runtime/backend/mesh-completion-table.js +160 -50
  43. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
  44. package/dist/runtime/backend/mesh-dispatch-pump.js +53 -36
  45. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  46. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  47. package/dist/runtime/backend/node/node-backend-adapter-support.js +33 -31
  48. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  49. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  50. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  51. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  52. package/dist/runtime/backend/node/node-raw-binding-port.js +50 -25
  53. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +22 -16
  54. package/dist/runtime/backend/node/node-raw-mesh-backend.js +133 -149
  55. package/dist/runtime/backend/node/node-socket-backend-adapter.js +15 -10
  56. package/dist/runtime/backend/raw-binding-port.d.ts +10 -3
  57. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  58. package/dist/runtime/backend/runtime-message.js +5 -0
  59. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  60. package/dist/runtime/backend/runtime-values.js +2 -1
  61. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  62. package/dist/runtime/channels/channel-clients.js +58 -21
  63. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
  64. package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
  65. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  66. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  67. package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
  68. package/dist/runtime/channels/channel-dispatchers.js +27 -26
  69. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  70. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  71. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  72. package/dist/runtime/channels/channel-envelope.js +83 -8
  73. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  74. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  75. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  76. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  77. package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
  78. package/dist/runtime/channels/channel-runtime-manager.js +12 -12
  79. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  80. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  81. package/dist/runtime/channels/channel-transports.d.ts +18 -15
  82. package/dist/runtime/channels/channel-transports.js +48 -31
  83. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  84. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  85. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  86. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  87. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  88. package/dist/runtime/channels/source-spot-router.js +4 -4
  89. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  90. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  91. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  92. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  93. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  94. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  95. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  96. package/dist/runtime/diagnostics/message-flow.js +3 -3
  97. package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
  98. package/dist/runtime/execution/serial-execution-queue.js +1 -0
  99. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  100. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  101. package/dist/runtime/foundation/durable-service-request.js +98 -0
  102. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  103. package/dist/runtime/foundation/operation-identity.js +5 -1
  104. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +37 -6
  105. package/dist/runtime/foundation/raw-service-mesh-runtime.js +473 -220
  106. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  107. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  108. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  109. package/dist/runtime/foundation/service-mailbox.js +2 -1
  110. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
  111. package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
  112. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  113. package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
  114. package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
  115. package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -9
  116. package/dist/runtime/foundation/service-stateful-runtime.js +78 -126
  117. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -7
  118. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  119. package/dist/runtime/foundation/service-topology-registry.d.ts +16 -4
  120. package/dist/runtime/foundation/service-topology-registry.js +69 -30
  121. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
  122. package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
  123. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  124. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  125. package/dist/runtime/host/actor-packet-relay.js +7 -7
  126. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  127. package/dist/runtime/host/application-job-queue.d.ts +28 -9
  128. package/dist/runtime/host/application-job-queue.js +214 -50
  129. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  130. package/dist/runtime/host/entry-actor-runtime.js +4 -1
  131. package/dist/runtime/host/index.d.ts +7 -1
  132. package/dist/runtime/host/index.js +154 -126
  133. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  134. package/dist/runtime/host/instance-activation-authority.js +89 -25
  135. package/dist/runtime/host/remote-bound-session-relay.js +2 -18
  136. package/dist/runtime/host/route-mesh-runtime.js +1 -1
  137. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  138. package/dist/runtime/host/service-relocation-control.js +10 -4
  139. package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
  140. package/dist/runtime/host/service-relocation-host-runtime.js +215 -243
  141. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  142. package/dist/runtime/host/spot-address-transport.js +28 -14
  143. package/dist/runtime/host/spot-runtime-options-factory.js +3 -2
  144. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  145. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  146. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  147. package/dist/runtime/locations/actor-location-claims.js +34 -19
  148. package/dist/runtime/locations/domain-store-contract.d.ts +2 -2
  149. package/dist/runtime/locations/in-memory-authority-store.d.ts +4 -2
  150. package/dist/runtime/locations/in-memory-authority-store.js +80 -8
  151. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  152. package/dist/runtime/locations/in-memory-location-store.js +19 -3
  153. package/dist/runtime/locations/internal-location-contracts.d.ts +3 -0
  154. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  155. package/dist/runtime/locations/lifecycle.js +2 -5
  156. package/dist/runtime/locations/location-store-repository.d.ts +3 -2
  157. package/dist/runtime/locations/location-store-repository.js +165 -22
  158. package/dist/runtime/locations/resolvers.d.ts +2 -1
  159. package/dist/runtime/locations/resolvers.js +10 -1
  160. package/dist/runtime/locations/runtime.d.ts +1 -1
  161. package/dist/runtime/locations/runtime.js +24 -23
  162. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  163. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  164. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  165. package/dist/runtime/messaging/packet-name.js +8 -24
  166. package/dist/runtime/messaging/request-result.d.ts +2 -0
  167. package/dist/runtime/messaging/request-result.js +54 -0
  168. package/dist/runtime/messaging/submission-result.d.ts +2 -1
  169. package/dist/runtime/messaging/submission-result.js +7 -4
  170. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
  171. package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
  172. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
  173. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
  174. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +9 -2
  175. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
  176. package/dist/runtime/spots/index.d.ts +7 -3
  177. package/dist/runtime/spots/index.js +23 -16
  178. package/dist/runtime/spots/spot-activation.d.ts +3 -1
  179. package/dist/runtime/spots/spot-activation.js +21 -12
  180. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  181. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  182. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  183. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  184. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  185. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  186. package/dist/runtime/spots/spot-entry-activation.js +9 -3
  187. package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
  188. package/dist/runtime/spots/spot-handler-registry.js +18 -8
  189. package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
  190. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +2 -1
  191. package/dist/runtime/spots/spot-node-runtime-manager.js +4 -11
  192. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  193. package/dist/runtime/spots/spot-outbound.js +24 -15
  194. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  195. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  196. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  197. package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -1
  198. package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
  199. package/dist/runtime/spots/spot-timer.js +1 -0
  200. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  201. package/dist/runtime/streams/stream-session-runtime.js +14 -28
  202. package/package.json +3 -3
  203. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  204. package/src/contracts/Channels/Calls.ts +2 -1
  205. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  206. package/src/contracts/Configuration/Builders.ts +1 -2
  207. package/src/contracts/Configuration/Configs.ts +0 -6
  208. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  209. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  210. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  211. package/src/contracts/Configuration/index.ts +1 -6
  212. package/src/contracts/Handlers/Attributes.ts +14 -21
  213. package/src/contracts/Handlers/JsonContract.ts +8 -216
  214. package/src/contracts/Spots/Contracts.ts +2 -1
  215. package/src/internal.ts +1 -0
  216. package/src/nest-integration.ts +1 -0
  217. package/src/runtime/actors/actor-client.ts +40 -16
  218. package/src/runtime/actors/actor-handoff.ts +22 -8
  219. package/src/runtime/actors/actor-join-relocation.ts +1 -0
  220. package/src/runtime/actors/actor-local-native-join.ts +17 -26
  221. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  222. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  223. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  224. package/src/runtime/actors/index.ts +19 -5
  225. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  226. package/src/runtime/admission.ts +18 -5
  227. package/src/runtime/application-jobs/application-ingress-record-owner.ts +53 -27
  228. package/src/runtime/application-jobs/application-job-queue-scope.ts +56 -22
  229. package/src/runtime/application-jobs/contracts.ts +28 -2
  230. package/src/runtime/backend/contracts/index.ts +63 -32
  231. package/src/runtime/backend/mesh-completion-table.ts +175 -59
  232. package/src/runtime/backend/mesh-dispatch-pump.ts +59 -32
  233. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  234. package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -31
  235. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  236. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  237. package/src/runtime/backend/node/node-raw-binding-port.ts +73 -37
  238. package/src/runtime/backend/node/node-raw-mesh-backend.ts +209 -176
  239. package/src/runtime/backend/node/node-socket-backend-adapter.ts +32 -13
  240. package/src/runtime/backend/raw-binding-port.ts +18 -3
  241. package/src/runtime/backend/runtime-message.ts +6 -0
  242. package/src/runtime/backend/runtime-values.ts +1 -0
  243. package/src/runtime/channels/channel-clients.ts +90 -41
  244. package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
  245. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  246. package/src/runtime/channels/channel-dispatchers.ts +29 -27
  247. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  248. package/src/runtime/channels/channel-envelope.ts +133 -8
  249. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  250. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  251. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  252. package/src/runtime/channels/channel-runtime-manager.ts +29 -12
  253. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  254. package/src/runtime/channels/channel-transports.ts +128 -60
  255. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  256. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  257. package/src/runtime/channels/source-spot-router.ts +8 -4
  258. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  259. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  260. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  261. package/src/runtime/diagnostics/message-flow.ts +1 -1
  262. package/src/runtime/execution/serial-execution-queue.ts +2 -0
  263. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  264. package/src/runtime/foundation/durable-service-request.ts +137 -0
  265. package/src/runtime/foundation/operation-identity.ts +5 -1
  266. package/src/runtime/foundation/raw-service-mesh-runtime.ts +642 -253
  267. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  268. package/src/runtime/foundation/service-mailbox.ts +7 -1
  269. package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
  270. package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
  271. package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
  272. package/src/runtime/foundation/service-stateful-runtime.ts +128 -160
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -84
  274. package/src/runtime/foundation/service-topology-registry.ts +103 -42
  275. package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
  276. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  277. package/src/runtime/host/actor-packet-relay.ts +7 -0
  278. package/src/runtime/host/actor-runtime-options-factory.ts +14 -2
  279. package/src/runtime/host/application-job-queue.ts +249 -48
  280. package/src/runtime/host/entry-actor-runtime.ts +5 -0
  281. package/src/runtime/host/index.ts +224 -160
  282. package/src/runtime/host/instance-activation-authority.ts +132 -27
  283. package/src/runtime/host/remote-bound-session-relay.ts +2 -23
  284. package/src/runtime/host/route-mesh-runtime.ts +1 -1
  285. package/src/runtime/host/service-relocation-control.ts +11 -5
  286. package/src/runtime/host/service-relocation-host-runtime.ts +317 -291
  287. package/src/runtime/host/spot-address-transport.ts +49 -24
  288. package/src/runtime/host/spot-runtime-options-factory.ts +4 -0
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  290. package/src/runtime/locations/actor-location-claims.ts +52 -30
  291. package/src/runtime/locations/domain-store-contract.ts +6 -2
  292. package/src/runtime/locations/in-memory-authority-store.ts +113 -9
  293. package/src/runtime/locations/in-memory-location-store.ts +25 -3
  294. package/src/runtime/locations/internal-location-contracts.ts +4 -0
  295. package/src/runtime/locations/lifecycle.ts +8 -26
  296. package/src/runtime/locations/location-store-repository.ts +220 -15
  297. package/src/runtime/locations/resolvers.ts +25 -2
  298. package/src/runtime/locations/runtime.ts +28 -24
  299. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  300. package/src/runtime/messaging/packet-name.ts +5 -25
  301. package/src/runtime/messaging/request-result.ts +58 -0
  302. package/src/runtime/messaging/submission-result.ts +7 -3
  303. package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
  304. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  305. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +45 -23
  306. package/src/runtime/spots/index.ts +30 -2
  307. package/src/runtime/spots/spot-activation.ts +33 -10
  308. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  309. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  310. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  311. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  312. package/src/runtime/spots/spot-entry-activation.ts +12 -2
  313. package/src/runtime/spots/spot-handler-registry.ts +41 -8
  314. package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
  315. package/src/runtime/spots/spot-node-runtime-manager.ts +7 -12
  316. package/src/runtime/spots/spot-outbound.ts +36 -16
  317. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  318. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  319. package/src/runtime/spots/spot-runtime-ports.ts +3 -0
  320. package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
  321. package/src/runtime/spots/spot-timer.ts +5 -1
  322. package/src/runtime/streams/stream-session-runtime.ts +13 -30
@@ -135,6 +135,7 @@ export class ZLinkSpotActorPacketDrain {
135
135
  await this.dispatchNoBindActorRequest(noBindInfo, actorId, parts, actorRef);
136
136
  } else {
137
137
  await this.options.actorPacketHandler({
138
+ origin: 'remote',
138
139
  actorId,
139
140
  parts,
140
141
  returnResponse: false,
@@ -198,6 +199,7 @@ export class ZLinkSpotActorPacketDrain {
198
199
  ): Promise<void> {
199
200
  try {
200
201
  const response = await this.options.actorPacketHandler?.({
202
+ origin: 'remote',
201
203
  actorId,
202
204
  parts,
203
205
  returnResponse: true,
@@ -111,6 +111,7 @@ export class ZLinkSpotActorPacketRelayDispatch {
111
111
  actorPacketRelay.messageFollowContext !== undefined &&
112
112
  remoteBoundSessionTarget !== undefined;
113
113
  const response = await this.options.actorPacketHandler({
114
+ origin: 'remote',
114
115
  actorId: actorPacketRelay.actorId,
115
116
  parts: [header, payload],
116
117
  returnResponse: !followedBoundSessionReply,
@@ -106,7 +106,7 @@ export class ZLinkEntrySpotActivation {
106
106
  private readonly spotSerialExecutor: ZLinkSpotSerialExecutor;
107
107
  private readonly timers: ZLinkSpotTimerRegistry;
108
108
  private readonly actorHandlers = new ZLinkSpotActorHandlerRegistryRuntime();
109
- private readonly handlers = new DefaultZLinkSpotHandlerRegistry(this.actorHandlers);
109
+ private readonly handlers: DefaultZLinkSpotHandlerRegistry;
110
110
  private readonly outbound: DefaultZLinkSpotOutbound;
111
111
  private readonly workerRuntime: ZLinkWorkerRuntime;
112
112
  private readonly lifecycleMetrics: ZLinkSpotLifecycleMetrics;
@@ -125,6 +125,10 @@ export class ZLinkEntrySpotActivation {
125
125
  'Entry Spot activation requires a detached task runner.'
126
126
  );
127
127
  }
128
+ this.handlers = new DefaultZLinkSpotHandlerRegistry(
129
+ this.actorHandlers,
130
+ options.providerResolver
131
+ );
128
132
  this.serial = new ZLinkSpotSerialTurnExecutor(false, options.nativeSpot.routingId);
129
133
  this.spotSerialExecutor = new ZLinkSpotSerialExecutor(
130
134
  this.serial,
@@ -328,7 +332,10 @@ export class ZLinkEntrySpotActivation {
328
332
  await cleanup(() => this.timers.dispose());
329
333
  await cleanup(() => this.spotSerialExecutor.close());
330
334
  await cleanup(() => disposeLifecycleHandlers(this.entrySpot, this.options.detachedTaskRunner));
331
- await cleanup(() => this.options.nativeSpot.dispose());
335
+ await cleanup(async () => {
336
+ await this.options.entryActorRuntime?.releaseMembers?.(this.options.spotNodeName);
337
+ await this.options.nativeSpot.dispose();
338
+ });
332
339
  if (this.initialized) {
333
340
  this.lifecycleMetrics.closed('entry');
334
341
  }
@@ -465,6 +472,7 @@ export class ZLinkEntrySpotActivation {
465
472
  messageFollowOrigin
466
473
  } = delivery;
467
474
  const handoff = this.options.actorHandoffRuntime?.capture(
475
+ delivery.origin,
468
476
  actorId,
469
477
  parts,
470
478
  returnResponse,
@@ -480,6 +488,7 @@ export class ZLinkEntrySpotActivation {
480
488
  ) =>
481
489
  this.spotSerialExecutor.executeActor(actorId, () =>
482
490
  this.dispatchActorPacketInsideMailbox({
491
+ origin: delivery.origin,
483
492
  actorId,
484
493
  parts: replayedParts,
485
494
  returnResponse: replayReturnResponse,
@@ -503,6 +512,7 @@ export class ZLinkEntrySpotActivation {
503
512
  (parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef) =>
504
513
  this.spotSerialExecutor.executeActor(actor.context.actorId, () =>
505
514
  this.dispatchActorPacketInsideMailbox({
515
+ origin: 'remote',
506
516
  actorId: actor.context.actorId,
507
517
  parts,
508
518
  returnResponse,
@@ -16,7 +16,12 @@ import type {
16
16
  ZLinkSpotPacketHandlerRegistration,
17
17
  ZLinkSpotSubscriptionHandlerRegistration
18
18
  } from '../../contracts/Configuration/RegistrationTypes';
19
- import { ZLinkConfigurationException } from '../configuration';
19
+ import type { ZLinkProviderResolver } from '../../contracts/Common/ZLinkProviderResolver';
20
+ import { prepareHandlerInstance } from '../handlers/handler-instance-scope';
21
+ import {
22
+ ZLinkFrameworkInternalErrorKind,
23
+ createInternalFrameworkException
24
+ } from '../framework-errors-internal';
20
25
  import { ZLinkActorPacketKind, ZLinkSpotActorHandlerRegistryRuntime } from '../actors';
21
26
  import { readZLinkDecoratorMetadata } from '../../contracts/Handlers/Attributes';
22
27
 
@@ -34,7 +39,10 @@ export class DefaultZLinkSpotHandlerRegistry<
34
39
  > implements ZLinkSpotHandlerRegistry {
35
40
  private readonly entries: ZLinkSpotHandlerRegistration[] = [];
36
41
 
37
- constructor(private readonly actorHandlers?: ZLinkSpotActorHandlerRegistryRuntime) {}
42
+ constructor(
43
+ private readonly actorHandlers?: ZLinkSpotActorHandlerRegistryRuntime,
44
+ private readonly providerResolver?: ZLinkProviderResolver
45
+ ) {}
38
46
 
39
47
  addHandler<THandler>(handlerType: Type<THandler>, packetName?: string): this {
40
48
  const metadata = readZLinkDecoratorMetadata(handlerType).find(
@@ -42,7 +50,8 @@ export class DefaultZLinkSpotHandlerRegistry<
42
50
  );
43
51
  const resolvedPacketName = packetName ?? metadata?.packetName;
44
52
  if (metadata === undefined || resolvedPacketName === undefined) {
45
- throw new ZLinkConfigurationException(
53
+ throw createInternalFrameworkException(
54
+ ZLinkFrameworkInternalErrorKind.InvalidOperation,
46
55
  `Actor packet handler '${handlerType.name}' must declare a packet name.`
47
56
  );
48
57
  }
@@ -62,7 +71,8 @@ export class DefaultZLinkSpotHandlerRegistry<
62
71
  (entry) => entry.kind === 'spotActorSend' || entry.kind === 'spotActorRequest'
63
72
  );
64
73
  if (metadata?.packetName === undefined) {
65
- throw new ZLinkConfigurationException(
74
+ throw createInternalFrameworkException(
75
+ ZLinkFrameworkInternalErrorKind.InvalidOperation,
66
76
  `Actor packet handler '${handlerType.name}' must declare a packet name.`
67
77
  );
68
78
  }
@@ -78,10 +88,21 @@ export class DefaultZLinkSpotHandlerRegistry<
78
88
  const declared = readZLinkDecoratorMetadata(handlerType).find(
79
89
  (entry) => entry.kind === 'packet'
80
90
  )?.packetName;
91
+ prepareHandlerInstance(this.providerResolver, handlerType);
92
+ const resolvedPacketName = packetName ?? declared ?? handlerType.name;
93
+ if (
94
+ this.entries.some(
95
+ (entry) => entry.kind === 'packet' && entry.packetName === resolvedPacketName
96
+ )
97
+ )
98
+ throw createInternalFrameworkException(
99
+ ZLinkFrameworkInternalErrorKind.InvalidOperation,
100
+ `SPOT packet '${resolvedPacketName}' is already registered.`
101
+ );
81
102
  this.entries.push({
82
103
  kind: 'packet',
83
104
  handlerType,
84
- packetName: packetName ?? declared ?? handlerType.name
105
+ packetName: resolvedPacketName
85
106
  });
86
107
  return this;
87
108
  }
@@ -96,6 +117,7 @@ export class DefaultZLinkSpotHandlerRegistry<
96
117
  actorType: Type<TActor>,
97
118
  packetName: string
98
119
  ): this {
120
+ prepareHandlerInstance(this.providerResolver, handlerType);
99
121
  this.entries.push({
100
122
  kind: kind === ZLinkActorPacketKind.Send ? 'actorSend' : 'actorRequest',
101
123
  handlerType,
@@ -139,10 +161,16 @@ export class DefaultZLinkSpotHandlerRegistry<
139
161
 
140
162
  addSubscribe(handlerType: Type, channelName: string, topic: string): this {
141
163
  if (channelName.trim().length === 0) {
142
- throw new ZLinkConfigurationException('SPOT subscribe channel name must not be empty.');
164
+ throw createInternalFrameworkException(
165
+ ZLinkFrameworkInternalErrorKind.InvalidOperation,
166
+ 'SPOT subscribe channel name must not be empty.'
167
+ );
143
168
  }
144
169
  if (topic.trim().length === 0) {
145
- throw new ZLinkConfigurationException('SPOT subscribe topic must not be empty.');
170
+ throw createInternalFrameworkException(
171
+ ZLinkFrameworkInternalErrorKind.InvalidOperation,
172
+ 'SPOT subscribe topic must not be empty.'
173
+ );
146
174
  }
147
175
  if (
148
176
  this.entries.some(
@@ -153,8 +181,12 @@ export class DefaultZLinkSpotHandlerRegistry<
153
181
  entry.topic === topic
154
182
  )
155
183
  ) {
156
- return this;
184
+ throw createInternalFrameworkException(
185
+ ZLinkFrameworkInternalErrorKind.InvalidOperation,
186
+ `SPOT subscription '${channelName}/${topic}' is already registered.`
187
+ );
157
188
  }
189
+ prepareHandlerInstance(this.providerResolver, handlerType);
158
190
  this.entries.push({ kind: 'subscribe', handlerType, channelName, topic });
159
191
  return this;
160
192
  }
@@ -164,6 +196,7 @@ export class DefaultZLinkSpotHandlerRegistry<
164
196
  }
165
197
 
166
198
  addSpotHandler(handlerType: Type): this {
199
+ prepareHandlerInstance(this.providerResolver, handlerType);
167
200
  this.entries.push({ kind: 'spotHandler', handlerType });
168
201
  return this;
169
202
  }
@@ -164,15 +164,19 @@ class ZLinkSpotNodeAutoConnectExecutor implements IZLinkAutoConnectExecutor {
164
164
  }
165
165
 
166
166
  async connect(target: ZLinkAutoConnectTarget): Promise<boolean> {
167
- if (this.manualConnections) return false;
168
167
  const key = connectionKey(target);
168
+ if (
169
+ !this.connectionIntents.has(key) &&
170
+ this.node.hasPeerRouteOrConnectionIntent?.(target.nodeRid, target.endpoint) === true
171
+ )
172
+ return false;
169
173
  const intent = await this.lane.run(() => this.prepareConnectCore(key));
170
174
  if (intent === undefined) return true;
171
175
  return await runDetachedSpotNodeAutoConnect(() => this.connectPeer(target, key, intent));
172
176
  }
173
177
 
174
178
  disconnect(target: ZLinkAutoConnectTarget): void {
175
- if (this.manualConnections) return;
179
+ if (!this.connectionIntents.has(connectionKey(target))) return;
176
180
  this.disconnectPeer(target);
177
181
  }
178
182
 
@@ -1,3 +1,4 @@
1
+ import type { ApplicationJobOrigin } from '../application-jobs/contracts';
1
2
  import { RuntimeDisposal } from '../disposal';
2
3
  import { randomUUID } from 'node:crypto';
3
4
  import {
@@ -62,7 +63,6 @@ import {
62
63
  } from '../configuration';
63
64
  import type { ZLinkRuntimeEventPublisher } from '../diagnostics';
64
65
  import { runWithOutboundFlow } from '../diagnostics/flow-context';
65
- import { requireZLinkInfrastructureExecutionArea } from '../execution';
66
66
  import type { ZLinkListenerRecords } from '../foundation/listener-records';
67
67
  import {
68
68
  type ZLinkMessageFollowOrigin,
@@ -285,6 +285,7 @@ export class ZLinkSpotNodeRuntimeManager {
285
285
  routingId,
286
286
  receiveTimeoutMs: spotNode.router?.receiveTimeoutMs,
287
287
  applicationJobQueue: this.applicationJobQueue,
288
+ infrastructureTaskRunner: this.options.detachedTaskRunner,
288
289
  applicationJobReceiveFlowFailureSink: this.options.applicationJobReceiveFlowFailureSink,
289
290
  peerAdmissionSealed: () => this.options.peerAdmissionSealed?.(spotNodeName) ?? false
290
291
  });
@@ -324,6 +325,9 @@ export class ZLinkSpotNodeRuntimeManager {
324
325
  let pump: ZLinkMeshDispatchPump | undefined;
325
326
  const completions = new ZLinkMeshCompletionTable();
326
327
  try {
328
+ node.setCompletionHandler((terminal, materialize) =>
329
+ completions.complete(terminal, materialize)
330
+ );
327
331
  node.setBind(bind);
328
332
  if (spotNode.router?.advertiseHost !== undefined) {
329
333
  node.setAdvertiseHost(spotNode.router.advertiseHost);
@@ -871,17 +875,6 @@ export class ZLinkSpotNodeRuntimeManager {
871
875
  owner: ReadyRecord,
872
876
  record: ReceiveRecord
873
877
  ): Promise<void> {
874
- if (record.kind === ReceiveKind.Completion) {
875
- requireZLinkInfrastructureExecutionArea();
876
- const completions = this.meshCompletions.get(meshName);
877
- if (completions === undefined) {
878
- throw new ZLinkConfigurationException(
879
- `MeshNode '${meshName}' received a completion before its completion table was registered.`
880
- );
881
- }
882
- completions.complete(record);
883
- return;
884
- }
885
878
  const node = this.meshNodes.get(meshName);
886
879
  const targetsEntrySpot =
887
880
  owner.spotId === null ||
@@ -1051,6 +1044,7 @@ export class ZLinkSpotNodeRuntimeManager {
1051
1044
  }
1052
1045
 
1053
1046
  async dispatchEntryActorPacket(
1047
+ origin: ApplicationJobOrigin,
1054
1048
  actorId: string,
1055
1049
  parts: readonly Message[],
1056
1050
  returnResponse = false,
@@ -1090,6 +1084,7 @@ export class ZLinkSpotNodeRuntimeManager {
1090
1084
  );
1091
1085
  }
1092
1086
  return await activation.dispatchActorPacket({
1087
+ origin,
1093
1088
  actorId,
1094
1089
  parts,
1095
1090
  returnResponse,
@@ -1,3 +1,4 @@
1
+ import { createZLinkRequest } from '../messaging/request-result';
1
2
  import {
2
3
  type RoutingId,
3
4
  type ZLinkChannelClient,
@@ -174,6 +175,7 @@ export class DefaultZLinkSpotOutbound implements ZLinkSpotOutbound {
174
175
  }
175
176
 
176
177
  export interface ZLinkSpotAddressCallOptions {
178
+ readonly onAdmitted?: () => void;
177
179
  readonly metadata?: ReadonlyMap<string, string>;
178
180
  readonly instanceSpot: boolean;
179
181
  readonly instanceSpotType?: string;
@@ -232,6 +234,7 @@ export interface ZLinkSpotRoutedSendOptions {
232
234
  }
233
235
 
234
236
  export interface ZLinkSpotRoutedRequestOptions extends ZLinkSpotRoutedSendOptions {
237
+ readonly onAdmitted?: () => void;
235
238
  readonly timeoutMs?: number;
236
239
  readonly signal?: AbortSignal;
237
240
  }
@@ -308,14 +311,13 @@ function createAddressedSpotRequestCall(
308
311
  sourceSpotProvider?: () => ZLinkBackendSpot | undefined
309
312
  ): ZLinkSpotRequestCall {
310
313
  const options = newAddressCallOptions();
311
- const begin = <TReply>(waitPolicy: 'async' | 'yield', signal?: AbortSignal) => {
312
- markSubmitted(options);
313
- rejectSameSpotAsyncRequest(serial, spotId, waitPolicy);
314
+ const begin = <TReply>(signal?: AbortSignal, onAdmitted?: () => void) => {
314
315
  return startRequestOnSerial<TReply>(serial, () => ({
315
316
  pending: transport.requestToSpotAddress<TReply>(spotId, request, {
316
317
  ...freezeAddressCallOptions(options, sourceSpotProvider?.()),
317
318
  timeoutMs: options.timeoutMs,
318
- signal
319
+ signal,
320
+ onAdmitted
319
321
  })
320
322
  }));
321
323
  };
@@ -356,12 +358,18 @@ function createAddressedSpotRequestCall(
356
358
  return this;
357
359
  },
358
360
  submit<TReply>(signal?: AbortSignal) {
359
- const pending = begin<TReply>('async', signal);
360
- return serial.isCurrentTurn ? pending : deliverOnSerial(serial, pending);
361
+ markSubmitted(options);
362
+ rejectSameSpotAsyncRequest(serial, spotId, 'async');
363
+ return createZLinkRequest(
364
+ (onAdmitted) => begin<TReply>(signal, onAdmitted),
365
+ (pending) => (serial.isCurrentTurn ? pending : deliverOnSerial(serial, pending))
366
+ );
361
367
  },
362
368
  yield<TReply>(signal?: AbortSignal) {
363
369
  const turn = requireZLinkYieldTurn();
364
- const pending = begin<TReply>('yield', signal);
370
+ markSubmitted(options);
371
+ rejectSameSpotAsyncRequest(serial, spotId, 'yield');
372
+ const pending = begin<TReply>(signal);
365
373
  return turn.yieldPromise(pending);
366
374
  }
367
375
  };
@@ -475,8 +483,12 @@ function wrapRequestCall(
475
483
  serial: ZLinkSpotSerialTurnExecutor,
476
484
  inner: ZLinkChannelRequestCall
477
485
  ): ZLinkChannelRequestCall {
478
- const begin = <TReply>(signal?: AbortSignal) =>
479
- startRequestOnSerial(serial, () => ({ pending: inner.submit<TReply>(signal) }));
486
+ const begin = <TReply>(signal?: AbortSignal, onAdmitted?: () => void) =>
487
+ startRequestOnSerial(serial, () => {
488
+ const pending = inner.submit<TReply>(signal);
489
+ if (onAdmitted !== undefined) void pending.admitted.then(onAdmitted, () => undefined);
490
+ return { pending };
491
+ });
480
492
  return {
481
493
  metadata(key: string | ZLinkMessageMetadata, value?: string) {
482
494
  if (typeof key === 'string') inner.metadata(key, value!);
@@ -488,8 +500,10 @@ function wrapRequestCall(
488
500
  return this;
489
501
  },
490
502
  submit<TReply>(signal?: AbortSignal) {
491
- const pending = begin<TReply>(signal);
492
- return serial.isCurrentTurn ? pending : deliverOnSerial(serial, pending);
503
+ return createZLinkRequest(
504
+ (onAdmitted) => begin<TReply>(signal, onAdmitted),
505
+ (pending) => (serial.isCurrentTurn ? pending : deliverOnSerial(serial, pending))
506
+ );
493
507
  },
494
508
  yield<TReply>(signal?: AbortSignal) {
495
509
  const turn = requireZLinkYieldTurn();
@@ -571,15 +585,15 @@ function wrapRoutedSpotRequestCall(
571
585
  ): ZLinkRequestCall & Pick<ZLinkChannelRequestCall, 'yield'> {
572
586
  let selectedTimeoutMs: number | undefined;
573
587
  const metadata = new Map<string, string>();
574
- const begin = <TReply>(waitPolicy: 'async' | 'yield', signal?: AbortSignal) => {
588
+ const begin = <TReply>(signal?: AbortSignal, onAdmitted?: () => void) => {
575
589
  // A request to the current Spot would wait behind the handler that owns
576
590
  // the same Spot claim. Reject it before resolving a route or submitting
577
591
  // transport work; one-way self-send remains a valid FIFO admission.
578
- rejectSameSpotAsyncRequest(serial, spot.spotId, waitPolicy);
579
592
  return startRequestOnSerial<TReply>(serial, () => ({
580
593
  pending: requestToSpotHandle<TReply>(transport, spot, request, {
581
594
  timeoutMs: selectedTimeoutMs,
582
595
  signal,
596
+ onAdmitted,
583
597
  metadata,
584
598
  spotRouterChannelIdForMesh,
585
599
  sourceSpot: sourceSpotProvider?.()
@@ -602,12 +616,16 @@ function wrapRoutedSpotRequestCall(
602
616
  return this;
603
617
  },
604
618
  submit<TReply>(signal?: AbortSignal) {
605
- const pending = begin<TReply>('async', signal);
606
- return serial.isCurrentTurn ? pending : deliverOnSerial(serial, pending);
619
+ rejectSameSpotAsyncRequest(serial, spot.spotId, 'async');
620
+ return createZLinkRequest(
621
+ (onAdmitted) => begin<TReply>(signal, onAdmitted),
622
+ (pending) => (serial.isCurrentTurn ? pending : deliverOnSerial(serial, pending))
623
+ );
607
624
  },
608
625
  yield<TReply>(signal?: AbortSignal) {
609
626
  const turn = requireZLinkYieldTurn();
610
- const pending = begin<TReply>('yield', signal);
627
+ rejectSameSpotAsyncRequest(serial, spot.spotId, 'yield');
628
+ const pending = begin<TReply>(signal);
611
629
  return turn.yieldPromise(pending);
612
630
  }
613
631
  };
@@ -628,6 +646,7 @@ function rejectSameSpotAsyncRequest(
628
646
  }
629
647
 
630
648
  export interface ZLinkSpotHandleCallOptions {
649
+ readonly onAdmitted?: () => void;
631
650
  readonly metadata?: ReadonlyMap<string, string>;
632
651
  readonly timeoutMs?: number;
633
652
  readonly signal?: AbortSignal;
@@ -672,6 +691,7 @@ export async function requestToSpotHandle<TReply = unknown>(
672
691
  packetName,
673
692
  timeoutMs: options.timeoutMs,
674
693
  signal: options.signal,
694
+ onAdmitted: options.onAdmitted,
675
695
  metadata: options.metadata
676
696
  };
677
697
  if (options.sourceSpot !== undefined && transport.requestFromSpotToSpot !== undefined) {
@@ -50,6 +50,7 @@ interface ZLinkRoutedSpotPacketDispatchOptions {
50
50
 
51
51
  interface ZLinkRoutedSpotPacketContext {
52
52
  readonly channelName: string;
53
+ readonly onAdmitted?: () => void;
53
54
  readonly contentType?: string;
54
55
  readonly workOptions?: ZLinkSerialWorkOptions;
55
56
  readonly admissionTimeoutMs?: number;
@@ -265,7 +266,7 @@ export class ZLinkRoutedSpotPacketDispatch {
265
266
  }
266
267
  await activation.serial.execute(
267
268
  runHandler,
268
- context.workOptions,
269
+ { ...context.workOptions, onAdmitted: context.onAdmitted },
269
270
  instanceIntent ? runHandler : undefined
270
271
  );
271
272
  }
@@ -2,6 +2,11 @@ import type { RoutingId } from '../../contracts/Common';
2
2
  import type { ZLinkFrameworkRuntimeState, ZLinkSpotKind } from '../../contracts';
3
3
 
4
4
  export interface ZLinkSpotRouteResolver {
5
+ resolve(
6
+ spotId: RoutingId,
7
+ signal: AbortSignal | undefined,
8
+ instanceIntent: true
9
+ ): Promise<ZLinkSpotRouteTarget | ZLinkInstanceReactivationRoute>;
5
10
  resolve(spotId: RoutingId, signal?: AbortSignal): Promise<ZLinkSpotRouteTarget>;
6
11
  invalidate?(spotId: RoutingId): void;
7
12
  }
@@ -28,3 +33,12 @@ export interface ZLinkSpotRouteTarget {
28
33
  /** Current state of the owning MeshNode, when the route was resolved from Location Store. */
29
34
  readonly targetNodeState?: ZLinkFrameworkRuntimeState;
30
35
  }
36
+
37
+ export interface ZLinkInstanceReactivationRoute extends Pick<
38
+ ZLinkSpotRouteTarget,
39
+ 'spotId' | 'spotKind' | 'stableType'
40
+ > {
41
+ readonly kind: 'coldActivation';
42
+ readonly meshName: string;
43
+ readonly stableType: string;
44
+ }
@@ -1,3 +1,4 @@
1
+ import type { ApplicationJobOrigin } from '../application-jobs/contracts';
1
2
  import type {
2
3
  ActorRef,
3
4
  RoutingId,
@@ -21,6 +22,7 @@ import type {
21
22
  import type { ZLinkBackendSpotNode } from '../backend/contracts';
22
23
 
23
24
  export interface ZLinkEntryActorRuntime {
25
+ releaseMembers?(meshName: string): Promise<void>;
24
26
  resolveActor(actorId: string): ZLinkActor | undefined;
25
27
  commitActorTransaction(actor: ZLinkActor, onJoined: () => Promise<void>): Promise<void>;
26
28
  destroyActor(
@@ -151,6 +153,7 @@ export interface ZLinkSpotBoundSessionRuntime {
151
153
 
152
154
  export interface ZLinkSpotActorHandoffRuntime {
153
155
  capture(
156
+ origin: ApplicationJobOrigin,
154
157
  actorId: string,
155
158
  parts: readonly Message[],
156
159
  returnResponse?: boolean,
@@ -68,9 +68,6 @@ export class ZLinkSpotSubscriptionDispatch {
68
68
  }
69
69
  const key = subscriptionKey(registration.channelName, registration.topic);
70
70
  const existing = this.handlers.get(key) ?? [];
71
- if (existing.some((entry) => entry.handlerType === registration.handlerType)) {
72
- continue;
73
- }
74
71
  existing.push(registration);
75
72
  this.handlers.set(key, existing);
76
73
  this.options.nativeSpot.setSubscription(registration.channelName, registration.topic);
@@ -19,7 +19,10 @@ import { ZLinkTimerOverrunPolicy } from '../../contracts';
19
19
  import { validateTimerRegistration } from '../../contracts/Configuration/TimerRegistrationValidator';
20
20
  import { throwIfAborted } from '../abort';
21
21
  import { ZLinkSpotSerialTurnExecutor } from './spot-serial-turn-executor';
22
- import { resolveLifecycleHandler } from '../handlers/handler-instance-scope';
22
+ import {
23
+ prepareHandlerInstance,
24
+ resolveLifecycleHandler
25
+ } from '../handlers/handler-instance-scope';
23
26
  import { createInboundFlow, runWithFlow } from '../diagnostics/flow-context';
24
27
  import type { ZLinkExecutionBarrier } from '../execution';
25
28
  import { ZLinkStateLane } from '../execution/state-lane';
@@ -135,6 +138,7 @@ export class ZLinkSpotTimerRegistry {
135
138
  ): Promise<ZLinkTimer> {
136
139
  validateTimerRegistration(name, periodMs, options);
137
140
  throwIfAborted(signal);
141
+ prepareHandlerInstance(providerResolver, handlerType);
138
142
  const handler = await resolveLifecycleHandler(spot, handlerType, providerResolver);
139
143
  const prepared = await this.lane.run(() => this.prepareAddCore(name));
140
144
  if (prepared.previous !== undefined) await prepared.previous.timer.cancel(signal);
@@ -95,29 +95,6 @@ const systemLivenessClock: ZLinkStreamLivenessClock = {
95
95
  clearTimer: (timer) => clearTimeout(timer as ReturnType<typeof setTimeout>)
96
96
  };
97
97
 
98
- class ZLinkStreamReceiveWake {
99
- private pending?: Promise<void>;
100
- private resolvePending?: () => void;
101
- private readonly finish = (): void => {
102
- const resolve = this.resolvePending;
103
- this.pending = undefined;
104
- this.resolvePending = undefined;
105
- resolve?.();
106
- };
107
-
108
- wait(): Promise<void> {
109
- if (this.pending !== undefined) return this.pending;
110
- this.pending = new Promise<void>((resolve) => {
111
- this.resolvePending = resolve;
112
- });
113
- return this.pending;
114
- }
115
-
116
- wake(): void {
117
- this.finish();
118
- }
119
- }
120
-
121
98
  export interface ZLinkStreamSessionContextFactory {
122
99
  createSessionContext(
123
100
  stream: ZLinkManagedStream,
@@ -928,7 +905,7 @@ export class ZLinkStreamSessionNodeRuntime {
928
905
  private readonly receiveAbortController = new AbortController();
929
906
  private receiveLoop: Promise<void> | undefined;
930
907
  private monitorLoop: Promise<void> | undefined;
931
- private readonly receiveWake = new ZLinkStreamReceiveWake();
908
+ private receiveWake: AbortController | undefined;
932
909
  private receiveWorkSinceYield = 0;
933
910
  constructor(
934
911
  private readonly options: ZLinkStreamSessionNodeRuntimeOptions & ZLinkStreamLivenessOptions
@@ -1048,7 +1025,7 @@ export class ZLinkStreamSessionNodeRuntime {
1048
1025
  let packet: ZLinkBackendStreamPacket | undefined;
1049
1026
  let packetTransferred = false;
1050
1027
  try {
1051
- permit = await this.options.applicationJobQueue.acquire(signal);
1028
+ permit = await this.options.applicationJobQueue.acquire(signal, 'remote');
1052
1029
  if (this.isReceiveStopped(signal)) {
1053
1030
  permit.releaseAfterInternalProcessing();
1054
1031
  break;
@@ -1455,14 +1432,20 @@ export class ZLinkStreamSessionNodeRuntime {
1455
1432
  }
1456
1433
 
1457
1434
  private async waitReceiveLoopWake(signal: AbortSignal): Promise<void> {
1458
- await Promise.race([
1459
- this.options.readablePoller.waitForReadable(signal),
1460
- this.receiveWake.wait()
1461
- ]);
1435
+ const wake = new AbortController();
1436
+ this.receiveWake = wake;
1437
+ try {
1438
+ // Readiness, internal wake and shutdown share one cancellable wait;
1439
+ // no losing Promise retains reactions across receive cycles.
1440
+ await this.options.readablePoller.waitForReadable(AbortSignal.any([signal, wake.signal]));
1441
+ } finally {
1442
+ wake.abort();
1443
+ this.receiveWake = undefined;
1444
+ }
1462
1445
  }
1463
1446
 
1464
1447
  private wakeReceiveLoop(): void {
1465
- this.receiveWake.wake();
1448
+ this.receiveWake?.abort();
1466
1449
  }
1467
1450
 
1468
1451
  private getOrCreateSession(routingId: unknown): ZLinkStreamSessionRuntime | undefined {