@zlink-systems/framework 0.30.1 → 0.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
  3. package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
  4. package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
  5. package/dist/contracts/Common/encoded-payload-storage.js +5 -2
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -1
  7. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
  8. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
  9. package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
  10. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  11. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
  12. package/dist/contracts/Locations/Rows.d.ts +2 -0
  13. package/dist/contracts/Spots/Contracts.d.ts +4 -0
  14. package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
  15. package/dist/runtime/abort.d.ts +5 -0
  16. package/dist/runtime/abort.js +10 -0
  17. package/dist/runtime/actors/actor-authority-publication.js +3 -2
  18. package/dist/runtime/actors/actor-client.d.ts +0 -1
  19. package/dist/runtime/actors/actor-client.js +38 -45
  20. package/dist/runtime/actors/actor-context.d.ts +2 -0
  21. package/dist/runtime/actors/actor-context.js +46 -9
  22. package/dist/runtime/actors/actor-handoff.d.ts +7 -3
  23. package/dist/runtime/actors/actor-handoff.js +212 -88
  24. package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
  25. package/dist/runtime/actors/actor-local-native-join.js +4 -0
  26. package/dist/runtime/actors/actor-mailbox.js +27 -1
  27. package/dist/runtime/actors/actor-remote-joiner.js +3 -1
  28. package/dist/runtime/actors/actor-reply.d.ts +4 -0
  29. package/dist/runtime/actors/actor-reply.js +29 -0
  30. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
  31. package/dist/runtime/actors/actor-runtime-state.js +2 -20
  32. package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
  33. package/dist/runtime/actors/index.d.ts +6 -2
  34. package/dist/runtime/actors/index.js +37 -21
  35. package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
  36. package/dist/runtime/actors/session-disconnected-wire.js +48 -0
  37. package/dist/runtime/admission.d.ts +9 -1
  38. package/dist/runtime/admission.js +55 -32
  39. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
  40. package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
  41. package/dist/runtime/application-jobs/contracts.d.ts +2 -0
  42. package/dist/runtime/backend/contracts/index.d.ts +19 -3
  43. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
  44. package/dist/runtime/backend/mesh-completion-table.js +5 -0
  45. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
  46. package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
  47. package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
  48. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
  49. package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
  50. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
  51. package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
  52. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  53. package/dist/runtime/channels/channel-clients.js +20 -5
  54. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
  55. package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
  56. package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
  57. package/dist/runtime/channels/channel-dispatchers.js +44 -37
  58. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  59. package/dist/runtime/channels/channel-envelope.js +74 -31
  60. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
  61. package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
  62. package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
  63. package/dist/runtime/channels/channel-runtime-manager.js +4 -4
  64. package/dist/runtime/channels/channel-transports.d.ts +0 -1
  65. package/dist/runtime/channels/channel-transports.js +35 -33
  66. package/dist/runtime/channels/client-server-location-runtime.js +5 -4
  67. package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
  68. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  69. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  70. package/dist/runtime/channels/fanout-location-runtime.js +3 -3
  71. package/dist/runtime/diagnostics/flow-context.js +19 -7
  72. package/dist/runtime/diagnostics/index.js +4 -9
  73. package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
  74. package/dist/runtime/diagnostics/message-flow.js +35 -5
  75. package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
  76. package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
  77. package/dist/runtime/execution/index.d.ts +4 -2
  78. package/dist/runtime/execution/index.js +33 -10
  79. package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
  80. package/dist/runtime/execution/serial-execution-queue.js +21 -2
  81. package/dist/runtime/execution/state-lane.d.ts +2 -0
  82. package/dist/runtime/execution/state-lane.js +5 -0
  83. package/dist/runtime/foundation/operation-registry.d.ts +25 -1
  84. package/dist/runtime/foundation/operation-registry.js +86 -18
  85. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
  86. package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
  87. package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
  88. package/dist/runtime/foundation/service-liveness-registry.js +38 -0
  89. package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
  90. package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
  91. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
  92. package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
  93. package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
  94. package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
  95. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
  96. package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
  97. package/dist/runtime/foundation/service-stateful-registry.js +24 -26
  98. package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
  99. package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
  100. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
  101. package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
  102. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
  103. package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
  104. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  105. package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
  106. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
  107. package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
  108. package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
  109. package/dist/runtime/host/actor-packet-relay.js +59 -72
  110. package/dist/runtime/host/actor-placement-coordinator.js +25 -8
  111. package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
  112. package/dist/runtime/host/actor-transfer-runtime.js +85 -331
  113. package/dist/runtime/host/application-job-queue.d.ts +24 -3
  114. package/dist/runtime/host/application-job-queue.js +28 -41
  115. package/dist/runtime/host/index.d.ts +5 -1
  116. package/dist/runtime/host/index.js +171 -97
  117. package/dist/runtime/host/location-runtime-owner.js +2 -6
  118. package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
  119. package/dist/runtime/host/mesh-router-resolver.js +14 -6
  120. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
  121. package/dist/runtime/host/remote-bound-session-relay.js +71 -190
  122. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
  123. package/dist/runtime/host/route-mesh-runtime.js +5 -3
  124. package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
  125. package/dist/runtime/host/runtime-shutdown.js +3 -2
  126. package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
  127. package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
  128. package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
  129. package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
  130. package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
  131. package/dist/runtime/locations/auto-connect-loop.js +22 -14
  132. package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
  133. package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
  134. package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
  135. package/dist/runtime/locations/descriptor-publication.js +11 -0
  136. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  137. package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
  138. package/dist/runtime/locations/in-memory-authority-store.js +56 -19
  139. package/dist/runtime/locations/in-memory-location-store.js +1 -10
  140. package/dist/runtime/locations/index.d.ts +1 -0
  141. package/dist/runtime/locations/index.js +1 -0
  142. package/dist/runtime/locations/lease-tracker.js +1 -6
  143. package/dist/runtime/locations/location-store-repository.d.ts +51 -1
  144. package/dist/runtime/locations/location-store-repository.js +363 -139
  145. package/dist/runtime/locations/relocation-blob.d.ts +18 -1
  146. package/dist/runtime/locations/relocation-blob.js +52 -1
  147. package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
  148. package/dist/runtime/locations/request-source-resolver.js +80 -0
  149. package/dist/runtime/locations/resolvers.js +1 -1
  150. package/dist/runtime/locations/runtime.d.ts +6 -2
  151. package/dist/runtime/locations/runtime.js +37 -30
  152. package/dist/runtime/messaging/payload-codec.d.ts +7 -1
  153. package/dist/runtime/messaging/payload-codec.js +7 -6
  154. package/dist/runtime/messaging/request-result.js +29 -26
  155. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
  156. package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
  157. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
  158. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
  159. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
  160. package/dist/runtime/spots/index.d.ts +18 -11
  161. package/dist/runtime/spots/index.js +234 -176
  162. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  163. package/dist/runtime/spots/spot-activation-registry.js +21 -11
  164. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  165. package/dist/runtime/spots/spot-activation-state.js +7 -7
  166. package/dist/runtime/spots/spot-activation.d.ts +6 -3
  167. package/dist/runtime/spots/spot-activation.js +123 -44
  168. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
  169. package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
  170. package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
  171. package/dist/runtime/spots/spot-actor-membership.js +0 -8
  172. package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
  173. package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
  174. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
  175. package/dist/runtime/spots/spot-entry-activation.js +14 -9
  176. package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
  177. package/dist/runtime/spots/spot-handler-registry.js +6 -2
  178. package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
  179. package/dist/runtime/spots/spot-manager-public.js +2 -2
  180. package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
  181. package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
  182. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
  183. package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
  184. package/dist/runtime/spots/spot-outbound.js +3 -3
  185. package/dist/runtime/spots/spot-remote-codec.js +5 -1
  186. package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
  187. package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
  188. package/dist/runtime/spots/spot-serial-executor.js +61 -8
  189. package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
  190. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
  191. package/dist/runtime/spots/spot-timer.d.ts +57 -5
  192. package/dist/runtime/spots/spot-timer.js +287 -103
  193. package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
  194. package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
  195. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
  196. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
  197. package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
  198. package/dist/runtime/streams/bound-session-service.d.ts +1 -1
  199. package/dist/runtime/streams/bound-session-service.js +6 -11
  200. package/dist/runtime/streams/index.d.ts +3 -2
  201. package/dist/runtime/streams/index.js +6 -4
  202. package/dist/runtime/streams/managed-stream.js +3 -2
  203. package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
  204. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
  205. package/dist/runtime/streams/session-actor-coordinator.js +15 -32
  206. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
  207. package/dist/runtime/streams/stream-session-runtime.js +1 -4
  208. package/dist/runtime/workers/index.js +1 -1
  209. package/package.json +3 -3
  210. package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
  211. package/src/contracts/Common/encoded-payload-storage.ts +6 -3
  212. package/src/contracts/Configuration/Builders.ts +4 -1
  213. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
  214. package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
  215. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  216. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
  217. package/src/contracts/Locations/Rows.ts +2 -0
  218. package/src/contracts/Spots/Contracts.ts +8 -0
  219. package/src/contracts/Spots/ZLinkSpot.ts +3 -3
  220. package/src/runtime/abort.ts +12 -0
  221. package/src/runtime/actors/actor-authority-publication.ts +3 -2
  222. package/src/runtime/actors/actor-client.ts +61 -70
  223. package/src/runtime/actors/actor-context.ts +49 -9
  224. package/src/runtime/actors/actor-handoff.ts +282 -106
  225. package/src/runtime/actors/actor-join-relocation.ts +2 -0
  226. package/src/runtime/actors/actor-local-native-join.ts +4 -0
  227. package/src/runtime/actors/actor-mailbox.ts +40 -2
  228. package/src/runtime/actors/actor-remote-joiner.ts +6 -1
  229. package/src/runtime/actors/actor-reply.ts +42 -0
  230. package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
  231. package/src/runtime/actors/actor-runtime-state.ts +2 -20
  232. package/src/runtime/actors/actor-source-transfer.ts +1 -34
  233. package/src/runtime/actors/index.ts +41 -27
  234. package/src/runtime/actors/session-disconnected-wire.ts +66 -0
  235. package/src/runtime/admission.ts +69 -34
  236. package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
  237. package/src/runtime/application-jobs/contracts.ts +2 -0
  238. package/src/runtime/backend/contracts/index.ts +39 -4
  239. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
  240. package/src/runtime/backend/mesh-completion-table.ts +4 -0
  241. package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
  242. package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
  243. package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
  244. package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
  245. package/src/runtime/channels/channel-clients.ts +49 -24
  246. package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
  247. package/src/runtime/channels/channel-dispatchers.ts +116 -72
  248. package/src/runtime/channels/channel-envelope.ts +105 -36
  249. package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
  250. package/src/runtime/channels/channel-runtime-manager.ts +12 -5
  251. package/src/runtime/channels/channel-transports.ts +49 -58
  252. package/src/runtime/channels/client-server-location-runtime.ts +11 -10
  253. package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
  254. package/src/runtime/channels/fanout-location-runtime.ts +17 -9
  255. package/src/runtime/diagnostics/flow-context.ts +20 -7
  256. package/src/runtime/diagnostics/index.ts +1 -7
  257. package/src/runtime/diagnostics/message-flow.ts +47 -9
  258. package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
  259. package/src/runtime/execution/index.ts +40 -14
  260. package/src/runtime/execution/serial-execution-queue.ts +31 -4
  261. package/src/runtime/execution/state-lane.ts +7 -0
  262. package/src/runtime/foundation/operation-registry.ts +98 -20
  263. package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
  264. package/src/runtime/foundation/service-liveness-registry.ts +39 -0
  265. package/src/runtime/foundation/service-mailbox.ts +8 -0
  266. package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
  267. package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
  268. package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
  269. package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
  270. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
  271. package/src/runtime/foundation/service-stateful-registry.ts +38 -35
  272. package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
  274. package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
  275. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  276. package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
  277. package/src/runtime/host/actor-packet-relay.ts +113 -94
  278. package/src/runtime/host/actor-placement-coordinator.ts +31 -8
  279. package/src/runtime/host/actor-transfer-runtime.ts +104 -430
  280. package/src/runtime/host/application-job-queue.ts +29 -44
  281. package/src/runtime/host/index.ts +286 -129
  282. package/src/runtime/host/location-runtime-owner.ts +2 -6
  283. package/src/runtime/host/mesh-router-resolver.ts +13 -5
  284. package/src/runtime/host/remote-bound-session-relay.ts +86 -248
  285. package/src/runtime/host/route-mesh-runtime.ts +11 -5
  286. package/src/runtime/host/runtime-shutdown.ts +15 -4
  287. package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
  288. package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
  290. package/src/runtime/locations/auto-connect-loop.ts +22 -14
  291. package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
  292. package/src/runtime/locations/auto-connect-types.ts +0 -1
  293. package/src/runtime/locations/descriptor-publication.ts +7 -0
  294. package/src/runtime/locations/domain-store-contract.ts +5 -0
  295. package/src/runtime/locations/in-memory-authority-store.ts +85 -23
  296. package/src/runtime/locations/in-memory-location-store.ts +1 -12
  297. package/src/runtime/locations/index.ts +1 -0
  298. package/src/runtime/locations/lease-tracker.ts +2 -9
  299. package/src/runtime/locations/location-store-repository.ts +628 -152
  300. package/src/runtime/locations/relocation-blob.ts +75 -1
  301. package/src/runtime/locations/request-source-resolver.ts +138 -0
  302. package/src/runtime/locations/resolvers.ts +2 -2
  303. package/src/runtime/locations/runtime.ts +70 -40
  304. package/src/runtime/messaging/payload-codec.ts +8 -11
  305. package/src/runtime/messaging/request-result.ts +33 -29
  306. package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
  307. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
  308. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
  309. package/src/runtime/spots/index.ts +375 -281
  310. package/src/runtime/spots/spot-activation-registry.ts +25 -13
  311. package/src/runtime/spots/spot-activation-state.ts +12 -19
  312. package/src/runtime/spots/spot-activation.ts +170 -86
  313. package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
  314. package/src/runtime/spots/spot-actor-membership.ts +0 -15
  315. package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
  316. package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
  317. package/src/runtime/spots/spot-entry-activation.ts +24 -19
  318. package/src/runtime/spots/spot-handler-registry.ts +15 -4
  319. package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
  320. package/src/runtime/spots/spot-manager-public.ts +2 -2
  321. package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
  322. package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
  323. package/src/runtime/spots/spot-outbound.ts +3 -3
  324. package/src/runtime/spots/spot-remote-codec.ts +9 -2
  325. package/src/runtime/spots/spot-runtime-ports.ts +0 -1
  326. package/src/runtime/spots/spot-serial-executor.ts +97 -25
  327. package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
  328. package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
  329. package/src/runtime/spots/spot-timer.ts +413 -157
  330. package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
  331. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
  332. package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
  333. package/src/runtime/streams/bound-session-service.ts +7 -10
  334. package/src/runtime/streams/index.ts +12 -6
  335. package/src/runtime/streams/managed-stream.ts +4 -2
  336. package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
  337. package/src/runtime/streams/session-actor-coordinator.ts +39 -88
  338. package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
  339. package/src/runtime/streams/stream-session-runtime.ts +1 -5
  340. package/src/runtime/workers/index.ts +1 -1
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZLinkLocationStoreRepository = void 0;
4
+ const routing_id_1 = require("../routing-id");
4
5
  const service_relocation_runtime_1 = require("../foundation/service-relocation-runtime");
