@zlink-systems/framework 0.29.1 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/LICENSE +150 -68
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
  4. package/dist/contracts/Channels/Calls.d.ts +2 -1
  5. package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  7. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  8. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  9. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  10. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  11. package/dist/contracts/Configuration/index.d.ts +1 -1
  12. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  13. package/dist/contracts/Handlers/Attributes.js +7 -11
  14. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  15. package/dist/contracts/Handlers/JsonContract.js +4 -153
  16. package/dist/contracts/Spots/Contracts.d.ts +2 -1
  17. package/dist/internal.d.ts +1 -0
  18. package/dist/internal.js +3 -1
  19. package/dist/nest-integration.d.ts +1 -1
  20. package/dist/nest-integration.js +2 -1
  21. package/dist/runtime/actors/actor-client.d.ts +1 -1
  22. package/dist/runtime/actors/actor-client.js +14 -12
  23. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  24. package/dist/runtime/actors/actor-handoff.js +15 -7
  25. package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
  26. package/dist/runtime/actors/actor-local-native-join.js +9 -12
  27. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  28. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  29. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  30. package/dist/runtime/actors/index.d.ts +2 -1
  31. package/dist/runtime/actors/index.js +18 -6
  32. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  33. package/dist/runtime/admission.d.ts +1 -1
  34. package/dist/runtime/admission.js +15 -5
  35. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +9 -9
  36. package/dist/runtime/application-jobs/application-ingress-record-owner.js +45 -23
  37. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +5 -2
  38. package/dist/runtime/application-jobs/application-job-queue-scope.js +41 -21
  39. package/dist/runtime/application-jobs/contracts.d.ts +15 -2
  40. package/dist/runtime/backend/contracts/index.d.ts +27 -27
  41. package/dist/runtime/backend/mesh-completion-table.d.ts +15 -5
  42. package/dist/runtime/backend/mesh-completion-table.js +160 -50
  43. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
  44. package/dist/runtime/backend/mesh-dispatch-pump.js +53 -36
  45. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  46. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  47. package/dist/runtime/backend/node/node-backend-adapter-support.js +33 -31
  48. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  49. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  50. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  51. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  52. package/dist/runtime/backend/node/node-raw-binding-port.js +50 -25
  53. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +22 -16
  54. package/dist/runtime/backend/node/node-raw-mesh-backend.js +133 -149
  55. package/dist/runtime/backend/node/node-socket-backend-adapter.js +15 -10
  56. package/dist/runtime/backend/raw-binding-port.d.ts +10 -3
  57. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  58. package/dist/runtime/backend/runtime-message.js +5 -0
  59. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  60. package/dist/runtime/backend/runtime-values.js +2 -1
  61. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  62. package/dist/runtime/channels/channel-clients.js +58 -21
  63. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
  64. package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
  65. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  66. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  67. package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
  68. package/dist/runtime/channels/channel-dispatchers.js +27 -26
  69. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  70. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  71. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  72. package/dist/runtime/channels/channel-envelope.js +83 -8
  73. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  74. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  75. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  76. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  77. package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
  78. package/dist/runtime/channels/channel-runtime-manager.js +12 -12
  79. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  80. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  81. package/dist/runtime/channels/channel-transports.d.ts +18 -15
  82. package/dist/runtime/channels/channel-transports.js +48 -31
  83. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  84. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  85. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  86. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  87. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  88. package/dist/runtime/channels/source-spot-router.js +4 -4
  89. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  90. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  91. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  92. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  93. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  94. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  95. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  96. package/dist/runtime/diagnostics/message-flow.js +3 -3
  97. package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
  98. package/dist/runtime/execution/serial-execution-queue.js +1 -0
  99. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  100. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  101. package/dist/runtime/foundation/durable-service-request.js +98 -0
  102. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  103. package/dist/runtime/foundation/operation-identity.js +5 -1
  104. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +37 -6
  105. package/dist/runtime/foundation/raw-service-mesh-runtime.js +473 -220
  106. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  107. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  108. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  109. package/dist/runtime/foundation/service-mailbox.js +2 -1
  110. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
  111. package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
  112. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  113. package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
  114. package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
  115. package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -9
  116. package/dist/runtime/foundation/service-stateful-runtime.js +78 -126
  117. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -7
  118. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  119. package/dist/runtime/foundation/service-topology-registry.d.ts +16 -4
  120. package/dist/runtime/foundation/service-topology-registry.js +69 -30
  121. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
  122. package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
  123. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  124. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  125. package/dist/runtime/host/actor-packet-relay.js +7 -7
  126. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  127. package/dist/runtime/host/application-job-queue.d.ts +28 -9
  128. package/dist/runtime/host/application-job-queue.js +214 -50
  129. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  130. package/dist/runtime/host/entry-actor-runtime.js +4 -1
  131. package/dist/runtime/host/index.d.ts +7 -1
  132. package/dist/runtime/host/index.js +154 -126
  133. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  134. package/dist/runtime/host/instance-activation-authority.js +89 -25
  135. package/dist/runtime/host/remote-bound-session-relay.js +2 -18
  136. package/dist/runtime/host/route-mesh-runtime.js +1 -1
  137. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  138. package/dist/runtime/host/service-relocation-control.js +10 -4
  139. package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
  140. package/dist/runtime/host/service-relocation-host-runtime.js +215 -243
  141. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  142. package/dist/runtime/host/spot-address-transport.js +28 -14
  143. package/dist/runtime/host/spot-runtime-options-factory.js +3 -2
  144. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  145. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  146. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  147. package/dist/runtime/locations/actor-location-claims.js +34 -19
  148. package/dist/runtime/locations/domain-store-contract.d.ts +2 -2
  149. package/dist/runtime/locations/in-memory-authority-store.d.ts +4 -2
  150. package/dist/runtime/locations/in-memory-authority-store.js +80 -8
  151. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  152. package/dist/runtime/locations/in-memory-location-store.js +19 -3
  153. package/dist/runtime/locations/internal-location-contracts.d.ts +3 -0
  154. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  155. package/dist/runtime/locations/lifecycle.js +2 -5
  156. package/dist/runtime/locations/location-store-repository.d.ts +3 -2
  157. package/dist/runtime/locations/location-store-repository.js +165 -22
  158. package/dist/runtime/locations/resolvers.d.ts +2 -1
  159. package/dist/runtime/locations/resolvers.js +10 -1
  160. package/dist/runtime/locations/runtime.d.ts +1 -1
  161. package/dist/runtime/locations/runtime.js +24 -23
  162. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  163. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  164. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  165. package/dist/runtime/messaging/packet-name.js +8 -24
  166. package/dist/runtime/messaging/request-result.d.ts +2 -0
  167. package/dist/runtime/messaging/request-result.js +54 -0
  168. package/dist/runtime/messaging/submission-result.d.ts +2 -1
  169. package/dist/runtime/messaging/submission-result.js +7 -4
  170. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
  171. package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
  172. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
  173. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
  174. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +9 -2
  175. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
  176. package/dist/runtime/spots/index.d.ts +7 -3
  177. package/dist/runtime/spots/index.js +23 -16
  178. package/dist/runtime/spots/spot-activation.d.ts +3 -1
  179. package/dist/runtime/spots/spot-activation.js +21 -12
  180. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  181. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  182. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  183. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  184. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  185. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  186. package/dist/runtime/spots/spot-entry-activation.js +9 -3
  187. package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
  188. package/dist/runtime/spots/spot-handler-registry.js +18 -8
  189. package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
  190. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +2 -1
  191. package/dist/runtime/spots/spot-node-runtime-manager.js +4 -11
  192. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  193. package/dist/runtime/spots/spot-outbound.js +24 -15
  194. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  195. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  196. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  197. package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -1
  198. package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
  199. package/dist/runtime/spots/spot-timer.js +1 -0
  200. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  201. package/dist/runtime/streams/stream-session-runtime.js +14 -28
  202. package/package.json +3 -3
  203. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  204. package/src/contracts/Channels/Calls.ts +2 -1
  205. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  206. package/src/contracts/Configuration/Builders.ts +1 -2
  207. package/src/contracts/Configuration/Configs.ts +0 -6
  208. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  209. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  210. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  211. package/src/contracts/Configuration/index.ts +1 -6
  212. package/src/contracts/Handlers/Attributes.ts +14 -21
  213. package/src/contracts/Handlers/JsonContract.ts +8 -216
  214. package/src/contracts/Spots/Contracts.ts +2 -1
  215. package/src/internal.ts +1 -0
  216. package/src/nest-integration.ts +1 -0
  217. package/src/runtime/actors/actor-client.ts +40 -16
  218. package/src/runtime/actors/actor-handoff.ts +22 -8
  219. package/src/runtime/actors/actor-join-relocation.ts +1 -0
  220. package/src/runtime/actors/actor-local-native-join.ts +17 -26
  221. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  222. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  223. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  224. package/src/runtime/actors/index.ts +19 -5
  225. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  226. package/src/runtime/admission.ts +18 -5
  227. package/src/runtime/application-jobs/application-ingress-record-owner.ts +53 -27
  228. package/src/runtime/application-jobs/application-job-queue-scope.ts +56 -22
  229. package/src/runtime/application-jobs/contracts.ts +28 -2
  230. package/src/runtime/backend/contracts/index.ts +63 -32
  231. package/src/runtime/backend/mesh-completion-table.ts +175 -59
  232. package/src/runtime/backend/mesh-dispatch-pump.ts +59 -32
  233. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  234. package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -31
  235. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  236. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  237. package/src/runtime/backend/node/node-raw-binding-port.ts +73 -37
  238. package/src/runtime/backend/node/node-raw-mesh-backend.ts +209 -176
  239. package/src/runtime/backend/node/node-socket-backend-adapter.ts +32 -13
  240. package/src/runtime/backend/raw-binding-port.ts +18 -3
  241. package/src/runtime/backend/runtime-message.ts +6 -0
  242. package/src/runtime/backend/runtime-values.ts +1 -0
  243. package/src/runtime/channels/channel-clients.ts +90 -41
  244. package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
  245. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  246. package/src/runtime/channels/channel-dispatchers.ts +29 -27
  247. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  248. package/src/runtime/channels/channel-envelope.ts +133 -8
  249. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  250. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  251. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  252. package/src/runtime/channels/channel-runtime-manager.ts +29 -12
  253. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  254. package/src/runtime/channels/channel-transports.ts +128 -60
  255. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  256. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  257. package/src/runtime/channels/source-spot-router.ts +8 -4
  258. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  259. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  260. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  261. package/src/runtime/diagnostics/message-flow.ts +1 -1
  262. package/src/runtime/execution/serial-execution-queue.ts +2 -0
  263. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  264. package/src/runtime/foundation/durable-service-request.ts +137 -0
  265. package/src/runtime/foundation/operation-identity.ts +5 -1
  266. package/src/runtime/foundation/raw-service-mesh-runtime.ts +642 -253
  267. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  268. package/src/runtime/foundation/service-mailbox.ts +7 -1
  269. package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
  270. package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
  271. package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
  272. package/src/runtime/foundation/service-stateful-runtime.ts +128 -160
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -84
  274. package/src/runtime/foundation/service-topology-registry.ts +103 -42
  275. package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
  276. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  277. package/src/runtime/host/actor-packet-relay.ts +7 -0
  278. package/src/runtime/host/actor-runtime-options-factory.ts +14 -2
  279. package/src/runtime/host/application-job-queue.ts +249 -48
  280. package/src/runtime/host/entry-actor-runtime.ts +5 -0
  281. package/src/runtime/host/index.ts +224 -160
  282. package/src/runtime/host/instance-activation-authority.ts +132 -27
  283. package/src/runtime/host/remote-bound-session-relay.ts +2 -23
  284. package/src/runtime/host/route-mesh-runtime.ts +1 -1
  285. package/src/runtime/host/service-relocation-control.ts +11 -5
  286. package/src/runtime/host/service-relocation-host-runtime.ts +317 -291
  287. package/src/runtime/host/spot-address-transport.ts +49 -24
  288. package/src/runtime/host/spot-runtime-options-factory.ts +4 -0
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  290. package/src/runtime/locations/actor-location-claims.ts +52 -30
  291. package/src/runtime/locations/domain-store-contract.ts +6 -2
  292. package/src/runtime/locations/in-memory-authority-store.ts +113 -9
  293. package/src/runtime/locations/in-memory-location-store.ts +25 -3
  294. package/src/runtime/locations/internal-location-contracts.ts +4 -0
  295. package/src/runtime/locations/lifecycle.ts +8 -26
  296. package/src/runtime/locations/location-store-repository.ts +220 -15
  297. package/src/runtime/locations/resolvers.ts +25 -2
  298. package/src/runtime/locations/runtime.ts +28 -24
  299. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  300. package/src/runtime/messaging/packet-name.ts +5 -25
  301. package/src/runtime/messaging/request-result.ts +58 -0
  302. package/src/runtime/messaging/submission-result.ts +7 -3
  303. package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
  304. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  305. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +45 -23
  306. package/src/runtime/spots/index.ts +30 -2
  307. package/src/runtime/spots/spot-activation.ts +33 -10
  308. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  309. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  310. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  311. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  312. package/src/runtime/spots/spot-entry-activation.ts +12 -2
  313. package/src/runtime/spots/spot-handler-registry.ts +41 -8
  314. package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
  315. package/src/runtime/spots/spot-node-runtime-manager.ts +7 -12
  316. package/src/runtime/spots/spot-outbound.ts +36 -16
  317. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  318. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  319. package/src/runtime/spots/spot-runtime-ports.ts +3 -0
  320. package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
  321. package/src/runtime/spots/spot-timer.ts +5 -1
  322. package/src/runtime/streams/stream-session-runtime.ts +13 -30
