@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
@@ -1,21 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ZLinkActorHandoffCoordinator = exports.DEFAULT_MESSAGE_FOLLOW_DURATION_MS = void 0;
3
+ exports.ZLinkActorHandoffCoordinator = exports.RELOCATED_REQUEST_OWNED_BY_REQUESTER = exports.DEFAULT_MESSAGE_FOLLOW_DURATION_MS = void 0;
4
4
  exports.decodeHandoffPacket = decodeHandoffPacket;
5
5
  exports.replayActorHandoffBacklog = replayActorHandoffBacklog;
6
6
  const contracts_1 = require("../../contracts");
7
+ const Registration_1 = require("../../contracts/Configuration/Registration");
7
8
  const Options_1 = require("../../contracts/Locations/Options");
8
9
  const application_job_queue_scope_1 = require("../application-jobs/application-job-queue-scope");
9
10
  const runtime_message_1 = require("../backend/runtime-message");
10
11
  const message_follow_suppression_registry_1 = require("../foundation/message-follow-suppression-registry");
12
+ const service_stateful_registry_1 = require("../foundation/service-stateful-registry");
13
+ const operation_identity_1 = require("../foundation/operation-identity");
14
+ const stream_wire_1 = require("@zlink-systems/stream-wire");
11
15
  const framework_errors_internal_1 = require("../framework-errors-internal");
16
+ const request_deadline_1 = require("../messaging/request-deadline");
12
17
  const routing_id_1 = require("../routing-id");
13
18
  const protocol_1 = require("../streams/protocol");
14
19
  const actor_message_follow_context_1 = require("./actor-message-follow-context");
15
20
  const actor_packet_relay_wire_1 = require("./actor-packet-relay-wire");
16
21
  const actor_routed_json_request_1 = require("./actor-routed-json-request");
17
22
  exports.DEFAULT_MESSAGE_FOLLOW_DURATION_MS = Options_1.zlinkDefaultLocationOptions.messageFollowDurationMs;