5
6
  const service_authority_payload_codec_1 = require("../foundation/service-authority-payload-codec");
6
7
  const actor_authority_payload_codec_1 = require("../actors/actor-authority-payload-codec");
@@ -15,7 +16,7 @@ const RegistrationBuilderPolicy_1 = require("../../contracts/Configuration/Regis
15
16
  const Locations_1 = require("../../contracts/Locations");
16
17
  const Stores_1 = require("../../contracts/Locations/Stores");
17
18
  const actor_join_recovery_codec_1 = require("../foundation/actor-join-recovery-codec");
18
- const routing_id_1 = require("../routing-id");
19
+ const routing_id_2 = require("../routing-id");
19
20
  const aggregate_inventory_store_1 = require("./aggregate-inventory-store");
20
21
  const authority_key_codec_1 = require("./authority-key-codec");
21
22
  const in_memory_location_store_1 = require("./in-memory-location-store");
@@ -45,28 +46,47 @@ const MAX_OWNER_CLEANUP_BATCH_ROWS = 2_047;
45
46
  */
46
47
  class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMemoryLocationStore {
47
48
  nowProvider;
49
+ metrics;
48
50
  provider;
51
+ confirmedCapacities = new Map();
49
52
  aggregateInventory;
50
- constructor(provider, nowProvider = () => new Date()) {
53
+ constructor(provider, nowProvider = () => new Date(), metrics) {
51
54
  super(nowProvider);
52
55
  this.nowProvider = nowProvider;
56
+ this.metrics = metrics;
53
57
  // Classify only failures of the opaque SPI, before interpreting its records.
58
+ const confirm = (key, bytes) => {
59
+ if (this.confirmedCapacities.has(key.value)) {
60
+ this.confirmedCapacities.set(key.value, bytes === undefined ? emptyCapacityRecord() : decodeJson(bytes));
61
+ }
62
+ };
54
63
  this.provider = {
55
64
  async read(key, signal) {
65
+ let result;
56
66
  try {
57
- return await provider.read(key, signal);
67
+ result = await provider.read(key, signal);
58
68
  }
59
69
  catch (error) {
60
70
  throw locationStoreProviderFailure(error, signal);
61
71
  }
72
+ confirm(key, result.kind === 'found' ? result.value.bytes : undefined);
73
+ return result;
62
74
  },
63
75
  async write(request, signal) {
76
+ let result;
64
77
  try {
65
- return await provider.write(request, signal);
78
+ result = await provider.write(request, signal);
66
79
  }
67
80
  catch (error) {
68
81
  throw locationStoreProviderFailure(error, signal);
69
82
  }
83
+ if (result.kind === 'applied') {
84
+ for (const mutation of request.mutations) {
85
+ if (mutation.kind === 'put')
86
+ confirm(mutation.key, mutation.bytes);
87
+ }
88
+ }
89
+ return result;
70
90
  },
71
91
  async scan(request, signal) {
72
92
  try {
@@ -79,7 +99,26 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
79
99
  };
80
100
  this.aggregateInventory = new aggregate_inventory_store_1.ZLinkAggregateInventoryStore(this.provider);
81
101
  }
102
+ async observeStore(operation, request) {
103
+ try {
104
+ return await request();
105
+ }
106
+ catch (error) {
107
+ if (error instanceof contracts_2.ZLinkFrameworkException &&
108
+ error.kind === contracts_2.ZLinkFrameworkErrorKind.Unavailable) {
109
+ this.metrics?.recordLocationStoreError(operation);
110
+ }
111
+ throw error;
112
+ }
113
+ }
114
+ confirmedCapacity(key, limits) {
115
+ const record = this.confirmedCapacities.get(capacityKey(key.meshName, String(key.rid)).value);
116
+ return record === undefined ? undefined : projectCapacity(limits, record);
117
+ }
82
118
  async readAuthority(key, signal) {
119
+ return this.observeStore('read', () => this.readAuthorityRequest(key, signal));
120
+ }
121
+ async readAuthorityRequest(key, signal) {
83
122
  const result = await this.provider.read(authorityKey(key.value), signal);
84
123
  if (result.kind === 'missing') {
85
124
  return { kind: 'missing', storeNow: result.storeNow };
@@ -87,6 +126,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
87
126
  return await this.projectAuthority(decodeAuthorityRecord(result.value.bytes), result.value.version, result.value.storeNow, signal);
88
127
  }
89
128
  async listAuthorities(prefix, cursor, limit, signal) {
129
+ return this.observeStore('read', () => this.listAuthoritiesRequest(prefix, cursor, limit, signal));
130
+ }
131
+ async listAuthoritiesRequest(prefix, cursor, limit, signal) {
90
132
  if (!Number.isInteger(limit) || limit < 1 || limit > Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE) {
91
133
  throw new RangeError(`Authority scan limit must be in 1..${Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE}.`);
92
134
  }
@@ -114,6 +156,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
114
156
  };
115
157
  }
116
158
  async compareExchangeAuthority(key, expectedStoreVersion, mutation, signal) {
159
+ return this.observeStore('compare_exchange', () => this.compareExchangeAuthorityRequest(key, expectedStoreVersion, mutation, signal));
160
+ }
161
+ async compareExchangeAuthorityRequest(key, expectedStoreVersion, mutation, signal) {
117
162
  if (mutation.kind !== 'delete') {
118
163
  validatePayloadSize(mutation.payload, 'Authority payload');
119
164
  }
@@ -310,6 +355,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
310
355
  }
311
356
  }
312
357
  async prepareAggregate(request, signal) {
358
+ return this.observeStore('compare_exchange', () => this.prepareAggregateRequest(request, signal));
359
+ }
360
+ async prepareAggregateRequest(request, signal) {
313
361
  validateProviderAggregateRequest(request);
314
362
  const fence = aggregateFence(request.aggregateId, request.aggregateGeneration);
315
363
  const rowKey = aggregateKey(fence);
@@ -550,7 +598,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
550
598
  const aggregateRecord = decodeJson(aggregateRaced.value.bytes);
551
599
  if (aggregateRecord.requestFingerprint === fingerprint &&
552
600
  (aggregateRecord.state === 'staging' || aggregateRecord.state === 'prepared')) {
553
- return await this.prepareAggregate(request, signal);
601
+ return await this.prepareAggregateRequest(request, signal);
554
602
  }
555
603
  }
556
604
  await this.clearAggregateMarkers(fence, installed, signal);
@@ -622,6 +670,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
622
670
  }
623
671
  }
624
672
  async commitAggregate(fence, signal) {
673
+ return this.observeStore('compare_exchange', () => this.commitAggregateRequest(fence, signal));
674
+ }
675
+ async commitAggregateRequest(fence, signal) {
625
676
  validateAggregateFence(fence);
626
677
  return await this.commitAggregateCore(fence, signal);
627
678
  }
@@ -804,6 +855,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
804
855
  }
805
856
  }
