@zlink-systems/framework 0.30.1 → 0.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
  3. package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
  4. package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
  5. package/dist/contracts/Common/encoded-payload-storage.js +5 -2
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -1
  7. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
  8. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
  9. package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
  10. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  11. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
  12. package/dist/contracts/Locations/Rows.d.ts +2 -0
  13. package/dist/contracts/Spots/Contracts.d.ts +4 -0
  14. package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
  15. package/dist/runtime/abort.d.ts +5 -0
  16. package/dist/runtime/abort.js +10 -0
  17. package/dist/runtime/actors/actor-authority-publication.js +3 -2
  18. package/dist/runtime/actors/actor-client.d.ts +0 -1
  19. package/dist/runtime/actors/actor-client.js +38 -45
  20. package/dist/runtime/actors/actor-context.d.ts +2 -0
  21. package/dist/runtime/actors/actor-context.js +46 -9
  22. package/dist/runtime/actors/actor-handoff.d.ts +7 -3
  23. package/dist/runtime/actors/actor-handoff.js +212 -88
  24. package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
  25. package/dist/runtime/actors/actor-local-native-join.js +4 -0
  26. package/dist/runtime/actors/actor-mailbox.js +27 -1
  27. package/dist/runtime/actors/actor-remote-joiner.js +3 -1
  28. package/dist/runtime/actors/actor-reply.d.ts +4 -0
  29. package/dist/runtime/actors/actor-reply.js +29 -0
  30. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
  31. package/dist/runtime/actors/actor-runtime-state.js +2 -20
  32. package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
  33. package/dist/runtime/actors/index.d.ts +6 -2
  34. package/dist/runtime/actors/index.js +37 -21
  35. package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
  36. package/dist/runtime/actors/session-disconnected-wire.js +48 -0
  37. package/dist/runtime/admission.d.ts +9 -1
  38. package/dist/runtime/admission.js +55 -32
  39. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
  40. package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
  41. package/dist/runtime/application-jobs/contracts.d.ts +2 -0
  42. package/dist/runtime/backend/contracts/index.d.ts +19 -3
  43. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
  44. package/dist/runtime/backend/mesh-completion-table.js +5 -0
  45. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
  46. package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
  47. package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
  48. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
  49. package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
  50. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
  51. package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
  52. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  53. package/dist/runtime/channels/channel-clients.js +20 -5
  54. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
  55. package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
  56. package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
  57. package/dist/runtime/channels/channel-dispatchers.js +44 -37
  58. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  59. package/dist/runtime/channels/channel-envelope.js +74 -31
  60. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
  61. package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
  62. package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
  63. package/dist/runtime/channels/channel-runtime-manager.js +4 -4
  64. package/dist/runtime/channels/channel-transports.d.ts +0 -1
  65. package/dist/runtime/channels/channel-transports.js +35 -33
  66. package/dist/runtime/channels/client-server-location-runtime.js +5 -4
  67. package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
  68. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  69. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  70. package/dist/runtime/channels/fanout-location-runtime.js +3 -3
  71. package/dist/runtime/diagnostics/flow-context.js +19 -7
  72. package/dist/runtime/diagnostics/index.js +4 -9
  73. package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
  74. package/dist/runtime/diagnostics/message-flow.js +35 -5
  75. package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
  76. package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
  77. package/dist/runtime/execution/index.d.ts +4 -2
  78. package/dist/runtime/execution/index.js +33 -10
  79. package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
  80. package/dist/runtime/execution/serial-execution-queue.js +21 -2
  81. package/dist/runtime/execution/state-lane.d.ts +2 -0
  82. package/dist/runtime/execution/state-lane.js +5 -0
  83. package/dist/runtime/foundation/operation-registry.d.ts +25 -1
  84. package/dist/runtime/foundation/operation-registry.js +86 -18
  85. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
  86. package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
  87. package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
  88. package/dist/runtime/foundation/service-liveness-registry.js +38 -0
  89. package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
  90. package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
  91. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
  92. package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
  93. package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
  94. package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
  95. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
  96. package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
  97. package/dist/runtime/foundation/service-stateful-registry.js +24 -26
  98. package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
  99. package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
  100. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
  101. package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
  102. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
  103. package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
  104. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  105. package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
  106. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
  107. package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
  108. package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
  109. package/dist/runtime/host/actor-packet-relay.js +59 -72
  110. package/dist/runtime/host/actor-placement-coordinator.js +25 -8
  111. package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
  112. package/dist/runtime/host/actor-transfer-runtime.js +85 -331
  113. package/dist/runtime/host/application-job-queue.d.ts +24 -3
  114. package/dist/runtime/host/application-job-queue.js +28 -41
  115. package/dist/runtime/host/index.d.ts +5 -1
  116. package/dist/runtime/host/index.js +171 -97
  117. package/dist/runtime/host/location-runtime-owner.js +2 -6
  118. package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
  119. package/dist/runtime/host/mesh-router-resolver.js +14 -6
  120. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
  121. package/dist/runtime/host/remote-bound-session-relay.js +71 -190
  122. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
  123. package/dist/runtime/host/route-mesh-runtime.js +5 -3
  124. package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
  125. package/dist/runtime/host/runtime-shutdown.js +3 -2
  126. package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
  127. package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
  128. package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
  129. package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
  130. package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
  131. package/dist/runtime/locations/auto-connect-loop.js +22 -14
  132. package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
  133. package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
  134. package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
  135. package/dist/runtime/locations/descriptor-publication.js +11 -0
  136. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  137. package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
  138. package/dist/runtime/locations/in-memory-authority-store.js +56 -19
  139. package/dist/runtime/locations/in-memory-location-store.js +1 -10
  140. package/dist/runtime/locations/index.d.ts +1 -0
  141. package/dist/runtime/locations/index.js +1 -0
  142. package/dist/runtime/locations/lease-tracker.js +1 -6
  143. package/dist/runtime/locations/location-store-repository.d.ts +51 -1
  144. package/dist/runtime/locations/location-store-repository.js +363 -139
  145. package/dist/runtime/locations/relocation-blob.d.ts +18 -1
  146. package/dist/runtime/locations/relocation-blob.js +52 -1
  147. package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
  148. package/dist/runtime/locations/request-source-resolver.js +80 -0
  149. package/dist/runtime/locations/resolvers.js +1 -1
  150. package/dist/runtime/locations/runtime.d.ts +6 -2
  151. package/dist/runtime/locations/runtime.js +37 -30
  152. package/dist/runtime/messaging/payload-codec.d.ts +7 -1
  153. package/dist/runtime/messaging/payload-codec.js +7 -6
  154. package/dist/runtime/messaging/request-result.js +29 -26
  155. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
  156. package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
  157. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
  158. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
  159. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
  160. package/dist/runtime/spots/index.d.ts +18 -11
  161. package/dist/runtime/spots/index.js +234 -176
  162. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  163. package/dist/runtime/spots/spot-activation-registry.js +21 -11
  164. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  165. package/dist/runtime/spots/spot-activation-state.js +7 -7
  166. package/dist/runtime/spots/spot-activation.d.ts +6 -3
  167. package/dist/runtime/spots/spot-activation.js +123 -44
  168. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
  169. package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
  170. package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
  171. package/dist/runtime/spots/spot-actor-membership.js +0 -8
  172. package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
  173. package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
  174. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
  175. package/dist/runtime/spots/spot-entry-activation.js +14 -9
  176. package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
  177. package/dist/runtime/spots/spot-handler-registry.js +6 -2
  178. package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
  179. package/dist/runtime/spots/spot-manager-public.js +2 -2
  180. package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
  181. package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
  182. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
  183. package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
  184. package/dist/runtime/spots/spot-outbound.js +3 -3
  185. package/dist/runtime/spots/spot-remote-codec.js +5 -1
  186. package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
  187. package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
  188. package/dist/runtime/spots/spot-serial-executor.js +61 -8
  189. package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
  190. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
  191. package/dist/runtime/spots/spot-timer.d.ts +57 -5
  192. package/dist/runtime/spots/spot-timer.js +287 -103
  193. package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
  194. package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
  195. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
  196. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
  197. package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
  198. package/dist/runtime/streams/bound-session-service.d.ts +1 -1
  199. package/dist/runtime/streams/bound-session-service.js +6 -11
  200. package/dist/runtime/streams/index.d.ts +3 -2
  201. package/dist/runtime/streams/index.js +6 -4
  202. package/dist/runtime/streams/managed-stream.js +3 -2
  203. package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
  204. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
  205. package/dist/runtime/streams/session-actor-coordinator.js +15 -32
  206. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
  207. package/dist/runtime/streams/stream-session-runtime.js +1 -4
  208. package/dist/runtime/workers/index.js +1 -1
  209. package/package.json +3 -3
  210. package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
  211. package/src/contracts/Common/encoded-payload-storage.ts +6 -3
  212. package/src/contracts/Configuration/Builders.ts +4 -1
  213. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
  214. package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
  215. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  216. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
  217. package/src/contracts/Locations/Rows.ts +2 -0
  218. package/src/contracts/Spots/Contracts.ts +8 -0
  219. package/src/contracts/Spots/ZLinkSpot.ts +3 -3
  220. package/src/runtime/abort.ts +12 -0
  221. package/src/runtime/actors/actor-authority-publication.ts +3 -2
  222. package/src/runtime/actors/actor-client.ts +61 -70
  223. package/src/runtime/actors/actor-context.ts +49 -9
  224. package/src/runtime/actors/actor-handoff.ts +282 -106
  225. package/src/runtime/actors/actor-join-relocation.ts +2 -0
  226. package/src/runtime/actors/actor-local-native-join.ts +4 -0
  227. package/src/runtime/actors/actor-mailbox.ts +40 -2
  228. package/src/runtime/actors/actor-remote-joiner.ts +6 -1
  229. package/src/runtime/actors/actor-reply.ts +42 -0
  230. package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
  231. package/src/runtime/actors/actor-runtime-state.ts +2 -20
  232. package/src/runtime/actors/actor-source-transfer.ts +1 -34
  233. package/src/runtime/actors/index.ts +41 -27
  234. package/src/runtime/actors/session-disconnected-wire.ts +66 -0
  235. package/src/runtime/admission.ts +69 -34
  236. package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
  237. package/src/runtime/application-jobs/contracts.ts +2 -0
  238. package/src/runtime/backend/contracts/index.ts +39 -4
  239. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
  240. package/src/runtime/backend/mesh-completion-table.ts +4 -0
  241. package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
  242. package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
  243. package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
  244. package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
  245. package/src/runtime/channels/channel-clients.ts +49 -24
  246. package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
  247. package/src/runtime/channels/channel-dispatchers.ts +116 -72
  248. package/src/runtime/channels/channel-envelope.ts +105 -36
  249. package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
  250. package/src/runtime/channels/channel-runtime-manager.ts +12 -5
  251. package/src/runtime/channels/channel-transports.ts +49 -58
  252. package/src/runtime/channels/client-server-location-runtime.ts +11 -10
  253. package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
  254. package/src/runtime/channels/fanout-location-runtime.ts +17 -9
  255. package/src/runtime/diagnostics/flow-context.ts +20 -7
  256. package/src/runtime/diagnostics/index.ts +1 -7
  257. package/src/runtime/diagnostics/message-flow.ts +47 -9
  258. package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
  259. package/src/runtime/execution/index.ts +40 -14
  260. package/src/runtime/execution/serial-execution-queue.ts +31 -4
  261. package/src/runtime/execution/state-lane.ts +7 -0
  262. package/src/runtime/foundation/operation-registry.ts +98 -20
  263. package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
  264. package/src/runtime/foundation/service-liveness-registry.ts +39 -0
  265. package/src/runtime/foundation/service-mailbox.ts +8 -0
  266. package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
  267. package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
  268. package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
  269. package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
  270. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
  271. package/src/runtime/foundation/service-stateful-registry.ts +38 -35
  272. package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
  274. package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
  275. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  276. package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
  277. package/src/runtime/host/actor-packet-relay.ts +113 -94
  278. package/src/runtime/host/actor-placement-coordinator.ts +31 -8
  279. package/src/runtime/host/actor-transfer-runtime.ts +104 -430
  280. package/src/runtime/host/application-job-queue.ts +29 -44
  281. package/src/runtime/host/index.ts +286 -129
  282. package/src/runtime/host/location-runtime-owner.ts +2 -6
  283. package/src/runtime/host/mesh-router-resolver.ts +13 -5
  284. package/src/runtime/host/remote-bound-session-relay.ts +86 -248
  285. package/src/runtime/host/route-mesh-runtime.ts +11 -5
  286. package/src/runtime/host/runtime-shutdown.ts +15 -4
  287. package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
  288. package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
  290. package/src/runtime/locations/auto-connect-loop.ts +22 -14
  291. package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
  292. package/src/runtime/locations/auto-connect-types.ts +0 -1
  293. package/src/runtime/locations/descriptor-publication.ts +7 -0
  294. package/src/runtime/locations/domain-store-contract.ts +5 -0
  295. package/src/runtime/locations/in-memory-authority-store.ts +85 -23
  296. package/src/runtime/locations/in-memory-location-store.ts +1 -12
  297. package/src/runtime/locations/index.ts +1 -0
  298. package/src/runtime/locations/lease-tracker.ts +2 -9
  299. package/src/runtime/locations/location-store-repository.ts +628 -152
  300. package/src/runtime/locations/relocation-blob.ts +75 -1
  301. package/src/runtime/locations/request-source-resolver.ts +138 -0
  302. package/src/runtime/locations/resolvers.ts +2 -2
  303. package/src/runtime/locations/runtime.ts +70 -40
  304. package/src/runtime/messaging/payload-codec.ts +8 -11
  305. package/src/runtime/messaging/request-result.ts +33 -29
  306. package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
  307. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
  308. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
  309. package/src/runtime/spots/index.ts +375 -281
  310. package/src/runtime/spots/spot-activation-registry.ts +25 -13
  311. package/src/runtime/spots/spot-activation-state.ts +12 -19
  312. package/src/runtime/spots/spot-activation.ts +170 -86
  313. package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
  314. package/src/runtime/spots/spot-actor-membership.ts +0 -15
  315. package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
  316. package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
  317. package/src/runtime/spots/spot-entry-activation.ts +24 -19
  318. package/src/runtime/spots/spot-handler-registry.ts +15 -4
  319. package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
  320. package/src/runtime/spots/spot-manager-public.ts +2 -2
  321. package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
  322. package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
  323. package/src/runtime/spots/spot-outbound.ts +3 -3
  324. package/src/runtime/spots/spot-remote-codec.ts +9 -2
  325. package/src/runtime/spots/spot-runtime-ports.ts +0 -1
  326. package/src/runtime/spots/spot-serial-executor.ts +97 -25
  327. package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
  328. package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
  329. package/src/runtime/spots/spot-timer.ts +413 -157
  330. package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
  331. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
  332. package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
  333. package/src/runtime/streams/bound-session-service.ts +7 -10
  334. package/src/runtime/streams/index.ts +12 -6
  335. package/src/runtime/streams/managed-stream.ts +4 -2
  336. package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
  337. package/src/runtime/streams/session-actor-coordinator.ts +39 -88
  338. package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
  339. package/src/runtime/streams/stream-session-runtime.ts +1 -5
  340. package/src/runtime/workers/index.ts +1 -1