18
- const RELOCATION_REPLY_RETENTION_MS = 24 * 60 * 60 * 1_000;
23
+ exports.RELOCATED_REQUEST_OWNED_BY_REQUESTER = Symbol('relocated request owned by requester');
19
24
  function requireExactTargetOwnerFence(actorId, fence) {
20
25
  if (fence === undefined) {
21
26
  throw new Error(`Actor '${actorId}' handoff requires a committed target owner fence.`);
@@ -31,6 +36,8 @@ function requireExactTargetOwnerFence(actorId, fence) {
31
36
  class ZLinkActorHandoffCoordinator {
32
37
  options;
33
38
  active = new Map();
39
+ // Each route is stored once: Actor -> native fence -> location owner id.
40
+ // Native ingress has the complete fence except the location owner's text id.
34
41
  messageFollowRoutes = new Map();
35
42
  messageFollowSuppression = new message_follow_suppression_registry_1.MessageFollowSuppressionRegistry();
36
43
  // Relocation preserves ObjectGeneration, so (nodeRid, objectGeneration) alone
@@ -56,7 +63,10 @@ class ZLinkActorHandoffCoordinator {
56
63
  this.startHandoff(actorId, oldGeneration, 'provisional');
57
64
  }
58
65
  startHandoff(actorId, oldGeneration, phase) {
59
- if (this.active.has(actorId)) {
66
+ // A releasing handoff has returned its hold to the Actor FIFO; only its
67
+ // durable prefix drain remains, and the next hold takes over its ingress.
68
+ const previous = this.active.get(actorId);
69
+ if (this.isActive(actorId)) {
60
70
  throw new Error(`Actor '${actorId}' already has an active packet handoff.`);
61
71
  }
62
72
  if (oldGeneration <= 0n) {
@@ -92,6 +102,25 @@ class ZLinkActorHandoffCoordinator {
92
102
  nodeGeneration: source.nodeGeneration,
93
103
  authorityOwnerGeneration: source.authorityOwnerGeneration
94
104
  });
105
+ const pending = [];
106
+ if (previous?.prefixRelease !== undefined) {
107
+ // Only records still in the FIFO belong to the new barrier. Running
108
+ // records keep their existing terminal; withdrawn records surrender
109
+ // readiness and move their payload before later ingress can arrive.
110
+ for (let index = 0; index < previous.pending.length;) {
111
+ const record = previous.pending[index];
112
+ if (record.withdraw?.() === true) {
113
+ record.withdraw = undefined;
114
+ pending.push(record);
115
+ previous.pending.splice(index, 1);
116
+ previous.prefixRelease.cursor -= 1;
117
+ previous.pendingBytes -= packetBytes(record.packet);
118
+ }
119
+ else {
120
+ index += 1;
121
+ }
122
+ }
123
+ }
95
124
  this.active.set(actorId, {
96
125
  oldGeneration,
97
126
  oldNodeRid: sourceOwner.nodeRid,
@@ -101,25 +130,20 @@ class ZLinkActorHandoffCoordinator {
101
130
  phase,
102
131
  deferredJoin: phase === 'provisional',
103
132
  connectionBoundSealed: false,
104
- pending: [],
105
- nextIndex: 0,
133
+ pending,
134
+ nextIndex: pending.reduce((next, record) => Math.max(next, record.packet.index + 1), 0),
106
135
  snapshotIndex: -1,
107
- pendingBytes: 0
136
+ pendingBytes: pending.reduce((bytes, record) => bytes + packetBytes(record.packet), 0)
108
137
  });
109
138
  }
139
+ /** True while a hold owns this Actor's ingress, before its release to the Actor FIFO. */
110
140
  isActive(actorId) {
111
- return this.active.has(actorId);
141
+ const handoff = this.active.get(actorId);
142
+ return handoff !== undefined && handoff.phase !== 'releasing';
112
143
  }
113
144
  isProvisional(actorId) {
114
145
  return this.active.get(actorId)?.phase === 'provisional';
115
146
  }
116
- promoteProvisional(actorId) {
117
- const handoff = this.active.get(actorId);
118
- if (handoff?.phase !== 'provisional') {
119
- throw new Error(`Actor '${actorId}' does not have a provisional packet handoff.`);
120
- }
121
- handoff.phase = 'relocating';
122
- }
123
147
  sealConnectionBoundIngress(actorId) {
124
148
  const handoff = this.active.get(actorId);
125
149
  if (handoff !== undefined)
@@ -166,6 +190,33 @@ class ZLinkActorHandoffCoordinator {
166
190
  return { terminal: Promise.resolve() };
167
191
  return this.admitHandoffPrefix(actorId, handoff, queue, preparation, start);
168
192
  }
193
+ /** Installs a restored target's payload in the same owner used by local handoffs. */
194
+ admitTransferredPrefix(actorId, objectGeneration, packets, queue, preparation, start, onResult) {
195
+ this.beginProvisional(actorId, objectGeneration);
196
+ const handoff = this.requireActive(actorId);
197
+ for (const packet of packets) {
198
+ handoff.pending.push({
199
+ packet,
200
+ origin: 'remote',
201
+ resolve: (response) => {
202
+ if (response !== exports.RELOCATED_REQUEST_OWNED_BY_REQUESTER) {
203
+ onResult(packet, { index: packet.index, ok: true, response });
204
+ }
205
+ },
206
+ reject: (error) => onResult(packet, {
207
+ index: packet.index,
208
+ ok: false,
209
+ error: error instanceof Error ? error.message : String(error),
210
+ errorKind: error instanceof contracts_1.ZLinkFrameworkException
211
+ ? (0, framework_errors_internal_1.internalFrameworkErrorKind)(error)
212
+ : undefined
213
+ })
214
+ });
215
+ handoff.nextIndex = Math.max(handoff.nextIndex, packet.index + 1);
216
+ handoff.pendingBytes += packetBytes(packet);
217
+ }
218
+ return this.admitHandoffPrefix(actorId, handoff, queue, preparation, start);
219
+ }
169
220
  admitHandoffPrefix(actorId, handoff, queue, preparation, start) {
170
221
  if (handoff.releaseTask !== undefined) {
171
222
  return { terminal: handoff.releaseTask };
@@ -241,6 +292,9 @@ class ZLinkActorHandoffCoordinator {
241
292
  prepared = undefined;
242
293
  };
243
294
  return {
295
+ onWithdrawable: (withdraw) => {
296
+ pending.withdraw = withdraw;
297
+ },
244
298
  payloadBytes: packetBytes(pending.packet),
245
299
  preparation: {
246
300
  prepare: async (signal) => {
@@ -264,6 +318,9 @@ class ZLinkActorHandoffCoordinator {
264
318
  cancel
265
319
  },
266
320
  drain: async (replay) => {
321
+ // The FIFO claim, rather than this prefix's eventual terminal,
322
+ // ends the record's durable ownership and transfer capability.
323
+ pending.withdraw = undefined;
267
324
  const admission = prepared === undefined
268
325
  ? undefined
269
326
  : (operation) => prepared.run(operation);
@@ -423,10 +480,22 @@ class ZLinkActorHandoffCoordinator {
423
480
  }
424
481
  }
425
482
  capture(origin, actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef, deadlineUnixMs, messageFollowOrigin, provisionalReplay, onAdmitted) {
426
- const incomingContext = (0, actor_message_follow_context_1.actorMessageFollowContext)(fallbackActorRef);
483
+ let incomingContext = (0, actor_message_follow_context_1.actorMessageFollowContext)(fallbackActorRef);
427
484
  const originalDeadlineUnixMs = deadlineUnixMs ?? incomingContext?.deadlineUnixMs ?? packetDeadlineUnixMs(parts);
428
- const handoff = this.active.get(actorId);
485
+ const followRoute = this.findMessageFollowRoute(actorId, incomingContext, messageFollowOrigin?.target);
486
+ // An exact departed tenure belongs to its committed route, even while the
487
+ // same Actor incarnation is performing a later Join on this node.
488
+ const handoff = followRoute === undefined ? this.active.get(actorId) : undefined;
489
+ if (incomingContext === undefined &&
490
+ followRoute !== undefined &&
491
+ messageFollowOrigin?.target !== undefined) {
492
+ incomingContext = this.createInitialIngressContext(followRoute.sourceOwner, messageFollowOrigin.target.actor.generation, parts, returnResponse, originalDeadlineUnixMs, messageFollowOrigin);
493
+ }
429
494
  if (handoff !== undefined) {
495
+ if (handoff.phase === 'releasing' &&
496
+ handoff.prefixRelease !== undefined &&
497
+ handoff.pending.at(-1)?.withdraw === undefined)
498
+ return undefined;
430
499
  if (parts.length < 2)
431
500
  return Promise.resolve(undefined);
432
501
  if (handoff.connectionBoundSealed &&
@@ -442,9 +511,13 @@ class ZLinkActorHandoffCoordinator {
442
511
  handoff.replay = provisionalReplay;
443
512
  }
444
513
  const context = incomingContext ??
445
- this.createInitialIngressContext(handoff.sourceOwner, handoff.oldGeneration, parts, returnResponse, originalDeadlineUnixMs);
514
+ this.createInitialIngressContext(handoff.sourceOwner, handoff.oldGeneration, parts, returnResponse, originalDeadlineUnixMs, messageFollowOrigin);
446
515
  try {
447
516
  this.validateContext(actorId, context, parts, returnResponse, fallbackActorRef);
517
+ // Accepted handoff retains its original deadline; Message Follow uses a local relay window.
518
+ if (context.deadlineUnixMs !== undefined && Date.now() >= context.deadlineUnixMs) {
519
+ throw actorDeadlineExceeded(actorId);
520
+ }
448
521
  }
449
522
  catch (error) {
450
523
  return Promise.reject(error);
@@ -473,8 +546,23 @@ class ZLinkActorHandoffCoordinator {
473
546
  return Promise.resolve(undefined);
474
547
  }
475
548
  const result = new Promise((resolve, reject) => {
476
- const source = this.captureRequestSource(handoff.sourceEvidence, context.replyRouteId);
549
+ const original = messageFollowOrigin?.requestSource;
550
+ const originalRidHex = original === undefined ? undefined : (0, routing_id_1.routingIdWireHex)(original.nodeRid);
551
+ const source = original === undefined
552
+ ? this.captureRequestSource(handoff.sourceEvidence, context.replyRouteId)
553
+ : {
554
+ ownerId: original.ownerId,
555
+ ownerLeaseGeneration: original.leaseGeneration.toString(),
556
+ nodeRid: String(original.nodeRid),
557
+ ...(originalRidHex === undefined ? {} : { nodeRidHex: originalRidHex }),
558
+ nodeGeneration: original.nodeGeneration.toString(),
559
+ replyRouteId: messageFollowOrigin.originalReplyRouteId.toString()
560
+ };
477
561
  const requestPacket = { ...packet, source };
562
+ if (original !== undefined) {
563
+ handoff.pending.push({ packet: requestPacket, origin, resolve, reject });
564
+ return;
565
+ }
478
566
  const route = {
479
567
  actorId,
480
568
  operationId: requestPacket.messageFollowContext.operationId,
@@ -491,7 +579,7 @@ class ZLinkActorHandoffCoordinator {
491
579
  this.replyRoutes.delete(source.replyRouteId);
492
580
  if (!route.delivered)
493
581
  route.reject(new Error('Relocation reply route retention expired.'));
494
- }, RELOCATION_REPLY_RETENTION_MS);
582
+ }, service_stateful_registry_1.RELOCATION_REPLY_RETENTION_MS);
495
583
  route.deadline.unref();
496
584
  this.replyRoutes.set(source.replyRouteId, route);
497
585
  handoff.pending.push({
@@ -515,7 +603,6 @@ class ZLinkActorHandoffCoordinator {
515
603
  }
516
604
  return result;
517
605
  }
518
- const followRoute = this.findMessageFollowRoute(actorId, incomingContext);
519
606
  const staleGeneration = fallbackActorRef?.objectGeneration;
520
607
  if (fallbackActorRef !== undefined &&
521
608
  this.options.isCurrentActorRef?.(actorId, fallbackActorRef) === true) {
@@ -589,16 +676,6 @@ class ZLinkActorHandoffCoordinator {
589
676
  handoff.snapshotIndex = handoff.pending.length - 1;
590
677
  return handoff.pending.map((entry) => entry.packet);
591
678
  }
592
- snapshotCoreBacklog(actorId) {
593
- const handoff = this.requireActive(actorId);
594
- let snapshotIndex = -1;
595
- while (snapshotIndex + 1 < handoff.pending.length &&
596
- handoff.pending[snapshotIndex + 1].packet.returnResponse === false) {
597
- snapshotIndex++;
598
- }
599
- handoff.snapshotIndex = snapshotIndex;
600
- return handoff.pending.slice(0, snapshotIndex + 1).map((entry) => entry.packet);
601
- }
602
679
  /**
603
680
  * Freezes the post-capture ingress segment immediately before the caller
604
681
  * appends the one-way cutover on the same relocation lane. Records returned
@@ -613,11 +690,22 @@ class ZLinkActorHandoffCoordinator {
613
690
  }
614
691
  complete(actorId, target, targetActorRef, results, targetOwnerFence) {
615
692
  const handoff = this.requireActive(actorId);
616
- const committedTargetOwner = requireExactTargetOwnerFence(actorId, targetOwnerFence);
693
+ const committedTargetOwner = targetOwnerFence === null ? null : requireExactTargetOwnerFence(actorId, targetOwnerFence);
617
694
  this.active.delete(actorId);
695
+ // Location runtime §10: a later owner has no source-local Follow route.
696
+ if (committedTargetOwner === null) {
697
+ const unavailable = actorLocationStale(actorId);
698
+ for (const pending of handoff.pending)
699
+ this.failReleasedPending(pending, unavailable);
700
+ return;
701
+ }
618
702
  const byIndex = new Map(results.map((result) => [result.index, result]));
619
703
  for (let i = 0; i <= handoff.snapshotIndex; i++) {
620
704
  const pending = handoff.pending[i];
705
+ if (pending.packet.messageFollowOrigin?.requestSource !== undefined) {
706
+ pending.resolve?.(exports.RELOCATED_REQUEST_OWNED_BY_REQUESTER);
707
+ continue;
708
+ }
621
709
  if (pending.packet.source !== undefined)
622
710
  continue;
623
711
  const result = byIndex.get(pending.packet.index);
@@ -655,15 +743,25 @@ class ZLinkActorHandoffCoordinator {
655
743
  }
656
744
  }
657
745
  messageFollowCount(actorId) {
658
- return actorId === undefined
659
- ? this.messageFollowRoutes.size
660
- : [...this.messageFollowRoutes.values()].filter((route) => route.targetActorRef.actorId === actorId).length;
746
+ let count = 0;
747
+ if (actorId === undefined) {
748
+ for (const id of this.messageFollowRoutes.keys())
749
+ count += this.messageFollowCount(id);
750
+ }
751
+ else {
752
+ const routes = this.messageFollowRoutes.get(actorId);
753
+ if (routes !== undefined) {
754
+ for (const owners of routes.values())
755
+ count += owners.size;
756
+ }
757
+ }
758
+ return count;
661
759
  }
662
760
  pendingCount(actorId) {
663
761
  return this.active.get(actorId)?.pending.length ?? 0;
664
762
  }
665
763
  isKnownStale(actor) {
666
- return (this.messageFollowCount(actor.actorId) === 0 &&
764
+ return (!this.messageFollowRoutes.has(actor.actorId) &&
667
765
  this.options.isCurrentActorRef?.(actor.actorId, actor) !== true &&
668
766
  this.isKnownStaleRef(actor.actorId, actor));
669
767
  }
@@ -782,8 +880,18 @@ class ZLinkActorHandoffCoordinator {
782
880
  refs.set(exactRefKey, departedAuthorityOwnerGeneration);
783
881
  }
784
882
  }
785
- const key = messageFollowRouteKey(actorId, oldGeneration, sourceOwner);
786
- const previous = this.messageFollowRoutes.get(key);
883
+ const key = messageFollowRouteKey(oldGeneration, sourceOwner.nodeRidHex ?? (0, routing_id_1.encodeRoutingIdStorageHex)(sourceOwner.nodeRid), sourceOwner.nodeGeneration, sourceOwner.authorityOwnerGeneration, sourceOwner.ownerLeaseGeneration);
884
+ let routes = this.messageFollowRoutes.get(actorId);
885
+ if (routes === undefined) {
886
+ routes = new Map();
887
+ this.messageFollowRoutes.set(actorId, routes);
888
+ }
889
+ let owners = routes.get(key);
890
+ if (owners === undefined) {
891
+ owners = new Map();
892
+ routes.set(key, owners);
893
+ }
894
+ const previous = owners.get(sourceOwner.ownerId);
787
895
  if (previous !== undefined)
788
896
  clearTimeout(previous.deadline);
789
897
  const suppressionFence = actorMessageFollowSuppressionFence(actorId, oldGeneration, sourceOwner, targetOwner);
@@ -813,15 +921,24 @@ class ZLinkActorHandoffCoordinator {
813
921
  else {
814
922
  this.messageFollowSuppression.replaceRoute(previous.suppressionFence, suppressionFence);
815
923
  }
816
- this.messageFollowRoutes.set(key, entry);
924
+ owners.set(sourceOwner.ownerId, entry);
817
925
  this.options.onMarker?.('message_follow_registered', actorId, this.messageFollowDurationMs);
818
926
  return entry;
819
927
  }
820
928
  removeMessageFollowRoute(entry) {
821
- if (this.messageFollowRoutes.get(entry.key) !== entry)
929
+ const actorId = entry.targetActorRef.actorId;
930
+ const routes = this.messageFollowRoutes.get(actorId);
931
+ if (routes === undefined)
932
+ return;
933
+ const owners = routes.get(entry.key);
934
+ if (owners?.get(entry.sourceOwner.ownerId) !== entry)
822
935
  return;
823
936
  clearTimeout(entry.deadline);
824
- this.messageFollowRoutes.delete(entry.key);
937
+ owners.delete(entry.sourceOwner.ownerId);
938
+ if (owners.size === 0)
939
+ routes.delete(entry.key);
940
+ if (routes.size === 0)
941
+ this.messageFollowRoutes.delete(actorId);
825
942
  this.messageFollowSuppression.expireRoute(entry.suppressionFence);
826
943
  this.pruneStaleTenureRecords(entry);
827
944
  this.options.onMarker?.('message_follow_route_removed', entry.targetActorRef.actorId);
@@ -858,19 +975,48 @@ class ZLinkActorHandoffCoordinator {
858
975
  if (refs.size === 0)
859
976
  this.staleActorRefs.delete(actorId);
860
977
  }
861
- findMessageFollowRoute(actorId, context) {
862
- if (context === undefined)
978
+ findMessageFollowRoute(actorId, context, nativeTarget) {
979
+ const routes = this.messageFollowRoutes.get(actorId);
980
+ if (routes === undefined)
863
981
  return undefined;
864
- return this.messageFollowRoutes.get(messageFollowRouteKey(actorId, BigInt(context.objectGeneration), context.targetOwner));
982
+ if (context === undefined) {
983
+ if (nativeTarget === undefined || nativeTarget.actor.actorId !== actorId)
984
+ return undefined;
985
+ return routes
986
+ .get(messageFollowRouteKey(nativeTarget.actor.generation, (0, routing_id_1.encodeRoutingIdStorageHex)(nativeTarget.actor.nodeRid), nativeTarget.targetNodeGeneration, nativeTarget.authorityOwnerGeneration, nativeTarget.ownerLeaseGeneration))
987
+ ?.values()
988
+ .next().value;
989
+ }
990
+ const owner = context.targetOwner;
991
+ return routes
992
+ .get(messageFollowRouteKey(BigInt(context.objectGeneration), owner.nodeRidHex ?? (0, routing_id_1.encodeRoutingIdStorageHex)(owner.nodeRid), owner.nodeGeneration, owner.authorityOwnerGeneration, owner.ownerLeaseGeneration))
993
+ ?.get(owner.ownerId);
865
994
  }
866
995
  hasMessageFollowRouteForStaleRef(actorId, actorRef) {
867
- return [...this.messageFollowRoutes.values()].some((route) => route.targetActorRef.actorId === actorId &&
868
- actorRef.objectGeneration === route.oldGeneration &&
869
- (route.oldNodeRid === undefined ||
870
- (0, routing_id_1.routingIdsEqual)(actorRef.nodeRid, (0, actor_message_follow_context_1.messageFollowOwnerNodeRid)(route.sourceOwner))));
996
+ const routes = this.messageFollowRoutes.get(actorId);
997
+ if (routes === undefined)
998
+ return false;
999
+ for (const owners of routes.values()) {
1000
+ for (const route of owners.values()) {
1001
+ if (actorRef.objectGeneration === route.oldGeneration &&
1002
+ (route.oldNodeRid === undefined ||
1003
+ (0, routing_id_1.routingIdsEqual)(actorRef.nodeRid, (0, actor_message_follow_context_1.messageFollowOwnerNodeRid)(route.sourceOwner))))
1004
+ return true;
1005
+ }
1006
+ }
1007
+ return false;
871
1008
  }
872
- createInitialIngressContext(sourceOwner, generation, parts, request, deadlineUnixMs) {
873
- const operationId = (0, actor_message_follow_context_1.createMessageFollowId)();
1009
+ createInitialIngressContext(sourceOwner, generation, parts, request, deadlineUnixMs, origin) {
1010
+ let operationId;
1011
+ if (origin === undefined) {
1012
+ operationId = (0, actor_message_follow_context_1.createMessageFollowId)();
1013
+ }
1014
+ else {
1015
+ const bytes = Buffer.allocUnsafe(operation_identity_1.OPERATION_IDENTITY_BYTES);
1016
+ bytes.writeBigUInt64BE(BigInt.asUintN(stream_wire_1.UINT64_BYTES * 8, origin.originalOperation.high));
1017
+ bytes.writeBigUInt64BE(BigInt.asUintN(stream_wire_1.UINT64_BYTES * 8, origin.originalOperation.low), stream_wire_1.UINT64_BYTES);
1018
+ operationId = bytes.toString('hex');
1019
+ }
874
1020
  return Object.freeze({
875
1021
  operationId,
876
1022
  objectGeneration: generation.toString(),
@@ -878,7 +1024,11 @@ class ZLinkActorHandoffCoordinator {
878
1024
  targetOwner: sourceOwner,
879
1025
  deadlineUnixMs,
880
1026
  correlationId: request ? (0, actor_message_follow_context_1.createMessageFollowId)() : undefined,
881
- replyRouteId: request ? (0, actor_message_follow_context_1.createMessageFollowId)() : undefined,
1027
+ replyRouteId: request
1028
+ ? origin === undefined
1029
+ ? (0, actor_message_follow_context_1.createMessageFollowId)()
1030
+ : operationId
1031
+ : undefined,
882
1032
  request,
883
1033
  hopCount: 0,
884
1034
  visitedOwners: Object.freeze([(0, actor_message_follow_context_1.messageFollowOwnerFenceKey)(sourceOwner)]),
@@ -893,9 +1043,6 @@ class ZLinkActorHandoffCoordinator {
893
1043
  if (context.objectGeneration === '0' || context.request !== request) {
894
1044
  throw actorLocationStale(actorId);
895
1045
  }
896
- if (context.deadlineUnixMs !== undefined && Date.now() >= context.deadlineUnixMs) {
897
- throw actorDeadlineExceeded(actorId);
898
- }
899
1046
  (0, actor_message_follow_context_1.verifyActorMessageFollowPayload)(context, parts);
900
1047
  }
901
1048
  isKnownStaleRef(actorId, actor) {
@@ -928,7 +1075,8 @@ class ZLinkActorHandoffCoordinator {
928
1075
  return BigInt(context.targetOwner.authorityOwnerGeneration);
929
1076
  }
930
1077
  const current = this.options.currentOwnerFence?.(actorId);
931
- if (current !== undefined && current.nodeRid === String(actor.nodeRid)) {
1078
+ if (current !== undefined &&
1079
+ (0, routing_id_1.routingIdsEqual)((0, actor_message_follow_context_1.messageFollowOwnerNodeRid)(current), actor.nodeRid)) {
932
1080
  return BigInt(current.authorityOwnerGeneration);
933
1081
  }
934
1082
  return undefined;
@@ -1011,19 +1159,20 @@ class ZLinkActorHandoffCoordinator {
1011
1159
  await this.messageFollowRelayed(actorId, entry, packet, advanced);
1012
1160
  return undefined;
1013
1161
  }
1014
- const remainingMs = remainingRequestTime(actorId, packet.messageFollowContext.deadlineUnixMs);
1162
+ const timeoutMs = this.options.requestTimeoutMs ?? Registration_1.DEFAULT_REQUEST_TIMEOUT_MS;
1163
+ const relayDeadlineMs = performance.now() + timeoutMs;
1015
1164
  if (this.options.routedTransport.requestRawToSpot === undefined) {
1016
- const reply = await awaitBeforeDeadline(this.options.routedTransport.requestToSpot(target, payload, {
1165
+ const reply = await (0, request_deadline_1.waitRequestReply)(this.options.routedTransport.requestToSpot(target, payload, {
1017
1166
  packetName: actor_packet_relay_wire_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET,
1018
- timeoutMs: remainingMs ?? this.options.requestTimeoutMs
1019
- }), actorId, remainingMs);
1167
+ timeoutMs
1168
+ }), actorId, relayDeadlineMs);
1020
1169
  if (reply.ok === false) {
1021
1170
  throw actorRelayError(actorId, reply.errorKind, reply.error);
1022
1171
  }
1023
1172
  await this.messageFollowRelayed(actorId, entry, packet, advanced);
1024
1173
  return reply.response;
1025
1174
  }
1026
- const response = await awaitBeforeDeadline((0, actor_routed_json_request_1.requestRoutedJsonReply)(this.options.routedTransport, target, payload, { timeoutMs: remainingMs ?? this.options.requestTimeoutMs }, `Actor Message Follow raw request is not available for '${actorId}'.`, (parts) => {
1175
+ const response = await (0, request_deadline_1.waitRequestReply)((0, actor_routed_json_request_1.requestRoutedJsonReply)(this.options.routedTransport, target, payload, { timeoutMs }, `Actor Message Follow raw request is not available for '${actorId}'.`, (parts) => {
1027
1176
  if (parts.length === 0) {
1028
1177
  throw new Error(`Actor Message Follow reply was empty for '${actorId}'.`);
1029
1178
  }
@@ -1032,7 +1181,7 @@ class ZLinkActorHandoffCoordinator {
1032
1181
  throw actorRelayError(actorId, reply.errorKind, reply.error);
1033
1182
  }
1034
1183
  return reply.response;
1035
- }), actorId, remainingMs);
1184
+ }), actorId, relayDeadlineMs);
1036
1185
  await this.messageFollowRelayed(actorId, entry, packet, advanced);
1037
1186
  return response;
1038
1187
  }
@@ -1180,31 +1329,6 @@ function packetDeadlineUnixMs(parts) {
1180
1329
  return undefined;
1181
1330
  }
1182
1331
  }
1183
- function remainingRequestTime(actorId, deadlineUnixMs) {
1184
- if (deadlineUnixMs === undefined)
1185
- return undefined;
1186
- const remaining = deadlineUnixMs - Date.now();
1187
- if (remaining <= 0)
1188
- throw actorDeadlineExceeded(actorId);
1189
- return Math.max(1, Math.ceil(remaining));
1190
- }
1191
- async function awaitBeforeDeadline(operation, actorId, remainingMs) {
1192
- if (remainingMs === undefined)
1193
- return await operation;
1194
- let timer;
1195
- try {
1196
- return await Promise.race([
1197
- operation,
1198
- new Promise((_resolve, reject) => {
1199
- timer = setTimeout(() => reject(actorDeadlineExceeded(actorId)), remainingMs);
1200
- })
1201
- ]);
1202
- }
1203
- finally {
1204
- if (timer !== undefined)
1205
- clearTimeout(timer);
1206
- }
1207
- }
1208
1332
  async function waitForHandoffReplayStart(start, signal) {
1209
1333
  if (signal.aborted)
1210
1334
  throw signal.reason;
@@ -1220,8 +1344,8 @@ async function waitForHandoffReplayStart(start, signal) {
1220
1344
  signal.removeEventListener('abort', abort);
1221
1345
  }
1222
1346
  }
1223
- function messageFollowRouteKey(actorId, objectGeneration, sourceOwner) {
1224
- return `${actorId}\u0000${objectGeneration}\u0000${(0, actor_message_follow_context_1.messageFollowOwnerFenceKey)(sourceOwner)}`;
1347
+ function messageFollowRouteKey(objectGeneration, nodeRidHex, nodeGeneration, authorityOwnerGeneration, ownerLeaseGeneration) {
1348
+ return `${objectGeneration}\u0000${nodeRidHex}\u0000${nodeGeneration}\u0000${authorityOwnerGeneration}\u0000${ownerLeaseGeneration}`;
1225
1349
  }
1226
1350
  function actorRefKey(nodeRid, generation) {
1227
1351
  return `${(0, routing_id_1.encodeRoutingIdStorageHex)(nodeRid)}\u0000${generation}`;
@@ -1233,7 +1357,7 @@ function requestSourcesEqual(expected, actual) {
1233
1357
  return (expected.replyRouteId === actual.replyRouteId &&
1234
1358
  expected.ownerId === actual.ownerId &&
1235
1359
  expected.ownerLeaseGeneration === actual.ownerLeaseGeneration &&
1236
- expected.nodeRid === actual.nodeRid &&
1360
+ (0, routing_id_1.routingIdsEqual)((0, routing_id_1.decodeRoutingId)(expected.nodeRid, expected.nodeRidHex), (0, routing_id_1.decodeRoutingId)(actual.nodeRid, actual.nodeRidHex)) &&
1237
1361
  expected.nodeGeneration === actual.nodeGeneration &&
1238
1362
  /^[1-9][0-9]*$/.test(actual.ownerLeaseGeneration) &&
1239
1363
  /^[1-9][0-9]*$/.test(actual.nodeGeneration));
@@ -32,6 +32,8 @@ export interface ZLinkActorJoinRelocation {
32
32
  readonly deadlineAtMs?: number;
33
33
  readonly signal?: AbortSignal;
34
34
  }): Promise<{
35
+ /** Source-only terminal after relay readiness transferred public completion. */
36
+ readonly sourceCleanup?: () => Promise<void>;
35
37
  readonly actorRef: ZLinkBackendActorRef;
36
38
  readonly membershipEpoch: bigint;
37
39
  readonly spotGeneration: bigint;
@@ -248,6 +248,10 @@ class ZLinkLocalNativeActorJoin {
248
248
  admission.parts[0]?.close();
249
249
  throw error;
250
250
  }
251
+ if (relocated.sourceCleanup !== undefined) {
252
+ admission.parts[0]?.close();
253
+ return { accepted: false, sourceCleanup: relocated.sourceCleanup };
254
+ }
251
255
  state.setNativeActorRef(relocated.actorRef);
252
256
  if (entrySpot) {
253
257
  state.clearJoinedSpot();
@@ -14,8 +14,34 @@ class ZLinkActorSerialExecutor {
14
14
  this.scheduler = new serial_execution_queue_1.ZLinkSerialExecutionQueue((record) => this.runRecord(record), options, sharedOwner);
15
15
  }
16
16
  execute(operation, workOptions) {
17
+ const initial = (0, application_job_queue_scope_1.currentApplicationJobPermit)();
18
+ if (initial !== undefined &&
19
+ workOptions?.lane !== 'lifecycle' &&
20
+ this.scheduler.hasPendingDurableApplication) {
21
+ let prepared;
22
+ const cancel = () => {
23
+ prepared?.releaseAfterInternalProcessing();
24
+ prepared = undefined;
25
+ };
26
+ const terminal = this.scheduler.admitDurablePrefix(() => (0, application_job_queue_scope_1.runWithApplicationJobPermit)(prepared, () => (0, actor_execution_context_1.runZLinkActorExecution)(this.actorId, this.sourceSpotId, operation)), workOptions, undefined, {
27
+ prepare: async (signal) => {
28
+ if (initial.reacquire === undefined) {
29
+ throw new Error('Durable Actor ingress requires its host permit source.');
30
+ }
31
+ prepared = await initial.reacquire(signal);
32
+ if (signal.aborted) {
33
+ cancel();
34
+ throw signal.reason;
35
+ }
36
+ prepared.markApplicationQueued();
37
+ },
38
+ cancel
39
+ });
40
+ initial.releaseAfterInternalProcessing();
41
+ return terminal;
42
+ }
17
43
  const boundOperation = (0, application_job_queue_scope_1.bindApplicationJobPermit)(() => (0, actor_execution_context_1.runZLinkActorExecution)(this.actorId, this.sourceSpotId, operation));
18
- return (0, application_job_queue_scope_1.hasApplicationJobPermit)()
44
+ return initial !== undefined
19
45
  ? this.scheduler.submitPreAdmitted(boundOperation, workOptions)
20
46
  : this.scheduler.submit(boundOperation, workOptions);
21
47
  }
@@ -78,7 +78,9 @@ class ZLinkActorNativeJoinCoordinator {
78
78
  return this.withDeferredJoinFinalizer(actor, state, target, result, completionOperationId);
79
79
  }
80
80
  withDeferredJoinFinalizer(actor, state, target, result, operationId) {
81
- if (operationId === undefined || this.options.sourceTransfer === undefined)
81
+ if (result.sourceCleanup !== undefined ||
82
+ operationId === undefined ||
83
+ this.options.sourceTransfer === undefined)
82
84
  return result;
83
85
  return {
84
86
  ...result,
@@ -0,0 +1,4 @@
1
+ import { encodeFrameworkPayload } from '../messaging/payload-codec';
2
+ import { ZLinkStreamMessageKind } from '../streams/protocol';
3
+ /** Ordinary dispatch and relocation use the same typed Actor reply envelope. */
4
+ export declare function encodeActorReply(requestHeaderBytes: Uint8Array, kind: ZLinkStreamMessageKind.Response | ZLinkStreamMessageKind.Error, payload: unknown, serializers: Parameters<typeof encodeFrameworkPayload>[1], flowEnabled: boolean): readonly Buffer[];
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.encodeActorReply = encodeActorReply;
4
+ const payload_codec_1 = require("../messaging/payload-codec");
5
+ const protocol_1 = require("../streams/protocol");
6
+ /** Ordinary dispatch and relocation use the same typed Actor reply envelope. */
7
+ function encodeActorReply(requestHeaderBytes, kind, payload, serializers, flowEnabled) {
8
+ const requestHeader = (0, protocol_1.decodeStreamHeader)(requestHeaderBytes, flowEnabled);
9
+ const encoded = kind === protocol_1.ZLinkStreamMessageKind.Response
10
+ ? (0, payload_codec_1.encodeFrameworkPayload)(payload, serializers, requestHeader.name, 'reply')
11
+ : (0, payload_codec_1.encodeFrameworkPayload)(payload);
12
+ try {
13
+ const frame = (0, protocol_1.encodeStreamFrame)({
14
+ kind,
15
+ codec: (0, protocol_1.streamCodecForContentType)(encoded.contentType),
16
+ flags: protocol_1.ZLinkStreamHeaderFlags.None,
17
+ requestSeq: requestHeader.requestSeq,
18
+ name: '',
19
+ metadata: new Map(),
20
+ correlationId: requestHeader.correlationId,
21
+ flowId: requestHeader.flowId,
22
+ flowOrigin: requestHeader.flowOrigin
23
+ }, encoded.message.data());
24
+ return [Buffer.from(frame.buffer, frame.byteOffset, frame.byteLength)];
25
+ }
26
+ finally {
27
+ encoded.message.close();
28
+ }
29
+ }
@@ -8,6 +8,8 @@ import type { ZLinkActorTransferRegistry } from './actor-transfer-registry';
8
8
  import type { ZLinkRuntimeAdmissionGate } from '../admission';
9
9
  import type { ZLinkActivationAdmission } from '../activation-admission';
10
10
  export interface ZLinkActorJoinRuntimeResult<TReply> {
11
+ /** Relay-ready transferred completion; this continuation only releases source work. */
12
+ readonly sourceCleanup?: () => Promise<void>;
11
13
  readonly accepted: boolean;
12
14
  readonly actor?: import('../../contracts').ActorRef;
13
15
  readonly reply?: TReply;