@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
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZLinkSpotNodeRuntimeManager = void 0;
4
4
  exports.createFrameworkEntrySpotId = createFrameworkEntrySpotId;
5
+ exports.registrationAcceptsNewActor = registrationAcceptsNewActor;
5
6
  const disposal_1 = require("../disposal");
6
7
  const node_crypto_1 = require("node:crypto");
7
8
  const contracts_1 = require("../../contracts");
@@ -68,6 +69,9 @@ class ZLinkSpotNodeRuntimeManager {
68
69
  configureLocationAutoConnect(runtime, stores, options, events) {
69
70
  this.locationAutoConnect = (0, spot_node_autoconnect_1.createSpotNodeLocationAutoConnectContext)(runtime, stores, options, events);
70
71
  }
72
+ async requestPeerReconcile(meshName, peerRid) {
73
+ await Promise.all(this.autoConnectLoops.map((loop) => loop.requestPeerReconcile(meshName, peerRid)));
74
+ }
71
75
  async startLocationAutoConnect(signal) {
72
76
  const location = this.locationAutoConnect;
73
77
  if (location === undefined || this.autoConnectLoops.length > 0) {
@@ -82,6 +86,7 @@ class ZLinkSpotNodeRuntimeManager {
82
86
  const capability = (0, spot_node_autoconnect_1.spotNodeAutoConnectCapability)(spotNodeName, spotNode, node);
83
87
  if (capability === undefined)
84
88
  continue;
89
+ node.setRequestSourceAcceptance?.((nodeRid, nodeGeneration, nodeRidStorageHex, sourceSignal) => location.requestSources.accept(capability.local.meshName, nodeRid, nodeGeneration, nodeRidStorageHex, sourceSignal));
85
90
  const reconciler = new locations_1.ZLinkAutoConnectReconciler({
86
91
  local: capability.local,
87
92
  localRow: capability.localRow,
@@ -152,6 +157,22 @@ class ZLinkSpotNodeRuntimeManager {
152
157
  if (this.options.dispatchErrors !== undefined) {
153
158
  node.setDispatchErrorReporter?.(this.options.dispatchErrors, spotNodeName);
154
159
  }
160
+ // Session-Actor binding §4: the Session owner identity comes from the
161
+ // host's own descriptor or from a peer descriptor that passed the
162
+ // Location runtime §4.1 owner lease check.
163
+ node.setSessionOwnerDescriptors?.({
164
+ local: () => this.locationAutoConnect?.runtime.currentOwnerToken,
165
+ peer: async (peerRid, peerGeneration) => {
166
+ const location = this.locationAutoConnect;
167
+ if (location === undefined)
168
+ return undefined;
169
+ const descriptor = (await location.runtime.listLiveMeshNodes(spotNodeName)).find((candidate) => (0, routing_id_1.routingIdsEqual)(candidate.rid, peerRid) &&
170
+ candidate.lifecycleGeneration === peerGeneration);
171
+ return descriptor === undefined
172
+ ? undefined
173
+ : { ownerId: descriptor.ownerId, leaseGeneration: descriptor.leaseGeneration };
174
+ }
175
+ });
155
176
  node.setMailboxRecordDroppedHandler?.((record) => this.options.dispatchErrors?.report({
156
177
  surface: ZLinkDispatchOptions_1.ZLinkDispatchErrorSurface.RouteMeshChannel,
157
178
  messageKind: ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send,
@@ -257,7 +278,7 @@ class ZLinkSpotNodeRuntimeManager {
257
278
  this.meshNodes.delete(spotNodeName);
258
279
  completions.dispose(error);
259
280
  await pump?.dispose();
260
- node.close();
281
+ await node.close();
261
282
  throw error;
262
283
  }
263
284
  }
@@ -283,9 +304,8 @@ class ZLinkSpotNodeRuntimeManager {
283
304
  return;
284
305
  const ownerChanged = this.publishedOwnerToken !== undefined && !sameOwnerToken(this.publishedOwnerToken, owner);
285
306
  if (ownerChanged) {
286
- // A new owner token can refer to an empty or replaced Store. The cached
287
- // descriptor was written under the previous lease and must not force a
288
- // Renew against a row that no longer exists.
307
+ // A descriptor confirmed under the previous lease must not supply
308
+ // cached population data for a new owner token.
289
309
  this.publishedMeshNodeDescriptors.clear();
290
310
  }
291
311
  for (const [meshName, registration] of this.options.registration.spotNodes) {
@@ -301,7 +321,7 @@ class ZLinkSpotNodeRuntimeManager {
301
321
  const capabilities = [
302
322
  ...userSpots.map(([stableType, factory]) => objectCapability('user_spot', stableType, factory)),
303
323
  ...instanceSpots.map(([stableType, factory]) => objectCapability('instance_spot', stableType, factory)),
304
- ...actors.map(([stableType, factory]) => objectCapability('actor', stableType, factory))
324
+ ...actors.map(([stableType, factory]) => objectCapability('actor', stableType, factory, registrationAcceptsNewActor(registration, stableType)))
305
325
  ].sort((left, right) => {
306
326
  const kindOrder = left.objectKind.localeCompare(right.objectKind);
307
327
  return kindOrder !== 0 ? kindOrder : left.stableType.localeCompare(right.stableType);
@@ -316,9 +336,8 @@ class ZLinkSpotNodeRuntimeManager {
316
336
  // The raw MeshNode resolves port zero and applies AdvertiseHost once.
317
337
  // Discovery and RouteMesh hello must publish that same public identity.
318
338
  endpoint: status.localEndpoint,
319
- objectRole: effectiveObjectRole(registration),
339
+ ...this.localDescriptorFields(meshName, registration, state),
320
340
  entrySpotId: this.entrySpotId(meshName, registration),
321
- placementWeight: this.placementWeight(meshName),
322
341
  populationCapacity: {
323
342
  actors: {
324
343
  active: current?.populationCapacity.actors.active ?? 0,
@@ -348,13 +367,6 @@ class ZLinkSpotNodeRuntimeManager {
348
367
  active: 0,
349
368
  limit: registration.activationConcurrencyLimit ?? InternalDefaults_1.DEFAULT_ACTIVATION_CONCURRENCY_LIMIT
350
369
  },
351
- channelWeights: Object.fromEntries(this.serverChannels(meshName).map(([channelName, channel]) => [
352
- channelName,
353
- state === contracts_1.ZLinkFrameworkRuntimeState.Draining
354
- ? 0
355
- : this.effectiveChannelWeight(meshName, channelName, channel.weight ?? RegistrationBuilderPolicy_1.ZLINK_DEFAULT_PUBLIC_WEIGHT)
356
- ])),
357
- applicationVersion: this.options.registration.applicationVersion,
358
370
  maintenanceWave: this.options.registration.maintenanceWave,
359
371
  spotTypes: [
360
372
  ...userSpots.map(([stableType]) => stableType),
@@ -365,11 +377,12 @@ class ZLinkSpotNodeRuntimeManager {
365
377
  state,
366
378
  securityIdentity: 'default'
367
379
  };
368
- const result = await location.runtime.writeMeshNode(descriptor, ownerChanged
369
- ? Locations_1.ZLinkLocationWriteIntent.Renew
370
- : current === undefined
371
- ? Locations_1.ZLinkLocationWriteIntent.NewClaim
372
- : Locations_1.ZLinkLocationWriteIntent.Renew, signal);
380
+ // Revision is issued before submission: an unconfirmed Store write may
381
+ // already have applied, so the next publication must not reuse it.
382
+ this.descriptorRevisionByMesh.set(meshName, descriptor.descriptorRevision);
383
+ const result = await location.runtime.writeMeshNode(descriptor, previousRevision === 0n
384
+ ? Locations_1.ZLinkLocationWriteIntent.NewClaim
385
+ : Locations_1.ZLinkLocationWriteIntent.Renew, signal);
373
386
  if (result.status !== Locations_1.ZLinkLocationWriteStatus.Stored) {
374
387
  throw new configuration_1.ZLinkConfigurationException(`MeshNode '${meshName}' descriptor publication failed: ${result.status}.`);
375
388
  }
@@ -379,10 +392,22 @@ class ZLinkSpotNodeRuntimeManager {
379
392
  leaseGeneration: location.runtime.currentOwnerToken.leaseGeneration,
380
393
  updatedAt: result.updatedAt
381
394
  });
382
- this.descriptorRevisionByMesh.set(meshName, descriptor.descriptorRevision);
383
395
  }
384
396
  this.publishedOwnerToken = owner;
385
397
  }
398
+ localDescriptorFields(meshName, registration, state) {
399
+ return {
400
+ objectRole: effectiveObjectRole(registration),
401
+ placementWeight: this.placementWeight(meshName),
402
+ channelWeights: Object.fromEntries(this.serverChannels(meshName).map(([channelName, channel]) => [
403
+ channelName,
404
+ state === contracts_1.ZLinkFrameworkRuntimeState.Draining
405
+ ? 0
406
+ : this.effectiveChannelWeight(meshName, channelName, channel.weight ?? RegistrationBuilderPolicy_1.ZLINK_DEFAULT_PUBLIC_WEIGHT)
407
+ ])),
408
+ applicationVersion: this.options.registration.applicationVersion
409
+ };
410
+ }
386
411
  async reconcileAndPublishMeshNodeState(state, meshName, signal) {
387
412
  const location = this.locationAutoConnect;
388
413
  const node = this.meshNodes.get(meshName);
@@ -392,12 +417,15 @@ class ZLinkSpotNodeRuntimeManager {
392
417
  const owner = location.runtime.currentOwnerToken;
393
418
  if (owner === undefined)
394
419
  return;
395
- const current = (await location.runtime.listLiveMeshNodes(meshName, signal)).find((descriptor) => String(descriptor.rid) === String(status.routingId) &&
420
+ const current = (await location.runtime.listLiveMeshNodes(meshName, signal)).find((descriptor) => (0, routing_id_1.routingIdsEqual)(descriptor.rid, status.routingId) &&
396
421
  descriptor.lifecycleGeneration === status.lifecycleGeneration &&
397
422
  descriptor.ownerId === owner.ownerId &&
398
423
  descriptor.leaseGeneration === owner.leaseGeneration);
399
424
  if (current !== undefined) {
400
- this.publishedMeshNodeDescriptors.set(meshName, current);
425
+ this.publishedMeshNodeDescriptors.set(meshName, {
426
+ ...current,
427
+ ...this.localDescriptorFields(meshName, this.options.registration.spotNodes.get(meshName), state)
428
+ });
401
429
  this.descriptorRevisionByMesh.set(meshName, maxBigInt(this.descriptorRevisionByMesh.get(meshName) ?? 0n, current.descriptorRevision));
402
430
  this.publishedOwnerToken = owner;
403
431
  }
@@ -583,11 +611,13 @@ class ZLinkSpotNodeRuntimeManager {
583
611
  };
584
612
  await settle(publishers.map(async (publisher) => publisher.close()));
585
613
  await settle(autoConnectLoops.map((loop) => loop.prepareTransportShutdown()));
586
- await settle(entryActivations.reverse().map((activation) => activation.dispose(deadline)));
587
- await settle(meshPumps.reverse().map((pump) => pump.dispose()));
614
+ await settle(entryActivations
615
+ .reverse()
616
+ .map((activation) => (0, abort_1.awaitWithAbort)(activation.dispose(deadline), signal)));
617
+ await settle(meshPumps.reverse().map((pump) => pump.dispose(signal)));
588
618
  await settle(meshNodes.reverse().map(async (node) => {
589
- node.shutdown(DEFAULT_SPOT_NODE_SHUTDOWN_TIMEOUT_MS);
590
- node.close();
619
+ await node.shutdown(DEFAULT_SPOT_NODE_SHUTDOWN_TIMEOUT_MS);
620
+ await node.close();
591
621
  }));
592
622
  for (const completions of meshCompletions) {
593
623
  completions.dispose();
@@ -604,26 +634,37 @@ class ZLinkSpotNodeRuntimeManager {
604
634
  this.meshNodes.clear();
605
635
  this.meshCompletions.clear();
606
636
  }
607
- async dispatchMeshRecord(meshName, owner, record) {
637
+ /**
638
+ * Node and Channel records go straight to the framework dispatcher in the
639
+ * pump's turn. Only Spot and Actor records addressed to the Entry Spot wait
640
+ * for its activation first.
641
+ */
642
+ dispatchMeshRecord(meshName, owner, record) {
643
+ if ((record.kind === service_runtime_contracts_1.ReceiveKind.ActorSend ||
644
+ record.kind === service_runtime_contracts_1.ReceiveKind.ActorRequest ||
645
+ record.kind === service_runtime_contracts_1.ReceiveKind.SpotSend ||
646
+ record.kind === service_runtime_contracts_1.ReceiveKind.SpotRequest ||
647
+ record.kind === service_runtime_contracts_1.ReceiveKind.SpotMulticast) &&
648
+ this.targetsEntrySpot(meshName, owner)) {
649
+ return this.ensureEntryActivation(meshName).then(() => this.dispatchFrameworkRecord(meshName, owner, record));
650
+ }
651
+ return this.dispatchFrameworkRecord(meshName, owner, record);
652
+ }
653
+ targetsEntrySpot(meshName, owner) {
654
+ if (owner.spotId === null)
655
+ return true;
608
656
  const node = this.meshNodes.get(meshName);
609
- const targetsEntrySpot = owner.spotId === null ||
610
- (node !== undefined &&
611
- (0, routing_id_1.routingIdsEqual)(owner.spotId, String(node.status().routingId)));
612
- if (targetsEntrySpot &&
613
- (record.kind === service_runtime_contracts_1.ReceiveKind.ActorSend ||
614
- record.kind === service_runtime_contracts_1.ReceiveKind.ActorRequest ||
615
- record.kind === service_runtime_contracts_1.ReceiveKind.SpotSend ||
616
- record.kind === service_runtime_contracts_1.ReceiveKind.SpotRequest ||
617
- record.kind === service_runtime_contracts_1.ReceiveKind.SpotMulticast)) {
618
- await this.ensureEntryActivation(meshName);
619
- }
657
+ return (node !== undefined &&
658
+ (0, routing_id_1.routingIdsEqual)(owner.spotId, String(node.status().routingId)));
659
+ }
660
+ dispatchFrameworkRecord(meshName, owner, record) {
620
661
  const dispatcher = this.options.meshRecordDispatcher;
621
662
  if (dispatcher === undefined) {
622
- throw new configuration_1.ZLinkConfigurationException(`MeshNode '${meshName}' received a record before its framework dispatcher was registered.`);
663
+ return Promise.reject(new configuration_1.ZLinkConfigurationException(`MeshNode '${meshName}' received a record before its framework dispatcher was registered.`));
623
664
  }
624
- await dispatcher(meshName, owner, record);
665
+ return dispatcher(meshName, owner, record);
625
666
  }
626
- async dispatchEntrySpotRecord(meshName, owner, record) {
667
+ async dispatchEntrySpotRecord(meshName, owner, record, admit) {
627
668
  if (record.kind !== service_runtime_contracts_1.ReceiveKind.SpotSend &&
628
669
  record.kind !== service_runtime_contracts_1.ReceiveKind.SpotRequest &&
629
670
  record.kind !== service_runtime_contracts_1.ReceiveKind.SpotMulticast) {
@@ -638,7 +679,8 @@ class ZLinkSpotNodeRuntimeManager {
638
679
  if (record.topic === null || record.topic.length === 0) {
639
680
  throw new configuration_1.ZLinkConfigurationException('MeshNode Entry Spot multicast record is missing its topic.');
640
681
  }
641
- await activation.dispatchSubscriptionRecord(record.topic, record.parts, record.sourceNodeRid);
682
+ const dispatch = () => activation.dispatchSubscriptionRecord(record.topic, record.parts, record.sourceNodeRid);
683
+ await (admit === undefined ? dispatch() : admit(dispatch));
642
684
  return true;
643
685
  }
644
686
  const envelope = (0, channel_envelope_1.decodeChannelEnvelope)(record.parts, undefined, this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true);
@@ -648,15 +690,20 @@ class ZLinkSpotNodeRuntimeManager {
648
690
  channelName: envelope.header.channelName,
649
691
  contentType: envelope.header.contentType
650
692
  };
651
- if (record.kind === service_runtime_contracts_1.ReceiveKind.SpotSend) {
652
- await activation.dispatchPacketEncoded(envelope.packetName, decodePayload, context, false);
653
- return true;
654
- }
655
693
  try {
656
- const response = await activation.dispatchPacketEncoded(envelope.packetName, decodePayload, context, true);
657
- requireEntrySpotReply(record.reply((0, channel_envelope_1.encodeChannelReplyParts)(envelope.header, response, codecs)));
694
+ const dispatch = async () => {
695
+ if (record.kind === service_runtime_contracts_1.ReceiveKind.SpotSend) {
696
+ await activation.dispatchPacketEncoded(envelope.packetName, decodePayload, context, false);
697
+ return;
698
+ }
699
+ const response = await activation.dispatchPacketEncoded(envelope.packetName, decodePayload, context, true);
700
+ requireEntrySpotReply(record.reply((0, channel_envelope_1.encodeChannelReplyParts)(envelope.header, response, codecs)));
701
+ };
702
+ await (admit === undefined ? dispatch() : admit(dispatch));
658
703
  }
659
704
  catch (error) {
705
+ if (record.kind !== service_runtime_contracts_1.ReceiveKind.SpotRequest)
706
+ throw error;
660
707
  requireEntrySpotReply(record.reply((0, channel_envelope_1.encodeChannelErrorReplyParts)(envelope.header, error)));
661
708
  }
662
709
  return true;
@@ -784,6 +831,13 @@ class ZLinkSpotNodeRuntimeManager {
784
831
  }
785
832
  await activation.commitServiceActorJoin(actor, handoffBacklog);
786
833
  }
834
+ admitEntryActorPacketPrefix(meshName, actorId, records) {
835
+ const activation = this.entryActivations.get(meshName);
836
+ if (activation === undefined) {
837
+ throw new configuration_1.ZLinkConfigurationException(`Entry Spot Actor '${actorId}' has no activation for MeshNode '${meshName}'.`);
838
+ }
839
+ return activation.admitActorPacketPrefix(actorId, records);
840
+ }
787
841
  executeEntryActor(meshName, actorId, operation) {
788
842
  const activation = this.entryActivations.get(meshName);
789
843
  if (activation === undefined) {
@@ -910,16 +964,27 @@ function effectiveObjectRole(registration) {
910
964
  ? contracts_1.ZLinkObjectRole.Server
911
965
  : contracts_1.ZLinkObjectRole.None;
912
966
  }
913
- function objectCapability(objectKind, stableType, factory) {
967
+ function objectCapability(objectKind, stableType, factory, entryAccepted = false) {
914
968
  const policy = factory.relocation?.kind ?? 'disabled';
915
969
  return {
916
970
  objectKind,
917
971
  stableType,
918
972
  policy,
919
973
  hasSnapshotAdapter: policy === 'snapshot',
920
- limit: objectKind === 'actor' ? 0 : (factory.options?.stableTypeLimit ?? 0)
974
+ limit: objectKind === 'actor' ? 0 : (factory.options?.stableTypeLimit ?? 0),
975
+ entryAccepted
921
976
  };
922
977
  }
978
+ /**
979
+ * The one decision for creating a new Actor on this node (Actor model §6.3): the node registered
980
+ * an Entry Spot type that accepts the Actor type and an Actor factory for it. Publication and the
981
+ * target refusal both read it.
982
+ */
983
+ function registrationAcceptsNewActor(registration, stableType) {
984
+ return (registration.entrySpotType !== undefined &&
985
+ registration.entrySpotActorType === stableType &&
986
+ effectiveActorRegistrations(registration).some(([type]) => type === stableType));
987
+ }
923
988
  function aggregatePlacementCapacity(actorLimit, spotLimit) {
924
989
  const unlimited = RegistrationBuilderPolicy_1.ZLINK_MAX_CAPACITY;
925
990
  const actors = actorLimit === 0 ? unlimited : actorLimit;
@@ -162,7 +162,7 @@ function createAddressedSpotRequestCall(serial, transport, spotId, request, sour
162
162
  markSubmitted(options);
163
163
  rejectSameSpotAsyncRequest(serial, spotId, 'yield');
164
164
  const pending = begin(signal);
165
- return turn.yieldPromise(pending);
165
+ return turn.yieldFrameworkPromise(pending);
166
166
  }
167
167
  };
168
168
  }
@@ -277,7 +277,7 @@ function wrapRequestCall(serial, inner) {
277
277
  yield(signal) {
278
278
  const turn = (0, execution_1.requireZLinkYieldTurn)();
279
279
  const pending = begin(signal);
280
- return turn.yieldPromise(pending);
280
+ return turn.yieldFrameworkPromise(pending);
281
281
  }
282
282
  };
283
283
  }
@@ -366,7 +366,7 @@ function wrapRoutedSpotRequestCall(serial, transport, spot, request, spotRouterC
366
366
  const turn = (0, execution_1.requireZLinkYieldTurn)();
367
367
  rejectSameSpotAsyncRequest(serial, spot.spotId, 'yield');
368
368
  const pending = begin(signal);
369
- return turn.yieldPromise(pending);
369
+ return turn.yieldFrameworkPromise(pending);
370
370
  }
371
371
  };
372
372
  }
@@ -85,7 +85,11 @@ function decodeHandoffBacklog(value) {
85
85
  BigInt(source.ownerLeaseGeneration) <= 0n ||
86
86
  source.nodeRid.length === 0 ||
87
87
  BigInt(source.nodeGeneration) <= 0n ||
88
- source.replyRouteId !== messageFollowContext.replyRouteId)) ||
88
+ source.replyRouteId !==
89
+ (packet.messageFollowOrigin !== undefined &&
90
+ (0, routing_id_1.routingIdsEqual)((0, routing_id_1.decodeRoutingId)(source.nodeRid, source.nodeRidHex), packet.messageFollowOrigin.sourceNodeRid)
91
+ ? packet.messageFollowOrigin.originalReplyRouteId.toString()
92
+ : messageFollowContext.replyRouteId))) ||
89
93
  (!packet.returnResponse && source !== undefined)) {
90
94
  throw new Error('Remote actor handoff request source fence is invalid.');
91
95
  }
@@ -33,7 +33,6 @@ export interface ZLinkSpotActorTransferRuntime {
33
33
  commitRoutedActor(actor: ZLinkActor, spotId: RoutingId, spot: ZLinkSpot): void;
34
34
  clearRoutedActor(actor: ZLinkActor): void;
35
35
  rollbackRoutedActor(actor: ZLinkActor, signal?: AbortSignal): Promise<void>;
36
- notifyCoreSourceLeave(actor: ZLinkActor, callback: () => Promise<void>): Promise<void>;
37
36
  actorEntryNodeRid(actor: ZLinkActor): RoutingId | undefined;
38
37
  }
39
38
  export interface ZLinkSpotBoundSessionRuntime {
@@ -1,7 +1,10 @@
1
1
  import { ZLinkUserSpotExecutionMode } from '../../contracts';
2
+ import type { ZLinkActorHandoffDispatch, ZLinkActorHandoffPrefixAdmission, ZLinkActorHandoffPrefixRecord } from '../actors/actor-handoff';
2
3
  import type { ZLinkExecutionBarrier } from '../execution';
3
4
  import type { ZLinkSerialSchedulerOptions, ZLinkSerialWorkOptions } from '../execution/serial-execution-queue';
4
5
  import { ZLinkSpotSerialTurnExecutor } from './spot-serial-turn-executor';
6
+ export type ZLinkSpotPreparationCompletion = 'publication' | 'first-terminal';
7
+ export type ZLinkActorPacketTurnDispatch = (serial: ZLinkSpotSerialTurnExecutor, ...args: Parameters<ZLinkActorHandoffDispatch>) => ReturnType<ZLinkActorHandoffDispatch>;
5
8
  /**
6
9
  * Owns every application serial unit that belongs to one Spot activation.
7
10
  *
@@ -19,11 +22,18 @@ export declare class ZLinkSpotSerialExecutor {
19
22
  private executionBarrier;
20
23
  private closing;
21
24
  private closePromise;
25
+ private preparation?;
22
26
  constructor(spotSerial: ZLinkSpotSerialTurnExecutor, executionMode: ZLinkUserSpotExecutionMode, sourceSpotId: unknown, actorOptions?: ZLinkSerialSchedulerOptions | undefined);
23
27
  setExecutionBarrier(barrier: ZLinkExecutionBarrier): void;
28
+ get isPreparing(): boolean;
29
+ beginPreparation(kind?: 'activation' | 'relocation'): void;
30
+ openPreparationAdmission(): void;
31
+ finishPreparation(terminal?: () => Promise<void>): Promise<void>;
24
32
  executeSpot<T>(operation: () => Promise<T> | T, workOptions?: ZLinkSerialWorkOptions): Promise<T>;
25
33
  executeActor<T>(actorId: string, operation: (serial: ZLinkSpotSerialTurnExecutor) => Promise<T> | T, workOptions?: ZLinkSerialWorkOptions): Promise<T>;
26
34
  executeTimer<T>(timerName: string, operation: () => Promise<T> | T, workOptions?: ZLinkSerialWorkOptions): Promise<T>;
35
+ /** Admits held packets through the same Actor FIFO as ordinary ingress. */
36
+ admitActorPacketPrefix(actorId: string, records: readonly ZLinkActorHandoffPrefixRecord[], dispatch: ZLinkActorPacketTurnDispatch): ZLinkActorHandoffPrefixAdmission;
27
37
  isTimerExecuting(timerName: string): boolean;
28
38
  executeLifecycle<T>(operation: () => Promise<T> | T, workOptions?: ZLinkSerialWorkOptions): Promise<T>;
29
39
  terminateActor(actorId: string, terminal: () => Promise<void>): Promise<void>;
@@ -21,6 +21,7 @@ class ZLinkSpotSerialExecutor {
21
21
  executionBarrier;
22
22
  closing = false;
23
23
  closePromise;
24
+ preparation;
24
25
  constructor(spotSerial, executionMode, sourceSpotId, actorOptions) {
25
26
  this.spotSerial = spotSerial;
26
27
  this.executionMode = executionMode;
@@ -38,6 +39,49 @@ class ZLinkSpotSerialExecutor {
38
39
  for (const serial of this.timerSerials.values())
39
40
  serial.setExecutionBarrier(barrier);
40
41
  }
42
+ get isPreparing() {
43
+ return this.preparation !== undefined;
44
+ }
45
+ beginPreparation(kind = 'activation') {
46
+ if (this.preparation !== undefined || this.executionBarrier === undefined)
47
+ throw new Error('Activation preparation requires one unowned execution barrier.');
48
+ const barrier = this.executionBarrier;
49
+ const seal = barrier.seal(kind);
50
+ let complete;
51
+ const terminal = new Promise((resolve) => {
52
+ complete = resolve;
53
+ });
54
+ // The staging seal itself owns target preparation. No normal preparation
55
+ // item is admitted in addition to this lifecycle owner.
56
+ const execution = this.spotSerial.executeControlLifecycleOperation(async () => {
57
+ const finish = await terminal;
58
+ await finish?.();
59
+ }, {
60
+ canExecuteApplication: (record) => record.context === undefined || !barrier.isCurrent(seal)
61
+ });
62
+ this.preparation = { seal, complete, execution };
63
+ }
64
+ openPreparationAdmission() {
65
+ if (this.preparation !== undefined)
66
+ this.executionBarrier.abort(this.preparation.seal);
67
+ }
68
+ async finishPreparation(terminal) {
69
+ const preparation = this.preparation;
70
+ if (preparation === undefined) {
71
+ await terminal?.();
72
+ return;
73
+ }
74
+ preparation.complete(terminal);
75
+ try {
76
+ await preparation.execution;
77
+ }
78
+ finally {
79
+ if (this.preparation === preparation) {
80
+ this.executionBarrier.abort(preparation.seal);
81
+ this.preparation = undefined;
82
+ }
83
+ }
84
+ }
41
85
  executeSpot(operation, workOptions) {
42
86
  return this.spotSerial.execute(operation, workOptions);
43
87
  }
@@ -45,17 +89,26 @@ class ZLinkSpotSerialExecutor {
45
89
  const serial = this.actorSerial(actorId);
46
90
  return this.actorExecutor(actorId).execute(() => operation(serial), workOptions);
47
91
  }
48
- /** @internal Restores a durable Actor FIFO prefix without starting it. */
49
- admitActorDurablePrefix(actorId, records) {
92
+ executeTimer(timerName, operation, workOptions) {
93
+ return this.timerSerial(timerName).post(operation, workOptions);
94
+ }
95
+ /** Admits held packets through the same Actor FIFO as ordinary ingress. */
96
+ admitActorPacketPrefix(actorId, records, dispatch) {
50
97
  const serial = this.actorSerial(actorId);
51
- return this.actorExecutor(actorId).admitDurablePrefix(records.map((record) => ({
52
- operation: (executeChild) => record.operation((child) => executeChild(() => child(serial))),
98
+ const terminals = this.actorExecutor(actorId).admitDurablePrefix(records.map((record) => ({
99
+ operation: (executeChild) => record.drain((parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef) => executeChild(() => dispatch(serial, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef))),
53
100
  preparation: record.preparation,
54
- workOptions: record.workOptions
101
+ workOptions: { payloadBytes: record.payloadBytes, onWithdrawable: record.onWithdrawable }
55
102
  })));
56
- }
57
- executeTimer(timerName, operation, workOptions) {
58
- return this.timerSerial(timerName).execute(operation, workOptions);
103
+ const terminal = Promise.allSettled(terminals).then((outcomes) => {
104
+ const errors = outcomes.flatMap((outcome) => outcome.status === 'rejected' ? [outcome.reason] : []);
105
+ if (errors.length === 1)
106
+ throw errors[0];
107
+ if (errors.length > 1) {
108
+ throw new AggregateError(errors, `Actor '${actorId}' durable prefix replay failed.`);
109
+ }
110
+ });
111
+ return { terminal };
59
112
  }
60
113
  isTimerExecuting(timerName) {
61
114
  if (this.executionMode === contracts_1.ZLinkUserSpotExecutionMode.SpotWide) {
@@ -94,7 +94,7 @@ class ZLinkSpotSerialTurnExecutor {
94
94
  * this so they never run inline inside another callback's turn.
95
95
  */
96
96
  post(operation, workOptions) {
97
- return this.enqueueApplicationTurn(operation, workOptions);
97
+ return this.enqueueApplicationTurn(operation, workOptions, undefined, true);
98
98
  }
99
99
  /**
100
100
  * Queues a one-way turn in serial order. Handler completion is reported
@@ -181,11 +181,22 @@ class ZLinkSpotSerialTurnExecutor {
181
181
  visitPendingApplication(visitor) {
182
182
  this.scheduler.visitPendingApplication(visitor);
183
183
  }
184
- async enqueueApplicationTurn(operation, workOptions = {}, replay) {
184
+ async enqueueApplicationTurn(operation, workOptions = {}, replay, retainWhilePreparing = false) {
185
185
  this.lastActivityAtMs = performance.now();
186
186
  let barrierClaim;
187
187
  try {
188
188
  const entry = this.executionBarrier?.enter();
189
+ if (entry instanceof Promise &&
190
+ retainWhilePreparing &&
191
+ this.scheduler.retainsApplicationForLifecycle) {
192
+ try {
193
+ return await this.submitQueuedTurn(operation, workOptions, entry);
194
+ }
195
+ catch (error) {
196
+ (await entry).release();
197
+ throw error;
198
+ }
199
+ }
189
200
  barrierClaim = entry instanceof Promise ? await entry : entry;
190
201
  const refusal = this.applicationAdmissionRefusal(replay !== undefined);
191
202
  if (refusal !== undefined)
@@ -224,6 +235,12 @@ class ZLinkSpotSerialTurnExecutor {
224
235
  : this.scheduler.submit(boundOperation, options, barrierClaim);
225
236
  }
226
237
  runQueuedRecord(record) {
238
+ if (record.context instanceof Promise) {
239
+ return record.context.then((claim) => {
240
+ Object.assign(record, { context: claim });
241
+ return this.runQueuedRecord(record);
242
+ });
243
+ }
227
244
  const context = record.context;
228
245
  if (context?.replay !== undefined && record.operation === context.replay) {
229
246
  context.release();
@@ -130,7 +130,7 @@ class ZLinkSpotSubscriptionDispatch {
130
130
  const subSource = message.routingId === null ? undefined : String(message.routingId);
131
131
  const inboundFlow = (0, flow_context_1.createInboundFlow)(envelope.header.flowId, envelope.header.flowOrigin, this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true, undefined);
132
132
  try {
133
- await this.options.serial.execute(() => (0, flow_context_1.runWithFlow)(inboundFlow, async () => {
133
+ await this.options.serial.post(() => (0, flow_context_1.runWithFlow)(inboundFlow, async () => {
134
134
  // Payload deserialization belongs to the Spot serial turn. Queue
135
135
  // admission and execution authority therefore precede this work.
136
136
  const event = (0, channel_envelope_1.decodeChannelPayload)(envelope, this.channelCodecs());