@@ -14,6 +14,9 @@ exports.encodeApplicationPayload = encodeApplicationPayload;
14
14
  exports.encodeMultipartApplicationPayload = encodeMultipartApplicationPayload;
15
15
  exports.decodeApplicationPayload = decodeApplicationPayload;
16
16
  exports.decodeApplicationPayloadView = decodeApplicationPayloadView;
17
+ exports.decodeMultipartApplicationPayloadView = decodeMultipartApplicationPayloadView;
18
+ exports.decodeMultipartApplicationParts = decodeMultipartApplicationParts;
19
+ exports.decodeMultipartParts = decodeMultipartParts;
17
20
  exports.validateApplicationPayloadFrame = validateApplicationPayloadFrame;
18
21
  exports.encodeRouteMeshAdmission = encodeRouteMeshAdmission;
19
22
  exports.decodeRouteMeshAdmission = decodeRouteMeshAdmission;
@@ -37,6 +40,10 @@ exports.APPLICATION_PAYLOAD_MINIMUM_FIELD_BYTES = 1 +
37
40
  APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES;
38
41
  const MAX_U32 = stream_wire_1.UINT32_MAX;
39
42
  const MAX_U64 = stream_wire_1.UINT64_MAX;
43
+ // The framework multipart frame always carries these two schema constants;
44
+ // decoding compares their bytes in place instead of decoding text.
45
+ const MULTIPART_PACKET_NAME_BYTES = Buffer.from(service_wire_constants_generated_1.SERVICE_FRAMEWORK_MULTIPART_PACKET_NAME);
46
+ const MULTIPART_CONTENT_TYPE_BYTES = Buffer.from(service_wire_constants_generated_1.SERVICE_FRAMEWORK_MULTIPART_CONTENT_TYPE);
40
47
  exports.M6A_SERVICE_WIRE_MAGIC = service_wire_constants_generated_1.SERVICE_WIRE_MAGIC;