@@ -1,4 +1,4 @@
1
- // <auto-generated> DO NOT EDIT. schema-sha256: 818fcd2f767793be8b5f626e5ac688807e671e546af2b11786e6fbaa02010ba5
1
+ // <auto-generated> DO NOT EDIT. schema-sha256: c9a343a64d205ce666d1e866df72538c11b3b52cf4bff41562e46d4aeaf20df6
2
2
  export interface ServiceWireRouteFence { readonly id: string; readonly generation: bigint; readonly targetNodeRid: Uint8Array; readonly targetNodeGeneration: bigint; readonly expectedAuthorityOwnerGeneration: bigint; readonly expectedOwnerLeaseGeneration: bigint; }
3
3
  export interface ApplicationPayloadEnvelopeV1 { readonly packetName: string; readonly contentType: string; readonly payload: Uint8Array; }
4
4
  export interface ActorJoin28 { readonly correlation: bigint; readonly actor: ServiceWireRouteFence; readonly entry: boolean; readonly targetSpot: ServiceWireRouteFence; readonly payload?: ApplicationPayloadEnvelopeV1; }
@@ -19,7 +19,7 @@ export interface ServiceWireRouteFence { readonly id: string; readonly generatio
19
19
  export function encodeActorJoin28(value: ActorJoin28): readonly Uint8Array[] { const out=[90,77,1,28,0]; if(value.correlation===0n) throw new RangeError("correlation"); u64(out,value.correlation); fence(out,value.actor); out.push(value.entry?1:0); fence(out,value.targetSpot); return value.payload===undefined?[Uint8Array.from(out)]:[Uint8Array.from(out),encodePayload(value.payload)]; }
20
20
  export function decodeActorJoin28(frames: readonly Uint8Array[]): ActorJoin28 { if(frames.length<1||frames.length>2)throw new RangeError("actorJoin frames");const bytes=frames[0]!; const at={value:0}; if(bytes.length<5 || bytes[at.value++]!==90 || bytes[at.value++]!==77 || bytes[at.value++]!==1 || bytes[at.value++]!==28 || bytes[at.value++]!==0) throw new RangeError("actorJoin header"); const correlation=read64(bytes,at); const actor=readFence(bytes,at); const entry=bytes[at.value++]; const targetSpot=readFence(bytes,at); if(correlation===0n || entry>1 || at.value!==bytes.length) throw new RangeError("actorJoin body"); const payload=frames.length===2?decodePayload(frames[1]!):undefined; return payload===undefined?{ correlation, actor, entry:entry===1, targetSpot }:{ correlation, actor, entry:entry===1, targetSpot,payload }; }
21
21
  export type RelocationObjectIdentity = { readonly objectKind:"actor";readonly actorId:string;readonly objectGeneration:bigint;readonly expectedAuthorityOwnerGeneration:bigint; }|{ readonly objectKind:"userSpot";readonly spotId:string;readonly objectGeneration:bigint;readonly expectedAuthorityOwnerGeneration:bigint; }|{ readonly objectKind:"instanceSpot";readonly instanceType:string;readonly spotId:string;readonly objectGeneration:bigint; };
22
- export interface RelocationEnvelopeV1 { readonly relocationHigh: bigint; readonly relocationLow: bigint; readonly object: RelocationObjectIdentity; readonly applicationVersion: bigint; readonly applicationStates: readonly { readonly participantId: bigint; readonly hasState: boolean; readonly payload: Uint8Array; }[]; readonly savedWork: readonly { readonly participantId: bigint; readonly order: bigint; readonly frozenRecord: Uint8Array; }[]; readonly timerRegistrations: readonly { readonly participantId: bigint; readonly name: string; readonly handlerType: string; readonly periodMilliseconds: bigint; readonly overrunPolicy: 1|2|3; readonly maxCatchUpTicks: bigint; readonly stopOnUnhandledException: boolean; readonly lastCompletedDeliveryIndex: bigint; readonly lastCompletedScheduledIndex: bigint; readonly nextScheduledAtUnixMilliseconds: bigint; }[]; readonly pendingTimerTicks: readonly { readonly participantId: bigint; readonly order: bigint; readonly timerName: string; readonly deliveryIndex: bigint; readonly scheduledIndex: bigint; readonly scheduledAtUnixMilliseconds: bigint; readonly skippedTicks: bigint; }[]; }
22
+ export interface RelocationEnvelopeV1 { readonly relocationHigh: bigint; readonly relocationLow: bigint; readonly object: RelocationObjectIdentity; readonly applicationVersion: bigint; readonly applicationStates: readonly { readonly participantId: bigint; readonly hasState: boolean; readonly payload: Uint8Array; }[]; readonly savedWork: readonly { readonly participantId: bigint; readonly order: bigint; readonly frozenRecord: Uint8Array; }[]; readonly timerRegistrations: readonly { readonly participantId: bigint; readonly name: string; readonly handlerType: string; readonly periodMilliseconds: bigint; readonly overrunPolicy: 1|2|3; readonly maxCatchUpTicks: bigint; readonly stopOnUnhandledException: boolean; readonly lastCompletedDeliveryIndex: bigint; readonly lastCompletedScheduledIndex: bigint; readonly nextScheduledAtUnixMilliseconds: bigint; }[]; readonly pendingTimerTicks: readonly { readonly participantId: bigint; readonly order: bigint; readonly timerName: string; readonly deliveryIndex: bigint; readonly scheduledIndex: bigint; readonly scheduledAtUnixMilliseconds: bigint; readonly skippedTicks: bigint; }[]; readonly sessionBindings: readonly {readonly participantId:bigint;readonly sessionOwnerNodeRid:Uint8Array;readonly sessionOwnerNodeGeneration:bigint;readonly sessionOwnerId:string;readonly sessionOwnerLeaseGeneration:bigint;readonly sessionRid:Uint8Array;readonly bindingGeneration:bigint;}[]; }
23
23
  export interface RelocationDataChunkV1 { readonly order:number;readonly data:Uint8Array; }
24
24
  export interface RelocationChunkEntryV1 { readonly order:number;readonly reference:string;readonly length:bigint;readonly checksumCrc32c:number; }
25
25
  export interface RelocationManifestV1 { readonly logicalFormatVersion:1;readonly totalLength:bigint;readonly totalChecksumCrc32c:number;readonly inventoryDigestSha256:Uint8Array;readonly chunks:readonly RelocationChunkEntryV1[]; }
@@ -51,8 +51,8 @@ function skipFrozenRecord(bytes:Uint8Array,at:{value:number}):void{const kind=re
51
51
  function compareUtf8(a:string,b:string):number{const x=text.encode(a),y=text.encode(b),n=Math.min(x.length,y.length);for(let i=0;i<n;i++)if(x[i]!==y[i])return x[i]!-y[i]!;return x.length-y.length;}
52
52
  function writeRelocationObject(out:number[],value:RelocationObjectIdentity):void{const kind=value.objectKind==="actor"?1:value.objectKind==="userSpot"?2:3;out.push(kind);body16(out,b=>{if(value.objectKind==="actor"){text8(b,value.actorId);if(value.objectGeneration===0n||value.expectedAuthorityOwnerGeneration===0n)throw new RangeError("object");u64(b,value.objectGeneration);u64(b,value.expectedAuthorityOwnerGeneration);}else if(value.objectKind==="userSpot"){text8(b,value.spotId);if(value.objectGeneration===0n||value.expectedAuthorityOwnerGeneration===0n)throw new RangeError("object");u64(b,value.objectGeneration);u64(b,value.expectedAuthorityOwnerGeneration);}else{text8(b,value.instanceType);text8(b,value.spotId);if(value.objectGeneration===0n)throw new RangeError("object");u64(b,value.objectGeneration);}});}
53
53
  function readRelocationObject(bytes:Uint8Array,at:{value:number}):RelocationObjectIdentity{const kind=read8(bytes,at),end=boundedEnd(bytes,at,read16(bytes,at),"relocation object");let value:RelocationObjectIdentity;if(kind===1)value={objectKind:"actor",actorId:readText8(bytes,at),objectGeneration:nonzero64(bytes,at,"object generation"),expectedAuthorityOwnerGeneration:nonzero64(bytes,at,"authority generation")};else if(kind===2)value={objectKind:"userSpot",spotId:readText8(bytes,at),objectGeneration:nonzero64(bytes,at,"object generation"),expectedAuthorityOwnerGeneration:nonzero64(bytes,at,"authority generation")};else if(kind===3)value={objectKind:"instanceSpot",instanceType:readText8(bytes,at),spotId:readText8(bytes,at),objectGeneration:nonzero64(bytes,at,"object generation")};else throw new RangeError("object kind");exactEnd(at,end,"relocation object");return value;}
54
- export function encodeRelocationEnvelopeV1(value:RelocationEnvelopeV1):Uint8Array{const out:number[]=[];if(value.relocationHigh===0n&&value.relocationLow===0n)throw new RangeError("relocation");u64(out,value.relocationHigh);u64(out,value.relocationLow);writeRelocationObject(out,value.object);if(value.applicationVersion<0n||value.applicationVersion>9223372036854775807n)throw new RangeError("application version");u64(out,value.applicationVersion);sorted(value.applicationStates,(a,b)=>a.participantId<b.participantId?-1:a.participantId>b.participantId?1:0,"applicationStates");if(value.applicationStates.length===0)throw new RangeError("applicationStates");u32(out,value.applicationStates.length);for(const s of value.applicationStates){if(s.participantId===0n)throw new RangeError("participant");u64(out,s.participantId);out.push(s.hasState?1:0);body64(out,b=>{if(s.hasState)bytes64(b,s.payload);else if(s.payload.length!==0)throw new RangeError("absent state payload");});}sorted(value.savedWork,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"savedWork");u32(out,value.savedWork.length);for(const w of value.savedWork){if(w.participantId===0n||w.order===0n)throw new RangeError("saved work");const at={value:0};skipFrozenRecord(w.frozenRecord,at);exactEnd(at,w.frozenRecord.length,"frozen record");u64(out,w.participantId);u64(out,w.order);appendBytes(out,w.frozenRecord);}sorted(value.timerRegistrations,(a,b)=>a.participantId===b.participantId?compareUtf8(a.name,b.name):a.participantId<b.participantId?-1:1,"timerRegistrations");u32(out,value.timerRegistrations.length);for(const t of value.timerRegistrations){if(t.participantId===0n||t.periodMilliseconds===0n||t.maxCatchUpTicks===0n||t.overrunPolicy<1||t.overrunPolicy>3)throw new RangeError("timer");u64(out,t.participantId);text8(out,t.name);text8(out,t.handlerType);u64(out,t.periodMilliseconds);out.push(t.overrunPolicy);u64(out,t.maxCatchUpTicks);out.push(t.stopOnUnhandledException?1:0);u64(out,t.lastCompletedDeliveryIndex);u64(out,t.lastCompletedScheduledIndex);u64(out,t.nextScheduledAtUnixMilliseconds);}sorted(value.pendingTimerTicks,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"pendingTimerTicks");u32(out,value.pendingTimerTicks.length);for(const p of value.pendingTimerTicks){if(p.participantId===0n||p.order===0n||p.deliveryIndex===0n||p.scheduledIndex===0n)throw new RangeError("pending timer");u64(out,p.participantId);u64(out,p.order);text8(out,p.timerName);u64(out,p.deliveryIndex);u64(out,p.scheduledIndex);u64(out,p.scheduledAtUnixMilliseconds);u64(out,p.skippedTicks);}if(out.length>274877906944)throw new RangeError("relocation logical bytes");return Uint8Array.from(out);}
55
- export function decodeRelocationEnvelopeV1(chunks:readonly Uint8Array[]):RelocationEnvelopeV1{const n=chunks.reduce((s,c)=>s+c.length,0);if(n>274877906944)throw new RangeError("relocation logical bytes");const bytes=new Uint8Array(n);let offset=0;for(const c of chunks){bytes.set(c,offset);offset+=c.length;}const at={value:0},relocationHigh=read64(bytes,at),relocationLow=read64(bytes,at);if(relocationHigh===0n&&relocationLow===0n)throw new RangeError("relocation");const object=readRelocationObject(bytes,at),applicationVersion=read64(bytes,at);if(applicationVersion>9223372036854775807n)throw new RangeError("application version");const applicationStates:RelocationEnvelopeV1["applicationStates"][number][]=[];const stateCount=read32(bytes,at);if(stateCount===0)throw new RangeError("applicationStates");for(let i=0,count=stateCount;i<count;i++){const participantId=nonzero64(bytes,at,"participant"),has=read8(bytes,at),end=boundedEnd(bytes,at,Number(read64(bytes,at)),"application state");if(has>1)throw new RangeError("application state");let payload=new Uint8Array();if(has===1)payload=take(bytes,at,Number(read64(bytes,at)),"state payload");exactEnd(at,end,"application state");applicationStates.push({participantId,hasState:has===1,payload});}const participants=new Set(applicationStates.map((s)=>s.participantId));const savedWork:RelocationEnvelopeV1["savedWork"][number][]=[];for(let i=0,count=read32(bytes,at);i<count;i++){const participantId=nonzero64(bytes,at,"participant");if(!participants.has(participantId))throw new RangeError("saved work participant");const order=nonzero64(bytes,at,"order"),start=at.value;skipFrozenRecord(bytes,at);savedWork.push({participantId,order,frozenRecord:bytes.slice(start,at.value)});}const timerRegistrations:RelocationEnvelopeV1["timerRegistrations"][number][]=[],registeredTimerNames=new Map<bigint,Set<string>>();for(let i=0,count=read32(bytes,at);i<count;i++){const participantId=nonzero64(bytes,at,"participant");if(!participants.has(participantId))throw new RangeError("timer participant");const name=readText8(bytes,at),handlerType=readText8(bytes,at),periodMilliseconds=nonzero64(bytes,at,"period"),overrunPolicy=read8(bytes,at);if(overrunPolicy<1||overrunPolicy>3)throw new RangeError("overrun policy");const maxCatchUpTicks=nonzero64(bytes,at,"catch-up"),stop=read8(bytes,at);if(stop>1)throw new RangeError("stop flag");let names=registeredTimerNames.get(participantId);if(names===undefined){names=new Set<string>();registeredTimerNames.set(participantId,names);}names.add(name);timerRegistrations.push({participantId,name,handlerType,periodMilliseconds,overrunPolicy:overrunPolicy as 1|2|3,maxCatchUpTicks,stopOnUnhandledException:stop===1,lastCompletedDeliveryIndex:read64(bytes,at),lastCompletedScheduledIndex:read64(bytes,at),nextScheduledAtUnixMilliseconds:read64(bytes,at)});}const pendingTimerTicks:RelocationEnvelopeV1["pendingTimerTicks"][number][]=[];for(let i=0,count=read32(bytes,at);i<count;i++){const participantId=nonzero64(bytes,at,"participant");if(!participants.has(participantId))throw new RangeError("pending timer participant");const order=nonzero64(bytes,at,"order"),timerName=readText8(bytes,at);if(registeredTimerNames.get(participantId)?.has(timerName)!==true)throw new RangeError("pending timer registration");pendingTimerTicks.push({participantId,order,timerName,deliveryIndex:nonzero64(bytes,at,"delivery"),scheduledIndex:nonzero64(bytes,at,"scheduled"),scheduledAtUnixMilliseconds:read64(bytes,at),skippedTicks:read64(bytes,at)});}exactEnd(at,bytes.length,"relocation envelope");sorted(applicationStates,(a,b)=>a.participantId<b.participantId?-1:a.participantId>b.participantId?1:0,"applicationStates");sorted(savedWork,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"savedWork");sorted(timerRegistrations,(a,b)=>a.participantId===b.participantId?compareUtf8(a.name,b.name):a.participantId<b.participantId?-1:1,"timerRegistrations");sorted(pendingTimerTicks,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"pendingTimerTicks");return{relocationHigh,relocationLow,object,applicationVersion,applicationStates,savedWork,timerRegistrations,pendingTimerTicks};}
54
+ export function encodeRelocationEnvelopeV1(value:RelocationEnvelopeV1):Uint8Array{const out:number[]=[];if(value.relocationHigh===0n&&value.relocationLow===0n)throw new RangeError("relocation");u64(out,value.relocationHigh);u64(out,value.relocationLow);writeRelocationObject(out,value.object);if(value.applicationVersion<0n||value.applicationVersion>9223372036854775807n)throw new RangeError("application version");u64(out,value.applicationVersion);sorted(value.applicationStates,(a,b)=>a.participantId<b.participantId?-1:a.participantId>b.participantId?1:0,"applicationStates");if(value.applicationStates.length===0)throw new RangeError("applicationStates");u32(out,value.applicationStates.length);for(const s of value.applicationStates){if(s.participantId===0n)throw new RangeError("participant");u64(out,s.participantId);out.push(s.hasState?1:0);body64(out,b=>{if(s.hasState)bytes64(b,s.payload);else if(s.payload.length!==0)throw new RangeError("absent state payload");});}sorted(value.savedWork,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"savedWork");u32(out,value.savedWork.length);for(const w of value.savedWork){if(w.participantId===0n||w.order===0n)throw new RangeError("saved work");const at={value:0};skipFrozenRecord(w.frozenRecord,at);exactEnd(at,w.frozenRecord.length,"frozen record");u64(out,w.participantId);u64(out,w.order);appendBytes(out,w.frozenRecord);}sorted(value.timerRegistrations,(a,b)=>a.participantId===b.participantId?compareUtf8(a.name,b.name):a.participantId<b.participantId?-1:1,"timerRegistrations");u32(out,value.timerRegistrations.length);for(const t of value.timerRegistrations){if(t.participantId===0n||t.periodMilliseconds===0n||t.maxCatchUpTicks===0n||t.overrunPolicy<1||t.overrunPolicy>3)throw new RangeError("timer");u64(out,t.participantId);text8(out,t.name);text8(out,t.handlerType);u64(out,t.periodMilliseconds);out.push(t.overrunPolicy);u64(out,t.maxCatchUpTicks);out.push(t.stopOnUnhandledException?1:0);u64(out,t.lastCompletedDeliveryIndex);u64(out,t.lastCompletedScheduledIndex);u64(out,t.nextScheduledAtUnixMilliseconds);}sorted(value.pendingTimerTicks,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"pendingTimerTicks");u32(out,value.pendingTimerTicks.length);for(const p of value.pendingTimerTicks){if(p.participantId===0n||p.order===0n||p.deliveryIndex===0n||p.scheduledIndex===0n)throw new RangeError("pending timer");u64(out,p.participantId);u64(out,p.order);text8(out,p.timerName);u64(out,p.deliveryIndex);u64(out,p.scheduledIndex);u64(out,p.scheduledAtUnixMilliseconds);u64(out,p.skippedTicks);}sorted(value.sessionBindings,(a,b)=>a.participantId<b.participantId?-1:a.participantId>b.participantId?1:0,"sessionBindings");if(value.sessionBindings.length>1024)throw new RangeError("bindings count");u32(out,value.sessionBindings.length);for(const b of value.sessionBindings){if(b.participantId===0n||b.sessionOwnerNodeGeneration===0n||b.sessionOwnerLeaseGeneration===0n||b.bindingGeneration===0n)throw new RangeError("binding");u64(out,b.participantId);rid(out,b.sessionOwnerNodeRid);u64(out,b.sessionOwnerNodeGeneration);text8(out,b.sessionOwnerId);u64(out,b.sessionOwnerLeaseGeneration);rid(out,b.sessionRid);u64(out,b.bindingGeneration);}if(out.length>274877906944)throw new RangeError("relocation logical bytes");return Uint8Array.from(out);}
55
+ export function decodeRelocationEnvelopeV1(chunks:readonly Uint8Array[]):RelocationEnvelopeV1{const n=chunks.reduce((s,c)=>s+c.length,0);if(n>274877906944)throw new RangeError("relocation logical bytes");const bytes=new Uint8Array(n);let offset=0;for(const c of chunks){bytes.set(c,offset);offset+=c.length;}const at={value:0},relocationHigh=read64(bytes,at),relocationLow=read64(bytes,at);if(relocationHigh===0n&&relocationLow===0n)throw new RangeError("relocation");const object=readRelocationObject(bytes,at),applicationVersion=read64(bytes,at);if(applicationVersion>9223372036854775807n)throw new RangeError("application version");const applicationStates:RelocationEnvelopeV1["applicationStates"][number][]=[];const stateCount=read32(bytes,at);if(stateCount===0)throw new RangeError("applicationStates");for(let i=0,count=stateCount;i<count;i++){const participantId=nonzero64(bytes,at,"participant"),has=read8(bytes,at),end=boundedEnd(bytes,at,Number(read64(bytes,at)),"application state");if(has>1)throw new RangeError("application state");let payload=new Uint8Array();if(has===1)payload=take(bytes,at,Number(read64(bytes,at)),"state payload");exactEnd(at,end,"application state");applicationStates.push({participantId,hasState:has===1,payload});}const participants=new Set(applicationStates.map((s)=>s.participantId));const savedWork:RelocationEnvelopeV1["savedWork"][number][]=[];for(let i=0,count=read32(bytes,at);i<count;i++){const participantId=nonzero64(bytes,at,"participant");if(!participants.has(participantId))throw new RangeError("saved work participant");const order=nonzero64(bytes,at,"order"),start=at.value;skipFrozenRecord(bytes,at);savedWork.push({participantId,order,frozenRecord:bytes.slice(start,at.value)});}const timerRegistrations:RelocationEnvelopeV1["timerRegistrations"][number][]=[],registeredTimerNames=new Map<bigint,Set<string>>();for(let i=0,count=read32(bytes,at);i<count;i++){const participantId=nonzero64(bytes,at,"participant");if(!participants.has(participantId))throw new RangeError("timer participant");const name=readText8(bytes,at),handlerType=readText8(bytes,at),periodMilliseconds=nonzero64(bytes,at,"period"),overrunPolicy=read8(bytes,at);if(overrunPolicy<1||overrunPolicy>3)throw new RangeError("overrun policy");const maxCatchUpTicks=nonzero64(bytes,at,"catch-up"),stop=read8(bytes,at);if(stop>1)throw new RangeError("stop flag");let names=registeredTimerNames.get(participantId);if(names===undefined){names=new Set<string>();registeredTimerNames.set(participantId,names);}names.add(name);timerRegistrations.push({participantId,name,handlerType,periodMilliseconds,overrunPolicy:overrunPolicy as 1|2|3,maxCatchUpTicks,stopOnUnhandledException:stop===1,lastCompletedDeliveryIndex:read64(bytes,at),lastCompletedScheduledIndex:read64(bytes,at),nextScheduledAtUnixMilliseconds:read64(bytes,at)});}const pendingTimerTicks:RelocationEnvelopeV1["pendingTimerTicks"][number][]=[];for(let i=0,count=read32(bytes,at);i<count;i++){const participantId=nonzero64(bytes,at,"participant");if(!participants.has(participantId))throw new RangeError("pending timer participant");const order=nonzero64(bytes,at,"order"),timerName=readText8(bytes,at);if(registeredTimerNames.get(participantId)?.has(timerName)!==true)throw new RangeError("pending timer registration");pendingTimerTicks.push({participantId,order,timerName,deliveryIndex:nonzero64(bytes,at,"delivery"),scheduledIndex:nonzero64(bytes,at,"scheduled"),scheduledAtUnixMilliseconds:read64(bytes,at),skippedTicks:read64(bytes,at)});}const sessionBindings:RelocationEnvelopeV1["sessionBindings"][number][]=[];const bindingCount=read32(bytes,at);if(bindingCount>1024)throw new RangeError("bindings count");for(let n=0;n<bindingCount;n++)sessionBindings.push({participantId:nonzero64(bytes,at,"participant"),sessionOwnerNodeRid:readRid(bytes,at),sessionOwnerNodeGeneration:nonzero64(bytes,at,"session node"),sessionOwnerId:readText8(bytes,at),sessionOwnerLeaseGeneration:nonzero64(bytes,at,"session lease"),sessionRid:readRid(bytes,at),bindingGeneration:nonzero64(bytes,at,"binding")});sorted(sessionBindings,(a,b)=>a.participantId<b.participantId?-1:a.participantId>b.participantId?1:0,"sessionBindings");exactEnd(at,bytes.length,"relocation envelope");sorted(applicationStates,(a,b)=>a.participantId<b.participantId?-1:a.participantId>b.participantId?1:0,"applicationStates");sorted(savedWork,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"savedWork");sorted(timerRegistrations,(a,b)=>a.participantId===b.participantId?compareUtf8(a.name,b.name):a.participantId<b.participantId?-1:1,"timerRegistrations");sorted(pendingTimerTicks,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"pendingTimerTicks");return{relocationHigh,relocationLow,object,applicationVersion,applicationStates,savedWork,timerRegistrations,pendingTimerTicks,sessionBindings};}
56
56
  function crc32c(bytes:Uint8Array):number{let crc=0xffffffff;for(const octet of bytes){crc^=octet;for(let bit=0;bit<8;bit++)crc=(crc>>>1)^((crc&1)!==0?0x82f63b78:0);}return(~crc)>>>0;}
57
57
  function encodeDurable(magic:readonly number[],body:readonly number[],maximum:number):Uint8Array{const out=[...magic,1,0,0];u32(out,body.length);appendBytes(out,body);if(out.length+4>maximum)throw new RangeError("durable format bytes");u32(out,crc32c(Uint8Array.from(out)));return Uint8Array.from(out);}
58
58
  function decodeDurable(bytes:Uint8Array,magic:readonly number[],maximum:number):Uint8Array{if(bytes.length>maximum||bytes.length<15||magic.some((v,i)=>bytes[i]!==v)||bytes[4]!==1||bytes[5]!==0||bytes[6]!==0)throw new RangeError("durable header");const at={value:7},length=read32(bytes,at),end=boundedEnd(bytes,at,length,"durable body");if(end+4!==bytes.length)throw new RangeError("durable length");const body=bytes.slice(at.value,end);at.value=end;const expected=read32(bytes,at);if(crc32c(bytes.slice(0,end))!==expected)throw new RangeError("durable checksum");return body;}
@@ -1,3 +1,4 @@
1
+ import type { ApplicationJobOrigin } from '../application-jobs/contracts';
1
2
  import type { ActorRef, RoutingId, ZLinkActor, ZLinkActorJoinOperationId } from '../../contracts';
2
3
  import type { ZLinkRemoteBoundSessionTarget } from '../actors/actor-runtime-state';
3
4
  import type { ZLinkDeferredJoinCompletion } from '../actors/deferred-join-completion';
@@ -13,6 +14,7 @@ const ADMISSION_RETENTION_MS = 30_000;
13
14
  * how long the underlying buffer stays valid.
14
15
  */
15
16
  export interface ZLinkParkedActorArrival {
17
+ readonly origin: ApplicationJobOrigin;
16
18
  readonly header: Buffer;
17
19
  readonly payload: Buffer;
18
20
  readonly returnResponse: boolean;
@@ -31,7 +33,14 @@ function objectKey(actorId: string, objectGeneration: bigint): string {
31
33
  }
32
34
 
33
35
  export type ZLinkFormalRemoteActorAdmissionState =
34
- 'provisional' | 'admitting' | 'admitted' | 'rejected' | 'committed' | 'aborted' | 'failed';
36
+ | 'provisional'
37
+ | 'admitting'
38
+ | 'admitted'
39
+ | 'restoring'
40
+ | 'rejected'
41
+ | 'committed'
42
+ | 'aborted'
43
+ | 'failed';
35
44
 
36
45
  export interface ZLinkFormalRemoteActorAdmission {
37
46
  readonly actorId: string;
@@ -76,7 +85,7 @@ export interface ZLinkFormalRemoteActorAdmissionRecord {
76
85
  }
77
86
 
78
87
  interface ZLinkFormalRemoteActorAdmissionEntry extends ZLinkFormalRemoteActorAdmissionRecord {
79
- readonly timer: ReturnType<typeof setTimeout>;
88
+ timer: ReturnType<typeof setTimeout>;
80
89
  readonly resolveResult: (result: ZLinkFormalRemoteActorAdmissionResult) => void;
81
90
  admission: ZLinkFormalRemoteActorAdmission;
82
91
  state: ZLinkFormalRemoteActorAdmissionState;
@@ -105,6 +114,35 @@ export class ZLinkFormalRemoteActorAdmissionRegistry {
105
114
  return this.admissions.get(transferId);
106
115
  }
107
116
 
117
+ /** PREPARE transfers prepared resources to the target attempt until its terminal. */
118
+ beginRestore(transferId: string): void {
119
+ const entry = this.admissions.get(transferId);
120
+ if (entry === undefined || (entry.state !== 'admitted' && entry.state !== 'restoring')) {
121
+ throw new Error(`Remote actor admission '${transferId}' is not ready to restore.`);
122
+ }
123
+ clearTimeout(entry.timer);
124
+ entry.state = 'restoring';
125
+ }
126
+
127
+ /** Retains successful commit replay; unsuccessful attempts release their resources now. */
128
+ finishRestore(transferId: string): void {
129
+ const entry = this.admissions.get(transferId);
130
+ if (entry === undefined) return;
131
+ if (entry.state === 'committed') {
132
+ clearTimeout(entry.timer);
133
+ entry.timer = this.scheduleExpiry(transferId);
134
+ } else {
135
+ this.abort(transferId);
136
+ this.delete(transferId);
137
+ }
138
+ }
139
+
140
+ private scheduleExpiry(transferId: string): ReturnType<typeof setTimeout> {
141
+ const timer = setTimeout(() => this.delete(transferId), ADMISSION_RETENTION_MS);
142
+ timer.unref();
143
+ return timer;
144
+ }
145
+
108
146
  begin(input: ZLinkFormalRemoteActorAdmission): {
109
147
  readonly record: ZLinkFormalRemoteActorAdmissionEntry;
110
148
  readonly created: boolean;
@@ -180,10 +218,7 @@ export class ZLinkFormalRemoteActorAdmissionRegistry {
180
218
  const resultTask = new Promise<ZLinkFormalRemoteActorAdmissionResult>((resolve) => {
181
219
  resolveResult = resolve;
182
220
  });
183
- const timer = setTimeout(() => {
184
- this.delete(input.transferId);
185
- }, ADMISSION_RETENTION_MS);
186
- timer.unref();
221
+ const timer = this.scheduleExpiry(input.transferId);
187
222
  const entry = {
188
223
  admission: input,
189
224
  state,
@@ -307,7 +342,7 @@ export class ZLinkFormalRemoteActorAdmissionRegistry {
307
342
  markCommitted(transferId: string, actor: ZLinkActor): void {
308
343
  const entry = this.admissions.get(transferId);
309
344
  if (entry === undefined) return;
310
- if (entry.state !== 'admitted' && entry.state !== 'committed') {
345
+ if (entry.state !== 'admitted' && entry.state !== 'restoring' && entry.state !== 'committed') {
311
346
  throw new Error(`Remote actor admission '${transferId}' is not ready to commit.`);
312
347
  }
313
348
  entry.state = 'committed';
@@ -318,7 +353,7 @@ export class ZLinkFormalRemoteActorAdmissionRegistry {
318
353
  const entry = this.admissions.get(transferId);
319
354
  if (
320
355
  entry === undefined ||
321
- entry.state !== 'admitted' ||
356
+ (entry.state !== 'admitted' && entry.state !== 'restoring') ||
322
357
  entry.result === undefined ||
323
358
  'error' in entry.result ||
324
359
  !entry.result.accepted
@@ -352,7 +387,7 @@ export class ZLinkFormalRemoteActorAdmissionRegistry {
352
387
  */
353
388
  delete(transferId: string): void {
354
389
  const pending = this.admissions.get(transferId);
355
- if (pending === undefined) return;
390
+ if (pending === undefined || pending.state === 'restoring') return;
356
391
  clearTimeout(pending.timer);
357
392
  this.admissions.delete(transferId);
358
393
  this.failParked(pending);
@@ -367,20 +402,7 @@ function sameAdmission(
367
402
  left: ZLinkFormalRemoteActorAdmission,
368
403
  right: ZLinkFormalRemoteActorAdmission
369
404
  ): boolean {
370
- return (
371
- left.actorId === right.actorId &&
372
- left.actorType === right.actorType &&
373
- String(left.spotId) === String(right.spotId) &&
374
- left.targetSpotGeneration === right.targetSpotGeneration &&
375
- left.expectedMembershipEpoch === right.expectedMembershipEpoch &&
376
- left.requestFingerprint === right.requestFingerprint &&
377
- sameOperationId(left.completionOperationId, right.completionOperationId) &&
378
- String(left.sourceSpotId ?? '') === String(right.sourceSpotId ?? '') &&
379
- String(left.sourceActorNodeRid ?? '') === String(right.sourceActorNodeRid ?? '') &&
380
- left.actorRef.actorId === right.actorRef.actorId &&
381
- String(left.actorRef.nodeRid) === String(right.actorRef.nodeRid) &&
382
- left.actorRef.objectGeneration === right.actorRef.objectGeneration
383
- );
405
+ return left.actorType === right.actorType && sameProvisionalAdmission(left, right);
384
406
  }
385
407
 
386
408
  function sameProvisionalAdmission(
@@ -1,3 +1,4 @@
1
+ import type { ApplicationJobOrigin } from '../application-jobs/contracts';
1
2
  import { dispatchReasonFromError } from '../diagnostics/dispatch-error-details';
2
3
  import type {
3
4
  ActorRef,
@@ -190,6 +191,7 @@ export interface ZLinkSpotManagerOptions {
190
191
  ): Promise<void>;
191
192
  };
192
193
  readonly dispatchEntryActorPacket?: (
194
+ origin: ApplicationJobOrigin,
193
195
  actorId: string,
194
196
  parts: readonly Message[],
195
197
  returnResponse?: boolean,
@@ -213,6 +215,7 @@ export interface ZLinkSpotManagerOptions {
213
215
  operation: () => Promise<T>
214
216
  ) => Promise<T>;
215
217
  readonly actorCountProvider?: (spotId: RoutingId) => number;
218
+ readonly releaseActorMembers?: (meshName: string, spotId: RoutingId) => Promise<void>;
216
219
  readonly userSpotExecutionMode?: (
217
220
  meshName: string,
218
221
  spotType: Type<ZLinkSpot>
@@ -406,6 +409,7 @@ export class DefaultZLinkSpotManager {
406
409
  nodeRid: options.nodeRid,
407
410
  nodeRidProvider: options.nodeRidProvider,
408
411
  actorCountProvider: options.actorCountProvider,
412
+ releaseActorMembers: options.releaseActorMembers,
409
413
  userSpotExecutionMode: options.userSpotExecutionMode,
410
414
  userSpotRelocationCoordinationMode: options.userSpotRelocationCoordinationMode,
411
415
  channelClient: options.channelClient,
@@ -1532,6 +1536,7 @@ export class DefaultZLinkSpotManager {
1532
1536
  }
1533
1537
 
1534
1538
  dispatchRoutedActorPacket(
1539
+ origin: ApplicationJobOrigin,
1535
1540
  spotId: RoutingId,
1536
1541
  actorId: string,
1537
1542
  parts: readonly Message[],
@@ -1544,6 +1549,7 @@ export class DefaultZLinkSpotManager {
1544
1549
  throw new ZLinkConfigurationException(`Spot '${spotId}' is not active.`);
1545
1550
  }
1546
1551
  return this.dispatchActorPacket(
1552
+ origin,
1547
1553
  activation,
1548
1554
  actorId,
1549
1555
  parts,
@@ -1555,6 +1561,7 @@ export class DefaultZLinkSpotManager {
1555
1561
 
1556
1562
  /** @internal Replays a record already owned by the Actor handoff queue. */
1557
1563
  dispatchRoutedActorPacketDirect(
1564
+ origin: ApplicationJobOrigin,
1558
1565
  spotId: RoutingId,
1559
1566
  actorId: string,
1560
1567
  parts: readonly Message[],
@@ -1567,6 +1574,7 @@ export class DefaultZLinkSpotManager {
1567
1574
  throw new ZLinkConfigurationException(`Spot '${spotId}' is not active.`);
1568
1575
  }
1569
1576
  return this.activationLifecycle.dispatchActorPacketDirect(
1577
+ origin,
1570
1578
  activation,
1571
1579
  actorId,
1572
1580
  parts,
@@ -1614,6 +1622,7 @@ export class DefaultZLinkSpotManager {
1614
1622
  readonly workOptions?: import('../execution/serial-execution-queue').ZLinkSerialWorkOptions;
1615
1623
  readonly admissionTimeoutMs?: number;
1616
1624
  readonly signal?: AbortSignal;
1625
+ readonly onAdmitted?: () => void;
1617
1626
  }
1618
1627
  ): Promise<TReply> {
1619
1628
  return await this.routedSpotPackets.request<TReply>(spotId, packetName, request, context);
@@ -1965,6 +1974,7 @@ export class DefaultZLinkSpotManager {
1965
1974
  }
1966
1975
 
1967
1976
  async dispatchMeshActor(
1977
+ origin: ApplicationJobOrigin,
1968
1978
  meshName: string,
1969
1979
  owner: ReadyRecord,
1970
1980
  record: ReceiveRecord
@@ -2027,6 +2037,7 @@ export class DefaultZLinkSpotManager {
2027
2037
  }
2028
2038
  const response = targetsEntrySpot
2029
2039
  ? await this.options.dispatchEntryActorPacket?.(
2040
+ origin,
2030
2041
  actor.actorId,
2031
2042
  record.parts,
2032
2043
  request,
@@ -2036,6 +2047,7 @@ export class DefaultZLinkSpotManager {
2036
2047
  record.messageFollowOrigin
2037
2048
  )
2038
2049
  : await this.dispatchMeshActorPacket(
2050
+ origin,
2039
2051
  meshName,
2040
2052
  spotId,
2041
2053
  actor.actorId,
@@ -2693,6 +2705,7 @@ export class DefaultZLinkSpotManager {
2693
2705
  );
2694
2706
  }
2695
2707
  return await this.options.dispatchEntryActorPacket(
2708
+ 'remote',
2696
2709
  entryActor.context.actorId,
2697
2710
  parts,
2698
2711
  returnResponse,
@@ -2922,6 +2935,7 @@ export class DefaultZLinkSpotManager {
2922
2935
  pendingTransfer.handoffBacklog,
2923
2936
  (parts, returnResponse, remoteBoundSessionTarget, _fallbackActorRef) =>
2924
2937
  this.dispatchActorPacket(
2938
+ 'remote',
2925
2939
  activation,
2926
2940
  actor.context.actorId,
2927
2941
  parts,
@@ -3064,7 +3078,7 @@ export class DefaultZLinkSpotManager {
3064
3078
  }
3065
3079
  const outcome = admission.result ?? (await admission.resultTask);
3066
3080
  if ('error' in outcome) throw outcome.error;
3067
- if (!outcome.accepted || admission.state !== 'admitted') {
3081
+ if (!outcome.accepted || (admission.state !== 'admitted' && admission.state !== 'restoring')) {
3068
3082
  throw new Error(`Actor Join relocation '${relocationId}' has no accepted admission.`);
3069
3083
  }
3070
3084
  const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
@@ -3124,6 +3138,11 @@ export class DefaultZLinkSpotManager {
3124
3138
  return true;
3125
3139
  }
3126
3140
 
3141
+ beginActorJoinRelocation(relocationId: string): () => void {
3142
+ this.formalRemoteActorAdmissions.beginRestore(relocationId);
3143
+ return () => this.formalRemoteActorAdmissions.finishRestore(relocationId);
3144
+ }
3145
+
3127
3146
  async restoreCanonicalActorJoinRecovery(
3128
3147
  recovery: CanonicalActorJoinRecovery,
3129
3148
  signal?: AbortSignal
@@ -3136,7 +3155,11 @@ export class DefaultZLinkSpotManager {
3136
3155
  );
3137
3156
  }
3138
3157
  const outcome = admission.result ?? (await admission.resultTask);
3139
- if ('error' in outcome || !outcome.accepted || admission.state !== 'admitted') {
3158
+ if (
3159
+ 'error' in outcome ||
3160
+ !outcome.accepted ||
3161
+ (admission.state !== 'admitted' && admission.state !== 'restoring')
3162
+ ) {
3140
3163
  throw new Error(
3141
3164
  `Actor Join recovery '${recovery.request.handoffId}' has no accepted admission.`
3142
3165
  );
@@ -3271,6 +3294,7 @@ export class DefaultZLinkSpotManager {
3271
3294
  }
3272
3295
 
3273
3296
  private async dispatchActorPacket(
3297
+ origin: ApplicationJobOrigin,
3274
3298
  activation: ZLinkSpotActivation,
3275
3299
  actorId: string,
3276
3300
  parts: readonly Message[],
@@ -3281,6 +3305,7 @@ export class DefaultZLinkSpotManager {
3281
3305
  messageFollowOrigin?: ZLinkMessageFollowOrigin
3282
3306
  ): Promise<unknown> {
3283
3307
  return await this.activationLifecycle.dispatchActorPacket(
3308
+ origin,
3284
3309
  activation,
3285
3310
  actorId,
3286
3311
  parts,
@@ -3311,6 +3336,7 @@ export class DefaultZLinkSpotManager {
3311
3336
  for (const arrival of drained) {
3312
3337
  try {
3313
3338
  const response = await this.dispatchActorPacket(
3339
+ arrival.origin,
3314
3340
  activation,
3315
3341
  actor.context.actorId,
3316
3342
  [RuntimeMessage.from(arrival.header), RuntimeMessage.from(arrival.payload)],
@@ -3327,6 +3353,7 @@ export class DefaultZLinkSpotManager {
3327
3353
  }
3328
3354
 
3329
3355
  private async dispatchMeshActorPacket(
3356
+ origin: ApplicationJobOrigin,
3330
3357
  meshName: string,
3331
3358
  spotId: RoutingId,
3332
3359
  actorId: string,
@@ -3343,6 +3370,7 @@ export class DefaultZLinkSpotManager {
3343
3370
  );
3344
3371
  }
3345
3372
  return await this.dispatchActorPacket(
3373
+ origin,
3346
3374
  activation,
3347
3375
  actorId,
3348
3376
  parts,
@@ -1,3 +1,4 @@
1
+ import type { ApplicationJobOrigin } from '../application-jobs/contracts';
1
2
  import type {
2
3
  ActorRef,
3
4
  RoutingId,
@@ -100,6 +101,7 @@ export interface ZLinkSpotActivationLifecycleOptions {
100
101
  readonly nodeRid?: RoutingId;
101
102
  readonly nodeRidProvider?: (meshName: string) => RoutingId | undefined;
102
103
  readonly actorCountProvider?: (spotId: RoutingId) => number;
104
+ readonly releaseActorMembers?: (meshName: string, spotId: RoutingId) => Promise<void>;
103
105
  readonly userSpotExecutionMode?: (
104
106
  meshName: string,
105
107
  spotType: Type<ZLinkSpot>
@@ -214,7 +216,10 @@ export class ZLinkSpotActivationLifecycle {
214
216
  );
215
217
  const serialExecutor = new ZLinkSpotSerialExecutor(serial, executionMode, spotId);
216
218
  const actorHandlers = new ZLinkSpotActorHandlerRegistryRuntime();
217
- const handlers = new DefaultZLinkSpotHandlerRegistry(actorHandlers);
219
+ const handlers = new DefaultZLinkSpotHandlerRegistry(
220
+ actorHandlers,
221
+ this.options.providerResolver
222
+ );
218
223
  applySpotHandlerRegistrations(
219
224
  handlers,
220
225
  implementation as unknown as Type<ZLinkSpot>,
@@ -380,7 +385,10 @@ export class ZLinkSpotActivationLifecycle {
380
385
  spotId
381
386
  );
382
387
  const actorHandlers = new ZLinkSpotActorHandlerRegistryRuntime();
383
- const handlers = new DefaultZLinkSpotHandlerRegistry(actorHandlers);
388
+ const handlers = new DefaultZLinkSpotHandlerRegistry(
389
+ actorHandlers,
390
+ this.options.providerResolver
391
+ );
384
392
  const instanceHandlers = new DefaultZLinkInstanceSpotHandlerRegistry(handlers);
385
393
  applySpotHandlerRegistrations(handlers, implementation as unknown as Type<ZLinkSpot>, {
386
394
  packetHandlers: this.options.spotPacketHandlers
@@ -532,7 +540,10 @@ export class ZLinkSpotActivationLifecycle {
532
540
  );
533
541
  const serialExecutor = new ZLinkSpotSerialExecutor(serial, executionMode, spotId);
534
542
  const actorHandlers = new ZLinkSpotActorHandlerRegistryRuntime();
535
- const handlers = new DefaultZLinkSpotHandlerRegistry(actorHandlers);
543
+ const handlers = new DefaultZLinkSpotHandlerRegistry(
544
+ actorHandlers,
545
+ this.options.providerResolver
546
+ );
536
547
  applySpotHandlerRegistrations(handlers, spotType, {
537
548
  actorSendHandlers: this.options.spotActorSendHandlers,
538
549
  actorRequestHandlers: this.options.spotActorRequestHandlers,
@@ -857,6 +868,7 @@ export class ZLinkSpotActivationLifecycle {
857
868
  }
858
869
 
859
870
  async dispatchActorPacket(
871
+ origin: ApplicationJobOrigin,
860
872
  activation: ZLinkSpotActivation,
861
873
  actorId: string,
862
874
  parts: readonly Message[],
@@ -867,6 +879,7 @@ export class ZLinkSpotActivationLifecycle {
867
879
  messageFollowOrigin?: ZLinkMessageFollowOrigin
868
880
  ): Promise<unknown> {
869
881
  return await this.actorAdmission.dispatchActorPacket(
882
+ origin,
870
883
  activation,
871
884
  actorId,
872
885
  parts,
@@ -880,6 +893,7 @@ export class ZLinkSpotActivationLifecycle {
880
893
 
881
894
  /** @internal Dispatches a held Actor record after its handoff owner releases it. */
882
895
  dispatchActorPacketDirect(
896
+ origin: ApplicationJobOrigin,
883
897
  activation: ZLinkSpotActivation,
884
898
  actorId: string,
885
899
  parts: readonly Message[],
@@ -888,6 +902,7 @@ export class ZLinkSpotActivationLifecycle {
888
902
  fallbackActorRef?: ActorRef
889
903
  ): Promise<unknown> {
890
904
  return this.actorAdmission.dispatchActorPacketDirect(
905
+ origin,
891
906
  activation,
892
907
  actorId,
893
908
  parts,
@@ -1044,10 +1059,12 @@ export class ZLinkSpotActivationLifecycle {
1044
1059
  } catch (error) {
1045
1060
  // An OnClosing failure is diagnostic and cleanup continues. It is
1046
1061
  // returned so host shutdown can classify its teardown outcome.
1047
- this.options.closeErrorSink?.reportRuntimeTaskException(
1048
- `spot ${String(activation.spotId)} onClosing`,
1049
- error
1050
- );
1062
+ if (reason !== ZLinkSpotCloseReason.HostShutdown) {
1063
+ this.options.closeErrorSink?.reportRuntimeTaskException(
1064
+ `spot ${String(activation.spotId)} onClosing`,
1065
+ error
1066
+ );
1067
+ }
1051
1068
  closingFailure = error;
1052
1069
  }
1053
1070
  }
@@ -1088,7 +1105,12 @@ export class ZLinkSpotActivationLifecycle {
1088
1105
  }
1089
1106
  if (!state.nativeDisposed) {
1090
1107
  await cleanup(
1091
- () => activation.nativeSpot?.dispose(),
1108
+ async () => {
1109
+ if (reason === ZLinkSpotCloseReason.HostShutdown) {
1110
+ await this.options.releaseActorMembers?.(locationMeshName, activation.spotId);
1111
+ }
1112
+ await activation.nativeSpot?.dispose();
1113
+ },
1092
1114
  () => {
1093
1115
  state.nativeDisposed = true;
1094
1116
  }
@@ -1116,8 +1138,9 @@ export class ZLinkSpotActivationLifecycle {
1116
1138
  }
1117
1139
  );
1118
1140
  }
1119
- if (errors.length === 1) throw errors[0];
1120
- if (errors.length > 1) {
1141
+ if (errors.length > 0) {
1142
+ if (closingFailure !== undefined) errors.unshift(closingFailure);
1143
+ if (errors.length === 1) throw errors[0];
1121
1144
  throw new AggregateError(errors, `Spot '${activation.spotId}' cleanup failed.`);
1122
1145
  }
1123
1146
  return closingFailure;
@@ -1,3 +1,5 @@
1
+ import { currentApplicationJobOrigin } from '../application-jobs/application-job-queue-scope';
2
+ import type { ApplicationJobOrigin } from '../application-jobs/contracts';
1
3
  import type { ActorRef, ZLinkActor } from '../../contracts';
2
4
  import type { Message } from '../../contracts/Common/Message';
3
5
  import type { ZLinkMessageFollowOrigin } from '../foundation/service-runtime-contracts';
@@ -39,6 +41,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
39
41
  constructor(private readonly options: AdmissionOptions) {}
40
42
 
41
43
  async dispatchActorPacket(
44
+ origin: ApplicationJobOrigin,
42
45
  activation: ZLinkSpotActivation,
43
46
  actorId: string,
44
47
  parts: readonly Message[],
@@ -49,6 +52,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
49
52
  messageFollowOrigin?: ZLinkMessageFollowOrigin
50
53
  ): Promise<unknown> {
51
54
  const handoff = this.options.actorHandoffRuntime?.capture(
55
+ origin,
52
56
  actorId,
53
57
  parts,
54
58
  returnResponse,
@@ -63,6 +67,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
63
67
  replayFallbackActorRef
64
68
  ) =>
65
69
  this.dispatchActorPacketDirect(
70
+ origin,
66
71
  activation,
67
72
  actorId,
68
73
  replayedParts,
@@ -73,6 +78,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
73
78
  );
74
79
  if (handoff !== undefined) return await handoff;
75
80
  return await this.dispatchActorPacketDirect(
81
+ origin,
76
82
  activation,
77
83
  actorId,
78
84
  parts,
@@ -116,6 +122,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
116
122
  packets: {
117
123
  handle: (delivery) =>
118
124
  this.dispatchActorPacket(
125
+ 'remote',
119
126
  activation,
120
127
  delivery.actorId,
121
128
  delivery.parts,
@@ -149,6 +156,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
149
156
 
150
157
  /** @internal Dispatches a coordinator-owned replay without recapturing it. */
151
158
  dispatchActorPacketDirect(
159
+ origin: ApplicationJobOrigin,
152
160
  activation: ZLinkSpotActivation,
153
161
  actorId: string,
154
162
  parts: readonly Message[],
@@ -159,6 +167,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
159
167
  ): Promise<unknown> {
160
168
  return activation.executeActor(actorId, (actorSerial) =>
161
169
  this.dispatchActorPacketInActorTurn(
170
+ origin,
162
171
  activation,
163
172
  actorSerial,
164
173
  actorId,
@@ -190,6 +199,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
190
199
  record.drain((parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef) =>
191
200
  executeChild((actorSerial) =>
192
201
  this.dispatchActorPacketInActorTurn(
202
+ currentApplicationJobOrigin(),
193
203
  activation,
194
204
  actorSerial,
195
205
  actorId,
@@ -217,6 +227,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
217
227
  }
218
228
 
219
229
  private dispatchActorPacketInActorTurn(
230
+ origin: ApplicationJobOrigin,
220
231
  activation: ZLinkSpotActivation,
221
232
  actorSerial: ZLinkSpotSerialTurnExecutor,
222
233
  actorId: string,
@@ -250,6 +261,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
250
261
  dispatchErrors: this.options.dispatchErrors,
251
262
  routeToActorJoinPrewarm: this.options.routeToActorJoinPrewarm
252
263
  }).dispatch(
264
+ origin,
253
265
  actorId,
254
266
  parts,
255
267
  returnResponse,
@@ -305,6 +317,7 @@ export class ZLinkSpotActorAdmissionCoordinator {
305
317
  backlog,
306
318
  (parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef) =>
307
319
  this.dispatchActorPacketDirect(
320
+ 'remote',
308
321
  activation,
309
322
  actor.context.actorId,
310
323
  parts,
@@ -1,3 +1,4 @@
1
+ import type { ApplicationJobOrigin } from '../application-jobs/contracts';
1
2
  import {
2
3
  ZLinkFrameworkInternalErrorKind,
3
4
  createInternalFrameworkException,
@@ -57,6 +58,7 @@ export interface ZLinkActorRequestTerminal {
57
58
 
58
59
  /** One admitted Actor packet and the routing context that must move with it. */
59
60
  export interface ZLinkActorPacketDelivery {
61
+ readonly origin: ApplicationJobOrigin;
60
62
  readonly actorId: string;
61
63
  readonly parts: readonly Message[];
62
64
  readonly returnResponse: boolean;
@@ -79,6 +81,7 @@ export type ZLinkRouteToActorJoinPrewarm = (
79
81
  actorId: string,
80
82
  objectGeneration: bigint,
81
83
  arrival: {
84
+ readonly origin: ApplicationJobOrigin;
82
85
  readonly header: Buffer;
83
86
  readonly payload: Buffer;
84
87
  readonly returnResponse: boolean;
@@ -133,6 +136,7 @@ export class ZLinkSpotActorPacketDispatch {
133
136
  constructor(private readonly options: ZLinkSpotActorPacketDispatchOptions) {}
134
137
 
135
138
  dispatch(
139
+ origin: ApplicationJobOrigin,
136
140
  actorId: string,
137
141
  parts: readonly Message[],
138
142
  returnResponse = false,
@@ -141,6 +145,7 @@ export class ZLinkSpotActorPacketDispatch {
141
145
  requestTerminal?: ZLinkActorRequestTerminal
142
146
  ): Promise<unknown> {
143
147
  return this.dispatchDelivery({
148
+ origin,
144
149
  actorId,
145
150
  parts,
146
151
  returnResponse,
@@ -212,6 +217,7 @@ export class ZLinkSpotActorPacketDispatch {
212
217
  const actor = this.options.resolveActor(actorId);
213
218
  if (actor === undefined) {
214
219
  return this.handleMissingActor(
220
+ delivery.origin,
215
221
  actorId,
216
222
  parts,
217
223
  header,
@@ -250,6 +256,7 @@ export class ZLinkSpotActorPacketDispatch {
250
256
  }
251
257
 
252
258
  private async handleMissingActor(
259
+ origin: ApplicationJobOrigin,
253
260
  actorId: string,
254
261
  parts: readonly Message[],
255
262
  header: ReturnType<typeof decodeStreamHeader>,
@@ -271,6 +278,7 @@ export class ZLinkSpotActorPacketDispatch {
271
278
  (messageKind !== ZLinkDispatchMessageKind.ActorRequest || requestTerminal !== undefined)
272
279
  ) {
273
280
  const parked = this.parkForActorJoinPrewarm(
281
+ origin,
274
282
  actorId,
275
283
  parts,
276
284
  messageKind,
@@ -328,6 +336,7 @@ export class ZLinkSpotActorPacketDispatch {
328
336
  * lifetime.
329
337
  */
330
338
  private parkForActorJoinPrewarm(
339
+ origin: ApplicationJobOrigin,
331
340
  actorId: string,
332
341
  parts: readonly Message[],
333
342
  messageKind: ZLinkDispatchMessageKind,
@@ -369,6 +378,7 @@ export class ZLinkSpotActorPacketDispatch {
369
378
  actorId,
370
379
  fallbackActorRef.objectGeneration,
371
380
  {
381
+ origin,
372
382
  header: Buffer.from(parts[0].data()),
373
383
  payload: Buffer.from(parts[1].data()),
374
384
  returnResponse,