806
857
  async abortAggregate(fence, signal) {
858
+ return this.observeStore('compare_exchange', () => this.abortAggregateRequest(fence, signal));
859
+ }
860
+ async abortAggregateRequest(fence, signal) {
807
861
  validateAggregateFence(fence);
808
862
  const rowKey = aggregateKey(fence);
809
863
  for (;;) {
@@ -859,6 +913,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
859
913
  }
860
914
  }
861
915
  async releaseEndedReservation(key, expectedStoreVersion, signal, request) {
916
+ return this.observeStore('release', () => this.releaseEndedReservationRequest(key, expectedStoreVersion, signal, request));
917
+ }
918
+ async releaseEndedReservationRequest(key, expectedStoreVersion, signal, request) {
862
919
  return ((await this.tryReleaseEndedReservation(key, expectedStoreVersion, signal, request)) ===
863
920
  'reclaimed');
864
921
  }
@@ -881,9 +938,8 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
881
938
  this.provider.read(descriptorKey, signal),
882
939
  this.provider.read(capacityRowKey, signal)
883
940
  ]);
884
- if (lease.kind === 'found' && lease.value.expiresAt === undefined)
885
- throw new Error('Location Store owner lease record is invalid.');
886
941
  const ownerLive = sameLiveOwner(lease, snapshot);
942
+ let members = [];
887
943
  if (snapshot.allocation.state === 'active') {
888
944
  if (ownerLive)
889
945
  return 'notReclaimable';
@@ -896,42 +952,10 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
896
952
  spot.stableType !== request.intent.stableType ||
897
953
  spot.spotId !== request.key.globalId ||
898
954
  spot.activationRecovery !== undefined;
899
- if (spot?.kind === 'user_spot') {
900
- // The snapshot starts only after the old owner's lease was found invalid.
901
- for (const prefix of [`${PREFIX}actor:`, `${AUTHORITY_PREIMAGE_PREFIX}actor\0`]) {
902
- membershipSnapshot: for (;;) {
903
- let snapshotHasMember = false;
904
- let cursor;
905
- do {
906
- const page = await this.provider.scan({ prefix, cursor, limit: Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE }, signal);
907
- if (page.kind === 'expired')
908
- continue membershipSnapshot;
909
- for (const item of page.value.items) {
910
- if (prefix === `${PREFIX}actor:`) {
911
- const actor = normalizeActor(decodeJson(item.value.bytes).descriptor);
912
- snapshotHasMember ||=
913
- actor.spotKind === contracts_1.ZLinkSpotKind.User &&
914
- String(actor.spotId) === spot.spotId &&
915
- actor.spotGeneration === snapshot.objectGeneration;
916
- }
917
- else {
918
- const authority = decodeAuthorityRecord(item.value.bytes).snapshot;
919
- if (authority.allocation.objectKind !== 'actor')
920
- continue;
921
- const actor = (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(authority.payload));
922
- snapshotHasMember ||=
923
- actor?.currentSpotKind === contracts_1.ZLinkSpotKind.User &&
924
- actor.currentSpotId === spot.spotId &&
925
- actor.currentSpotGeneration === snapshot.objectGeneration;
926
- }
927
- }
928
- cursor = page.value.nextCursor;
929
- } while (cursor !== undefined);
930
- unavailable ||= snapshotHasMember;
931
- break;
932
- }
933
- }
934
- }
955
+ if (spot?.kind === 'user_spot' &&
956
+ !unavailable &&
957
+ request?.actorRelocationPolicy === 'disabled')
958
+ members = await this.readEndedSpotMembers(spot.spotId, snapshot.objectGeneration, signal);
935
959
  }
936
960
  if (unavailable || request?.actorRelocationPolicy !== 'disabled')
937
961
  throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'Object owner lease is unavailable.');
@@ -943,48 +967,136 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
943
967
  if (snapshot.allocation.state !== 'active' &&
944
968
  (record.aggregate !== undefined || hasRelocationAuthority(snapshot.payload)))
945
969
  return 'notReclaimable';