41
48
  exports.M6A_SERVICE_WIRE_MAJOR = service_wire_constants_generated_1.SERVICE_WIRE_MAJOR;
42
49
  exports.M6A_SERVICE_WIRE_REQUIRED_CAPABILITY = service_wire_constants_generated_1.SERVICE_WIRE_REQUIRED_CAPABILITY;
@@ -52,7 +59,7 @@ function encodeNodeSendHeader() {
52
59
  return prefix(exports.M6aServiceWireCommand.nodeSend);
53
60
  }
54
61
  function encodeNodeRequestHeader(correlation) {
55
- return withU64(prefix(exports.M6aServiceWireCommand.nodeRequest), correlation, 'correlation');
62
+ return withU64(exports.M6aServiceWireCommand.nodeRequest, correlation, 0);
56
63
  }
57
64
  function decodeNodeRequestHeader(frame, header = decodeHeader(frame)) {
58
65
  if (header.command !== exports.M6aServiceWireCommand.nodeRequest ||
@@ -63,7 +70,10 @@ function decodeNodeRequestHeader(frame, header = decodeHeader(frame)) {
63
70
  return readNonZeroU64(asBuffer(frame), PREFIX_SIZE, 'correlation');
64
71
  }
65
72
  function encodeChannelSendHeader(channelName) {
66
- return concat(prefix(exports.M6aServiceWireCommand.channelSend), encodeText8(channelName, 'channelName'));
73
+ const length = channelNameLength(channelName);
74
+ const result = frame(exports.M6aServiceWireCommand.channelSend, 1 + length);
75
+ writeText8(result, PREFIX_SIZE, channelName, length);
76
+ return result;
67
77
  }
68
78
  function decodeChannelSendHeader(frame, header = decodeHeader(frame)) {
69
79
  if (header.command !== exports.M6aServiceWireCommand.channelSend || header.flags !== 0) {
@@ -75,7 +85,13 @@ function decodeChannelSendHeader(frame, header = decodeHeader(frame)) {
75
85
  return channelName;
76
86
  }
77
87
  function encodeChannelRequestHeader(correlation, channelName) {
78
- return concat(withU64(prefix(exports.M6aServiceWireCommand.channelRequest), correlation, 'correlation'), encodeText8(channelName, 'channelName'));
88
+ const length = channelNameLength(channelName);
89
+ const result = withU64(exports.M6aServiceWireCommand.channelRequest, correlation, 1 + length);
90
+ writeText8(result, PREFIX_SIZE + 8, channelName, length);
91
+ return result;
92
+ }
93
+ function channelNameLength(channelName) {
94
+ return (0, service_wire_binary_primitives_1.canonicalServiceWireTextLength)(channelName, 'channelName', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
79
95
  }
80
96
  function decodeChannelRequestHeader(frame, header = decodeHeader(frame)) {
81
97
  if (header.command !== exports.M6aServiceWireCommand.channelRequest || header.flags !== 0) {
@@ -87,7 +103,7 @@ function decodeChannelRequestHeader(frame, header = decodeHeader(frame)) {
87
103
  reader.end();
88
104
  return { correlation, channelName };
89
105
  }
90
- function encodeReplyHeader(correlation, terminalResult = 0, failureCode = 0, tail = Buffer.alloc(0)) {
106
+ function encodeReplyHeader(correlation, terminalResult = 0, failureCode = 0, tail) {
91
107
  validateReplyFields(correlation, terminalResult, failureCode);
92
108
  // service-wire-v1.schema.json: reply(20).tail -> `request-specific-tail`,
93
109
  // a conditional-union with NO `bodyLengthType`, so the selected case's
@@ -95,12 +111,12 @@ function encodeReplyHeader(correlation, terminalResult = 0, failureCode = 0, tai
95
111
  // length on the wire; an empty tail yields exactly 21 bytes. (Contrast
96
112
  // `actor-join-reply-tail`, which does declare `bodyLengthType: u16` and
97
113
  // therefore carries its own inner length prefix.)
98
- const result = Buffer.alloc(PREFIX_SIZE + 16 + tail.byteLength);
99
- prefix(exports.M6aServiceWireCommand.reply).copy(result);
114
+ const result = frame(exports.M6aServiceWireCommand.reply, 16 + (tail?.byteLength ?? 0));
100
115
  result.writeBigUInt64BE(correlation, PREFIX_SIZE);
101
116
  result.writeUInt32BE(terminalResult, PREFIX_SIZE + 8);
102
117
  result.writeUInt32BE(failureCode, PREFIX_SIZE + 12);
103
- Buffer.from(tail).copy(result, PREFIX_SIZE + 16);
118
+ if (tail !== undefined)
119
+ result.set(tail, PREFIX_SIZE + 16);
104
120
  return result;
105
121
  }
106
122
  function decodeReplyHeader(frame) {
@@ -118,7 +134,8 @@ function decodeReplyHeader(frame) {
118
134
  correlation: bytes.readBigUInt64BE(PREFIX_SIZE),
119
135
  terminalResult: bytes.readUInt32BE(PREFIX_SIZE + 8),
120
136
  failureCode: bytes.readUInt32BE(PREFIX_SIZE + 12),
121
- tail: Buffer.from(bytes.subarray(PREFIX_SIZE + 16))
137
+ // A view of the frame: the caller validates the tail before the frame is released.
138
+ tail: bytes.subarray(PREFIX_SIZE + 16)
122
139
  };
123
140
  validateReplyFields(result.correlation, result.terminalResult, result.failureCode);
124
141
  return result;
@@ -159,14 +176,11 @@ function encodeMultipartApplicationPayload(parts, packetName, contentType) {
159
176
  return result;
160
177
  }
161
178
  function allocateApplicationPayload(packetName, contentType, payloadLength) {
162
- const packetNameBytes = (0, service_wire_binary_primitives_1.encodeCanonicalServiceWireText)(packetName, 'packetName', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
163
- const contentTypeBytes = (0, service_wire_binary_primitives_1.encodeCanonicalServiceWireText)(contentType, 'contentType', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
179
+ const packetNameLength = (0, service_wire_binary_primitives_1.canonicalServiceWireTextLength)(packetName, 'packetName', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
180
+ const contentTypeLength = (0, service_wire_binary_primitives_1.canonicalServiceWireTextLength)(contentType, 'contentType', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
164
181
  if (payloadLength > MAX_U32)
165
182
  fail('Application payload exceeds u32.');
166
- const frameLength = exports.APPLICATION_PAYLOAD_MINIMUM_FIELD_BYTES +
167
- packetNameBytes.byteLength +
168
- contentTypeBytes.byteLength +
169
- payloadLength;
183
+ const frameLength = exports.APPLICATION_PAYLOAD_MINIMUM_FIELD_BYTES + packetNameLength + contentTypeLength + payloadLength;
170
184
  const prefixLength = 1 + APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES;
171
185
  const bodyLength = frameLength - prefixLength;
172
186
  if (bodyLength > MAX_U32)
@@ -174,13 +188,8 @@ function allocateApplicationPayload(packetName, contentType, payloadLength) {
174
188
  const result = Buffer.alloc(frameLength);
175
189
  result[0] = exports.APPLICATION_PAYLOAD_VERSION;
176
190
  result.writeUInt32BE(bodyLength, 1);
177
- let offset = prefixLength;
178
- result[offset++] = packetNameBytes.byteLength;
179
- result.set(packetNameBytes, offset);
180
- offset += packetNameBytes.byteLength;
181
- result[offset++] = contentTypeBytes.byteLength;
182
- result.set(contentTypeBytes, offset);
183
- offset += contentTypeBytes.byteLength;
191
+ let offset = writeText8(result, prefixLength, packetName, packetNameLength);
192
+ offset = writeText8(result, offset, contentType, contentTypeLength);
184
193
  result.writeUInt32BE(payloadLength, offset);
185
194
  return result;
186
195
  }
@@ -197,20 +206,111 @@ function decodeApplicationPayload(frame) {
197
206
  * they must hand the multipart bytes to another runtime-owned queue.
198
207
  */
199
208
  function decodeApplicationPayloadView(frame) {
200
- const reader = new Reader(frame);
201
- if (reader.u8('version') !== exports.APPLICATION_PAYLOAD_VERSION)
202
- fail('Invalid application payload version.');
203
- const bodyLength = reader.u32('bodyLength');
204
- if (bodyLength !== reader.remaining)
205
- fail('Application payload body length mismatch.');
209
+ const reader = applicationPayloadReader(frame);
206
210
  const packetName = reader.text8('packetName');
207
211
  const contentType = reader.text8('contentType');
208
- const payloadLength = reader.u32('payloadLength');
209
- if (payloadLength !== reader.remaining)
212
+ return { packetName, contentType, payload: applicationPayloadView(reader) };
213
+ }
214
+ /**
215
+ * Decodes the framework multipart application frame, whose packet name and
216
+ * content type are the schema's multipart constants, and returns a view of its
217
+ * multipart payload without decoding either text field.
218
+ */
219
+ function decodeMultipartApplicationPayloadView(frame) {
220
+ const bytes = asBuffer(frame);
221
+ const offset = multipartApplicationPayloadOffset(bytes);
222
+ return {
223
+ packetName: service_wire_constants_generated_1.SERVICE_FRAMEWORK_MULTIPART_PACKET_NAME,
224
+ contentType: service_wire_constants_generated_1.SERVICE_FRAMEWORK_MULTIPART_CONTENT_TYPE,
225
+ payload: bytes.subarray(offset)
226
+ };
227
+ }
228
+ /** Materializes final message parts directly over the retained application frame. */
229
+ function decodeMultipartApplicationParts(frame, materialize, release) {
230
+ const bytes = asBuffer(frame);
231
+ return decodeMultipartParts(bytes, materialize, release, multipartApplicationPayloadOffset(bytes));
232
+ }
233
+ function multipartApplicationPayloadOffset(bytes) {
234
+ let offset = applicationPayloadBodyOffset(bytes);
235
+ offset = expectText8At(bytes, offset, MULTIPART_PACKET_NAME_BYTES, 'packetName');
236
+ offset = expectText8At(bytes, offset, MULTIPART_CONTENT_TYPE_BYTES, 'contentType');
237
+ return applicationPayloadDataOffset(bytes, offset);
238
+ }
239
+ function expectText8At(bytes, offset, expected, field) {
240
+ if (bytes.length <= offset)
241
+ fail(`Truncated ${field}.length.`);
242
+ const length = bytes[offset++];
243
+ if (bytes.length - offset < length)
244
+ fail(`Truncated ${field}.`);
245
+ if (length !== expected.length || expected.compare(bytes, offset, offset + length) !== 0) {
246
+ fail(`Unexpected ${field}.`);
247
+ }
248
+ return offset + length;
249
+ }
250
+ function applicationPayloadBodyOffset(bytes) {
251
+ if (bytes.length === 0)
252
+ fail('Truncated version.');
253
+ if (bytes[0] !== exports.APPLICATION_PAYLOAD_VERSION)
254
+ fail('Invalid application payload version.');
255
+ const offset = 1 + APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES;
256
+ if (bytes.length < offset)
257
+ fail('Truncated bodyLength.');
258
+ if (bytes.readUInt32BE(1) !== bytes.length - offset)
259
+ fail('Application payload body length mismatch.');
260
+ return offset;
261
+ }
262
+ function applicationPayloadDataOffset(bytes, offset) {
263
+ if (bytes.length - offset < APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES)
264
+ fail('Truncated payloadLength.');
265
+ const length = bytes.readUInt32BE(offset);
266
+ offset += APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES;
267
+ if (length !== bytes.length - offset)
210
268
  fail('Application payload length mismatch.');
211
- const payload = reader.view(payloadLength, 'payload');
212
- reader.end();
213
- return { packetName, contentType, payload };
269
+ return offset;
270
+ }
271
+ function applicationPayloadReader(frame) {
272
+ const bytes = asBuffer(frame);
273
+ return new Reader(bytes, applicationPayloadBodyOffset(bytes));
274
+ }
275
+ function applicationPayloadView(reader) {
276
+ return reader.buffer.subarray(applicationPayloadDataOffset(reader.buffer, reader.offset));
277
+ }
278
+ function decodeMultipartParts(payload, materialize, release, offset = 0) {
279
+ const bytes = asBuffer(payload);
280
+ if (bytes.length - offset < 4)
281
+ throw new ServiceWireProtocolError('Truncated multipart payload.');
282
+ const count = bytes.readUInt32BE(offset);
283
+ if (count === 0 || count > Math.floor((bytes.length - offset - 4) / 4)) {
284
+ throw new ServiceWireProtocolError('Invalid multipart part count.');
285
+ }
286
+ const result = new Array(count);
287
+ offset += 4;
288
+ let index = 0;
289
+ try {
290
+ for (; index < count; index++) {
291
+ if (bytes.length - offset < 4) {
292
+ throw new ServiceWireProtocolError('Truncated multipart part length.');
293
+ }
294
+ const length = bytes.readUInt32BE(offset);
295
+ offset += 4;
296
+ if (bytes.length - offset < length) {
297
+ throw new ServiceWireProtocolError('Truncated multipart part.');
298
+ }
299
+ result[index] = materialize(bytes.subarray(offset, offset + length));
300
+ offset += length;
301
+ }
302
+ if (offset !== bytes.length) {
303
+ throw new ServiceWireProtocolError('Multipart payload has trailing bytes.');
304
+ }
305
+ return result;
306
+ }
307
+ catch (error) {
308
+ if (release !== undefined) {
309
+ for (let retained = 0; retained < index; retained++)
310
+ release(result[retained]);
311
+ }
312
+ throw error;
313
+ }
214
314
  }
215
315
  /**
216
316
  * Validates the M6A envelope without retaining a second payload buffer. The
@@ -219,12 +319,7 @@ function decodeApplicationPayloadView(frame) {
219
319
  * message is admitted to an execution queue.
220
320
  */
221
321
  function validateApplicationPayloadFrame(frame) {
222
- const reader = new Reader(frame);
223
- if (reader.u8('version') !== exports.APPLICATION_PAYLOAD_VERSION)
224
- fail('Invalid application payload version.');
225
- const bodyLength = reader.u32('bodyLength');
226
- if (bodyLength !== reader.remaining)
227
- fail('Application payload body length mismatch.');
322
+ const reader = applicationPayloadReader(frame);
228
323
  reader.text8('packetName');
229
324
  reader.text8('contentType');
230
325
  const payloadLength = reader.u32('payloadLength');
@@ -381,19 +476,35 @@ function decodeHeader(frame) {
381
476
  fail('Unsupported service wire major.');
382
477
  return { command: frame[3], flags: frame[4] };
383
478
  }
479
+ /** Allocates a whole service wire record once and writes its prefix; the caller fills the body. */
480
+ function frame(command, bodyLength) {
481
+ const result = Buffer.allocUnsafe(PREFIX_SIZE + bodyLength);
482
+ result[0] = exports.M6A_SERVICE_WIRE_MAGIC[0];
483
+ result[1] = exports.M6A_SERVICE_WIRE_MAGIC[1];
484
+ result[2] = exports.M6A_SERVICE_WIRE_MAJOR;
485
+ result[3] = command;
486
+ result[4] = 0;
487
+ return result;
488
+ }
384
489
  function prefix(command) {
385
- return Buffer.from([
386
- exports.M6A_SERVICE_WIRE_MAGIC[0],
387
- exports.M6A_SERVICE_WIRE_MAGIC[1],
388
- exports.M6A_SERVICE_WIRE_MAJOR,
389
- command,
390
- 0
391
- ]);
392
- }
393
- function withU64(head, value, field) {
394
- if (value <= 0n || value > MAX_U64)
395
- fail(`${field} must be a non-zero u64.`);
396
- return concat(head, encodeU64(value));
490
+ return frame(command, 0);
491
+ }
492
+ /** A record whose body starts with the non-zero u64 correlation, followed by `restLength` bytes. */
493
+ function withU64(command, correlation, restLength) {
494
+ if (correlation <= 0n || correlation > MAX_U64)
495
+ fail('correlation must be a non-zero u64.');
496
+ const result = frame(command, 8 + restLength);
497
+ result.writeBigUInt64BE(correlation, PREFIX_SIZE);
498
+ return result;
499
+ }
500
+ /**
501
+ * Writes a validated text8 field — the byte length from
502
+ * canonicalServiceWireTextLength, then the UTF-8 text — and returns the next offset.
503
+ */
504
+ function writeText8(target, offset, value, length) {
505
+ target[offset] = length;
506
+ target.write(value, offset + 1, length, 'utf8');
507
+ return offset + 1 + length;
397
508
  }
398
509
  function encodeU16(value) {
399
510
  if (!Number.isInteger(value) || value < 0 || value > 0xffff)
@@ -437,7 +548,9 @@ function readNonZeroU64(bytes, offset, field) {
437
548
  return result;
438
549
  }
439
550
  function asBuffer(value) {
440
- return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
551
+ return Buffer.isBuffer(value)
552
+ ? value
553
+ : Buffer.from(value.buffer, value.byteOffset, value.byteLength);
441
554
  }
442
555
  function validateAdmissionCommand(command) {
443
556
  if (command !== exports.M6aServiceWireCommand.hello &&
@@ -543,13 +656,13 @@ class Reader {
543
656
  const length = this.u8(`${field}.length`);
544
657
  if (length === 0)
545
658
  fail(`${field} must be non-empty.`);
546
- return decodeText(this.bytes(length, field), field);
659
+ return decodeText(this.view(length, field), field);
547
660
  }
548
661
  text16(field) {
549
662
  const length = this.u16(`${field}.length`);
550
663
  if (length === 0 || length > SERVICE_ROUTE_TEXT_MAX_BYTES)
551
664
  fail(`${field} has invalid length.`);
552
- return decodeText(this.bytes(length, field), field);
665
+ return decodeText(this.view(length, field), field);
553
666
  }
554
667
  bytes(length, field) {
555
668
  this.require(length, field);
@@ -6,6 +6,7 @@ import type { DefaultZLinkActorManager } from '../actors';
6
6
  import type { DefaultZLinkSpotManager, ZLinkSpotNodeRuntimeManager } from '../spots';
7
7
  import type { ZLinkDetachedTaskRunner } from '../spots/spot-actor-join-dispatch';
8
8
  import type { ZLinkBoundSessionResponsePort, ZLinkSessionBindingConfirmationOptions, ZLinkStreamActorLookupPort } from '../streams/stream-binding-runtime-ports';
9
+ import type { ServiceStreamSessionBinding } from '../foundation/service-runtime-contracts';
9
10
  import { type ZLinkStreamFrameHeader } from '../streams/protocol';
10
11
  import type { MeshRouterResolver } from './mesh-router-resolver';
11
12
  import type { ZLinkStoreLocationResolvers } from '../locations';
@@ -29,12 +30,11 @@ export declare class ZLinkActorPacketRelay {
29
30
  private readonly options;
30
31
  private readonly targets;
31
32
  constructor(options: ZLinkActorPacketRelayOptions);
32
- notifyBoundActorDisconnected(actor: ZLinkSessionActor, signal?: AbortSignal): Promise<void>;
33
+ notifyBoundActorDisconnected(actor: ZLinkSessionActor, signal?: AbortSignal, binding?: ServiceStreamSessionBinding): Promise<void>;
33
34
  clearRemoteActorPacketTarget(actorId: string): void;
34
35
  updateRemoteActorPacketTarget(actorId: string, value: unknown): Promise<void>;
35
36
  actorPacketTargetForState(actorId: string): ZLinkRemoteActorPacketTarget | undefined;
36
- notifyActorDisconnectedById(actorId: string, signal?: AbortSignal): Promise<void>;
37
- notifyLocalActorDisconnectedById(actorId: string, signal?: AbortSignal): Promise<void>;
37
+ notifyLocalActorDisconnectedById(actorId: string, signal?: AbortSignal, binding?: ServiceStreamSessionBinding, bindingActorRef?: ActorRef): Promise<void>;
38
38
  receiveRemoteActorPacketRelay(payload: unknown, _routeContext: ZLinkRouteMessageContext): Promise<{
39
39
  readonly ok: boolean;
40
40
  readonly error?: unknown;
@@ -52,8 +52,10 @@ export declare class ZLinkActorPacketRelay {
52
52
  */
53
53
  private installSameNodeSessionBinding;
54
54
  relayRemoteActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message): Promise<boolean>;
55
- notifyRemoteActorDisconnected(actorId: string, remoteTarget: ZLinkRemoteBoundSessionTarget | ZLinkRemoteActorPacketTarget, signal?: AbortSignal, bindingActorRef?: ActorRef): Promise<void>;
55
+ notifyRemoteActorDisconnected(actorId: string, remoteTarget: ZLinkRemoteBoundSessionTarget | ZLinkRemoteActorPacketTarget, signal?: AbortSignal, bindingActorRef?: ActorRef, binding?: ServiceStreamSessionBinding): Promise<void>;
56
+ private disconnectedFrame;
56
57
  private requireCurrentRemoteBinding;
58
+ private matchesCurrentRemoteBinding;
57
59
  private requestRemoteTarget;
58
60
  private relayLocalActorPacket;
59
61
  private sendCapturedOrCurrentBoundSessionResponse;
@@ -5,12 +5,14 @@ const framework_errors_internal_1 = require("../framework-errors-internal");
5
5
  const runtime_message_1 = require("../backend/runtime-message");
6
6
  const contracts_1 = require("../../contracts");
7
7
  const ConfigurationException_1 = require("../../contracts/Configuration/ConfigurationException");
8
+ const abort_1 = require("../abort");
8
9
  const actors_1 = require("../actors");
9
10
  const actor_packet_relay_wire_1 = require("../actors/actor-packet-relay-wire");
10
11
  const actor_routed_json_request_1 = require("../actors/actor-routed-json-request");
11
12
  const actor_message_follow_context_1 = require("../actors/actor-message-follow-context");
12
13
  const bound_session_wire_1 = require("../actors/bound-session-wire");
13
14
  const routing_id_1 = require("../routing-id");
15
+ const session_disconnected_wire_1 = require("../actors/session-disconnected-wire");
14
16
  const submission_result_1 = require("../messaging/submission-result");
15
17
  const actor_session_binding_runtime_owner_1 = require("../streams/actor-session-binding-runtime-owner");
16
18
  const protocol_1 = require("../streams/protocol");
@@ -32,29 +34,14 @@ class ZLinkActorPacketRelay {
32
34
  spotRouterChannelIdForMesh: spotRouterChannelIdByMesh?.call(options.meshRouters) ?? ((meshName) => meshName)
33
35
  });
34
36
  }
35
- async notifyBoundActorDisconnected(actor, signal) {
36
- const state = this.options.actorManager()?.getState(actor.actorId);
37
- const currentRemoteBoundSessionTarget = state?.spotId === undefined ? undefined : state.remoteBoundSessionTarget;
38
- const currentRemoteActorPacketTarget = state?.spotId === undefined ? undefined : state.remoteActorPacketTarget;
39
- const remoteTarget = currentRemoteBoundSessionTarget ??
40
- currentRemoteActorPacketTarget ??
41
- (state?.spotId === undefined ? undefined : this.targets.cachedTargetForActor(actor));
42
- if (remoteTarget !== undefined) {
43
- await this.notifyRemoteActorDisconnected(actor.actorId, remoteTarget, signal, actor.ref);
44
- return;
45
- }
37
+ async notifyBoundActorDisconnected(actor, signal, binding) {
38
+ // The Session binding owns this route, including after relocation and detach (§5, §7).
46
39
  const actorRefTarget = this.targets.targetForActorRef(actor.ref);
47
40
  if (actorRefTarget !== undefined) {
48
- await this.notifyRemoteActorDisconnected(actor.actorId, actorRefTarget, signal, actor.ref);
41
+ await this.notifyRemoteActorDisconnected(actor.actorId, actorRefTarget, signal, actor.ref, binding);
49
42
  return;
50
43
  }
51
- if (state?.spotId !== undefined && state.actor !== undefined) {
52
- const handled = await this.requireSpotManager().notifyJoinedSpotActorDisconnected(state.spotId, state.actor, signal);
53
- if (handled) {
54
- return;
55
- }
56
- }
57
- await this.notifyActorDisconnectedById(actor.actorId, signal);
44
+ await this.notifyLocalActorDisconnectedById(actor.actorId, signal, binding, actor.ref);
58
45
  }
59
46
  clearRemoteActorPacketTarget(actorId) {
60
47
  this.targets.clear(actorId);
@@ -65,34 +52,22 @@ class ZLinkActorPacketRelay {
65
52
  actorPacketTargetForState(actorId) {
66
53
  return this.targets.targetForState(actorId);
67
54
  }
68
- async notifyActorDisconnectedById(actorId, signal) {
55
+ async notifyLocalActorDisconnectedById(actorId, signal, binding, bindingActorRef) {
56
+ (0, abort_1.throwIfAborted)(signal);
69
57
  const state = this.options.actorManager()?.getState(actorId);
70
- const remoteTarget = state === undefined
71
- ? undefined
72
- : (state.remoteBoundSessionTarget ?? state.remoteActorPacketTarget);
73
- if (remoteTarget !== undefined) {
74
- await this.notifyRemoteActorDisconnected(actorId, remoteTarget, signal);
75
- return;
76
- }
77
- await this.notifyLocalActorDisconnectedById(actorId, signal);
78
- }
79
- async notifyLocalActorDisconnectedById(actorId, signal) {
80
- const state = this.options.actorManager()?.getState(actorId);
81
- if (state?.spotId !== undefined && state.actor !== undefined) {
82
- const handled = await this.requireSpotManager().notifyJoinedSpotActorDisconnected(state.spotId, state.actor, signal);
83
- if (handled) {
84
- return;
85
- }
86
- }
87
- const localActor = state?.actor;
88
- if (localActor === undefined) {
89
- throw new Error(`Actor '${actorId}' does not have a local actor instance.`);
58
+ const frame = this.disconnectedFrame(actorId, binding);
59
+ const header = runtime_message_1.ZLinkBufferMessage.fromOwned(Buffer.from(frame.header));
60
+ const body = runtime_message_1.ZLinkBufferMessage.fromOwned(frame.payload);
61
+ try {
62
+ if (state?.spotId === undefined)
63
+ await this.requireSpotNodeRuntime().dispatchEntryActorPacket('local', actorId, [header, body], false, undefined, bindingActorRef);
64
+ else
65
+ await this.requireSpotManager().dispatchRoutedActorPacket('local', state.spotId, actorId, [header, body], false, undefined, bindingActorRef);
90
66
  }
91
- const meshName = state?.meshName;
92
- if (meshName === undefined) {
93
- throw new Error(`Actor '${actorId}' does not have a RouteMesh identity.`);
67
+ finally {
68
+ header.close();
69
+ body.close();
94
70
  }
95
- await this.requireSpotNodeRuntime().notifyEntrySpotActorDisconnected(meshName, localActor, signal);
96
71
  }
97
72
  async receiveRemoteActorPacketRelay(payload, _routeContext) {
98
73
  const relay = (0, actor_packet_relay_wire_1.decodeRemoteActorPacketRelayPayload)(payload);
@@ -159,22 +134,23 @@ class ZLinkActorPacketRelay {
159
134
  }
160
135
  return { ok: true, response: { acknowledged: true } };
161
136
  }
162
- if (frameHeader.name === actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET) {
163
- this.requireCurrentRemoteBinding(relay, _routeContext);
164
- await this.notifyLocalActorDisconnectedById(relay.actorId);
165
- return {
166
- ok: true,
167
- actorPacketTarget: (0, actor_packet_relay_wire_1.encodeRemoteActorPacketTarget)(this.actorPacketTargetForState(relay.actorId))
168
- };
169
- }
170
- if (remoteBoundSessionTarget !== undefined) {
137
+ if (remoteBoundSessionTarget !== undefined &&
138
+ frameHeader.name !== actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET) {
171
139
  this.requireCurrentRemoteBinding(relay, _routeContext);
172
140
  }
173
141
  const state = this.options.actorManager()?.getState(relay.actorId);
174
- if (frameHeader.kind === protocol_1.ZLinkStreamMessageKind.Send) {
142
+ if (frameHeader.kind === protocol_1.ZLinkStreamMessageKind.Send ||
143
+ frameHeader.name === actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET) {
175
144
  const dispatch = state?.spotId === undefined
176
145
  ? this.requireSpotNodeRuntime().dispatchEntryActorPacket('remote', relay.actorId, [header, body], false, remoteBoundSessionTarget, fallbackActorRef)
177
146
  : this.requireSpotManager().dispatchRoutedActorPacket('remote', state.spotId, relay.actorId, [header, body], false, remoteBoundSessionTarget, fallbackActorRef);
147
+ if (frameHeader.name === actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET) {
148
+ await dispatch;
149
+ return {
150
+ ok: true,
151
+ actorPacketTarget: (0, actor_packet_relay_wire_1.encodeRemoteActorPacketTarget)(this.actorPacketTargetForState(relay.actorId))
152
+ };
153
+ }
178
154
  // Spec 05 §1.3: a one-way Session Actor relay completes at relay
179
155
  // queue admission, not after the remote application turn. In
180
156
  // particular, a handler may register a deferred Join whose relocation
@@ -469,21 +445,14 @@ class ZLinkActorPacketRelay {
469
445
  }
470
446
  return true;
471
447
  }
472
- async notifyRemoteActorDisconnected(actorId, remoteTarget, signal, bindingActorRef) {
448
+ async notifyRemoteActorDisconnected(actorId, remoteTarget, signal, bindingActorRef, binding) {
473
449
  const spotKind = 'spotKind' in remoteTarget ? remoteTarget.spotKind : undefined;
474
- const header = {
475
- kind: protocol_1.ZLinkStreamMessageKind.Send,
476
- codec: protocol_1.ZLinkStreamCodec.Raw,
477
- flags: protocol_1.ZLinkStreamHeaderFlags.None,
478
- name: actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET,
479
- metadata: new Map()
480
- };
450
+ const frame = this.disconnectedFrame(actorId, binding, 'sessionNodeRid' in remoteTarget ? remoteTarget : undefined);
481
451
  const payload = (0, actor_packet_relay_wire_1.encodeRemoteActorPacketRelayPayload)({
482
452
  actorId,
483
453
  routerChannelId: remoteTarget.routerChannelId,
484
454
  bindingActorRef,
485
- header: (0, protocol_1.encodeStreamHeader)(header),
486
- payload: Buffer.alloc(0)
455
+ ...frame
487
456
  });
488
457
  if ((spotKind ?? contracts_1.ZLinkSpotKind.Entry) === contracts_1.ZLinkSpotKind.Entry) {
489
458
  await this.options.routeTransport.request(remoteTarget.routerChannelId, String(remoteTarget.targetNodeRid), actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET, payload, this.options.requestTimeoutMs, signal);
@@ -500,18 +469,36 @@ class ZLinkActorPacketRelay {
500
469
  signal
501
470
  });
502
471
  }
472
+ disconnectedFrame(actorId, binding, target) {
473
+ const current = binding === undefined
474
+ ? (this.options.actorManager()?.getState(actorId)?.boundSession ?? target)
475
+ : undefined;
476
+ const header = {
477
+ kind: protocol_1.ZLinkStreamMessageKind.Send,
478
+ codec: protocol_1.ZLinkStreamCodec.Raw,
479
+ flags: protocol_1.ZLinkStreamHeaderFlags.None,
480
+ name: actors_1.ZLINK_REMOTE_ACTOR_SESSION_DISCONNECTED_PACKET,
481
+ metadata: new Map()
482
+ };
483
+ return {
484
+ header: (0, protocol_1.encodeStreamHeader)(header),
485
+ payload: (0, session_disconnected_wire_1.encodeSessionDisconnected)(binding?.sessionOwnerNodeRid ?? current?.sessionNodeRid, binding?.sessionOwnerNodeGeneration ?? current?.sessionOwnerNodeGeneration, binding?.bindingGeneration ?? current?.bindingGeneration)
486
+ };
487
+ }
503
488
  requireCurrentRemoteBinding(relay, routeContext) {
504
- const state = this.options.actorManager()?.getState(relay.actorId);
505
- const current = state?.boundSession;
506
- if (current === undefined ||
507
- current.sessionNodeRid === undefined ||
508
- !(0, routing_id_1.routingIdsEqual)(current.sessionNodeRid, routeContext.sourceNodeRid) ||
509
- current.bindingGeneration === undefined ||
510
- relay.bindingGeneration === undefined ||
511
- current.bindingGeneration !== BigInt(relay.bindingGeneration)) {
489
+ if (!this.matchesCurrentRemoteBinding(relay, routeContext)) {
512
490
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorSessionNotBound, `Actor '${relay.actorId}' bound session identity is stale.`, true);
513
491
  }
514
492
  }
493
+ matchesCurrentRemoteBinding(relay, routeContext) {
494
+ const current = this.options.actorManager()?.getState(relay.actorId)?.boundSession;
495
+ return (current !== undefined &&
496
+ current.sessionNodeRid !== undefined &&
497
+ (0, routing_id_1.routingIdsEqual)(current.sessionNodeRid, routeContext.sourceNodeRid) &&
498
+ current.bindingGeneration !== undefined &&
499
+ relay.bindingGeneration !== undefined &&
500
+ current.bindingGeneration === BigInt(relay.bindingGeneration));
501
+ }
515
502
  async requestRemoteTarget(target, request, unavailableMessage, decodeReply, signal) {
516
503
  if (target.spotKind === contracts_1.ZLinkSpotKind.Entry) {
517
504
  try {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZLinkActorPlacementCoordinator = void 0;
4
+ const routing_id_1 = require("../routing-id");
4
5
  const framework_errors_internal_1 = require("../framework-errors-internal");
5
6
  const node_crypto_1 = require("node:crypto");
6
7
  const runtime_values_1 = require("../backend/runtime-values");
@@ -33,6 +34,13 @@ class ZLinkActorPlacementCoordinator {
33
34
  for (;;) {
34
35
  const target = await this.options.target(meshName, stableType, deadline.signal, excluded);
35
36
  if (target === undefined) {
37
+ // Entry eligibility limits new creation, not lookup of a Ready Actor (Actor model §6.3, §6.5).
38
+ if (!createOnly) {
39
+ const current = await this.options.store.readAuthority((0, authority_key_codec_1.encodeAuthorityKey)('actor', actorId), deadline.signal);
40
+ const existing = existingActor(current, actorId, stableType);
41
+ if (existing !== undefined)
42
+ return { status: 'existing', actor: existing };
43
+ }
36
44
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.PlacementCapacityExhausted, `No eligible Actor placement target is ready for '${stableType}'.`, true);
37
45
  }
38
46
  const creatingPayload = (0, actor_authority_publication_1.encodeActorAuthorityIdentity)({
@@ -75,7 +83,7 @@ class ZLinkActorPlacementCoordinator {
75
83
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorTypeMismatch, `Actor '${actorId}' is registered with another stable type.`);
76
84
  }
77
85
  if (reserved.kind === 'placementCapacityExhausted') {
78
- excluded.add(String(target.nodeRid));
86
+ excluded.add((0, routing_id_1.encodeRoutingIdStorageHex)(target.nodeRid));
79
87
  continue;
80
88
  }
81
89
  if (reserved.kind === 'alreadyExists' || reserved.kind === 'conflict') {
@@ -106,6 +114,13 @@ class ZLinkActorPlacementCoordinator {
106
114
  }
107
115
  if (remote === undefined)
108
116
  throw transportFailure;
117
+ if ((0, framework_errors_internal_1.internalFrameworkErrorKindFromWireReply)(remote.terminalResult, remote.failureCode) ===
118
+ framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RouteNotConnected) {
119
+ // The target refused before the callback and cancelled its reservation
120
+ // (Actor model §6.3); exclude this host run like a Reserve failure.
121
+ excluded.add((0, routing_id_1.encodeRoutingIdStorageHex)(target.nodeRid));
122
+ continue;
123
+ }
109
124
  if (remote.terminalResult !== runtime_values_1.RequestResult.Ok || remote.failureCode !== 0) {
110
125
  // Classify the (terminal, fine failure code) pair via the shared
111
126
  // ownership-aware translator instead of collapsing every non-OK
@@ -274,12 +289,14 @@ function creationTarget(snapshot) {
274
289
  }
275
290
  };
276
291
  }
277
- function existingActor(reserved, actorId, stableType) {
278
- const snapshot = reserved.kind === 'alreadyExists'
279
- ? reserved.current
280
- : reserved.kind === 'conflict' && reserved.current.kind === 'snapshot'
281
- ? reserved.current
282
- : undefined;
292
+ function existingActor(current, actorId, stableType) {
293
+ const snapshot = current.kind === 'snapshot'
294
+ ? current
295
+ : current.kind === 'alreadyExists'
296
+ ? current.current
297
+ : current.kind === 'conflict' && current.current.kind === 'snapshot'
298
+ ? current.current
299
+ : undefined;
283
300
  if (snapshot === undefined ||
284
301
  snapshot.allocation.state !== 'active' ||
285
302
  snapshot.allocation.objectKind !== 'actor' ||
@@ -348,7 +365,7 @@ function requireExactReservation(current, record) {
348
365
  current.allocation.stableType !== record.stableType ||
349
366
  current.objectGeneration !== record.reservation.objectGeneration ||
350
367
  current.authorityOwnerGeneration !== record.reservation.authorityOwnerGeneration ||
351
- String(current.allocation.descriptor.rid) !== record.reservation.targetNodeRid ||
368
+ !(0, routing_id_1.routingIdsEqual)(current.allocation.descriptor.rid, record.reservation.targetNodeRid) ||
352
369
  current.allocation.descriptorLifecycleGeneration !== record.reservation.targetNodeGeneration ||
353
370
  current.ownerId !== record.reservation.targetOwnerId ||
354
371
  current.ownerLeaseGeneration !== record.reservation.targetOwnerLeaseGeneration ||