@zlink-systems/framework 0.30.3 → 0.32.0

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 (398) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Actors/ZLinkActor.d.ts +2 -0
  3. package/dist/contracts/Actors/ZLinkSessionBindingIdentity.d.ts +6 -0
  4. package/dist/contracts/Actors/ZLinkSessionBindingIdentity.js +2 -0
  5. package/dist/contracts/Actors/index.d.ts +1 -0
  6. package/dist/contracts/Actors/index.js +1 -0
  7. package/dist/contracts/Common/CoreTypes.d.ts +1 -0
  8. package/dist/contracts/Common/HandlerMessageType.d.ts +8 -0
  9. package/dist/contracts/Common/HandlerMessageType.js +41 -0
  10. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +1 -1
  11. package/dist/contracts/Common/ZLinkEncodedPayload.js +12 -20
  12. package/dist/contracts/Common/ZLinkMessage.js +11 -7
  13. package/dist/contracts/Common/encoded-payload-storage.d.ts +0 -2
  14. package/dist/contracts/Common/encoded-payload-storage.js +4 -16
  15. package/dist/contracts/Common/index.d.ts +1 -1
  16. package/dist/contracts/Common/payload-slab.d.ts +4 -0
  17. package/dist/contracts/Common/payload-slab.js +30 -0
  18. package/dist/contracts/Configuration/RegistrationBuilders.js +15 -9
  19. package/dist/contracts/Configuration/RegistrationTypes.d.ts +19 -0
  20. package/dist/contracts/Handlers/Contexts.d.ts +1 -0
  21. package/dist/contracts/Locations/Authority.d.ts +2 -0
  22. package/dist/internal.d.ts +9 -0
  23. package/dist/internal.js +23 -1
  24. package/dist/nest-integration.d.ts +1 -0
  25. package/dist/nest-integration.js +3 -1
  26. package/dist/runtime/actors/actor-client.d.ts +6 -2
  27. package/dist/runtime/actors/actor-client.js +120 -82
  28. package/dist/runtime/actors/actor-context.js +16 -5
  29. package/dist/runtime/actors/actor-execution-context.js +2 -2
  30. package/dist/runtime/actors/actor-handoff.d.ts +12 -1
  31. package/dist/runtime/actors/actor-handoff.js +79 -34
  32. package/dist/runtime/actors/actor-join-deferred-scope.js +6 -6
  33. package/dist/runtime/actors/actor-local-native-join.d.ts +2 -2
  34. package/dist/runtime/actors/actor-local-native-join.js +19 -17
  35. package/dist/runtime/actors/actor-mailbox.d.ts +1 -1
  36. package/dist/runtime/actors/actor-remote-joiner.d.ts +2 -2
  37. package/dist/runtime/actors/actor-remote-joiner.js +4 -4
  38. package/dist/runtime/actors/actor-routed-join-transport.d.ts +9 -3
  39. package/dist/runtime/actors/actor-routed-json-request.d.ts +3 -0
  40. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -2
  41. package/dist/runtime/actors/actor-runtime-state.d.ts +1 -1
  42. package/dist/runtime/actors/spot-actor-dispatch.d.ts +9 -5
  43. package/dist/runtime/actors/spot-actor-dispatch.js +60 -38
  44. package/dist/runtime/admission.d.ts +6 -4
  45. package/dist/runtime/admission.js +21 -10
  46. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +1 -0
  47. package/dist/runtime/application-jobs/application-ingress-record-owner.js +3 -0
  48. package/dist/runtime/backend/contracts/index.d.ts +26 -10
  49. package/dist/runtime/backend/mesh-completion-table.d.ts +7 -1
  50. package/dist/runtime/backend/mesh-completion-table.js +84 -20
  51. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +19 -6
  52. package/dist/runtime/backend/mesh-dispatch-pump.js +246 -147
  53. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -2
  54. package/dist/runtime/backend/node/node-backend-adapter-support.js +27 -19
  55. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +5 -2
  56. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +70 -13
  57. package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
  58. package/dist/runtime/backend/node/node-event-loop-poller.js +4 -3
  59. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +5 -1
  60. package/dist/runtime/backend/node/node-raw-binding-port.d.ts +7 -2
  61. package/dist/runtime/backend/node/node-raw-binding-port.js +99 -63
  62. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +34 -16
  63. package/dist/runtime/backend/node/node-raw-mesh-backend.js +210 -106
  64. package/dist/runtime/backend/node/node-socket-backend-adapter.js +20 -6
  65. package/dist/runtime/backend/raw-binding-port.d.ts +6 -3
  66. package/dist/runtime/channels/channel-clients.js +3 -3
  67. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +11 -7
  68. package/dist/runtime/channels/channel-dispatch-pipeline.js +40 -22
  69. package/dist/runtime/channels/channel-dispatch-services.d.ts +3 -1
  70. package/dist/runtime/channels/channel-dispatch-services.js +7 -6
  71. package/dist/runtime/channels/channel-dispatchers.d.ts +13 -6
  72. package/dist/runtime/channels/channel-dispatchers.js +57 -36
  73. package/dist/runtime/channels/channel-envelope.d.ts +2 -2
  74. package/dist/runtime/channels/channel-envelope.js +609 -83
  75. package/dist/runtime/channels/channel-multipart.d.ts +1 -0
  76. package/dist/runtime/channels/channel-multipart.js +10 -6
  77. package/dist/runtime/channels/channel-outbound-operations.d.ts +6 -9
  78. package/dist/runtime/channels/channel-outbound-operations.js +107 -105
  79. package/dist/runtime/channels/channel-receive-loops.d.ts +9 -7
  80. package/dist/runtime/channels/channel-receive-loops.js +126 -90
  81. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +23 -6
  82. package/dist/runtime/channels/channel-runtime-lifecycle.js +47 -38
  83. package/dist/runtime/channels/channel-runtime-manager.d.ts +13 -6
  84. package/dist/runtime/channels/channel-runtime-manager.js +32 -14
  85. package/dist/runtime/channels/channel-socket-registry.d.ts +28 -4
  86. package/dist/runtime/channels/channel-socket-registry.js +9 -1
  87. package/dist/runtime/channels/channel-transports.d.ts +23 -16
  88. package/dist/runtime/channels/channel-transports.js +139 -119
  89. package/dist/runtime/channels/dispatch-error-reporter.d.ts +4 -4
  90. package/dist/runtime/channels/dispatch-error-reporter.js +5 -5
  91. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  92. package/dist/runtime/channels/local-spot-route-transport.d.ts +5 -2
  93. package/dist/runtime/channels/local-spot-route-transport.js +15 -18
  94. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +6 -3
  95. package/dist/runtime/channels/router-socket-spot-route-transport.js +33 -19
  96. package/dist/runtime/channels/source-spot-router.d.ts +6 -3
  97. package/dist/runtime/channels/source-spot-router.js +34 -23
  98. package/dist/runtime/channels/spot-node-route-transport.d.ts +6 -3
  99. package/dist/runtime/channels/spot-node-route-transport.js +23 -17
  100. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +6 -3
  101. package/dist/runtime/channels/spot-route-bridge-transport.js +38 -24
  102. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +8 -4
  103. package/dist/runtime/channels/spot-route-dispatch-strategy.js +36 -23
  104. package/dist/runtime/diagnostics/dispatch-error-details.js +9 -3
  105. package/dist/runtime/diagnostics/message-flow-bootstrap.d.ts +1 -0
  106. package/dist/runtime/diagnostics/message-flow-bootstrap.js +8 -0
  107. package/dist/runtime/diagnostics/message-flow-delivery.d.ts +47 -0
  108. package/dist/runtime/diagnostics/message-flow-delivery.js +149 -0
  109. package/dist/runtime/diagnostics/message-flow-record.d.ts +50 -0
  110. package/dist/runtime/diagnostics/message-flow-record.js +228 -0
  111. package/dist/runtime/diagnostics/message-flow-worker.d.ts +1 -0
  112. package/dist/runtime/diagnostics/message-flow-worker.js +118 -0
  113. package/dist/runtime/diagnostics/message-flow.d.ts +7 -19
  114. package/dist/runtime/diagnostics/message-flow.js +42 -290
  115. package/dist/runtime/diagnostics/runtime-metrics.d.ts +4 -3
  116. package/dist/runtime/diagnostics/runtime-metrics.js +8 -4
  117. package/dist/runtime/execution/index.d.ts +1 -0
  118. package/dist/runtime/execution/index.js +6 -3
  119. package/dist/runtime/execution/serial-execution-queue.d.ts +26 -13
  120. package/dist/runtime/execution/serial-execution-queue.js +75 -71
  121. package/dist/runtime/foundation/durable-service-request.d.ts +12 -3
  122. package/dist/runtime/foundation/durable-service-request.js +158 -73
  123. package/dist/runtime/foundation/operation-registry.d.ts +33 -3
  124. package/dist/runtime/foundation/operation-registry.js +272 -33
  125. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +62 -23
  126. package/dist/runtime/foundation/raw-service-mesh-runtime.js +373 -194
  127. package/dist/runtime/foundation/request-runtime.d.ts +17 -0
  128. package/dist/runtime/foundation/request-runtime.js +163 -0
  129. package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
  130. package/dist/runtime/foundation/service-discovery-registry.js +6 -0
  131. package/dist/runtime/foundation/service-liveness-registry.d.ts +1 -1
  132. package/dist/runtime/foundation/service-mailbox.d.ts +4 -2
  133. package/dist/runtime/foundation/service-mailbox.js +4 -1
  134. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -2
  135. package/dist/runtime/foundation/service-relocation-object-owner.js +12 -5
  136. package/dist/runtime/foundation/service-runtime-contracts.d.ts +7 -2
  137. package/dist/runtime/foundation/service-stateful-registry.d.ts +6 -2
  138. package/dist/runtime/foundation/service-stateful-registry.js +38 -17
  139. package/dist/runtime/foundation/service-stateful-runtime.d.ts +91 -26
  140. package/dist/runtime/foundation/service-stateful-runtime.js +245 -120
  141. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -0
  142. package/dist/runtime/foundation/service-stateful-wire-codec.js +15 -0
  143. package/dist/runtime/foundation/service-topology-registry.d.ts +2 -0
  144. package/dist/runtime/foundation/service-topology-registry.js +13 -3
  145. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  146. package/dist/runtime/foundation/service-wire-constants.generated.js +12 -0
  147. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +5 -1
  148. package/dist/runtime/foundation/service-wire-m6a-codec.js +50 -15
  149. package/dist/runtime/host/actor-packet-relay.d.ts +5 -6
  150. package/dist/runtime/host/actor-packet-relay.js +58 -57
  151. package/dist/runtime/host/actor-placement-coordinator.d.ts +1 -1
  152. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
  153. package/dist/runtime/host/actor-runtime-options-factory.js +3 -2
  154. package/dist/runtime/host/actor-transfer-runtime.d.ts +3 -3
  155. package/dist/runtime/host/application-job-queue.d.ts +7 -5
  156. package/dist/runtime/host/application-job-queue.js +33 -21
  157. package/dist/runtime/host/bound-session-relay.js +0 -1
  158. package/dist/runtime/host/channel-runtime-options-factory.d.ts +2 -0
  159. package/dist/runtime/host/channel-runtime-options-factory.js +1 -0
  160. package/dist/runtime/host/entry-actor-runtime.d.ts +5 -2
  161. package/dist/runtime/host/entry-actor-runtime.js +2 -2
  162. package/dist/runtime/host/index.d.ts +106 -37
  163. package/dist/runtime/host/index.js +303 -151
  164. package/dist/runtime/host/location-runtime-owner.d.ts +2 -2
  165. package/dist/runtime/host/location-runtime-owner.js +1 -1
  166. package/dist/runtime/host/service-relocation-host-runtime.d.ts +195 -45
  167. package/dist/runtime/host/service-relocation-host-runtime.js +257 -144
  168. package/dist/runtime/host/spot-address-transport.d.ts +3 -0
  169. package/dist/runtime/host/spot-address-transport.js +73 -76
  170. package/dist/runtime/host/spot-runtime-options-factory.js +2 -0
  171. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -1
  172. package/dist/runtime/host/user-spot-creation-coordinator.js +49 -21
  173. package/dist/runtime/internal-observation.d.ts +1 -0
  174. package/dist/runtime/internal-observation.js +5 -0
  175. package/dist/runtime/locations/actor-location-claims.d.ts +1 -1
  176. package/dist/runtime/locations/actor-location-claims.js +15 -6
  177. package/dist/runtime/locations/auto-connect-loop.d.ts +0 -1
  178. package/dist/runtime/locations/auto-connect-loop.js +25 -19
  179. package/dist/runtime/locations/auto-connect-planner.js +2 -5
  180. package/dist/runtime/locations/auto-connect-reconciler.d.ts +1 -0
  181. package/dist/runtime/locations/auto-connect-reconciler.js +35 -23
  182. package/dist/runtime/locations/in-memory-authority-store.d.ts +1 -0
  183. package/dist/runtime/locations/in-memory-authority-store.js +15 -5
  184. package/dist/runtime/locations/in-memory-location-store.d.ts +0 -2
  185. package/dist/runtime/locations/in-memory-location-store.js +1 -38
  186. package/dist/runtime/locations/lifecycle.d.ts +1 -1
  187. package/dist/runtime/locations/lifecycle.js +2 -2
  188. package/dist/runtime/locations/location-store-repository.d.ts +0 -1
  189. package/dist/runtime/locations/location-store-repository.js +163 -246
  190. package/dist/runtime/locations/resolvers.d.ts +8 -1
  191. package/dist/runtime/locations/resolvers.js +16 -2
  192. package/dist/runtime/locations/runtime.d.ts +3 -3
  193. package/dist/runtime/locations/runtime.js +12 -16
  194. package/dist/runtime/messaging/creation-payload-codec.js +8 -7
  195. package/dist/runtime/messaging/framework-json-v1.d.ts +1 -1
  196. package/dist/runtime/messaging/framework-json-v1.js +6 -2
  197. package/dist/runtime/messaging/payload-codec.js +21 -35
  198. package/dist/runtime/messaging/request-deadline.d.ts +4 -2
  199. package/dist/runtime/messaging/request-deadline.js +40 -25
  200. package/dist/runtime/messaging/request-result.d.ts +14 -1
  201. package/dist/runtime/messaging/request-result.js +74 -13
  202. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +4 -0
  203. package/dist/runtime/protocol/service_wire_codec.generated.js +17 -7
  204. package/dist/runtime/spots/index.d.ts +28 -7
  205. package/dist/runtime/spots/index.js +31 -6
  206. package/dist/runtime/spots/spot-activation-registry.d.ts +3 -2
  207. package/dist/runtime/spots/spot-activation-registry.js +13 -8
  208. package/dist/runtime/spots/spot-activation-state.d.ts +2 -0
  209. package/dist/runtime/spots/spot-activation-state.js +1 -0
  210. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +9 -4
  211. package/dist/runtime/spots/spot-actor-admission-coordinator.js +33 -12
  212. package/dist/runtime/spots/spot-actor-ingress-admission.d.ts +40 -0
  213. package/dist/runtime/spots/spot-actor-ingress-admission.js +78 -0
  214. package/dist/runtime/spots/spot-actor-membership.js +3 -3
  215. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +16 -43
  216. package/dist/runtime/spots/spot-actor-packet-dispatch.js +56 -113
  217. package/dist/runtime/spots/spot-actor-packet-drain.d.ts +1 -0
  218. package/dist/runtime/spots/spot-actor-packet-drain.js +12 -5
  219. package/dist/runtime/spots/spot-entry-activation.d.ts +4 -3
  220. package/dist/runtime/spots/spot-entry-activation.js +7 -12
  221. package/dist/runtime/spots/spot-handler-registry.d.ts +5 -1
  222. package/dist/runtime/spots/spot-handler-registry.js +31 -15
  223. package/dist/runtime/spots/spot-manager-public.js +3 -2
  224. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +11 -6
  225. package/dist/runtime/spots/spot-node-runtime-manager.js +6 -1
  226. package/dist/runtime/spots/spot-outbound.d.ts +8 -2
  227. package/dist/runtime/spots/spot-outbound.js +5 -5
  228. package/dist/runtime/spots/spot-route-packet-dispatch.js +13 -8
  229. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +3 -3
  230. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +9 -5
  231. package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -2
  232. package/dist/runtime/spots/spot-serial-executor.d.ts +2 -1
  233. package/dist/runtime/spots/spot-serial-turn-executor.js +20 -26
  234. package/dist/runtime/spots/spot-subscription-dispatch.js +5 -2
  235. package/dist/runtime/spots/spot-timer.d.ts +1 -1
  236. package/dist/runtime/streams/actor-session-binding-registry.d.ts +11 -3
  237. package/dist/runtime/streams/actor-session-binding-registry.js +28 -0
  238. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -2
  239. package/dist/runtime/streams/bound-actor-relay-sender.js +3 -4
  240. package/dist/runtime/streams/bound-session-service.js +6 -7
  241. package/dist/runtime/streams/index.d.ts +3 -3
  242. package/dist/runtime/streams/index.js +22 -2
  243. package/dist/runtime/streams/managed-stream.js +2 -1
  244. package/dist/runtime/streams/session-calls.d.ts +1 -1
  245. package/dist/runtime/streams/session-calls.js +3 -9
  246. package/dist/runtime/streams/session-context.d.ts +2 -2
  247. package/dist/runtime/streams/session-context.js +2 -2
  248. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -0
  249. package/dist/runtime/streams/stream-session-runtime.js +64 -33
  250. package/package.json +3 -3
  251. package/src/contracts/Actors/ZLinkActor.ts +6 -0
  252. package/src/contracts/Actors/ZLinkSessionBindingIdentity.ts +7 -0
  253. package/src/contracts/Actors/index.ts +1 -0
  254. package/src/contracts/Common/CoreTypes.ts +1 -0
  255. package/src/contracts/Common/HandlerMessageType.ts +50 -0
  256. package/src/contracts/Common/ZLinkEncodedPayload.ts +13 -25
  257. package/src/contracts/Common/ZLinkMessage.ts +11 -7
  258. package/src/contracts/Common/encoded-payload-storage.ts +4 -16
  259. package/src/contracts/Common/index.ts +1 -1
  260. package/src/contracts/Common/payload-slab.ts +29 -0
  261. package/src/contracts/Configuration/RegistrationBuilders.ts +29 -15
  262. package/src/contracts/Configuration/RegistrationTypes.ts +19 -0
  263. package/src/contracts/Handlers/Contexts.ts +1 -0
  264. package/src/contracts/Locations/Authority.ts +7 -1
  265. package/src/internal.ts +17 -0
  266. package/src/nest-integration.ts +1 -0
  267. package/src/runtime/actors/actor-client.ts +257 -163
  268. package/src/runtime/actors/actor-context.ts +26 -14
  269. package/src/runtime/actors/actor-execution-context.ts +2 -2
  270. package/src/runtime/actors/actor-handoff.ts +86 -51
  271. package/src/runtime/actors/actor-join-deferred-scope.ts +6 -6
  272. package/src/runtime/actors/actor-local-native-join.ts +38 -17
  273. package/src/runtime/actors/actor-mailbox.ts +1 -1
  274. package/src/runtime/actors/actor-remote-joiner.ts +8 -4
  275. package/src/runtime/actors/actor-routed-join-transport.ts +13 -5
  276. package/src/runtime/actors/actor-routed-json-request.ts +3 -0
  277. package/src/runtime/actors/actor-runtime-contracts.ts +4 -2
  278. package/src/runtime/actors/actor-runtime-state.ts +1 -1
  279. package/src/runtime/actors/spot-actor-dispatch.ts +70 -68
  280. package/src/runtime/admission.ts +42 -15
  281. package/src/runtime/application-jobs/application-ingress-record-owner.ts +4 -0
  282. package/src/runtime/backend/contracts/index.ts +77 -10
  283. package/src/runtime/backend/mesh-completion-table.ts +106 -15
  284. package/src/runtime/backend/mesh-dispatch-pump.ts +294 -146
  285. package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -32
  286. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +91 -34
  287. package/src/runtime/backend/node/node-event-loop-poller.ts +14 -5
  288. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +5 -1
  289. package/src/runtime/backend/node/node-raw-binding-port.ts +180 -69
  290. package/src/runtime/backend/node/node-raw-mesh-backend.ts +386 -157
  291. package/src/runtime/backend/node/node-socket-backend-adapter.ts +56 -11
  292. package/src/runtime/backend/raw-binding-port.ts +13 -5
  293. package/src/runtime/channels/channel-clients.ts +26 -11
  294. package/src/runtime/channels/channel-dispatch-pipeline.ts +77 -65
  295. package/src/runtime/channels/channel-dispatch-services.ts +7 -12
  296. package/src/runtime/channels/channel-dispatchers.ts +93 -39
  297. package/src/runtime/channels/channel-envelope.ts +680 -144
  298. package/src/runtime/channels/channel-multipart.ts +17 -13
  299. package/src/runtime/channels/channel-outbound-operations.ts +204 -178
  300. package/src/runtime/channels/channel-receive-loops.ts +160 -107
  301. package/src/runtime/channels/channel-runtime-lifecycle.ts +64 -59
  302. package/src/runtime/channels/channel-runtime-manager.ts +74 -27
  303. package/src/runtime/channels/channel-socket-registry.ts +20 -5
  304. package/src/runtime/channels/channel-transports.ts +414 -287
  305. package/src/runtime/channels/dispatch-error-reporter.ts +4 -9
  306. package/src/runtime/channels/local-spot-route-transport.ts +27 -29
  307. package/src/runtime/channels/router-socket-spot-route-transport.ts +63 -32
  308. package/src/runtime/channels/source-spot-router.ts +75 -38
  309. package/src/runtime/channels/spot-node-route-transport.ts +67 -37
  310. package/src/runtime/channels/spot-route-bridge-transport.ts +62 -30
  311. package/src/runtime/channels/spot-route-dispatch-strategy.ts +105 -34
  312. package/src/runtime/diagnostics/dispatch-error-details.ts +10 -2
  313. package/src/runtime/diagnostics/message-flow-bootstrap.ts +6 -0
  314. package/src/runtime/diagnostics/message-flow-delivery.ts +171 -0
  315. package/src/runtime/diagnostics/message-flow-record.ts +295 -0
  316. package/src/runtime/diagnostics/message-flow-worker.ts +146 -0
  317. package/src/runtime/diagnostics/message-flow.ts +49 -362
  318. package/src/runtime/diagnostics/runtime-metrics.ts +10 -4
  319. package/src/runtime/execution/index.ts +6 -0
  320. package/src/runtime/execution/serial-execution-queue.ts +94 -96
  321. package/src/runtime/foundation/durable-service-request.ts +212 -89
  322. package/src/runtime/foundation/operation-registry.ts +287 -38
  323. package/src/runtime/foundation/raw-service-mesh-runtime.ts +617 -292
  324. package/src/runtime/foundation/request-runtime.ts +227 -0
  325. package/src/runtime/foundation/service-discovery-registry.ts +7 -0
  326. package/src/runtime/foundation/service-liveness-registry.ts +1 -1
  327. package/src/runtime/foundation/service-mailbox.ts +7 -2
  328. package/src/runtime/foundation/service-relocation-object-owner.ts +21 -6
  329. package/src/runtime/foundation/service-runtime-contracts.ts +12 -2
  330. package/src/runtime/foundation/service-stateful-registry.ts +52 -19
  331. package/src/runtime/foundation/service-stateful-runtime.ts +365 -198
  332. package/src/runtime/foundation/service-stateful-wire-codec.ts +18 -0
  333. package/src/runtime/foundation/service-topology-registry.ts +21 -3
  334. package/src/runtime/foundation/service-wire-constants.generated.ts +10 -0
  335. package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -17
  336. package/src/runtime/host/actor-packet-relay.ts +160 -156
  337. package/src/runtime/host/actor-placement-coordinator.ts +1 -1
  338. package/src/runtime/host/actor-runtime-options-factory.ts +7 -2
  339. package/src/runtime/host/actor-transfer-runtime.ts +3 -3
  340. package/src/runtime/host/application-job-queue.ts +56 -27
  341. package/src/runtime/host/bound-session-relay.ts +0 -1
  342. package/src/runtime/host/channel-runtime-options-factory.ts +3 -0
  343. package/src/runtime/host/entry-actor-runtime.ts +14 -6
  344. package/src/runtime/host/index.ts +388 -113
  345. package/src/runtime/host/location-runtime-owner.ts +3 -3
  346. package/src/runtime/host/service-relocation-host-runtime.ts +380 -252
  347. package/src/runtime/host/spot-address-transport.ts +110 -95
  348. package/src/runtime/host/spot-runtime-options-factory.ts +3 -0
  349. package/src/runtime/host/user-spot-creation-coordinator.ts +69 -22
  350. package/src/runtime/internal-observation.ts +2 -0
  351. package/src/runtime/locations/actor-location-claims.ts +42 -16
  352. package/src/runtime/locations/auto-connect-loop.ts +24 -16
  353. package/src/runtime/locations/auto-connect-planner.ts +2 -5
  354. package/src/runtime/locations/auto-connect-reconciler.ts +37 -24
  355. package/src/runtime/locations/in-memory-authority-store.ts +27 -7
  356. package/src/runtime/locations/in-memory-location-store.ts +1 -74
  357. package/src/runtime/locations/lifecycle.ts +4 -2
  358. package/src/runtime/locations/location-store-repository.ts +228 -308
  359. package/src/runtime/locations/resolvers.ts +20 -8
  360. package/src/runtime/locations/runtime.ts +16 -28
  361. package/src/runtime/messaging/creation-payload-codec.ts +12 -10
  362. package/src/runtime/messaging/framework-json-v1.ts +10 -1
  363. package/src/runtime/messaging/payload-codec.ts +50 -75
  364. package/src/runtime/messaging/request-deadline.ts +47 -39
  365. package/src/runtime/messaging/request-result.ts +88 -17
  366. package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
  367. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
  368. package/src/runtime/spots/index.ts +57 -10
  369. package/src/runtime/spots/spot-activation-registry.ts +12 -8
  370. package/src/runtime/spots/spot-activation-state.ts +2 -0
  371. package/src/runtime/spots/spot-actor-admission-coordinator.ts +62 -37
  372. package/src/runtime/spots/spot-actor-ingress-admission.ts +157 -0
  373. package/src/runtime/spots/spot-actor-membership.ts +8 -5
  374. package/src/runtime/spots/spot-actor-packet-dispatch.ts +122 -206
  375. package/src/runtime/spots/spot-actor-packet-drain.ts +21 -6
  376. package/src/runtime/spots/spot-entry-activation.ts +25 -35
  377. package/src/runtime/spots/spot-handler-registry.ts +72 -15
  378. package/src/runtime/spots/spot-manager-public.ts +4 -2
  379. package/src/runtime/spots/spot-node-runtime-manager.ts +16 -7
  380. package/src/runtime/spots/spot-outbound.ts +26 -10
  381. package/src/runtime/spots/spot-route-packet-dispatch.ts +18 -8
  382. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +14 -8
  383. package/src/runtime/spots/spot-runtime-ports.ts +5 -2
  384. package/src/runtime/spots/spot-serial-executor.ts +1 -1
  385. package/src/runtime/spots/spot-serial-turn-executor.ts +25 -40
  386. package/src/runtime/spots/spot-subscription-dispatch.ts +9 -2
  387. package/src/runtime/spots/spot-timer.ts +1 -1
  388. package/src/runtime/streams/actor-session-binding-registry.ts +46 -3
  389. package/src/runtime/streams/bound-actor-relay-sender.ts +16 -5
  390. package/src/runtime/streams/bound-session-service.ts +10 -7
  391. package/src/runtime/streams/index.ts +30 -4
  392. package/src/runtime/streams/managed-stream.ts +2 -1
  393. package/src/runtime/streams/session-calls.ts +9 -14
  394. package/src/runtime/streams/session-context.ts +6 -11
  395. package/src/runtime/streams/stream-session-runtime.ts +79 -40
  396. package/dist/runtime/spots/spot-lifecycle-metrics.d.ts +0 -8
  397. package/dist/runtime/spots/spot-lifecycle-metrics.js +0 -17
  398. package/src/runtime/spots/spot-lifecycle-metrics.ts +0 -16