970
+ // Location runtime §6.1: the authority and every ended-owner member are released in
971
+ // one conditional batch. Each member is fenced by its row version and the observed
972
+ // (invalid) state of its own owner lease; member capacity is returned like the Spot's.
973
+ const conditions = [
974
+ { kind: 'version', key: rowKey, expected: current.value.version },
975
+ conditionFor(descriptorKey, descriptor)
976
+ ];
946
977
  const mutations = [
947
978
  { kind: 'delete', key: rowKey }
948
979
  ];
949
- if (capacity.kind === 'found') {
950
- const stored = decodeJson(capacity.value.bytes);
951
- try {
952
- mutations.push({
953
- kind: 'put',
954
- key: capacityRowKey,
955
- bytes: encodeJson({
956
- active: snapshot.allocation.state === 'active'
957
- ? subtractCapacity(stored.active, snapshot.allocation.capacity)
958
- : stored.active,
959
- pending: snapshot.allocation.state === 'reserved'
960
- ? subtractCapacity(stored.pending, snapshot.allocation.capacity)
961
- : stored.pending
962
- })
963
- });
980
+ const owners = new Map([[snapshot.ownerId, lease]]);
981
+ for (const member of members) {
982
+ let memberLease = owners.get(member.ownerId);
983
+ if (memberLease === undefined) {
984
+ memberLease = await this.provider.read(ownerKey(member.ownerId), signal);
985
+ owners.set(member.ownerId, memberLease);
986
+ }
987
+ if (memberLease.kind === 'found' &&
988
+ matchesLiveOwnerLease(memberLease, member.ownerId, member.leaseGeneration))
989
+ throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'User Spot still has a member with a live owner lease.');
990
+ conditions.push({ kind: 'version', key: member.key, expected: member.version });
991
+ mutations.push({ kind: 'delete', key: member.key });
992
+ }
993
+ for (const [ownerId, read] of owners)
994
+ conditions.push(conditionFor(ownerKey(ownerId), read));
995
+ const capacities = new Map([
996
+ [capacityRowKey.value, { read: capacity }]
997
+ ]);
998
+ const releases = [
999
+ { allocation: snapshot.allocation },
1000
+ ...members.map((member) => ({ allocation: member.allocation }))
1001
+ ];
1002
+ try {
1003
+ for (const { allocation } of releases) {
1004
+ const key = capacityKey(allocation.descriptor.meshName, String(allocation.descriptor.rid));
1005
+ let entry = capacities.get(key.value);
1006
+ if (entry === undefined) {
1007
+ entry = { read: await this.provider.read(key, signal) };
1008
+ capacities.set(key.value, entry);
1009
+ }
1010
+ if (entry.read.kind !== 'found')
1011
+ continue;
1012
+ const stored = entry.next ?? decodeJson(entry.read.value.bytes);
1013
+ entry.next = {
1014
+ active: allocation.state === 'active'
1015
+ ? subtractCapacity(stored.active, allocation.capacity)
1016
+ : stored.active,
1017
+ pending: allocation.state === 'reserved'
1018
+ ? subtractCapacity(stored.pending, allocation.capacity)
1019
+ : stored.pending
1020
+ };
964
1021
  }
965
- catch (error) {
966
- if (!(error instanceof contracts_2.ZLinkFrameworkException) ||
967
- error.kind !== contracts_2.ZLinkFrameworkErrorKind.DataLost)
968
- throw error;
969
- const observed = await this.provider.read(rowKey, signal);
970
- if (observed.kind === 'missing' ||
971
- observed.value.version.value !== current.value.version.value)
972
- return 'conflict';
1022
+ }
1023
+ catch (error) {
1024
+ if (!(error instanceof contracts_2.ZLinkFrameworkException) ||
1025
+ error.kind !== contracts_2.ZLinkFrameworkErrorKind.DataLost)
973
1026
  throw error;
1027
+ for (const authority of [{ key: rowKey, version: current.value.version }, ...members]) {
1028
+ const observed = await this.provider.read(authority.key, signal);
1029
+ if (observed.kind === 'missing' || observed.value.version.value !== authority.version.value)
1030
+ return 'conflict';
974
1031
  }
1032
+ throw error;
975
1033
  }
976
- const result = await this.provider.write({
977
- conditions: [
978
- { kind: 'version', key: rowKey, expected: current.value.version },
979
- conditionFor(leaseKey, lease),
980
- conditionFor(descriptorKey, descriptor),
981
- conditionFor(capacityRowKey, capacity)
982
- ],
983
- mutations
984
- }, signal);
1034
+ for (const [key, entry] of capacities) {
1035
+ conditions.push(conditionFor((0, in_memory_provider_location_store_1.storeKey)(key), entry.read));
1036
+ if (entry.next !== undefined)
1037
+ mutations.push({
1038
+ kind: 'put',
1039
+ key: (0, in_memory_provider_location_store_1.storeKey)(key),
1040
+ bytes: encodeJson(entry.next)
1041
+ });
1042
+ }
1043
+ // Every mutated key is also a condition key, so the condition count is the batch's
1044
+ // unique key count. A release beyond the provider bound changes nothing.
1045
+ if (conditions.length > Stores_1.ZLINK_PROVIDER_MAX_WRITE_KEYS)
1046
+ throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'User Spot member release exceeds one Location Store batch.');
1047
+ const result = await this.provider.write({ conditions, mutations }, signal);
985
1048
  return result.kind === 'applied' ? 'reclaimed' : 'conflict';
986
1049
  }
1050
+ /**
1051
+ * Reads every Actor membership of one User Spot incarnation from complete snapshot scans
1052
+ * (location runtime §6.1), from Actor authorities alone. An expired snapshot
1053
+ * discards the earlier pages and restarts; a Store failure propagates. A member authority
1054
+ * that is relocating, part of an aggregate or not yet activated keeps the Spot.
1055
+ */
1056
+ async readEndedSpotMembers(spotId, spotGeneration, signal) {
1057
+ membershipSnapshot: for (;;) {
1058
+ const members = [];
1059
+ let cursor;
1060
+ do {
1061
+ const page = await this.provider.scan({
1062
+ prefix: `${AUTHORITY_PREIMAGE_PREFIX}actor\0`,
1063
+ cursor,
1064
+ limit: Stores_1.ZLINK_PROVIDER_MAX_PAGE_SIZE
1065
+ }, signal);
1066
+ if (page.kind === 'expired')
1067
+ continue membershipSnapshot;
1068
+ for (const item of page.value.items) {
1069
+ const record = decodeAuthorityRecord(item.value.bytes);
1070
+ const authority = record.snapshot;
1071
+ if (authority.allocation.objectKind !== 'actor')
1072
+ continue;
1073
+ const actor = (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(authority.payload));
1074
+ if (actor?.currentSpotKind !== contracts_1.ZLinkSpotKind.User ||
1075
+ actor.currentSpotId !== spotId ||
1076
+ actor.currentSpotGeneration !== spotGeneration)
1077
+ continue;
1078
+ if (authority.allocation.state !== 'active' ||
1079
+ record.aggregate !== undefined ||
1080
+ hasRelocationAuthority(authority.payload) ||
1081
+ (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)(authority.payload)?.state !== 'ready')
1082
+ throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'User Spot still has a relocating or unactivated member.');
1083
+ members.push({
1084
+ key: item.key,
1085
+ version: item.value.version,
1086
+ ownerId: authority.ownerId,
1087
+ leaseGeneration: authority.ownerLeaseGeneration,
1088
+ allocation: authority.allocation
1089
+ });
1090
+ }
1091
+ cursor = page.value.nextCursor;
1092
+ } while (cursor !== undefined);
1093
+ return members;
1094
+ }
1095
+ }
987
1096
  async reserve(request, signal, deadlineUnixMs) {
1097
+ return this.observeStore('compare_exchange', () => this.reserveRequest(request, signal, deadlineUnixMs));
1098
+ }
1099
+ async reserveRequest(request, signal, deadlineUnixMs) {
988
1100
  const encodedAuthorityKey = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
989
1101
  const reservationId = (0, node_crypto_1.randomUUID)();
990
1102
  let reclaimVersion;
@@ -1112,6 +1224,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1112
1224
  }
1113
1225
  }
1114
1226
  async commit(request, signal, deadlineUnixMs) {
1227
+ return this.observeStore('compare_exchange', () => this.commitRequest(request, signal, deadlineUnixMs));
1228
+ }
1229
+ async commitRequest(request, signal, deadlineUnixMs) {
1115
1230
  const key = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
1116
1231
  const rowKey = authorityKey(key.value);
1117
1232
  for (;;) {
@@ -1188,6 +1303,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1188
1303
  }
1189
1304
  }
1190
1305
  async abort(request, signal, deadlineUnixMs) {
1306
+ return this.observeStore('compare_exchange', () => this.abortRequest(request, signal, deadlineUnixMs));
1307
+ }
1308
+ async abortRequest(request, signal, deadlineUnixMs) {
1191
1309
  const key = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
1192
1310
  const rowKey = authorityKey(key.value);
1193
1311
  for (;;) {
@@ -1210,12 +1328,6 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1210
1328
  this.provider.read(leaseKey, signal),
1211
1329
  this.provider.read(capacityRowKey, signal)
1212
1330
  ]);
1213
- if (leaseRead.kind === 'found' && leaseRead.value.expiresAt === undefined) {
1214
- // A lease is always written with a positive TTL, so a missing expiry
1215
- // is a corrupt record. Abort deletes authority state, so refuse
1216
- // rather than read the absence as expiry.
1217
- throw new Error('Location Store owner lease record is invalid.');
1218
- }
1219
1331
  if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined)
1220
1332
  return { kind: 'stale' };
1221
1333
  const capacity = capacityRead.kind === 'missing'
@@ -1249,6 +1361,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1249
1361
  }
1250
1362
  }
1251
1363
  async completeCreation(request, signal) {
1364
+ return this.observeStore('compare_exchange', () => this.completeCreationRequest(request, signal));
1365
+ }
1366
+ async completeCreationRequest(request, signal) {
1252
1367
  if (request.key.kind !== 'actor') {
1253
1368
  throw new TypeError('completeCreation is reserved for Actor creation.');
1254
1369
  }
@@ -1388,6 +1503,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1388
1503
  }
1389
1504
  }
1390
1505
  async readCreationTerminal(operation, signal) {
1506
+ return this.observeStore('read', () => this.readCreationTerminalRequest(operation, signal));
1507
+ }
1508
+ async readCreationTerminalRequest(operation, signal) {
1391
1509
  validateCreationOperation(operation);
1392
1510
  const result = await this.provider.read(creationTerminalKey(operation), signal);
1393
1511
  return result.kind === 'missing'
@@ -1398,6 +1516,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1398
1516
  };
1399
1517
  }
1400
1518
  async claimOwnerLease(ownerId, leaseTtlMs, signal) {
1519
+ return this.observeStore('compare_exchange', () => this.claimOwnerLeaseRequest(ownerId, leaseTtlMs, signal));
1520
+ }
1521
+ async claimOwnerLeaseRequest(ownerId, leaseTtlMs, signal) {
1401
1522
  requireOwnerInput(ownerId, leaseTtlMs);
1402
1523
  for (;;) {
1403
1524
  const [owner, counter] = await Promise.all([
@@ -1445,21 +1566,28 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1445
1566
  }
1446
1567
  }
1447
1568
  async readOwnerLease(ownerId, signal) {
1569
+ return this.observeStore('read', () => this.readOwnerLeaseRequest(ownerId, signal));
1570
+ }
1571
+ async readOwnerLeaseRequest(ownerId, signal) {
1448
1572
  const result = await this.provider.read(ownerKey(ownerId), signal);
1449
1573
  if (result.kind === 'missing')
1450
1574
  return { kind: 'missing' };
1575
+ const leaseExpiresAt = requireOwnerLeaseExpiry(result.value);
1451
1576
  const record = decodeOwnerRecord(result.value.bytes);
1452
- if (record.ownerId !== ownerId || result.value.expiresAt === undefined) {
1577
+ if (record.ownerId !== ownerId) {
1453
1578
  throw new Error('Location Store owner lease record is invalid.');
1454
1579
  }
1455
1580
  return {
1456
1581
  kind: 'found',
1457
1582
  token: { ownerId, leaseGeneration: BigInt(record.leaseGeneration) },
1458
- leaseExpiresAt: result.value.expiresAt,
1583
+ leaseExpiresAt,
1459
1584
  storeNow: result.value.storeNow
1460
1585
  };
1461
1586
  }
1462
1587
  async renewOwnerLease(token, leaseTtlMs, signal) {
1588
+ return this.observeStore('lease_renew', () => this.renewOwnerLeaseRequest(token, leaseTtlMs, signal));
1589
+ }
1590
+ async renewOwnerLeaseRequest(token, leaseTtlMs, signal) {
1463
1591
  requireOwnerInput(token.ownerId, leaseTtlMs);
1464
1592
  const key = ownerKey(token.ownerId);
1465
1593
  const current = await this.provider.read(key, signal);
@@ -1488,6 +1616,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1488
1616
  };
1489
1617
  }
1490
1618
  async releaseOwnerLease(token, signal) {
1619
+ return this.observeStore('release', () => this.releaseOwnerLeaseRequest(token, signal));
1620
+ }
1621
+ async releaseOwnerLeaseRequest(token, signal) {
1491
1622
  const key = ownerKey(token.ownerId);
1492
1623
  const current = await this.provider.read(key, signal);
1493
1624
  if (current.kind === 'missing')
@@ -1502,9 +1633,18 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1502
1633
  return result.kind === 'applied' ? 'released' : 'stale';
1503
1634
  }
1504
1635
  async updateMeshNode(descriptor, intent, signal) {
1636
+ return this.observeStore('compare_exchange', () => this.updateMeshNodeRequest(descriptor, intent, signal));
1637
+ }
1638
+ async updateMeshNodeRequest(descriptor, intent, signal) {
1639
+ const capacityRowKey = capacityKey(descriptor.meshName, String(descriptor.rid));
1640
+ if (!this.confirmedCapacities.has(capacityRowKey.value))
1641
+ this.confirmedCapacities.set(capacityRowKey.value, undefined);
1505
1642
  return this.updateDescriptor(meshKey(descriptor.meshName, descriptor.rid), descriptor, intent, reviveMeshDescriptor, sameMeshDescriptor, canRenewMesh, signal);
1506
1643
  }
1507
1644
  async removeMeshNode(key, owner, signal) {
1645
+ return this.observeStore('release', () => this.removeMeshNodeRequest(key, owner, signal));
1646
+ }
1647
+ async removeMeshNodeRequest(key, owner, signal) {
1508
1648
  const rowKey = meshKey(key.meshName, key.rid);
1509
1649
  const current = await this.provider.read(rowKey, signal);
1510
1650
  if (current.kind === 'missing')
@@ -1518,9 +1658,14 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1518
1658
  conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
1519
1659
  mutations: [{ kind: 'delete', key: rowKey }]
1520
1660
  }, signal);
1661
+ if (result.kind === 'applied')
1662
+ this.confirmedCapacities.delete(capacityKey(key.meshName, String(key.rid)).value);
1521
1663
  return result.kind === 'applied' ? Locations_1.ZLinkLocationWriteStatus.Stored : Locations_1.ZLinkLocationWriteStatus.IgnoredStale;
1522
1664
  }
1523
1665
  async listMeshNodes(meshName, page = {}, signal) {
1666
+ return this.observeStore('read', () => this.listMeshNodesRequest(meshName, page, signal));
1667
+ }
1668
+ async listMeshNodesRequest(meshName, page = {}, signal) {
1524
1669
  const result = await this.provider.scan({
1525
1670
  prefix: meshPrefix(meshName),
1526
1671
  cursor: page.continuationToken === undefined
@@ -1539,30 +1684,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1539
1684
  : decodeJson(capacityRead.value.bytes);
1540
1685
  return {
1541
1686
  ...descriptor,
1542
- populationCapacity: {
1543
- actors: {
1544
- ...descriptor.populationCapacity.actors,
1545
- active: capacity.active.actors,
1546
- reserved: capacity.pending.actors
1547
- },
1548
- spots: {
1549
- ...descriptor.populationCapacity.spots,
1550
- active: capacity.active.spots,
1551
- reserved: capacity.pending.spots
1552
- },
1553
- spotTypes: descriptor.populationCapacity.spotTypes.map((value) => {
1554
- const key = capacityTypeKey({
1555
- objectKind: value.objectKind,
1556
- stableType: value.stableType,
1557
- count: 0
1558
- });
1559
- return {
1560
- ...value,
1561
- active: capacity.active.spotTypes[key] ?? 0,
1562
- reserved: capacity.pending.spotTypes[key] ?? 0
1563
- };
1564
- })
1565
- }
1687
+ populationCapacity: projectCapacity(descriptor.populationCapacity, capacity)
1566
1688
  };
1567
1689
  }));
1568
1690
  return {
@@ -1571,54 +1693,99 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1571
1693
  };
1572
1694
  }
1573
1695
  async updateClientServer(descriptor, intent, signal) {
1696
+ return this.observeStore('compare_exchange', () => this.updateClientServerRequest(descriptor, intent, signal));
1697
+ }
1698
+ async updateClientServerRequest(descriptor, intent, signal) {
1574
1699
  validateClientServerDescriptor(descriptor);
1575
1700
  const normalized = reviveClientServerDescriptor(descriptor);
1576
1701
  return this.updateDescriptor(clientServerKey(normalized.channelName, normalized.serverRid), normalized, intent, reviveClientServerDescriptor, sameClientServerDescriptor, canRenewClientServer, signal);
1577
1702
  }