@@ -1,3 +1,4 @@
1
+ import { macrotaskBoundary } from '../abort';
1
2
  import type { ZLinkRuntimeMetrics } from '../diagnostics/runtime-metrics';
2
3
  import { routingIdsEqual, toBackendRoutingId } from '../routing-id';
3
4
  import {
@@ -205,12 +206,6 @@ interface OwnerCleanupCandidate {
205
206
  readonly scanVersion: ZLinkStoreVersion;
206
207
  }
207
208
 
208
- interface OwnerCleanupRecord {
209
- readonly descriptor: OwnedStoreRecord;
210
- }
211
-
212
- const MAX_OWNER_CLEANUP_BATCH_ROWS = 2_047;
213
-
214
209
  /**
215
210
  * Maps framework domain records to the minimal provider SPI.
216
211
  *
@@ -461,7 +456,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
461
456
  },
462
457
  signal
463
458
  );
464
- if (result.kind === 'conflict') continue;
459
+ if (result.kind === 'conflict') {
460
+ await macrotaskBoundary();
461
+ continue;
462
+ }
465
463
  const storeVersion = result.putVersions.find(
466
464
  (entry) => entry.key.value === rowKey.value
467
465
  )?.version;
@@ -547,7 +545,12 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
547
545
  }
548
546
  )
549
547
  : [];
550
- if (membershipConditions === undefined) return { kind: 'conflict', current: snapshot };
548
+ if (!Array.isArray(membershipConditions))
549
+ return {
550
+ kind: 'conflict',
551
+ current: snapshot,
552
+ membershipFailure: membershipConditions.failureKind
553
+ };
551
554
  const result = await this.provider.write(
552
555
  {
553
556
  conditions: [
@@ -610,7 +613,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
610
613
  },
611
614
  signal
612
615
  );
613
- if (result.kind === 'conflict') continue;
616
+ if (result.kind === 'conflict') {
617
+ await macrotaskBoundary();
618
+ continue;
619
+ }
614
620
  const storeVersion = result.putVersions.find(
615
621
  (entry) => entry.key.value === rowKey.value
616
622
  )?.version;
@@ -1191,7 +1197,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1191
1197
  signal,
1192
1198
  aggregate.targetOwner
1193
1199
  );
1194
- if (conditions === undefined) return { kind: 'stale' };
1200
+ if (!Array.isArray(conditions)) return { kind: 'stale' };
1195
1201
  membershipConditions.push(
1196
1202
  ...conditions.filter(
1197
1203
  (condition) =>
@@ -1323,11 +1329,18 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1323
1329
  key: ZLinkAuthorityKey,
1324
1330
  expectedStoreVersion: string,
1325
1331
  signal?: AbortSignal,
1326
- request?: ZLinkEndedOwnerReleaseIntent
1332
+ request?: ZLinkEndedOwnerReleaseIntent,
1333
+ requiredOwner?: ZLinkLocationOwnerToken
1327
1334
  ): Promise<boolean> {
1328
1335
  return (
1329
- (await this.tryReleaseEndedReservation(key, expectedStoreVersion, signal, request)) ===
1330
- 'reclaimed'
1336
+ (await this.tryReleaseEndedReservation(
1337
+ key,
1338
+ expectedStoreVersion,
1339
+ signal,
1340
+ request,
1341
+ undefined,
1342
+ requiredOwner
1343
+ )) === 'reclaimed'
1331
1344
  );
1332
1345
  }
1333
1346
 
@@ -1335,160 +1348,189 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1335
1348
  key: ZLinkAuthorityKey,
1336
1349
  expectedStoreVersion: string,
1337
1350
  signal?: AbortSignal,
1338
- request?: ZLinkEndedOwnerReleaseIntent
1351
+ request?: ZLinkEndedOwnerReleaseIntent,
1352
+ deadlineUnixMs?: bigint,
1353
+ requiredOwner?: ZLinkLocationOwnerToken
1339
1354
  ): Promise<'notReclaimable' | 'conflict' | 'reclaimed'> {
1340
- const rowKey = authorityKey(key.value);
1341
- const current = await this.provider.read(rowKey, signal);
1342
- if (current.kind === 'missing' || current.value.version.value !== expectedStoreVersion)
1343
- return 'conflict';
1344
- const record = decodeAuthorityRecord(current.value.bytes);
1345
- const snapshot = record.snapshot;
1346
- if (
1347
- snapshot.allocation.state === 'active'
1348
- ? request === undefined
1349
- : snapshot.pendingCreation === undefined
1350
- )
1351
- return 'notReclaimable';
1352
- const leaseKey = ownerKey(snapshot.ownerId);
1353
- const descriptorKey = meshKey(
1354
- snapshot.allocation.descriptor.meshName,
1355
- snapshot.allocation.descriptor.rid
1356
- );
1357
- const capacityRowKey = capacityKey(
1358
- snapshot.allocation.descriptor.meshName,
1359
- String(snapshot.allocation.descriptor.rid)
1360
- );
1361
- const [lease, descriptor, capacity] = await Promise.all([
1362
- this.provider.read(leaseKey, signal),
1363
- this.provider.read(descriptorKey, signal),
1364
- this.provider.read(capacityRowKey, signal)
1365
- ]);
1366
- const ownerLive = sameLiveOwner(lease, snapshot);
1367
- let members: EndedSpotMember[] = [];
1368
- if (snapshot.allocation.state === 'active') {
1369
- if (ownerLive) return 'notReclaimable';
1370
- let unavailable = record.aggregate !== undefined || hasRelocationAuthority(snapshot.payload);
1371
- if (snapshot.allocation.objectKind !== 'actor') {
1372
- const spot = decodeServiceReadySpotAuthority(snapshot.payload);
1373
- unavailable ||=
1374
- spot === undefined ||
1375
- spot.kind !== request?.key.kind ||
1376
- spot.stableType !== request.intent.stableType ||
1377
- spot.spotId !== request.key.globalId ||
1378
- spot.activationRecovery !== undefined;
1379
- if (
1380
- spot?.kind === 'user_spot' &&
1381
- !unavailable &&
1382
- request?.actorRelocationPolicy === 'disabled'
1383
- )
1384
- members = await this.readEndedSpotMembers(spot.spotId, snapshot.objectGeneration, signal);
1385
- }
1386
- if (unavailable || request?.actorRelocationPolicy !== 'disabled')
1387
- throw new ZLinkFrameworkException(
1388
- ZLinkFrameworkErrorKind.Unavailable,
1389
- 'Object owner lease is unavailable.'
1390
- );
1391
- } else if (
1392
- ownerLive &&
1393
- descriptor.kind === 'found' &&
1394
- reviveMeshDescriptor(
1395
- decodeCanonicalDescriptorRecord<ZLinkMeshNodeDescriptor>(descriptor.value.bytes).descriptor
1396
- ).lifecycleGeneration === snapshot.allocation.descriptorLifecycleGeneration
1397
- )
1398
- return 'notReclaimable';
1399
- if (
1400
- snapshot.allocation.state !== 'active' &&
1401
- (record.aggregate !== undefined || hasRelocationAuthority(snapshot.payload))
1402
- )
1403
- return 'notReclaimable';
1404
- // Location runtime §6.1: the authority and every ended-owner member are released in
1405
- // one conditional batch. Each member is fenced by its row version and the observed
1406
- // (invalid) state of its own owner lease; member capacity is returned like the Spot's.
1407
- const conditions: ZLinkStoreCondition[] = [
1408
- { kind: 'version', key: rowKey, expected: current.value.version },
1409
- conditionFor(descriptorKey, descriptor)
1410
- ];
1411
- const mutations: ZLinkStoreWriteRequest['mutations'][number][] = [
1412
- { kind: 'delete', key: rowKey }
1413
- ];
1414
- const owners = new Map<string, ZLinkStoreReadResult>([[snapshot.ownerId, lease]]);
1415
- for (const member of members) {
1416
- let memberLease = owners.get(member.ownerId);
1417
- if (memberLease === undefined) {
1418
- memberLease = await this.provider.read(ownerKey(member.ownerId), signal);
1419
- owners.set(member.ownerId, memberLease);
1420
- }
1355
+ for (;;) {
1356
+ throwIfOperationExpired(signal, deadlineUnixMs);
1357
+ const rowKey = authorityKey(key.value);
1358
+ const current = await this.provider.read(rowKey, signal);
1359
+ if (current.kind === 'missing') return 'conflict';
1360
+ const record = decodeAuthorityRecord(current.value.bytes);
1421
1361
  if (
1422
- memberLease.kind === 'found' &&
1423
- matchesLiveOwnerLease(memberLease, member.ownerId, member.leaseGeneration)
1362
+ current.value.version.value !== expectedStoreVersion &&
1363
+ record.visibleStoreVersion !== expectedStoreVersion
1424
1364
  )
1425
- throw new ZLinkFrameworkException(
1426
- ZLinkFrameworkErrorKind.Unavailable,
1427
- 'User Spot still has a member with a live owner lease.'
1428
- );
1429
- conditions.push({ kind: 'version', key: member.key, expected: member.version });
1430
- mutations.push({ kind: 'delete', key: member.key });
1431
- }
1432
- for (const [ownerId, read] of owners) conditions.push(conditionFor(ownerKey(ownerId), read));
1433
- const capacities = new Map<string, { read: ZLinkStoreReadResult; next?: CapacityRecord }>([
1434
- [capacityRowKey.value, { read: capacity }]
1435
- ]);
1436
- const releases: { allocation: StoredAuthoritySnapshot['allocation'] }[] = [
1437
- { allocation: snapshot.allocation },
1438
- ...members.map((member) => ({ allocation: member.allocation }))
1439
- ];
1440
- try {
1441
- for (const { allocation } of releases) {
1442
- const key = capacityKey(allocation.descriptor.meshName, String(allocation.descriptor.rid));
1443
- let entry = capacities.get(key.value);
1444
- if (entry === undefined) {
1445
- entry = { read: await this.provider.read(key, signal) };
1446
- capacities.set(key.value, entry);
1365
+ return 'conflict';
1366
+ const snapshot = record.snapshot;
1367
+ if (
1368
+ snapshot.allocation.state === 'active'
1369
+ ? request === undefined
1370
+ : snapshot.pendingCreation === undefined
1371
+ )
1372
+ return 'notReclaimable';
1373
+ const leaseKey = ownerKey(snapshot.ownerId);
1374
+ const descriptorKey = meshKey(
1375
+ snapshot.allocation.descriptor.meshName,
1376
+ snapshot.allocation.descriptor.rid
1377
+ );
1378
+ const capacityRowKey = capacityKey(
1379
+ snapshot.allocation.descriptor.meshName,
1380
+ String(snapshot.allocation.descriptor.rid)
1381
+ );
1382
+ const [lease, descriptor, capacity] = await Promise.all([
1383
+ this.provider.read(leaseKey, signal),
1384
+ this.provider.read(descriptorKey, signal),
1385
+ this.provider.read(capacityRowKey, signal)
1386
+ ]);
1387
+ const ownerLive = sameLiveOwner(lease, snapshot);
1388
+ if (
1389
+ requiredOwner !== undefined &&
1390
+ (!ownerLive ||
1391
+ requiredOwner.ownerId !== snapshot.ownerId ||
1392
+ requiredOwner.leaseGeneration !== snapshot.ownerLeaseGeneration)
1393
+ )
1394
+ return 'notReclaimable';
1395
+ let members: EndedSpotMember[] = [];
1396
+ if (snapshot.allocation.state === 'active') {
1397
+ if (ownerLive) return 'notReclaimable';
1398
+ let unavailable =
1399
+ record.aggregate !== undefined || hasRelocationAuthority(snapshot.payload);
1400
+ if (snapshot.allocation.objectKind !== 'actor') {
1401
+ const spot = decodeServiceReadySpotAuthority(snapshot.payload);
1402
+ unavailable ||=
1403
+ spot === undefined ||
1404
+ spot.kind !== request?.key.kind ||
1405
+ spot.stableType !== request.intent.stableType ||
1406
+ spot.spotId !== request.key.globalId ||
1407
+ spot.activationRecovery !== undefined;
1408
+ if (
1409
+ spot?.kind === 'user_spot' &&
1410
+ !unavailable &&
1411
+ request?.actorRelocationPolicy === 'disabled'
1412
+ )
1413
+ members = await this.readEndedSpotMembers(
1414
+ spot.spotId,
1415
+ snapshot.objectGeneration,
1416
+ signal
1417
+ );
1447
1418
  }
1448
- if (entry.read.kind !== 'found') continue;
1449
- const stored = entry.next ?? decodeJson<CapacityRecord>(entry.read.value.bytes);
1450
- entry.next = {
1451
- active:
1452
- allocation.state === 'active'
1453
- ? subtractCapacity(stored.active, allocation.capacity)
1454
- : stored.active,
1455
- pending:
1456
- allocation.state === 'reserved'
1457
- ? subtractCapacity(stored.pending, allocation.capacity)
1458
- : stored.pending
1459
- };
1460
- }
1461
- } catch (error) {
1419
+ if (unavailable || request?.actorRelocationPolicy !== 'disabled')
1420
+ throw new ZLinkFrameworkException(
1421
+ ZLinkFrameworkErrorKind.Unavailable,
1422
+ 'Object owner lease is unavailable.'
1423
+ );
1424
+ } else if (
1425
+ ownerLive &&
1426
+ descriptor.kind === 'found' &&
1427
+ reviveMeshDescriptor(
1428
+ decodeCanonicalDescriptorRecord<ZLinkMeshNodeDescriptor>(descriptor.value.bytes)
1429
+ .descriptor
1430
+ ).lifecycleGeneration === snapshot.allocation.descriptorLifecycleGeneration
1431
+ )
1432
+ return 'notReclaimable';
1462
1433
  if (
1463
- !(error instanceof ZLinkFrameworkException) ||
1464
- error.kind !== ZLinkFrameworkErrorKind.DataLost
1434
+ snapshot.allocation.state !== 'active' &&
1435
+ (record.aggregate !== undefined || hasRelocationAuthority(snapshot.payload))
1465
1436
  )
1437
+ return 'notReclaimable';
1438
+ // Location runtime §6.1: the authority and every ended-owner member are released in
1439
+ // one conditional batch. Each member is fenced by its row version and the observed
1440
+ // (invalid) state of its own owner lease; member capacity is returned like the Spot's.
1441
+ const conditions: ZLinkStoreCondition[] = [
1442
+ { kind: 'version', key: rowKey, expected: current.value.version },
1443
+ conditionFor(descriptorKey, descriptor)
1444
+ ];
1445
+ const mutations: ZLinkStoreWriteRequest['mutations'][number][] = [
1446
+ { kind: 'delete', key: rowKey }
1447
+ ];
1448
+ const owners = new Map<string, ZLinkStoreReadResult>([[snapshot.ownerId, lease]]);
1449
+ for (const member of members) {
1450
+ let memberLease = owners.get(member.ownerId);
1451
+ if (memberLease === undefined) {
1452
+ memberLease = await this.provider.read(ownerKey(member.ownerId), signal);
1453
+ owners.set(member.ownerId, memberLease);
1454
+ }
1455
+ if (
1456
+ memberLease.kind === 'found' &&
1457
+ matchesLiveOwnerLease(memberLease, member.ownerId, member.leaseGeneration)
1458
+ )
1459
+ throw new ZLinkFrameworkException(
1460
+ ZLinkFrameworkErrorKind.Unavailable,
1461
+ 'User Spot still has a member with a live owner lease.'
1462
+ );
1463
+ conditions.push({ kind: 'version', key: member.key, expected: member.version });
1464
+ mutations.push({ kind: 'delete', key: member.key });
1465
+ }
1466
+ for (const [ownerId, read] of owners) conditions.push(conditionFor(ownerKey(ownerId), read));
1467
+ const capacities = new Map<string, { read: ZLinkStoreReadResult; next?: CapacityRecord }>([
1468
+ [capacityRowKey.value, { read: capacity }]
1469
+ ]);
1470
+ const releases: { allocation: StoredAuthoritySnapshot['allocation'] }[] = [
1471
+ { allocation: snapshot.allocation },
1472
+ ...members.map((member) => ({ allocation: member.allocation }))
1473
+ ];
1474
+ try {
1475
+ for (const { allocation } of releases) {
1476
+ const key = capacityKey(
1477
+ allocation.descriptor.meshName,
1478
+ String(allocation.descriptor.rid)
1479
+ );
1480
+ let entry = capacities.get(key.value);
1481
+ if (entry === undefined) {
1482
+ entry = { read: await this.provider.read(key, signal) };
1483
+ capacities.set(key.value, entry);
1484
+ }
1485
+ if (entry.read.kind !== 'found') continue;
1486
+ const stored = entry.next ?? decodeJson<CapacityRecord>(entry.read.value.bytes);
1487
+ entry.next = {
1488
+ active:
1489
+ allocation.state === 'active'
1490
+ ? subtractCapacity(stored.active, allocation.capacity)
1491
+ : stored.active,
1492
+ pending:
1493
+ allocation.state === 'reserved'
1494
+ ? subtractCapacity(stored.pending, allocation.capacity)
1495
+ : stored.pending
1496
+ };
1497
+ }
1498
+ } catch (error) {
1499
+ if (
1500
+ !(error instanceof ZLinkFrameworkException) ||
1501
+ error.kind !== ZLinkFrameworkErrorKind.DataLost
1502
+ )
1503
+ throw error;
1504
+ for (const authority of [{ key: rowKey, version: current.value.version }, ...members]) {
1505
+ const observed = await this.provider.read(authority.key, signal);
1506
+ if (
1507
+ observed.kind === 'missing' ||
1508
+ observed.value.version.value !== authority.version.value
1509
+ )
1510
+ return 'conflict';
1511
+ }
1466
1512
  throw error;
1467
- for (const authority of [{ key: rowKey, version: current.value.version }, ...members]) {
1468
- const observed = await this.provider.read(authority.key, signal);
1469
- if (observed.kind === 'missing' || observed.value.version.value !== authority.version.value)
1470
- return 'conflict';
1471
1513
  }
1472
- throw error;
1473
- }
1474
- for (const [key, entry] of capacities) {
1475
- conditions.push(conditionFor(storeKey(key), entry.read));
1476
- if (entry.next !== undefined)
1477
- mutations.push({
1478
- kind: 'put',
1479
- key: storeKey(key),
1480
- bytes: encodeJson(entry.next satisfies CapacityRecord)
1481
- });
1514
+ for (const [key, entry] of capacities) {
1515
+ conditions.push(conditionFor(storeKey(key), entry.read));
1516
+ if (entry.next !== undefined)
1517
+ mutations.push({
1518
+ kind: 'put',
1519
+ key: storeKey(key),
1520
+ bytes: encodeJson(entry.next satisfies CapacityRecord)
1521
+ });
1522
+ }
1523
+ // Every mutated key is also a condition key, so the condition count is the batch's
1524
+ // unique key count. A release beyond the provider bound changes nothing.
1525
+ if (conditions.length > ZLINK_PROVIDER_MAX_WRITE_KEYS)
1526
+ throw new ZLinkFrameworkException(
1527
+ ZLinkFrameworkErrorKind.Unavailable,
1528
+ 'User Spot member release exceeds one Location Store batch.'
1529
+ );
1530
+ const result = await this.provider.write({ conditions, mutations }, signal);
1531
+ if (result.kind === 'applied') return 'reclaimed';
1532
+ await macrotaskBoundary();
1482
1533
  }
1483
- // Every mutated key is also a condition key, so the condition count is the batch's
1484
- // unique key count. A release beyond the provider bound changes nothing.
1485
- if (conditions.length > ZLINK_PROVIDER_MAX_WRITE_KEYS)
1486
- throw new ZLinkFrameworkException(
1487
- ZLinkFrameworkErrorKind.Unavailable,
1488
- 'User Spot member release exceeds one Location Store batch.'
1489
- );
1490
- const result = await this.provider.write({ conditions, mutations }, signal);
1491
- return result.kind === 'applied' ? 'reclaimed' : 'conflict';
1492
1534
  }
1493
1535
 
1494
1536
  /**
@@ -1596,7 +1638,8 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1596
1638
  encodedAuthorityKey,
1597
1639
  current.value.version.value,
1598
1640
  signal,
1599
- request
1641
+ request,
1642
+ deadlineUnixMs
1600
1643
  );
1601
1644
  if (reclaim === 'notReclaimable')
1602
1645
  return snapshot.allocation.state === 'active'
@@ -1964,7 +2007,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1964
2007
  request.target.owner
1965
2008
  )
1966
2009
  : [];
1967
- if (membershipConditions === undefined) return { kind: 'stale' };
2010
+ if (!Array.isArray(membershipConditions)) return { kind: 'stale' };
1968
2011
  const mutations =
1969
2012
  request.completion.kind === 'created'
1970
2013
  ? [
@@ -2818,50 +2861,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2818
2861
  const leaseKey = ownerKey(owner.ownerId);
2819
2862
  const lease = await this.provider.read(leaseKey, signal);
2820
2863
  if (liveOwnerLeaseGeneration(lease) !== owner.leaseGeneration) return 0n;
2821
- let removed = await this.removeOwnedAuthorities(owner, signal);
2822
- const candidates: OwnerCleanupCandidate[] = [];
2823
- for (const prefix of [
2824
- 'mesh-node\0',
2825
- 'client-server\0',
2826
- 'fanout-publisher\0',
2827
- `${PREFIX}spot:`,
2828
- `${PREFIX}actor:`,
2829
- `${PREFIX}route:`
2830
- ]) {
2831
- for (;;) {
2832
- const prefixCandidates: OwnerCleanupCandidate[] = [];
2833
- let cursor: ZLinkStoreScanCursor | undefined;
2834
- let expired = false;
2835
- do {
2836
- const result = await this.provider.scan({ prefix, cursor, limit: 1_000 }, signal);
2837
- if (result.kind === 'expired') {
2838
- expired = true;
2839
- break;
2840
- }
2841
- for (const item of result.value.items) {
2842
- prefixCandidates.push({ key: item.key, scanVersion: item.value.version });
2843
- }
2844
- cursor = result.value.nextCursor;
2845
- } while (cursor !== undefined);
2846
- if (expired) {
2847
- // Snapshot scan expiry invalidates every page from this prefix.
2848
- // Restart from its first page instead of silently leaving rows
2849
- // behind after a partial scan.
2850
- continue;
2851
- }
2852
- candidates.push(...prefixCandidates);
2853
- break;
2854
- }
2855
- }
2856
- for (let offset = 0; offset < candidates.length; offset += MAX_OWNER_CLEANUP_BATCH_ROWS) {
2857
- removed += await this.removeOwnerCleanupBatch(
2858
- owner,
2859
- leaseKey,
2860
- candidates.slice(offset, offset + MAX_OWNER_CLEANUP_BATCH_ROWS),
2861
- signal
2862
- );
2863
- }
2864
- return removed + (await super.removeAllByOwner(owner));
2864
+ return this.removeOwnedAuthorities(owner, signal);
2865
2865
  }
2866
2866
 
2867
2867
  private async removeOwnedAuthorities(
@@ -2944,91 +2944,20 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2944
2944
  signal
2945
2945
  );
2946
2946
  if (aborted.kind === 'aborted') removed += 1n;
2947
- }
2948
- return removed;
2949
- }
2950
-
2951
- private async removeOwnerCleanupBatch(
2952
- owner: ZLinkLocationOwnerToken,
2953
- leaseKey: ZLinkStoreKey,
2954
- candidates: readonly OwnerCleanupCandidate[],
2955
- signal?: AbortSignal
2956
- ): Promise<bigint> {
2957
- if (candidates.length === 0) return 0n;
2958
-
2959
- const currentRows = await Promise.all(
2960
- candidates.map((candidate) => this.provider.read(candidate.key, signal))
2961
- );
2962
- const unchangedOwnedRows: OwnerCleanupCandidate[] = [];
2963
- for (let index = 0; index < candidates.length; index += 1) {
2964
- const candidate = candidates[index]!;
2965
- const current = currentRows[index]!;
2966
- if (
2967
- current.kind === 'missing' ||
2968
- current.value.version.value !== candidate.scanVersion.value
2969
- ) {
2970
- continue;
2971
- }
2972
- const record = decodeJson<OwnerCleanupRecord>(current.value.bytes);
2973
- const descriptor = record.descriptor;
2974
- if (
2975
- descriptor.ownerId !== owner.ownerId ||
2976
- descriptorOwnerLeaseGeneration(descriptor) !== owner.leaseGeneration
2977
- ) {
2978
- continue;
2947
+ else if (aborted.kind === 'stale') {
2948
+ if (
2949
+ await this.releaseEndedReservationRequest(
2950
+ { value: encodedAuthority } as ZLinkAuthorityKey,
2951
+ current.value.version.value,
2952
+ signal,
2953
+ undefined,
2954
+ owner
2955
+ )
2956
+ )
2957
+ removed += 1n;
2979
2958
  }
2980
- unchangedOwnedRows.push({
2981
- key: candidate.key,
2982
- scanVersion: current.value.version
2983
- });
2984
- }
2985
- if (unchangedOwnedRows.length === 0) return 0n;
2986
-
2987
- const currentLease = await this.provider.read(leaseKey, signal);
2988
- if (
2989
- currentLease.kind === 'missing' ||
2990
- liveOwnerLeaseGeneration(currentLease) !== owner.leaseGeneration
2991
- ) {
2992
- return 0n;
2993
2959
  }
2994
- const result = await this.provider.write(
2995
- {
2996
- conditions: [
2997
- { kind: 'version', key: leaseKey, expected: currentLease.value.version },
2998
- ...unchangedOwnedRows.map((row) => ({
2999
- kind: 'version' as const,
3000
- key: row.key,
3001
- expected: row.scanVersion
3002
- }))
3003
- ],
3004
- mutations: unchangedOwnedRows.map((row) => ({
3005
- kind: 'delete' as const,
3006
- key: row.key
3007
- }))
3008
- },
3009
- signal
3010
- );
3011
- if (result.kind === 'applied') return BigInt(unchangedOwnedRows.length);
3012
-
3013
- // A row may have changed while the page was being prepared. Split the
3014
- // bounded batch so unaffected rows can still be removed atomically, while
3015
- // the changed row is discarded by the next version re-read. A changed
3016
- // owner lease causes every recursive branch to stop at the fence above.
3017
- if (unchangedOwnedRows.length === 1) return 0n;
3018
- const midpoint = Math.ceil(unchangedOwnedRows.length / 2);
3019
- const left = await this.removeOwnerCleanupBatch(
3020
- owner,
3021
- leaseKey,
3022
- unchangedOwnedRows.slice(0, midpoint),
3023
- signal
3024
- );
3025
- const right = await this.removeOwnerCleanupBatch(
3026
- owner,
3027
- leaseKey,
3028
- unchangedOwnedRows.slice(midpoint),
3029
- signal
3030
- );
3031
- return left + right;
2960
+ return removed;
3032
2961
  }
3033
2962
 
3034
2963
  private async updateDescriptor<T extends OwnedDescriptor>(
@@ -3214,10 +3143,16 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
3214
3143
  objectGeneration: bigint,
3215
3144
  signal?: AbortSignal,
3216
3145
  conditionedOwner?: ZLinkLocationOwnerToken
3217
- ): Promise<ZLinkStoreCondition[] | undefined> {
3146
+ ): Promise<
3147
+ | ZLinkStoreCondition[]
3148
+ | {
3149
+ readonly failureKind:
3150
+ ZLinkFrameworkErrorKind.NotFound | ZLinkFrameworkErrorKind.Unavailable;
3151
+ }
3152
+ > {
3218
3153
  const key = authorityKey(encodeAuthorityKey('user_spot', spotId).value);
3219
3154
  const read = await this.provider.read(key, signal);
3220
- if (read.kind === 'missing') return undefined;
3155
+ if (read.kind === 'missing') return { failureKind: ZLinkFrameworkErrorKind.NotFound };
3221
3156
  const record = decodeAuthorityRecord(read.value.bytes);
3222
3157
  const snapshot = record.snapshot;
3223
3158
  if (
@@ -3227,10 +3162,11 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
3227
3162
  snapshot.objectGeneration !== objectGeneration ||
3228
3163
  decodeServiceReadySpotAuthority(snapshot.payload)?.kind !== 'user_spot'
3229
3164
  )
3230
- return undefined;
3165
+ return { failureKind: ZLinkFrameworkErrorKind.Unavailable };
3231
3166
  const leaseKey = ownerKey(snapshot.ownerId);
3232
3167
  const lease = await this.provider.read(leaseKey, signal);
3233
- if (!sameLiveOwner(lease, snapshot)) return undefined;
3168
+ if (!sameLiveOwner(lease, snapshot))
3169
+ return { failureKind: ZLinkFrameworkErrorKind.Unavailable };
3234
3170
  return [
3235
3171
  { kind: 'version', key, expected: read.value.version },
3236
3172
  ...(conditionedOwner?.ownerId === snapshot.ownerId &&
@@ -3320,7 +3256,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
3320
3256
  { ownerId: location.ownerId, leaseGeneration: locationOwnerGeneration(location) }
3321
3257
  )
3322
3258
  : [];
3323
- if (membershipConditions === undefined) return rejected(lease.value.storeNow);
3259
+ if (!Array.isArray(membershipConditions)) return rejected(lease.value.storeNow);
3324
3260
 
3325
3261
  const result = await this.provider.write(
3326
3262
  {
@@ -3728,7 +3664,6 @@ type OwnedDescriptor =
3728
3664
 
3729
3665
  type LeaseOwnedLocation = ZLinkSpotLocation | ZLinkActorLocation;
3730
3666
  type StoredLocation = LeaseOwnedLocation | ZLinkRouteLocation;
3731
- type OwnedStoreRecord = OwnedDescriptor | StoredLocation;
3732
3667
 
3733
3668
  function validateProviderAggregateRequest(request: ZLinkAggregatePrepareRequest): void {
3734
3669
  requireText(request.aggregateId.value, 'aggregate ID');
@@ -5019,21 +4954,6 @@ function locationOwnerGeneration(value: LeaseOwnedLocation): bigint {
5019
4954
  return value.leaseGeneration;
5020
4955
  }
5021
4956
 
5022
- function descriptorOwnerLeaseGeneration(value: OwnedStoreRecord): bigint | undefined {
5023
- if ('leaseGeneration' in value) {
5024
- return typeof value.leaseGeneration === 'bigint'
5025
- ? value.leaseGeneration
5026
- : BigInt(value.leaseGeneration);
5027
- }
5028
- if ('generation' in value) {
5029
- return typeof value.generation === 'bigint' ? value.generation : BigInt(value.generation);
5030
- }
5031
- return undefined;
5032
- }
5033
-
5034
- // Location runtime §10: a write whose result was lost is confirmed by reading
5035
- // the same key. The stored row already is this write when it differs only in
5036
- // the time the Store stamped, as for every other descriptor kind.
5037
4957
  function sameMeshDescriptor(
5038
4958
  left: ZLinkMeshNodeDescriptor,
5039
4959
  right: ZLinkMeshNodeDescriptor