1578
1703
  async removeClientServer(key, owner, signal) {
1704
+ return this.observeStore('release', () => this.removeClientServerRequest(key, owner, signal));
1705
+ }
1706
+ async removeClientServerRequest(key, owner, signal) {
1579
1707
  return this.removeDescriptor(clientServerKey(key.channelName, key.serverRid), owner, reviveClientServerDescriptor, signal);
1580
1708
  }
1581
1709
  async listClientServers(channelName, page = {}, signal) {
1710
+ return this.observeStore('read', () => this.listClientServersRequest(channelName, page, signal));
1711
+ }
1712
+ async listClientServersRequest(channelName, page = {}, signal) {
1582
1713
  return this.listDescriptors(clientServerPrefix(channelName), page, reviveClientServerDescriptor, signal);
1583
1714
  }
1584
1715
  async updateFanoutPublisher(descriptor, intent, signal) {
1716
+ return this.observeStore('compare_exchange', () => this.updateFanoutPublisherRequest(descriptor, intent, signal));
1717
+ }
1718
+ async updateFanoutPublisherRequest(descriptor, intent, signal) {
1585
1719
  validateFanoutPublisherDescriptor(descriptor);
1586
1720
  const normalized = reviveFanoutDescriptor(descriptor);
1587
1721
  return this.updateDescriptor(fanoutKey(normalized.channelName, normalized.publisherRid), normalized, intent, reviveFanoutDescriptor, sameFanoutDescriptor, canRenewFanout, signal);
1588
1722
  }
1589
1723
  async removeFanoutPublisher(key, owner, signal) {
1724
+ return this.observeStore('release', () => this.removeFanoutPublisherRequest(key, owner, signal));
1725
+ }
1726
+ async removeFanoutPublisherRequest(key, owner, signal) {
1590
1727
  return this.removeDescriptor(fanoutKey(key.channelName, key.publisherRid), owner, reviveFanoutDescriptor, signal);
1591
1728
  }
1592
1729
  async listFanoutPublishers(channelName, page = {}, signal) {
1730
+ return this.observeStore('read', () => this.listFanoutPublishersRequest(channelName, page, signal));
1731
+ }
1732
+ async listFanoutPublishersRequest(channelName, page = {}, signal) {
1593
1733
  return this.listDescriptors(fanoutPrefix(channelName), page, reviveFanoutDescriptor, signal);
1594
1734
  }
1595
1735
  async updateSpot(location, intent, signal) {
1736
+ return this.observeStore('compare_exchange', () => this.updateSpotRequest(location, intent, signal));
1737
+ }
1738
+ async updateSpotRequest(location, intent, signal) {
1596
1739
  return this.updateOwnedLocation(spotKey(location.meshName, String(location.spotId)), normalizeSpot(location), intent, signal);
1597
1740
  }
1598
1741
  async removeSpot(key, owner, signal) {
1742
+ return this.observeStore('release', () => this.removeSpotRequest(key, owner, signal));
1743
+ }
1744
+ async removeSpotRequest(key, owner, signal) {
1599
1745
  return this.removeOwnedLocation(spotKey(key.meshName, String(key.spotId)), owner, signal);
1600
1746
  }
1601
1747
  async resolveSpot(key, signal) {
1748
+ return this.observeStore('read', () => this.resolveSpotRequest(key, signal));
1749
+ }
1750
+ async resolveSpotRequest(key, signal) {
1602
1751
  const value = await this.readOwnedLocation(spotKey(key.meshName, String(key.spotId)), signal);
1603
1752
  return value === undefined ? undefined : normalizeSpot(value);
1604
1753
  }
1605
1754
  async listSpots(filter, page = {}, signal) {
1755
+ return this.observeStore('read', () => this.listSpotsRequest(filter, page, signal));
1756
+ }
1757
+ async listSpotsRequest(filter, page = {}, signal) {
1606
1758
  return this.listOwnedLocations(`${PREFIX}spot:`, page, normalizeSpot, (value) => matchesSpot(value, filter), signal);
1607
1759
  }
1608
1760
  async updateActor(location, intent, signal) {
1761
+ return this.observeStore('compare_exchange', () => this.updateActorRequest(location, intent, signal));
1762
+ }
1763
+ async updateActorRequest(location, intent, signal) {
1609
1764
  return this.updateOwnedLocation(actorKey(location.meshName, location.actorId), normalizeActor(location), intent, signal, location);
1610
1765
  }
1611
1766
  async removeActor(key, owner, signal) {
1767
+ return this.observeStore('release', () => this.removeActorRequest(key, owner, signal));
1768
+ }
1769
+ async removeActorRequest(key, owner, signal) {
1612
1770
  return this.removeOwnedLocation(actorKey(key.meshName, key.actorId), owner, signal);
1613
1771
  }
1614
1772
  async resolveActor(key, signal) {
1773
+ return this.observeStore('read', () => this.resolveActorRequest(key, signal));
1774
+ }
1775
+ async resolveActorRequest(key, signal) {
1615
1776
  const value = await this.readOwnedLocation(actorKey(key.meshName, key.actorId), signal);
1616
1777
  return value === undefined ? undefined : normalizeActor(value);
1617
1778
  }
1618
1779
  async listActors(filter, page = {}, signal) {
1780
+ return this.observeStore('read', () => this.listActorsRequest(filter, page, signal));
1781
+ }
1782
+ async listActorsRequest(filter, page = {}, signal) {
1619
1783
  return this.listOwnedLocations(`${PREFIX}actor:`, page, normalizeActor, (value) => matchesActor(value, filter), signal);
1620
1784
  }
1621
1785
  async updateRoute(location, intent, signal) {
1786
+ return this.observeStore('compare_exchange', () => this.updateRouteRequest(location, intent, signal));
1787
+ }
1788
+ async updateRouteRequest(location, intent, signal) {
1622
1789
  const rowKey = routeKey(String(location.routeKind), location.routeKey);
1623
1790
  const normalized = normalizeRoute(location);
1624
1791
  const current = await this.provider.read(rowKey, signal);
@@ -1673,6 +1840,9 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1673
1840
  : rejected(result.storeNow);
1674
1841
  }
1675
1842
  async removeRoute(key, owner, signal) {
1843
+ return this.observeStore('release', () => this.removeRouteRequest(key, owner, signal));
1844
+ }
1845
+ async removeRouteRequest(key, owner, signal) {
1676
1846
  const rowKey = routeKey(String(key.routeKind), key.routeKey);
1677
1847
  const current = await this.provider.read(rowKey, signal);
1678
1848
  if (current.kind === 'missing')
@@ -1699,13 +1869,22 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1699
1869
  : rejected(result.storeNow);
1700
1870
  }
1701
1871
  async resolveRoute(key, signal) {
1872
+ return this.observeStore('read', () => this.resolveRouteRequest(key, signal));
1873
+ }
1874
+ async resolveRouteRequest(key, signal) {
1702
1875
  const value = await this.readOwnedLocation(routeKey(String(key.routeKind), key.routeKey), signal);
1703
1876
  return value === undefined ? undefined : normalizeRoute(value);
1704
1877
  }
1705
1878
  async listRoutes(filter, page = {}, signal) {
1879
+ return this.observeStore('read', () => this.listRoutesRequest(filter, page, signal));
1880
+ }
1881
+ async listRoutesRequest(filter, page = {}, signal) {
1706
1882
  return this.listOwnedLocations(`${PREFIX}route:`, page, normalizeRoute, (value) => matchesRoute(value, filter), signal);
1707
1883
  }
1708
1884
  async removeAllByOwner(owner, signal) {
1885
+ return this.observeStore('release', () => this.removeAllByOwnerRequest(owner, signal));
1886
+ }
1887
+ async removeAllByOwnerRequest(owner, signal) {
1709
1888
  const leaseKey = ownerKey(owner.ownerId);
1710
1889
  const lease = await this.provider.read(leaseKey, signal);
1711
1890
  if (liveOwnerLeaseGeneration(lease) !== owner.leaseGeneration)
@@ -1792,7 +1971,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1792
1971
  const encodedAuthority = authorityContractValueFromPreimage(candidate.key.value);
1793
1972
  const identity = (0, authority_key_codec_1.decodeAuthorityKey)({ value: encodedAuthority });
1794
1973
  if (record.snapshot.allocation.state === 'active') {
1795
- const result = await this.compareExchangeAuthority({ value: encodedAuthority }, current.value.version, { kind: 'delete' }, signal);
1974
+ const result = await this.compareExchangeAuthorityRequest({ value: encodedAuthority }, current.value.version, { kind: 'delete' }, signal);
1796
1975
  if (result.kind === 'deleted')
1797
1976
  removed += 1n;
1798
1977
  continue;
@@ -1800,7 +1979,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1800
1979
  const reservationId = record.snapshot.pendingCreation?.reservationId;
1801
1980
  if (reservationId === undefined)
1802
1981
  continue;
1803
- const aborted = await this.abort({
1982
+ const aborted = await this.abortRequest({
1804
1983
  key: identity,
1805
1984
  reservationId,
1806
1985
  expectedStoreVersion: current.value.version.value,
@@ -1922,10 +2101,23 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1922
2101
  const rowCondition = currentRow.kind === 'found'
1923
2102
  ? { kind: 'version', key: rowKey, expected: currentRow.value.version }
1924
2103
  : { kind: 'missing', key: rowKey };
1925
- const result = await this.provider.write({
1926
- conditions: [leaseValueCondition(leaseKey, { ownerId, leaseGeneration }), rowCondition],
1927
- mutations: [{ kind: 'put', key: rowKey, bytes: encodedDescriptor }]
1928
- }, signal);
2104
+ let result;
2105
+ try {
2106
+ result = await this.provider.write({
2107
+ conditions: [leaseValueCondition(leaseKey, { ownerId, leaseGeneration }), rowCondition],
2108
+ mutations: [{ kind: 'put', key: rowKey, bytes: encodedDescriptor }]
2109
+ }, signal);
2110
+ }
2111
+ catch (failure) {
2112
+ // Location runtime §10: the Store may have applied a write whose result
2113
+ // was lost. Re-read the same key; the same bytes confirm the write.
2114
+ const confirmed = await this.provider.read(rowKey, signal).catch(() => undefined);
2115
+ if (confirmed?.kind === 'found' &&
2116
+ Buffer.from(confirmed.value.bytes).equals(Buffer.from(encodedDescriptor))) {
2117
+ return { status: Locations_1.ZLinkLocationWriteStatus.Stored, generation, updatedAt: confirmed.value.storeNow };
2118
+ }
2119
+ throw failure;
2120
+ }
1929
2121
  if (result.kind === 'applied') {
1930
2122
  return { status: Locations_1.ZLinkLocationWriteStatus.Stored, generation, updatedAt: result.storeNow };
1931
2123
  }
@@ -2671,6 +2863,11 @@ function reviveCanonical(value, key = '') {
2671
2863
  }
2672
2864
  return value;
2673
2865
  }
2866
+ function requireOwnerLeaseExpiry(value) {
2867
+ if (value.expiresAt === undefined)
2868
+ throw new Error('Location Store owner lease record is invalid.');
2869
+ return value.expiresAt;
2870
+ }
2674
2871
  function decodeOwnerRecord(bytes) {
2675
2872
  const record = decodeJson(bytes);
2676
2873
  requireRecordVersion(record, 'owner lease');
@@ -2710,7 +2907,7 @@ function canonicalDescriptor(descriptor) {
2710
2907
  if ('serverRid' in descriptor)
2711
2908
  return {
2712
2909
  channelName: descriptor.channelName,
2713
- serverRoutingIdHex: (0, routing_id_1.encodeRoutingIdStorageHex)(descriptor.serverRid),
2910
+ serverRoutingIdHex: (0, routing_id_2.encodeRoutingIdStorageHex)(descriptor.serverRid),
2714
2911
  lifecycleGeneration: descriptor.lifecycleGeneration.toString(),
2715
2912
  descriptorRevision: descriptor.descriptorRevision.toString(),
2716
2913
  endpoint: descriptor.endpoint,
@@ -2724,7 +2921,7 @@ function canonicalDescriptor(descriptor) {
2724
2921
  const publisher = descriptor;
2725
2922
  return {
2726
2923
  channelName: publisher.channelName,
2727
- publisherRoutingIdHex: (0, routing_id_1.encodeRoutingIdStorageHex)(publisher.publisherRid),
2924
+ publisherRoutingIdHex: (0, routing_id_2.encodeRoutingIdStorageHex)(publisher.publisherRid),
2728
2925
  lifecycleGeneration: publisher.lifecycleGeneration.toString(),
2729
2926
  descriptorRevision: publisher.descriptorRevision.toString(),
2730
2927
  endpoint: publisher.endpoint,
@@ -2738,7 +2935,7 @@ function canonicalDescriptor(descriptor) {
2738
2935
  function canonicalMeshDescriptor(descriptor) {
2739
2936
  return {
2740
2937
  meshName: descriptor.meshName,
2741
- routingIdHex: (0, routing_id_1.encodeRoutingIdStorageHex)(descriptor.rid),
2938
+ routingIdHex: (0, routing_id_2.encodeRoutingIdStorageHex)(descriptor.rid),
2742
2939
  lifecycleGeneration: descriptor.lifecycleGeneration.toString(),
2743
2940
  descriptorRevision: descriptor.descriptorRevision.toString(),
2744
2941
  endpoint: descriptor.endpoint,
@@ -2839,7 +3036,7 @@ function encodeAuthorityRecord(record) {
2839
3036
  stableType: allocation.stableType,
2840
3037
  descriptor: {
2841
3038
  meshName: allocation.descriptor.meshName,
2842
- routingIdHex: (0, routing_id_1.encodeRoutingIdStorageHex)(allocation.descriptor.rid)
3039
+ routingIdHex: (0, routing_id_2.encodeRoutingIdStorageHex)(allocation.descriptor.rid)
2843
3040
  },
2844
3041
  descriptorLifecycleGeneration: allocation.descriptorLifecycleGeneration.toString(),
2845
3042
  capacity: canonicalAuthorityCapacity(allocation.capacity)
@@ -2890,7 +3087,7 @@ function decodeAuthorityRecord(bytes) {
2890
3087
  stableType: String(allocation.stableType),
2891
3088
  descriptor: {
2892
3089
  meshName: String(descriptor.meshName),
2893
- rid: (0, routing_id_1.decodeRoutingId)(String(descriptor.routingIdHex), descriptor.routingIdHex)
3090
+ rid: (0, routing_id_2.decodeRoutingId)(String(descriptor.routingIdHex), descriptor.routingIdHex)
2894
3091
  },
2895
3092
  descriptorLifecycleGeneration: BigInt(String(allocation.descriptorLifecycleGeneration)),
2896
3093
  capacity: {
@@ -3047,20 +3244,22 @@ function authoritySnapshot(snapshot, storeVersion, storeNow) {
3047
3244
  };
3048
3245
  }
3049
3246
  function liveTargetDescriptor(descriptorRead, leaseRead, target) {
3050
- if (descriptorRead.kind === 'missing' || leaseRead.kind === 'missing')
3247
+ if (leaseRead.kind === 'missing')
3248
+ return undefined;
3249
+ const leaseExpiresAt = requireOwnerLeaseExpiry(leaseRead.value);
3250
+ if (descriptorRead.kind === 'missing')
3051
3251
  return undefined;
3052
3252
  const descriptor = reviveMeshDescriptor(decodeCanonicalDescriptorRecord(descriptorRead.value.bytes).descriptor);
3053
3253
  const lease = decodeOwnerRecord(leaseRead.value.bytes);
3054
3254
  return descriptor.meshName === target.meshName &&
3055
- String(descriptor.rid) === String(target.nodeRid) &&
3255
+ (0, routing_id_1.routingIdsEqual)(descriptor.rid, (0, routing_id_1.toBackendRoutingId)(target.nodeRid)) &&
3056
3256
  descriptor.lifecycleGeneration === target.nodeLifecycleGeneration &&
3057
3257
  descriptor.ownerId === target.owner.ownerId &&
3058
3258
  descriptor.leaseGeneration === target.owner.leaseGeneration &&
3059
3259
  descriptor.objectRole === contracts_2.ZLinkObjectRole.Server &&
3060
3260
  lease.ownerId === target.owner.ownerId &&
3061
3261
  BigInt(lease.leaseGeneration) === target.owner.leaseGeneration &&
3062
- leaseRead.value.expiresAt !== undefined &&
3063
- leaseRead.value.expiresAt.getTime() > leaseRead.value.storeNow.getTime()
3262
+ leaseExpiresAt.getTime() > leaseRead.value.storeNow.getTime()
3064
3263
  ? descriptor
3065
3264
  : undefined;
3066
3265
  }
@@ -3148,7 +3347,7 @@ function sameCapacityVector(left, right) {
3148
3347
  }
3149
3348
  function sameCreationTarget(snapshot, target) {
3150
3349
  return (snapshot.allocation.descriptor.meshName === target.meshName &&
3151
- String(snapshot.allocation.descriptor.rid) === String(target.nodeRid) &&
3350
+ (0, routing_id_1.routingIdsEqual)(snapshot.allocation.descriptor.rid, target.nodeRid) &&
3152
3351
  snapshot.allocation.descriptorLifecycleGeneration === target.nodeLifecycleGeneration &&
3153
3352
  snapshot.ownerId === target.owner.ownerId &&
3154
3353
  snapshot.ownerLeaseGeneration === target.owner.leaseGeneration);
@@ -3163,8 +3362,7 @@ function sameLiveOwner(lease, snapshot) {
3163
3362
  return matchesLiveOwnerLease(lease, snapshot.ownerId, snapshot.ownerLeaseGeneration);
3164
3363
  }
3165
3364
  function matchesLiveOwnerLease(lease, ownerId, leaseGeneration) {
3166
- if (lease.value.expiresAt === undefined ||
3167
- lease.value.expiresAt.getTime() <= lease.value.storeNow.getTime()) {
3365
+ if (requireOwnerLeaseExpiry(lease.value).getTime() <= lease.value.storeNow.getTime()) {
3168
3366
  return false;
3169
3367
  }
3170
3368
  const owner = decodeOwnerRecord(lease.value.bytes);
@@ -3177,9 +3375,9 @@ function sameDescriptorPredecessor(expected, current) {
3177
3375
  return Buffer.from(expected.value.bytes).equals(Buffer.from(current.value.bytes));
3178
3376
  }
3179
3377
  function liveOwnerLeaseGeneration(lease) {
3180
- if (lease.kind === 'missing' ||
3181
- lease.value.expiresAt === undefined ||
3182
- lease.value.expiresAt.getTime() <= lease.value.storeNow.getTime()) {
3378
+ if (lease.kind === 'missing')
3379
+ return undefined;
3380
+ if (requireOwnerLeaseExpiry(lease.value).getTime() <= lease.value.storeNow.getTime()) {
3183
3381
  return undefined;
3184
3382
  }
3185
3383
  return BigInt(decodeOwnerRecord(lease.value.bytes).leaseGeneration);
@@ -3199,16 +3397,13 @@ function canTakeOverStoredLocation(intent, currentOwnerId, currentLeaseGeneratio
3199
3397
  currentLeaseGeneration !== nextLeaseGeneration &&
3200
3398
  liveLeaseGeneration === nextLeaseGeneration);
3201
3399
  }
3202
- function persistMeshDescriptor(descriptor) {
3203
- return descriptor;
3204
- }
3205
3400
  function reviveMeshDescriptor(descriptor) {
3206
3401
  const value = descriptor;
3207
3402
  if ('routingIdHex' in value) {
3208
3403
  const capacity = value.capacity;
3209
3404
  return {
3210
3405
  meshName: String(value.meshName),
3211
- rid: (0, routing_id_1.decodeRoutingId)(String(value.routingIdHex), value.routingIdHex),
3406
+ rid: (0, routing_id_2.decodeRoutingId)(String(value.routingIdHex), value.routingIdHex),
3212
3407
  lifecycleGeneration: BigInt(String(value.lifecycleGeneration)),
3213
3408
  descriptorRevision: BigInt(String(value.descriptorRevision)),
3214
3409
  endpoint: String(value.endpoint),
@@ -3240,7 +3435,7 @@ function reviveClientServerDescriptor(descriptor) {
3240
3435
  if ('serverRoutingIdHex' in value) {
3241
3436
  return {
3242
3437
  channelName: String(value.channelName),
3243
- serverRid: (0, routing_id_1.decodeRoutingId)(String(value.serverRoutingIdHex), value.serverRoutingIdHex),
3438
+ serverRid: (0, routing_id_2.decodeRoutingId)(String(value.serverRoutingIdHex), value.serverRoutingIdHex),
3244
3439
  lifecycleGeneration: BigInt(String(value.lifecycleGeneration)),
3245
3440
  descriptorRevision: BigInt(String(value.descriptorRevision)),
3246
3441
  endpoint: String(value.endpoint),
@@ -3263,7 +3458,7 @@ function reviveFanoutDescriptor(descriptor) {
3263
3458
  if ('publisherRoutingIdHex' in value) {
3264
3459
  return {
3265
3460
  channelName: String(value.channelName),
3266
- publisherRid: (0, routing_id_1.decodeRoutingId)(String(value.publisherRoutingIdHex), value.publisherRoutingIdHex),
3461
+ publisherRid: (0, routing_id_2.decodeRoutingId)(String(value.publisherRoutingIdHex), value.publisherRoutingIdHex),
3267
3462
  lifecycleGeneration: BigInt(String(value.lifecycleGeneration)),
3268
3463
  descriptorRevision: BigInt(String(value.descriptorRevision)),
3269
3464
  endpoint: String(value.endpoint),
@@ -3314,19 +3509,19 @@ function normalizeRoute(value) {
3314
3509
  function matchesSpot(value, filter) {
3315
3510
  return ((filter.meshName === undefined || value.meshName === filter.meshName) &&
3316
3511
  (filter.spotType === undefined || value.spotType === filter.spotType) &&
3317
- (filter.nodeRid === undefined || String(value.ownerNodeRid) === String(filter.nodeRid)) &&
3512
+ (filter.nodeRid === undefined || (0, routing_id_1.routingIdsEqual)(value.ownerNodeRid, filter.nodeRid)) &&
3318
3513
  (filter.spotKind === undefined || value.spotKind === filter.spotKind));
3319
3514
  }
3320
3515
  function matchesActor(value, filter) {
3321
3516
  return ((filter.actorType === undefined || value.actorType === filter.actorType) &&
3322
- (filter.nodeRid === undefined || String(value.ownerNodeRid) === String(filter.nodeRid)) &&
3517
+ (filter.nodeRid === undefined || (0, routing_id_1.routingIdsEqual)(value.ownerNodeRid, filter.nodeRid)) &&
3323
3518
  (filter.spotId === undefined || String(value.spotId) === String(filter.spotId)) &&
3324
3519
  (filter.locationKind === undefined || value.spotKind === filter.locationKind));
3325
3520
  }
3326
3521
  function matchesRoute(value, filter) {
3327
3522
  return ((filter.routeKind === undefined || value.routeKind === filter.routeKind) &&
3328
3523
  (filter.ownerNodeRid === undefined ||
3329
- String(value.ownerNodeRid) === String(filter.ownerNodeRid)) &&
3524
+ (0, routing_id_1.routingIdsEqual)(value.ownerNodeRid, filter.ownerNodeRid)) &&
3330
3525
  (filter.ownerId === undefined || value.ownerId === filter.ownerId));
3331
3526
  }
3332
3527
  function locationOwnerGeneration(value) {
@@ -3343,8 +3538,11 @@ function descriptorOwnerLeaseGeneration(value) {
3343
3538
  }
3344
3539
  return undefined;
3345
3540
  }
3541
+ // Location runtime §10: a write whose result was lost is confirmed by reading
3542
+ // the same key. The stored row already is this write when it differs only in
3543
+ // the time the Store stamped, as for every other descriptor kind.
3346
3544
  function sameMeshDescriptor(left, right) {
3347
- return Buffer.from(encodeJson(persistMeshDescriptor(left))).equals(Buffer.from(encodeJson(persistMeshDescriptor(right))));
3545
+ return descriptorFingerprint(left, ['updatedAt']) === descriptorFingerprint(right, ['updatedAt']);
3348
3546
  }
3349
3547
  function sameClientServerDescriptor(left, right) {
3350
3548
  return descriptorFingerprint(left, ['updatedAt']) === descriptorFingerprint(right, ['updatedAt']);
@@ -3446,7 +3644,7 @@ function requireOwnerInput(ownerId, leaseTtlMs) {
3446
3644
  function throwIfOperationExpired(signal, deadlineUnixMs) {
3447
3645
  signal?.throwIfAborted();
3448
3646
  if (deadlineUnixMs !== undefined && Date.now() >= Number(deadlineUnixMs)) {
3449
- throw new DOMException('Operation deadline exceeded.', 'TimeoutError');
3647
+ throw new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.DeadlineExceeded, 'Operation deadline exceeded.');
3450
3648
  }
3451
3649
  }
3452
3650
  // Store SPI §6: preserve caller failures and classify provider failures once.
@@ -3458,3 +3656,29 @@ function locationStoreProviderFailure(error, signal) {
3458
3656
  return error;
3459
3657
  return new contracts_2.ZLinkFrameworkException(contracts_2.ZLinkFrameworkErrorKind.Unavailable, 'Location Store provider is unavailable.', error);
3460
3658
  }
3659
+ function projectCapacity(limits, capacity) {
3660
+ return {
3661
+ actors: {
3662
+ ...limits.actors,
3663
+ active: capacity.active.actors,
3664
+ reserved: capacity.pending.actors
3665
+ },
3666
+ spots: {
3667
+ ...limits.spots,
3668
+ active: capacity.active.spots,
3669
+ reserved: capacity.pending.spots
3670
+ },
3671
+ spotTypes: limits.spotTypes.map((value) => {
3672
+ const key = capacityTypeKey({
3673
+ objectKind: value.objectKind,
3674
+ stableType: value.stableType,
3675
+ count: 0
3676
+ });
3677
+ return {
3678
+ ...value,
3679
+ active: capacity.active.spotTypes[key] ?? 0,
3680
+ reserved: capacity.pending.spotTypes[key] ?? 0
3681
+ };
3682
+ })
3683
+ };
3684
+ }