@zlink-systems/framework 0.21.0 → 0.22.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 (487) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Common/ZLinkMessage.js +5 -5
  3. package/dist/contracts/Configuration/CodecContentType.js +5 -7
  4. package/dist/contracts/Configuration/DiagnosticsValidation.js +1 -6
  5. package/dist/contracts/Configuration/EndpointNotation.js +4 -8
  6. package/dist/contracts/Configuration/Registration.js +14 -11
  7. package/dist/contracts/Configuration/RegistrationBuilders.js +32 -25
  8. package/dist/contracts/Configuration/RegistrationNormalizers.js +25 -26
  9. package/dist/contracts/Configuration/RegistrationValidators.js +36 -38
  10. package/dist/contracts/Configuration/SendTimeoutValidation.js +4 -4
  11. package/dist/contracts/Configuration/TimerRegistrationValidator.js +7 -7
  12. package/dist/contracts/Handlers/JsonContract.js +23 -11
  13. package/dist/contracts/Spots/SpotKind.js +16 -8
  14. package/dist/location-store-integration.js +16 -16
  15. package/dist/nest-integration.js +17 -11
  16. package/dist/runtime/abort.js +9 -5
  17. package/dist/runtime/actors/actor-authority-payload-codec.js +12 -16
  18. package/dist/runtime/actors/actor-authority-publication.js +18 -17
  19. package/dist/runtime/actors/actor-client.js +83 -63
  20. package/dist/runtime/actors/actor-context.js +24 -18
  21. package/dist/runtime/actors/actor-creation.js +4 -3
  22. package/dist/runtime/actors/actor-handoff.js +89 -92
  23. package/dist/runtime/actors/actor-local-native-join.js +18 -19
  24. package/dist/runtime/actors/actor-mailbox.js +1 -1
  25. package/dist/runtime/actors/actor-message-follow-context.js +24 -21
  26. package/dist/runtime/actors/actor-packet-relay-wire.js +1 -3
  27. package/dist/runtime/actors/actor-remote-joiner.js +20 -17
  28. package/dist/runtime/actors/actor-remote-wire.js +6 -7
  29. package/dist/runtime/actors/actor-runtime-state.js +87 -81
  30. package/dist/runtime/actors/actor-transfer-registry.js +3 -5
  31. package/dist/runtime/actors/bound-session-wire.js +14 -9
  32. package/dist/runtime/actors/deferred-join-accepted-journal.js +158 -124
  33. package/dist/runtime/actors/index.js +2 -5
  34. package/dist/runtime/actors/post-commit-actor-binder.js +3 -6
  35. package/dist/runtime/actors/post-commit-actor-location.js +1 -1
  36. package/dist/runtime/actors/spot-actor-dispatch.js +5 -5
  37. package/dist/runtime/actors/transferred-actor-rollback.js +4 -4
  38. package/dist/runtime/admission.js +2 -6
  39. package/dist/runtime/application-jobs/application-ingress-record-owner.js +2 -6
  40. package/dist/runtime/application-jobs/receive-flow-controller.js +11 -12
  41. package/dist/runtime/backend/mesh-completion-table.js +1 -3
  42. package/dist/runtime/backend/mesh-dispatch-pump.js +12 -16
  43. package/dist/runtime/backend/node/node-backend-adapter-factory.js +1 -3
  44. package/dist/runtime/backend/node/node-backend-adapter-support.js +26 -17
  45. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +4 -3
  46. package/dist/runtime/backend/node/node-raw-binding-port.js +7 -6
  47. package/dist/runtime/backend/node/node-raw-mesh-backend.js +116 -113
  48. package/dist/runtime/backend/node/node-socket-backend-adapter.js +12 -13
  49. package/dist/runtime/backend/runtime-message.js +3 -3
  50. package/dist/runtime/backend/runtime-values.d.ts +2 -2
  51. package/dist/runtime/backend/runtime-values.js +4 -5
  52. package/dist/runtime/channels/channel-clients.js +27 -24
  53. package/dist/runtime/channels/channel-dispatch-pipeline.js +10 -18
  54. package/dist/runtime/channels/channel-dispatch-services.js +7 -4
  55. package/dist/runtime/channels/channel-dispatchers.js +9 -9
  56. package/dist/runtime/channels/channel-envelope-inspection.js +16 -13
  57. package/dist/runtime/channels/channel-envelope.js +83 -47
  58. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  59. package/dist/runtime/channels/channel-receive-loops.js +20 -22
  60. package/dist/runtime/channels/channel-receive-task-tracker.js +1 -1
  61. package/dist/runtime/channels/channel-runtime-lifecycle.js +61 -56
  62. package/dist/runtime/channels/channel-runtime-manager.js +18 -9
  63. package/dist/runtime/channels/channel-socket-registry.js +126 -123
  64. package/dist/runtime/channels/channel-transports.js +43 -33
  65. package/dist/runtime/channels/client-server-location-runtime.js +32 -40
  66. package/dist/runtime/channels/client-server-service-wire.js +29 -22
  67. package/dist/runtime/channels/dispatch-error-reporter.js +9 -7
  68. package/dist/runtime/channels/fanout-location-runtime.js +34 -47
  69. package/dist/runtime/channels/fanout-service-wire.js +3 -5
  70. package/dist/runtime/channels/local-spot-route-transport.js +7 -1
  71. package/dist/runtime/channels/route-member-snapshot.js +3 -3
  72. package/dist/runtime/channels/source-spot-router.js +6 -2
  73. package/dist/runtime/channels/spot-route-bridge-transport.js +5 -2
  74. package/dist/runtime/channels/spot-route-dispatch-strategy.js +2 -2
  75. package/dist/runtime/channels/spot-route-target-resolver.js +6 -6
  76. package/dist/runtime/diagnostics/index.js +38 -10
  77. package/dist/runtime/diagnostics/message-flow.js +47 -39
  78. package/dist/runtime/diagnostics/runtime-metrics.js +18 -9
  79. package/dist/runtime/diagnostics/runtime-observation-queue.js +8 -10
  80. package/dist/runtime/diagnostics/topology-runtime-projections.js +17 -10
  81. package/dist/runtime/execution/index.js +7 -6
  82. package/dist/runtime/execution/serial-execution-queue.js +12 -18
  83. package/dist/runtime/execution/state-lane.js +2 -2
  84. package/dist/runtime/foundation/actor-join-recovery-codec.js +31 -23
  85. package/dist/runtime/foundation/event-loop-resources.js +4 -4
  86. package/dist/runtime/foundation/message-follow-suppression-registry.js +4 -4
  87. package/dist/runtime/foundation/raw-service-mesh-runtime.js +136 -136
  88. package/dist/runtime/foundation/route-mesh-connection-policy.js +4 -4
  89. package/dist/runtime/foundation/runtime-state-projections.js +22 -11
  90. package/dist/runtime/foundation/service-authority-payload-codec.js +13 -15
  91. package/dist/runtime/foundation/service-discovery-registry.js +35 -33
  92. package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +20 -22
  93. package/dist/runtime/foundation/service-liveness-registry.js +16 -12
  94. package/dist/runtime/foundation/service-maintenance-runtime.js +2 -4
  95. package/dist/runtime/foundation/service-relocation-aggregate-committer.js +24 -24
  96. package/dist/runtime/foundation/service-relocation-object-owner.js +6 -6
  97. package/dist/runtime/foundation/service-relocation-runtime.js +137 -94
  98. package/dist/runtime/foundation/service-runtime-contracts.js +5 -5
  99. package/dist/runtime/foundation/service-stateful-registry.js +24 -23
  100. package/dist/runtime/foundation/service-stateful-runtime.js +416 -438
  101. package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
  102. package/dist/runtime/foundation/service-topology-registry.js +96 -95
  103. package/dist/runtime/foundation/service-weighted-selection.js +6 -11
  104. package/dist/runtime/foundation/service-wire-binary-primitives.js +5 -6
  105. package/dist/runtime/foundation/service-wire-m6a-codec.js +46 -35
  106. package/dist/runtime/framework-errors-internal.js +7 -10
  107. package/dist/runtime/handlers/handler-instance-scope.js +4 -5
  108. package/dist/runtime/handlers/index.js +3 -1
  109. package/dist/runtime/host/actor-packet-relay.js +74 -70
  110. package/dist/runtime/host/actor-placement-coordinator.js +29 -31
  111. package/dist/runtime/host/actor-runtime-options-factory.js +12 -14
  112. package/dist/runtime/host/actor-transfer-authority-runtime.js +7 -9
  113. package/dist/runtime/host/actor-transfer-runtime.js +176 -153
  114. package/dist/runtime/host/application-job-queue.js +18 -22
  115. package/dist/runtime/host/bound-session-relay.js +3 -1
  116. package/dist/runtime/host/channel-runtime-options-factory.js +31 -14
  117. package/dist/runtime/host/host-capacity-status.js +8 -4
  118. package/dist/runtime/host/index.js +244 -227
  119. package/dist/runtime/host/instance-activation-authority.js +93 -96
  120. package/dist/runtime/host/location-runtime-owner.js +16 -14
  121. package/dist/runtime/host/mesh-router-resolver.js +11 -13
  122. package/dist/runtime/host/relocation-direct-transfer.js +10 -9
  123. package/dist/runtime/host/remote-actor-join-receiver.js +20 -15
  124. package/dist/runtime/host/remote-actor-packet-target-store.js +18 -22
  125. package/dist/runtime/host/remote-bound-session-relay.js +97 -73
  126. package/dist/runtime/host/route-mesh-runtime.js +64 -69
  127. package/dist/runtime/host/runtime-shutdown.js +1 -2
  128. package/dist/runtime/host/service-relocation-host-runtime.js +586 -511
  129. package/dist/runtime/host/spot-address-transport.js +69 -71
  130. package/dist/runtime/host/spot-runtime-options-factory.js +30 -29
  131. package/dist/runtime/host/stateful-authority-route-runtime.js +65 -68
  132. package/dist/runtime/host/user-spot-creation-coordinator.js +61 -67
  133. package/dist/runtime/locations/actor-location-claims.js +26 -20
  134. package/dist/runtime/locations/aggregate-inventory-store.js +72 -75
  135. package/dist/runtime/locations/authority-key-codec.js +7 -7
  136. package/dist/runtime/locations/auto-connect-loop.js +3 -3
  137. package/dist/runtime/locations/auto-connect-planner.js +25 -19
  138. package/dist/runtime/locations/auto-connect-reconciler.js +51 -31
  139. package/dist/runtime/locations/in-memory-authority-store.js +128 -118
  140. package/dist/runtime/locations/in-memory-location-store.js +195 -168
  141. package/dist/runtime/locations/in-memory-provider-location-store.js +8 -10
  142. package/dist/runtime/locations/key-codec.js +1 -1
  143. package/dist/runtime/locations/lease-tracker.js +23 -21
  144. package/dist/runtime/locations/lifecycle.js +4 -5
  145. package/dist/runtime/locations/location-store-repository.js +368 -324
  146. package/dist/runtime/locations/opaque-record-key.js +2 -2
  147. package/dist/runtime/locations/resolvers.js +73 -82
  148. package/dist/runtime/locations/runtime.js +68 -63
  149. package/dist/runtime/locations/spot-location-claims.js +39 -35
  150. package/dist/runtime/messaging/framework-json-v1.js +7 -7
  151. package/dist/runtime/messaging/packet-name.js +7 -6
  152. package/dist/runtime/messaging/payload-codec.js +21 -18
  153. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +30 -2
  154. package/dist/runtime/protocol/service_wire_codec.generated.js +1671 -234
  155. package/dist/runtime/routing-id.js +3 -5
  156. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +35 -31
  157. package/dist/runtime/spots/formal-remote-actor-transfer-registry.js +1 -2
  158. package/dist/runtime/spots/index.js +208 -219
  159. package/dist/runtime/spots/spot-activation-registry.js +15 -14
  160. package/dist/runtime/spots/spot-activation-state.js +17 -15
  161. package/dist/runtime/spots/spot-activation.js +33 -16
  162. package/dist/runtime/spots/spot-actor-admission-coordinator.js +18 -15
  163. package/dist/runtime/spots/spot-actor-membership.js +1 -3
  164. package/dist/runtime/spots/spot-actor-packet-dispatch.js +23 -20
  165. package/dist/runtime/spots/spot-actor-packet-drain.js +12 -10
  166. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +10 -6
  167. package/dist/runtime/spots/spot-closing.js +3 -7
  168. package/dist/runtime/spots/spot-context.js +2 -2
  169. package/dist/runtime/spots/spot-entry-activation.js +13 -14
  170. package/dist/runtime/spots/spot-handle.js +6 -3
  171. package/dist/runtime/spots/spot-handler-registry.js +12 -12
  172. package/dist/runtime/spots/spot-manager-public.js +5 -6
  173. package/dist/runtime/spots/spot-native-actor-join-admission.js +4 -3
  174. package/dist/runtime/spots/spot-node-autoconnect.js +15 -18
  175. package/dist/runtime/spots/spot-node-runtime-manager.js +74 -85
  176. package/dist/runtime/spots/spot-outbound.js +10 -14
  177. package/dist/runtime/spots/spot-remote-codec.js +22 -26
  178. package/dist/runtime/spots/spot-remote-route-codec.js +5 -7
  179. package/dist/runtime/spots/spot-route-packet-dispatch.js +16 -14
  180. package/dist/runtime/spots/spot-route-replies.js +4 -6
  181. package/dist/runtime/spots/spot-routed-actor-admission.js +9 -7
  182. package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +1 -2
  183. package/dist/runtime/spots/spot-routed-frame-dispatch.js +5 -5
  184. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +14 -10
  185. package/dist/runtime/spots/spot-serial-executor.js +5 -8
  186. package/dist/runtime/spots/spot-serial-turn-executor.js +4 -6
  187. package/dist/runtime/spots/spot-subscription-dispatch.js +5 -5
  188. package/dist/runtime/spots/spot-timer.js +25 -29
  189. package/dist/runtime/streams/actor-session-binding-registry.js +98 -107
  190. package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
  191. package/dist/runtime/streams/bound-actor-relay-sender.js +18 -16
  192. package/dist/runtime/streams/bound-session-service.js +8 -9
  193. package/dist/runtime/streams/index.js +20 -19
  194. package/dist/runtime/streams/managed-stream.js +32 -30
  195. package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
  196. package/dist/runtime/streams/protocol.js +29 -18
  197. package/dist/runtime/streams/session-actor-coordinator.js +34 -37
  198. package/dist/runtime/streams/session-context.js +30 -28
  199. package/dist/runtime/streams/session-provider.js +2 -2
  200. package/dist/runtime/streams/session-serial-executor.js +1 -2
  201. package/dist/runtime/streams/stream-frame-factory.js +11 -5
  202. package/dist/runtime/streams/stream-session-runtime.js +70 -66
  203. package/dist/runtime/workers/index.js +15 -4
  204. package/package.json +2 -2
  205. package/src/contracts/Channels/RouteCalls.ts +6 -1
  206. package/src/contracts/Common/ZLinkMessage.ts +5 -5
  207. package/src/contracts/Common/ZLinkMessageMetadata.ts +4 -3
  208. package/src/contracts/Configuration/Builders.ts +14 -14
  209. package/src/contracts/Configuration/CodecContentType.ts +8 -10
  210. package/src/contracts/Configuration/DiagnosticsValidation.ts +1 -6
  211. package/src/contracts/Configuration/EndpointNotation.ts +11 -11
  212. package/src/contracts/Configuration/ObjectRoles.ts +1 -3
  213. package/src/contracts/Configuration/Registration.ts +46 -17
  214. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +10 -8
  215. package/src/contracts/Configuration/RegistrationBuilders.ts +107 -96
  216. package/src/contracts/Configuration/RegistrationCodecRegistry.ts +9 -3
  217. package/src/contracts/Configuration/RegistrationNormalizers.ts +116 -84
  218. package/src/contracts/Configuration/RegistrationTypes.ts +21 -25
  219. package/src/contracts/Configuration/RegistrationValidators.ts +122 -73
  220. package/src/contracts/Configuration/RouteChannelInternalState.ts +1 -4
  221. package/src/contracts/Configuration/RuntimeEndpointConnections.ts +4 -1
  222. package/src/contracts/Configuration/SendTimeoutValidation.ts +6 -4
  223. package/src/contracts/Configuration/TimerRegistrationValidator.ts +8 -13
  224. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -6
  225. package/src/contracts/Errors/index.ts +1 -4
  226. package/src/contracts/Handlers/Attributes.ts +15 -9
  227. package/src/contracts/Handlers/IZLinkChannelHandlers.ts +24 -4
  228. package/src/contracts/Handlers/JsonContract.ts +53 -19
  229. package/src/contracts/Locations/ActorTransfer.ts +1 -5
  230. package/src/contracts/Locations/Authority.ts +4 -11
  231. package/src/contracts/Locations/Keys.ts +6 -1
  232. package/src/contracts/Locations/Options.ts +3 -2
  233. package/src/contracts/Locations/RelocationStore.ts +1 -4
  234. package/src/contracts/Locations/Resolvers.ts +5 -5
  235. package/src/contracts/Locations/RuntimeQuery.ts +6 -2
  236. package/src/contracts/Locations/Stores.ts +1 -2
  237. package/src/contracts/Locations/index.ts +2 -8
  238. package/src/contracts/RouteMesh/Contracts.ts +1 -7
  239. package/src/contracts/RouteMesh/RuntimeTopology.ts +1 -4
  240. package/src/contracts/Spots/Contracts.ts +2 -8
  241. package/src/contracts/Spots/SpotKind.ts +16 -8
  242. package/src/contracts/Spots/ZLinkSpot.ts +8 -11
  243. package/src/contracts/Streams/IZLinkSession.ts +0 -1
  244. package/src/contracts/Streams/IZLinkSessionActor.ts +5 -1
  245. package/src/contracts/Streams/IZLinkSessionPacketHandler.ts +5 -1
  246. package/src/internal.ts +5 -4
  247. package/src/location-store-integration.ts +24 -16
  248. package/src/nest-integration.ts +40 -25
  249. package/src/runtime/abort.ts +10 -4
  250. package/src/runtime/actors/actor-authority-payload-codec.ts +20 -29
  251. package/src/runtime/actors/actor-authority-publication.ts +92 -77
  252. package/src/runtime/actors/actor-client.ts +162 -133
  253. package/src/runtime/actors/actor-context.ts +138 -130
  254. package/src/runtime/actors/actor-creation.ts +47 -44
  255. package/src/runtime/actors/actor-execution-context.ts +6 -4
  256. package/src/runtime/actors/actor-handoff.ts +269 -293
  257. package/src/runtime/actors/actor-join-deferred-scope.ts +5 -4
  258. package/src/runtime/actors/actor-lifecycle-snapshot.ts +5 -8
  259. package/src/runtime/actors/actor-local-native-join.ts +131 -159
  260. package/src/runtime/actors/actor-mailbox.ts +16 -19
  261. package/src/runtime/actors/actor-message-follow-context.ts +46 -36
  262. package/src/runtime/actors/actor-packet-relay-wire.ts +32 -21
  263. package/src/runtime/actors/actor-remote-joiner.ts +50 -54
  264. package/src/runtime/actors/actor-remote-wire.ts +9 -13
  265. package/src/runtime/actors/actor-routed-join-transport.ts +10 -2
  266. package/src/runtime/actors/actor-runtime-contracts.ts +2 -5
  267. package/src/runtime/actors/actor-runtime-state.ts +127 -124
  268. package/src/runtime/actors/actor-transfer-registry.ts +9 -14
  269. package/src/runtime/actors/actor-transport-delivery-gate.ts +4 -6
  270. package/src/runtime/actors/bound-session-wire.ts +37 -17
  271. package/src/runtime/actors/deferred-join-accepted-journal.ts +351 -320
  272. package/src/runtime/actors/index.ts +43 -86
  273. package/src/runtime/actors/post-commit-actor-binder.ts +10 -10
  274. package/src/runtime/actors/post-commit-actor-location.ts +30 -23
  275. package/src/runtime/actors/spot-actor-dispatch.ts +78 -53
  276. package/src/runtime/actors/transferred-actor-rollback.ts +18 -13
  277. package/src/runtime/admission.ts +9 -9
  278. package/src/runtime/application-jobs/application-ingress-record-owner.ts +5 -15
  279. package/src/runtime/application-jobs/application-job-queue-handler-start-gate.ts +3 -2
  280. package/src/runtime/application-jobs/receive-flow-controller.ts +17 -14
  281. package/src/runtime/backend/contracts/index.ts +73 -52
  282. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -14
  283. package/src/runtime/backend/mesh-completion-table.ts +6 -9
  284. package/src/runtime/backend/mesh-dispatch-pump.ts +38 -30
  285. package/src/runtime/backend/node/node-backend-adapter-factory.ts +23 -21
  286. package/src/runtime/backend/node/node-backend-adapter-support.ts +36 -22
  287. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +59 -58
  288. package/src/runtime/backend/node/node-event-loop-poller.ts +2 -10
  289. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +12 -5
  290. package/src/runtime/backend/node/node-monitor-backend-adapter.ts +4 -3
  291. package/src/runtime/backend/node/node-raw-binding-port.ts +29 -29
  292. package/src/runtime/backend/node/node-raw-mesh-backend.ts +335 -383
  293. package/src/runtime/backend/node/node-socket-backend-adapter.ts +101 -54
  294. package/src/runtime/backend/runtime-message.ts +5 -3
  295. package/src/runtime/backend/runtime-values.ts +10 -7
  296. package/src/runtime/channels/channel-autoconnect.ts +1 -4
  297. package/src/runtime/channels/channel-clients.ts +93 -73
  298. package/src/runtime/channels/channel-dispatch-pipeline.ts +40 -42
  299. package/src/runtime/channels/channel-dispatch-services.ts +51 -49
  300. package/src/runtime/channels/channel-dispatchers.ts +152 -96
  301. package/src/runtime/channels/channel-envelope-inspection.ts +20 -16
  302. package/src/runtime/channels/channel-envelope.ts +256 -150
  303. package/src/runtime/channels/channel-multipart.ts +13 -5
  304. package/src/runtime/channels/channel-outbound-operations.ts +37 -41
  305. package/src/runtime/channels/channel-receive-loops.ts +102 -98
  306. package/src/runtime/channels/channel-receive-task-tracker.ts +1 -1
  307. package/src/runtime/channels/channel-runtime-lifecycle.ts +248 -190
  308. package/src/runtime/channels/channel-runtime-manager.ts +63 -37
  309. package/src/runtime/channels/channel-socket-options.ts +3 -10
  310. package/src/runtime/channels/channel-socket-registry.ts +331 -273
  311. package/src/runtime/channels/channel-transports.ts +215 -197
  312. package/src/runtime/channels/client-server-location-runtime.ts +116 -100
  313. package/src/runtime/channels/client-server-service-wire.ts +37 -36
  314. package/src/runtime/channels/dispatch-error-reporter.ts +11 -8
  315. package/src/runtime/channels/fanout-location-runtime.ts +91 -94
  316. package/src/runtime/channels/fanout-service-wire.ts +5 -12
  317. package/src/runtime/channels/handler-filter-scope.ts +1 -4
  318. package/src/runtime/channels/index.ts +1 -4
  319. package/src/runtime/channels/local-spot-route-transport.ts +20 -5
  320. package/src/runtime/channels/route-member-snapshot.ts +11 -5
  321. package/src/runtime/channels/router-socket-spot-route-transport.ts +1 -7
  322. package/src/runtime/channels/source-spot-router.ts +26 -22
  323. package/src/runtime/channels/spot-direct-envelope.ts +10 -8
  324. package/src/runtime/channels/spot-node-route-transport.ts +13 -16
  325. package/src/runtime/channels/spot-route-bridge-transport.ts +26 -9
  326. package/src/runtime/channels/spot-route-dispatch-strategy.ts +40 -13
  327. package/src/runtime/channels/spot-route-target-resolver.ts +18 -9
  328. package/src/runtime/codecs/index.ts +3 -2
  329. package/src/runtime/diagnostics/flow-context.ts +12 -3
  330. package/src/runtime/diagnostics/index.ts +96 -61
  331. package/src/runtime/diagnostics/internal-event-contracts.ts +87 -33
  332. package/src/runtime/diagnostics/message-flow.ts +95 -76
  333. package/src/runtime/diagnostics/runtime-metrics.ts +46 -24
  334. package/src/runtime/diagnostics/runtime-observation-queue.ts +17 -28
  335. package/src/runtime/diagnostics/topology-runtime-projections.ts +62 -43
  336. package/src/runtime/execution/index.ts +18 -26
  337. package/src/runtime/execution/serial-execution-queue.ts +31 -40
  338. package/src/runtime/execution/state-lane.ts +2 -2
  339. package/src/runtime/foundation/actor-join-recovery-codec.ts +69 -51
  340. package/src/runtime/foundation/event-loop-resources.ts +8 -4
  341. package/src/runtime/foundation/message-follow-suppression-registry.ts +7 -14
  342. package/src/runtime/foundation/operation-identity.ts +1 -2
  343. package/src/runtime/foundation/operation-registry.ts +8 -2
  344. package/src/runtime/foundation/raw-service-mesh-runtime.ts +312 -385
  345. package/src/runtime/foundation/route-mesh-connection-policy.ts +7 -8
  346. package/src/runtime/foundation/runtime-state-projections.ts +24 -23
  347. package/src/runtime/foundation/service-authority-payload-codec.ts +54 -57
  348. package/src/runtime/foundation/service-discovery-registry.ts +67 -59
  349. package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +28 -29
  350. package/src/runtime/foundation/service-liveness-registry.ts +18 -13
  351. package/src/runtime/foundation/service-mailbox.ts +14 -14
  352. package/src/runtime/foundation/service-maintenance-runtime.ts +22 -21
  353. package/src/runtime/foundation/service-metadata-codec.ts +2 -9
  354. package/src/runtime/foundation/service-relocation-aggregate-committer.ts +39 -36
  355. package/src/runtime/foundation/service-relocation-coordinator.ts +1 -4
  356. package/src/runtime/foundation/service-relocation-object-owner.ts +40 -58
  357. package/src/runtime/foundation/service-relocation-runtime.ts +292 -216
  358. package/src/runtime/foundation/service-runtime-contracts.ts +8 -8
  359. package/src/runtime/foundation/service-session-binding-ingress-port.ts +1 -4
  360. package/src/runtime/foundation/service-stateful-registry.ts +69 -59
  361. package/src/runtime/foundation/service-stateful-runtime.ts +1174 -1112
  362. package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
  363. package/src/runtime/foundation/service-topology-registry.ts +157 -159
  364. package/src/runtime/foundation/service-weighted-selection.ts +9 -15
  365. package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -12
  366. package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -47
  367. package/src/runtime/framework-errors-internal.ts +31 -30
  368. package/src/runtime/handlers/handler-instance-scope.ts +18 -29
  369. package/src/runtime/handlers/index.ts +18 -8
  370. package/src/runtime/host/actor-packet-relay.ts +290 -261
  371. package/src/runtime/host/actor-placement-coordinator.ts +165 -150
  372. package/src/runtime/host/actor-runtime-options-factory.ts +89 -87
  373. package/src/runtime/host/actor-transfer-authority-runtime.ts +46 -38
  374. package/src/runtime/host/actor-transfer-runtime.ts +391 -395
  375. package/src/runtime/host/application-job-queue.ts +32 -48
  376. package/src/runtime/host/bound-session-relay.ts +7 -9
  377. package/src/runtime/host/channel-runtime-options-factory.ts +75 -35
  378. package/src/runtime/host/host-capacity-status.ts +10 -9
  379. package/src/runtime/host/index.ts +861 -789
  380. package/src/runtime/host/instance-activation-authority.ts +125 -143
  381. package/src/runtime/host/location-runtime-owner.ts +38 -26
  382. package/src/runtime/host/mesh-router-resolver.ts +30 -23
  383. package/src/runtime/host/relocation-direct-transfer.ts +15 -15
  384. package/src/runtime/host/relocation-integrity-fault-gate.ts +3 -2
  385. package/src/runtime/host/remote-actor-join-receiver.ts +43 -34
  386. package/src/runtime/host/remote-actor-packet-target-store.ts +54 -52
  387. package/src/runtime/host/remote-bound-session-relay.ts +274 -247
  388. package/src/runtime/host/route-mesh-runtime-options.ts +1 -3
  389. package/src/runtime/host/route-mesh-runtime.ts +227 -181
  390. package/src/runtime/host/runtime-shutdown.ts +4 -3
  391. package/src/runtime/host/service-relocation-control.ts +14 -5
  392. package/src/runtime/host/service-relocation-host-runtime.ts +1388 -1165
  393. package/src/runtime/host/spot-address-transport.ts +284 -237
  394. package/src/runtime/host/spot-node-runtime-options-factory.ts +14 -8
  395. package/src/runtime/host/spot-runtime-options-factory.ts +71 -62
  396. package/src/runtime/host/stateful-authority-route-runtime.ts +117 -116
  397. package/src/runtime/host/user-spot-creation-coordinator.ts +225 -220
  398. package/src/runtime/locations/actor-location-claims.ts +61 -49
  399. package/src/runtime/locations/actor-session-route-claims.ts +1 -4
  400. package/src/runtime/locations/aggregate-inventory-store.ts +105 -134
  401. package/src/runtime/locations/authority-key-codec.ts +13 -10
  402. package/src/runtime/locations/auto-connect-loop.ts +14 -11
  403. package/src/runtime/locations/auto-connect-planner.ts +42 -31
  404. package/src/runtime/locations/auto-connect-reconciler.ts +106 -63
  405. package/src/runtime/locations/canonical-codec.ts +3 -1
  406. package/src/runtime/locations/creation-operation-id.ts +4 -3
  407. package/src/runtime/locations/domain-store-contract.ts +13 -7
  408. package/src/runtime/locations/in-memory-authority-store.ts +232 -199
  409. package/src/runtime/locations/in-memory-location-store.ts +432 -250
  410. package/src/runtime/locations/in-memory-provider-location-store.ts +16 -17
  411. package/src/runtime/locations/internal-store-contracts.ts +95 -38
  412. package/src/runtime/locations/key-codec.ts +3 -4
  413. package/src/runtime/locations/lease-tracker.ts +36 -27
  414. package/src/runtime/locations/lifecycle-runtime.ts +15 -3
  415. package/src/runtime/locations/lifecycle.ts +33 -28
  416. package/src/runtime/locations/location-store-repository.ts +1329 -1185
  417. package/src/runtime/locations/opaque-record-key.ts +4 -9
  418. package/src/runtime/locations/resolvers.ts +201 -178
  419. package/src/runtime/locations/runtime.ts +251 -159
  420. package/src/runtime/locations/spot-location-claims.ts +110 -112
  421. package/src/runtime/messaging/creation-payload-codec.ts +4 -1
  422. package/src/runtime/messaging/framework-json-v1.ts +34 -15
  423. package/src/runtime/messaging/packet-name.ts +8 -6
  424. package/src/runtime/messaging/payload-codec.ts +70 -50
  425. package/src/runtime/messaging/submission-result.ts +6 -9
  426. package/src/runtime/protocol/service_wire_codec.generated.ts +1376 -159
  427. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
  428. package/src/runtime/routing-id.ts +10 -7
  429. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +56 -62
  430. package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +23 -20
  431. package/src/runtime/spots/index.ts +593 -563
  432. package/src/runtime/spots/spot-activation-registry.ts +38 -34
  433. package/src/runtime/spots/spot-activation-state.ts +43 -51
  434. package/src/runtime/spots/spot-activation.ts +179 -116
  435. package/src/runtime/spots/spot-actor-admission-coordinator.ts +110 -78
  436. package/src/runtime/spots/spot-actor-join-dispatch.ts +57 -41
  437. package/src/runtime/spots/spot-actor-lifecycle-drain.ts +5 -7
  438. package/src/runtime/spots/spot-actor-membership.ts +25 -27
  439. package/src/runtime/spots/spot-actor-packet-dispatch.ts +184 -153
  440. package/src/runtime/spots/spot-actor-packet-drain.ts +54 -42
  441. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +37 -39
  442. package/src/runtime/spots/spot-closing.ts +11 -12
  443. package/src/runtime/spots/spot-context.ts +46 -26
  444. package/src/runtime/spots/spot-entry-activation.ts +84 -65
  445. package/src/runtime/spots/spot-handle.ts +17 -15
  446. package/src/runtime/spots/spot-handler-registry.ts +44 -31
  447. package/src/runtime/spots/spot-location-claim.ts +5 -4
  448. package/src/runtime/spots/spot-manager-public.ts +62 -82
  449. package/src/runtime/spots/spot-native-actor-join-admission.ts +20 -16
  450. package/src/runtime/spots/spot-node-autoconnect.ts +54 -61
  451. package/src/runtime/spots/spot-node-runtime-manager.ts +230 -221
  452. package/src/runtime/spots/spot-outbound.ts +47 -59
  453. package/src/runtime/spots/spot-publisher-transport.ts +5 -4
  454. package/src/runtime/spots/spot-remote-codec.ts +66 -65
  455. package/src/runtime/spots/spot-remote-route-codec.ts +61 -41
  456. package/src/runtime/spots/spot-route-packet-dispatch.ts +128 -95
  457. package/src/runtime/spots/spot-route-replies.ts +23 -24
  458. package/src/runtime/spots/spot-route-reply-wire.ts +3 -2
  459. package/src/runtime/spots/spot-routed-actor-admission.ts +37 -27
  460. package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +11 -17
  461. package/src/runtime/spots/spot-routed-frame-dispatch.ts +18 -15
  462. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +35 -26
  463. package/src/runtime/spots/spot-routing-internal.ts +1 -4
  464. package/src/runtime/spots/spot-runtime-ports.ts +5 -5
  465. package/src/runtime/spots/spot-serial-executor.ts +5 -9
  466. package/src/runtime/spots/spot-serial-turn-executor.ts +19 -26
  467. package/src/runtime/spots/spot-subscription-dispatch.ts +56 -46
  468. package/src/runtime/spots/spot-timer.ts +98 -91
  469. package/src/runtime/streams/actor-session-binding-registry.ts +277 -235
  470. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +7 -4
  471. package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
  472. package/src/runtime/streams/bound-actor-relay-sender.ts +53 -51
  473. package/src/runtime/streams/bound-session-response-target.ts +29 -8
  474. package/src/runtime/streams/bound-session-service.ts +39 -39
  475. package/src/runtime/streams/index.ts +176 -100
  476. package/src/runtime/streams/managed-stream.ts +98 -87
  477. package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
  478. package/src/runtime/streams/protocol.ts +73 -43
  479. package/src/runtime/streams/session-actor-coordinator.ts +97 -89
  480. package/src/runtime/streams/session-calls.ts +2 -8
  481. package/src/runtime/streams/session-context.ts +66 -48
  482. package/src/runtime/streams/session-provider.ts +5 -7
  483. package/src/runtime/streams/session-serial-executor.ts +7 -6
  484. package/src/runtime/streams/stream-binding-runtime-ports.ts +79 -29
  485. package/src/runtime/streams/stream-frame-factory.ts +55 -38
  486. package/src/runtime/streams/stream-session-runtime.ts +268 -210
  487. package/src/runtime/workers/index.ts +68 -29
@@ -67,10 +67,7 @@ import type {
67
67
  ZLinkSpotLocationFilter,
68
68
  ZLinkSpotLocationKey
69
69
  } from './internal-location-contracts';
70
- import {
71
- ZLinkFrameworkRuntimeState,
72
- ZLinkObjectRole
73
- } from '../../contracts';
70
+ import { ZLinkFrameworkRuntimeState, ZLinkObjectRole } from '../../contracts';
74
71
  import { ZLinkLocationWriteStatus as WriteStatus } from '../../contracts/Locations';
75
72
  import { ZLinkInMemoryLocationStore } from './in-memory-location-store';
76
73
  import { storeKey } from './in-memory-provider-location-store';
@@ -99,10 +96,7 @@ const AGGREGATE_COMMIT_RETRY_WINDOW_MS = 5_000;
99
96
  const MAX_AGGREGATE_COMMIT_CONFLICT_RETRIES = 64;
100
97
  const MAX_DESCRIPTOR_WRITE_RETRIES = 3;
101
98
 
102
- type StoredAuthoritySnapshot = Omit<
103
- ZLinkAuthoritySnapshot,
104
- 'kind' | 'storeVersion' | 'storeNow'
105
- >;
99
+ type StoredAuthoritySnapshot = Omit<ZLinkAuthoritySnapshot, 'kind' | 'storeVersion' | 'storeNow'>;
106
100
 
107
101
  interface AuthorityRecord {
108
102
  readonly snapshot: StoredAuthoritySnapshot;
@@ -224,13 +218,15 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
224
218
  if (!Number.isInteger(limit) || limit < 1 || limit > 1_000) {
225
219
  throw new RangeError('Authority scan limit must be in 1..1000.');
226
220
  }
227
- const scan = await this.provider.scan({
228
- prefix: AUTHORITY_PREIMAGE_PREFIX,
229
- cursor: cursor === undefined
230
- ? undefined
231
- : ({ value: cursor.encoded } as ZLinkStoreScanCursor),
232
- limit
233
- }, signal);
221
+ const scan = await this.provider.scan(
222
+ {
223
+ prefix: AUTHORITY_PREIMAGE_PREFIX,
224
+ cursor:
225
+ cursor === undefined ? undefined : ({ value: cursor.encoded } as ZLinkStoreScanCursor),
226
+ limit
227
+ },
228
+ signal
229
+ );
234
230
  if (scan.kind === 'expired') return { kind: 'scanExpired' };
235
231
  const items = [];
236
232
  for (const item of scan.value.items) {
@@ -247,9 +243,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
247
243
  return {
248
244
  kind: 'page',
249
245
  items,
250
- nextCursor: scan.value.nextCursor === undefined
251
- ? undefined
252
- : ({ encoded: scan.value.nextCursor.value } as ZLinkAuthorityScanCursor)
246
+ nextCursor:
247
+ scan.value.nextCursor === undefined
248
+ ? undefined
249
+ : ({ encoded: scan.value.nextCursor.value } as ZLinkAuthorityScanCursor)
253
250
  };
254
251
  }
255
252
 
@@ -280,39 +277,36 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
280
277
  return { kind: 'conflict', current: snapshot };
281
278
  }
282
279
  if (
283
- record.snapshot.allocation.state !== 'active'
284
- || (record.visibleStoreVersion ?? current.value.version.value)
285
- !== expectedStoreVersion.value
280
+ record.snapshot.allocation.state !== 'active' ||
281
+ (record.visibleStoreVersion ?? current.value.version.value) !== expectedStoreVersion.value
286
282
  ) {
287
283
  return { kind: 'conflict', current: snapshot };
288
284
  }
289
285
  if (mutation.kind === 'rebindOwnerLease') {
290
286
  if (
291
- mutation.expectedOwner.ownerId !== record.snapshot.ownerId
292
- || mutation.expectedOwner.leaseGeneration !== record.snapshot.ownerLeaseGeneration
293
- || mutation.targetOwner.ownerId !== record.snapshot.ownerId
294
- || mutation.targetOwner.leaseGeneration === record.snapshot.ownerLeaseGeneration
287
+ mutation.expectedOwner.ownerId !== record.snapshot.ownerId ||
288
+ mutation.expectedOwner.leaseGeneration !== record.snapshot.ownerLeaseGeneration ||
289
+ mutation.targetOwner.ownerId !== record.snapshot.ownerId ||
290
+ mutation.targetOwner.leaseGeneration === record.snapshot.ownerLeaseGeneration
295
291
  ) {
296
292
  return { kind: 'conflict', current: snapshot };
297
293
  }
298
294
  const descriptorKey = meshKey(
299
295
  record.snapshot.allocation.descriptor.meshName,
300
296
  record.snapshot.allocation.descriptor.rid
301
- );
297
+ );
302
298
  const [descriptorRead, targetLeaseRead] = await Promise.all([
303
299
  this.provider.read(descriptorKey, signal),
304
300
  this.provider.read(ownerKey(mutation.targetOwner.ownerId), signal)
305
301
  ]);
306
- if (liveTargetDescriptor(
307
- descriptorRead,
308
- targetLeaseRead,
309
- {
302
+ if (
303
+ liveTargetDescriptor(descriptorRead, targetLeaseRead, {
310
304
  meshName: record.snapshot.allocation.descriptor.meshName,
311
305
  nodeRid: record.snapshot.allocation.descriptor.rid,
312
306
  nodeLifecycleGeneration: record.snapshot.allocation.descriptorLifecycleGeneration,
313
307
  owner: mutation.targetOwner
314
- }
315
- ) === undefined) {
308
+ }) === undefined
309
+ ) {
316
310
  return { kind: 'conflict', current: snapshot };
317
311
  }
318
312
  const nextRecord: AuthorityRecord = {
@@ -324,17 +318,21 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
324
318
  payload: Buffer.from(mutation.payload)
325
319
  }
326
320
  };
327
- const result = await this.provider.write({
328
- conditions: [
329
- { kind: 'version', key: rowKey, expected: current.value.version },
330
- versionCondition(descriptorKey, descriptorRead),
331
- versionCondition(ownerKey(mutation.targetOwner.ownerId), targetLeaseRead)
332
- ],
333
- mutations: [{ kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(nextRecord) }]
334
- }, signal);
321
+ const result = await this.provider.write(
322
+ {
323
+ conditions: [
324
+ { kind: 'version', key: rowKey, expected: current.value.version },
325
+ versionCondition(descriptorKey, descriptorRead),
326
+ versionCondition(ownerKey(mutation.targetOwner.ownerId), targetLeaseRead)
327
+ ],
328
+ mutations: [{ kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(nextRecord) }]
329
+ },
330
+ signal
331
+ );
335
332
  if (result.kind === 'conflict') continue;
336
- const storeVersion = result.putVersions.find(entry =>
337
- entry.key.value === rowKey.value)?.version;
333
+ const storeVersion = result.putVersions.find(
334
+ (entry) => entry.key.value === rowKey.value
335
+ )?.version;
338
336
  if (storeVersion === undefined) {
339
337
  throw new Error('Authority lease rebind did not return a row version.');
340
338
  }
@@ -343,74 +341,70 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
343
341
  return { kind: 'stored', ...withoutKind };
344
342
  }
345
343
  if (
346
- mutation.kind === 'restore'
347
- && (
348
- mutation.expectedOwner.ownerId !== record.snapshot.ownerId
349
- || mutation.expectedOwner.leaseGeneration
350
- !== record.snapshot.ownerLeaseGeneration
351
- )
344
+ mutation.kind === 'restore' &&
345
+ (mutation.expectedOwner.ownerId !== record.snapshot.ownerId ||
346
+ mutation.expectedOwner.leaseGeneration !== record.snapshot.ownerLeaseGeneration)
352
347
  ) {
353
348
  return { kind: 'conflict', current: snapshot };
354
349
  }
355
350
  const leaseKey = ownerKey(record.snapshot.ownerId);
356
351
  const lease = await this.provider.read(leaseKey, signal);
357
- if (
358
- mutation.kind !== 'restore'
359
- && !sameLiveOwner(lease, record.snapshot)
360
- ) {
352
+ if (mutation.kind !== 'restore' && !sameLiveOwner(lease, record.snapshot)) {
361
353
  return { kind: 'conflict', current: snapshot };
362
354
  }
363
355
  const capacityRowKey = capacityKey(
364
356
  record.snapshot.allocation.descriptor.meshName,
365
357
  String(record.snapshot.allocation.descriptor.rid)
366
358
  );
367
- const capacityRead = mutation.kind === 'delete'
368
- ? await this.provider.read(capacityRowKey, signal)
369
- : undefined;
370
- const nextRecord: AuthorityRecord | undefined = mutation.kind === 'delete'
371
- ? undefined
372
- : {
373
- ...record,
374
- visibleStoreVersion: undefined,
375
- snapshot: {
376
- ...record.snapshot,
377
- payload: Buffer.from(mutation.payload)
378
- }
379
- };
380
- const result = await this.provider.write({
381
- conditions: [
382
- { kind: 'version', key: rowKey, expected: current.value.version },
383
- ...(mutation.kind === 'restore'
384
- ? []
385
- : [versionCondition(leaseKey, lease)]),
386
- ...(capacityRead === undefined
387
- ? []
388
- : [conditionFor(capacityRowKey, capacityRead)])
389
- ],
390
- mutations: mutation.kind === 'delete'
391
- ? [
392
- { kind: 'delete', key: rowKey },
393
- {
394
- kind: 'put',
395
- key: capacityRowKey,
396
- bytes: encodeJson({
397
- active: subtractCapacity(
398
- capacityRead?.kind === 'found'
399
- ? decodeJson<CapacityRecord>(capacityRead.value.bytes).active
400
- : emptyCapacityRecord().active,
401
- record.snapshot.allocation.capacity
402
- ),
403
- pending: capacityRead?.kind === 'found'
404
- ? decodeJson<CapacityRecord>(capacityRead.value.bytes).pending
405
- : emptyCapacityRecord().pending
406
- } satisfies CapacityRecord)
359
+ const capacityRead =
360
+ mutation.kind === 'delete' ? await this.provider.read(capacityRowKey, signal) : undefined;
361
+ const nextRecord: AuthorityRecord | undefined =
362
+ mutation.kind === 'delete'
363
+ ? undefined
364
+ : {
365
+ ...record,
366
+ visibleStoreVersion: undefined,
367
+ snapshot: {
368
+ ...record.snapshot,
369
+ payload: Buffer.from(mutation.payload)
407
370
  }
408
- ]
409
- : [{ kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(nextRecord!) }]
410
- }, signal);
371
+ };
372
+ const result = await this.provider.write(
373
+ {
374
+ conditions: [
375
+ { kind: 'version', key: rowKey, expected: current.value.version },
376
+ ...(mutation.kind === 'restore' ? [] : [versionCondition(leaseKey, lease)]),
377
+ ...(capacityRead === undefined ? [] : [conditionFor(capacityRowKey, capacityRead)])
378
+ ],
379
+ mutations:
380
+ mutation.kind === 'delete'
381
+ ? [
382
+ { kind: 'delete', key: rowKey },
383
+ {
384
+ kind: 'put',
385
+ key: capacityRowKey,
386
+ bytes: encodeJson({
387
+ active: subtractCapacity(
388
+ capacityRead?.kind === 'found'
389
+ ? decodeJson<CapacityRecord>(capacityRead.value.bytes).active
390
+ : emptyCapacityRecord().active,
391
+ record.snapshot.allocation.capacity
392
+ ),
393
+ pending:
394
+ capacityRead?.kind === 'found'
395
+ ? decodeJson<CapacityRecord>(capacityRead.value.bytes).pending
396
+ : emptyCapacityRecord().pending
397
+ } satisfies CapacityRecord)
398
+ }
399
+ ]
400
+ : [{ kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(nextRecord!) }]
401
+ },
402
+ signal
403
+ );
411
404
  if (result.kind === 'conflict') continue;
412
- const storeVersion = result.putVersions.find(entry =>
413
- entry.key.value === rowKey.value)?.version;
405
+ const storeVersion = result.putVersions.find(
406
+ (entry) => entry.key.value === rowKey.value
407
+ )?.version;
414
408
  if (mutation.kind === 'delete') {
415
409
  return {
416
410
  kind: 'deleted',
@@ -449,10 +443,13 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
449
443
  }
450
444
  } else {
451
445
  const staging = aggregateRecord(request, fingerprint, 'staging');
452
- const claimed = await this.provider.write({
453
- conditions: [{ kind: 'missing', key: rowKey }],
454
- mutations: [{ kind: 'put', key: rowKey, bytes: encodeJson(staging) }]
455
- }, signal);
446
+ const claimed = await this.provider.write(
447
+ {
448
+ conditions: [{ kind: 'missing', key: rowKey }],
449
+ mutations: [{ kind: 'put', key: rowKey, bytes: encodeJson(staging) }]
450
+ },
451
+ signal
452
+ );
456
453
  if (claimed.kind === 'conflict') {
457
454
  aggregateRead = await this.provider.read(rowKey, signal);
458
455
  if (aggregateRead.kind === 'missing') return { kind: 'conflict' };
@@ -460,8 +457,9 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
460
457
  const reconciled = reconcileAggregatePrepare(existing, fingerprint, fence);
461
458
  if (reconciled !== undefined) return reconciled;
462
459
  } else {
463
- const version = claimed.putVersions.find(value =>
464
- value.key.value === rowKey.value)?.version;
460
+ const version = claimed.putVersions.find(
461
+ (value) => value.key.value === rowKey.value
462
+ )?.version;
465
463
  if (version === undefined) {
466
464
  throw new Error('Aggregate staging did not return a Store version.');
467
465
  }
@@ -476,28 +474,21 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
476
474
  }
477
475
  }
478
476
  const aggregate = decodeJson<AggregateRecord>(aggregateRead.value.bytes);
479
- if (
480
- aggregate.state !== 'staging'
481
- || aggregate.requestFingerprint !== fingerprint
482
- ) {
477
+ if (aggregate.state !== 'staging' || aggregate.requestFingerprint !== fingerprint) {
483
478
  return { kind: 'conflict' };
484
479
  }
485
480
  try {
486
481
  await this.aggregateInventory.store(request, signal);
487
- const entries = await this.aggregateInventory.read(
488
- fence,
489
- request.inventoryDigest,
490
- signal
491
- );
482
+ const entries = await this.aggregateInventory.read(fence, request.inventoryDigest, signal);
492
483
  if (entries.length !== request.participants.length) {
493
484
  throw new Error('Aggregate inventory count changed after staging.');
494
485
  }
495
486
  await parallelForEach(request.participants, 64, async (participant, index) => {
496
487
  const entry = entries[index]!;
497
488
  if (
498
- entry.authorityKey !== participant.authorityKey.value
499
- || entry.expectedStoreVersion !== participant.expectedStoreVersion.value
500
- || entry.ownerTransition !== participant.ownerTransition
489
+ entry.authorityKey !== participant.authorityKey.value ||
490
+ entry.expectedStoreVersion !== participant.expectedStoreVersion.value ||
491
+ entry.ownerTransition !== participant.ownerTransition
501
492
  ) {
502
493
  throw new Error('Aggregate inventory differs from its participant request.');
503
494
  }
@@ -522,26 +513,19 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
522
513
  request.targetDescriptor.meshName,
523
514
  request.targetDescriptor.rid
524
515
  );
525
- const [
526
- descriptorRead,
527
- leaseRead,
528
- targetCapacityRead
529
- ] = await Promise.all([
516
+ const [descriptorRead, leaseRead, targetCapacityRead] = await Promise.all([
530
517
  this.provider.read(targetDescriptorKey, signal),
531
518
  this.provider.read(targetLeaseKey, signal),
532
519
  this.provider.read(targetCapacityKey, signal)
533
520
  ]);
534
- const descriptor = liveTargetDescriptor(
535
- descriptorRead,
536
- leaseRead,
537
- aggregateTarget(request)
538
- );
539
- const targetCapacity = targetCapacityRead.kind === 'missing'
540
- ? emptyCapacityRecord()
541
- : decodeJson<CapacityRecord>(targetCapacityRead.value.bytes);
521
+ const descriptor = liveTargetDescriptor(descriptorRead, leaseRead, aggregateTarget(request));
522
+ const targetCapacity =
523
+ targetCapacityRead.kind === 'missing'
524
+ ? emptyCapacityRecord()
525
+ : decodeJson<CapacityRecord>(targetCapacityRead.value.bytes);
542
526
  if (
543
- descriptor === undefined
544
- || !capacityAvailable(descriptor, request.capacity, targetCapacity)
527
+ descriptor === undefined ||
528
+ !capacityAvailable(descriptor, request.capacity, targetCapacity)
545
529
  ) {
546
530
  await this.abortAggregateStaging(fence, signal);
547
531
  return { kind: 'conflict' };
@@ -559,7 +543,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
559
543
  await this.abortAggregateStaging(fence, signal);
560
544
  return { kind: 'generationExhausted' };
561
545
  }
562
- } else if (ownerGenerationEnd !== ownerGenerationStart + BigInt(request.participants.length) - 1n) {
546
+ } else if (
547
+ ownerGenerationEnd !==
548
+ ownerGenerationStart + BigInt(request.participants.length) - 1n
549
+ ) {
563
550
  await this.abortAggregateStaging(fence, signal);
564
551
  return { kind: 'conflict' };
565
552
  }
@@ -582,8 +569,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
582
569
  const reservedAggregate = await this.provider.read(rowKey, signal);
583
570
  if (reservedAggregate.kind === 'missing') return { kind: 'conflict' };
584
571
  const reservedRecord = decodeJson<AggregateRecord>(reservedAggregate.value.bytes);
585
- if (reservedRecord.ownerGenerationStart === undefined
586
- || reservedRecord.ownerGenerationEnd === undefined) {
572
+ if (
573
+ reservedRecord.ownerGenerationStart === undefined ||
574
+ reservedRecord.ownerGenerationEnd === undefined
575
+ ) {
587
576
  return { kind: 'conflict' };
588
577
  }
589
578
  ownerGenerationStart = reservedRecord.ownerGenerationStart;
@@ -596,18 +585,15 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
596
585
  expectedStoreVersion: participant.expectedStoreVersion.value
597
586
  });
598
587
  if (participant.ownerTransition === 'newOwner') {
599
- sourceCapacity = addCapacityVector(
600
- sourceCapacity,
601
- record.snapshot.allocation.capacity
602
- );
588
+ sourceCapacity = addCapacityVector(sourceCapacity, record.snapshot.allocation.capacity);
603
589
  }
604
590
  continue;
605
591
  }
606
592
  if (
607
- record.aggregate !== undefined
608
- || record.snapshot.allocation.state !== 'active'
609
- || (record.visibleStoreVersion ?? current.value.version.value)
610
- !== participant.expectedStoreVersion.value
593
+ record.aggregate !== undefined ||
594
+ record.snapshot.allocation.state !== 'active' ||
595
+ (record.visibleStoreVersion ?? current.value.version.value) !==
596
+ participant.expectedStoreVersion.value
611
597
  ) {
612
598
  await this.clearAggregateMarkers(fence, installed, signal);
613
599
  await this.abortAggregateStaging(fence, signal);
@@ -621,75 +607,85 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
621
607
  return { kind: 'conflict' };
622
608
  }
623
609
  } else {
624
- sourceCapacity = addCapacityVector(
625
- sourceCapacity,
626
- record.snapshot.allocation.capacity
627
- );
610
+ sourceCapacity = addCapacityVector(sourceCapacity, record.snapshot.allocation.capacity);
628
611
  }
629
- const targetAuthorityOwnerGeneration = participant.ownerTransition === 'newOwner'
630
- ? ownerGenerationStart + BigInt(index)
631
- : record.snapshot.authorityOwnerGeneration;
612
+ const targetAuthorityOwnerGeneration =
613
+ participant.ownerTransition === 'newOwner'
614
+ ? ownerGenerationStart + BigInt(index)
615
+ : record.snapshot.authorityOwnerGeneration;
632
616
  const marker: AggregateParticipantFenceRecord = {
633
- aggregateId: fence.aggregateId.value,
634
- aggregateGeneration: fence.aggregateGeneration,
635
- index,
636
- expectedStoreVersion: participant.expectedStoreVersion.value,
637
- ownerTransition: participant.ownerTransition,
638
- targetAuthorityOwnerGeneration,
639
- authorityPayloadSha256: entry.authorityPayloadSha256,
640
- membershipMutationSha256: entry.membershipMutationSha256
641
- };
617
+ aggregateId: fence.aggregateId.value,
618
+ aggregateGeneration: fence.aggregateGeneration,
619
+ index,
620
+ expectedStoreVersion: participant.expectedStoreVersion.value,
621
+ ownerTransition: participant.ownerTransition,
622
+ targetAuthorityOwnerGeneration,
623
+ authorityPayloadSha256: entry.authorityPayloadSha256,
624
+ membershipMutationSha256: entry.membershipMutationSha256
625
+ };
642
626
  const reservingOwnerGenerationBlock = ownerGenerationCounterRead !== undefined;
643
- const stored = await this.provider.write({
644
- conditions: [
645
- { kind: 'version', key: authorityRowKey, expected: current.value.version },
646
- ...(reservingOwnerGenerationBlock
647
- ? [conditionFor(AUTHORITY_OWNER_COUNTER_KEY, ownerGenerationCounterRead!)]
648
- : []),
649
- ...(reservingOwnerGenerationBlock
650
- ? [{ kind: 'version' as const, key: rowKey, expected: aggregateRead.value.version }]
651
- : [])
652
- ],
653
- mutations: [
654
- {
655
- kind: 'put', key: authorityRowKey, bytes: encodeAuthorityRecord({
656
- ...record,
657
- aggregate: marker,
658
- visibleStoreVersion:
659
- record.visibleStoreVersion ?? current.value.version.value
660
- } satisfies AuthorityRecord)
661
- },
662
- ...(reservingOwnerGenerationBlock
663
- ? [
664
- {
665
- kind: 'put' as const,
666
- key: AUTHORITY_OWNER_COUNTER_KEY,
667
- bytes: encodeText((ownerGenerationEnd! + 1n).toString())
668
- },
669
- {
670
- kind: 'put' as const,
671
- key: rowKey,
672
- bytes: encodeJson({
673
- ...aggregate,
674
- ownerGenerationStart,
675
- ownerGenerationEnd
676
- } satisfies AggregateRecord)
677
- }
678
- ]
679
- : [])
680
- ]
681
- }, signal);
627
+ const stored = await this.provider.write(
628
+ {
629
+ conditions: [
630
+ { kind: 'version', key: authorityRowKey, expected: current.value.version },
631
+ ...(reservingOwnerGenerationBlock
632
+ ? [conditionFor(AUTHORITY_OWNER_COUNTER_KEY, ownerGenerationCounterRead!)]
633
+ : []),
634
+ ...(reservingOwnerGenerationBlock
635
+ ? [{ kind: 'version' as const, key: rowKey, expected: aggregateRead.value.version }]
636
+ : [])
637
+ ],
638
+ mutations: [
639
+ {
640
+ kind: 'put',
641
+ key: authorityRowKey,
642
+ bytes: encodeAuthorityRecord({
643
+ ...record,
644
+ aggregate: marker,
645
+ visibleStoreVersion: record.visibleStoreVersion ?? current.value.version.value
646
+ } satisfies AuthorityRecord)
647
+ },
648
+ ...(reservingOwnerGenerationBlock
649
+ ? [
650
+ {
651
+ kind: 'put' as const,
652
+ key: AUTHORITY_OWNER_COUNTER_KEY,
653
+ bytes: encodeText((ownerGenerationEnd! + 1n).toString())
654
+ },
655
+ {
656
+ kind: 'put' as const,
657
+ key: rowKey,
658
+ bytes: encodeJson({
659
+ ...aggregate,
660
+ ownerGenerationStart,
661
+ ownerGenerationEnd
662
+ } satisfies AggregateRecord)
663
+ }
664
+ ]
665
+ : [])
666
+ ]
667
+ },
668
+ signal
669
+ );
682
670
  if (stored.kind === 'conflict') {
683
671
  const raced = await this.provider.read(authorityRowKey, signal);
684
- if (raced.kind === 'found' && sameAggregateMarker(
685
- decodeAuthorityRecord(raced.value.bytes).aggregate, fence, index, participant
686
- )) {
672
+ if (
673
+ raced.kind === 'found' &&
674
+ sameAggregateMarker(
675
+ decodeAuthorityRecord(raced.value.bytes).aggregate,
676
+ fence,
677
+ index,
678
+ participant
679
+ )
680
+ ) {
687
681
  if (reservingOwnerGenerationBlock) {
688
682
  const reservedAggregate = await this.provider.read(rowKey, signal);
689
683
  if (reservedAggregate.kind === 'missing') return { kind: 'conflict' };
690
684
  const reservedRecord = decodeJson<AggregateRecord>(reservedAggregate.value.bytes);
691
- if (reservedRecord.ownerGenerationStart === undefined
692
- || reservedRecord.ownerGenerationEnd === undefined) {
685
+ if (
686
+ reservedRecord.ownerGenerationStart === undefined ||
687
+ reservedRecord.ownerGenerationEnd === undefined
688
+ ) {
693
689
  return { kind: 'conflict' };
694
690
  }
695
691
  ownerGenerationStart = reservedRecord.ownerGenerationStart;
@@ -697,7 +693,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
697
693
  ownerGenerationCounterRead = undefined;
698
694
  aggregateRead = reservedAggregate;
699
695
  }
700
- installed.push({ key: authorityRowKey, expectedStoreVersion: participant.expectedStoreVersion.value });
696
+ installed.push({
697
+ key: authorityRowKey,
698
+ expectedStoreVersion: participant.expectedStoreVersion.value
699
+ });
701
700
  continue;
702
701
  }
703
702
  // A peer can be in the middle of publishing this same aggregate.
@@ -706,8 +705,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
706
705
  const aggregateRaced = await this.provider.read(rowKey, signal);
707
706
  if (aggregateRaced.kind === 'found') {
708
707
  const aggregateRecord = decodeJson<AggregateRecord>(aggregateRaced.value.bytes);
709
- if (aggregateRecord.requestFingerprint === fingerprint
710
- && (aggregateRecord.state === 'staging' || aggregateRecord.state === 'prepared')) {
708
+ if (
709
+ aggregateRecord.requestFingerprint === fingerprint &&
710
+ (aggregateRecord.state === 'staging' || aggregateRecord.state === 'prepared')
711
+ ) {
711
712
  return await this.prepareAggregate(request, signal);
712
713
  }
713
714
  }
@@ -738,29 +739,32 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
738
739
  if (latest.state !== 'staging' || latest.requestFingerprint !== fingerprint) {
739
740
  return { kind: 'conflict' };
740
741
  }
741
- const reserved = await this.provider.write({
742
- conditions: [
743
- { kind: 'version', key: rowKey, expected: aggregateRead.value.version },
744
- versionCondition(targetDescriptorKey, descriptorRead),
745
- versionCondition(targetLeaseKey, leaseRead),
746
- conditionFor(targetCapacityKey, targetCapacityRead)
747
- ],
748
- mutations: [
749
- {
750
- kind: 'put',
751
- key: rowKey,
752
- bytes: encodeJson({ ...latest, state: 'prepared' } satisfies AggregateRecord)
753
- },
754
- {
755
- kind: 'put',
756
- key: targetCapacityKey,
757
- bytes: encodeJson({
758
- active: targetCapacity.active,
759
- pending: addCapacity(targetCapacity.pending, request.capacity)
760
- } satisfies CapacityRecord)
761
- }
762
- ]
763
- }, signal);
742
+ const reserved = await this.provider.write(
743
+ {
744
+ conditions: [
745
+ { kind: 'version', key: rowKey, expected: aggregateRead.value.version },
746
+ versionCondition(targetDescriptorKey, descriptorRead),
747
+ versionCondition(targetLeaseKey, leaseRead),
748
+ conditionFor(targetCapacityKey, targetCapacityRead)
749
+ ],
750
+ mutations: [
751
+ {
752
+ kind: 'put',
753
+ key: rowKey,
754
+ bytes: encodeJson({ ...latest, state: 'prepared' } satisfies AggregateRecord)
755
+ },
756
+ {
757
+ kind: 'put',
758
+ key: targetCapacityKey,
759
+ bytes: encodeJson({
760
+ active: targetCapacity.active,
761
+ pending: addCapacity(targetCapacity.pending, request.capacity)
762
+ } satisfies CapacityRecord)
763
+ }
764
+ ]
765
+ },
766
+ signal
767
+ );
764
768
  if (reserved.kind === 'conflict') {
765
769
  const raced = await this.provider.read(rowKey, signal);
766
770
  if (raced.kind === 'found') {
@@ -840,20 +844,12 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
840
844
  return { kind: 'stale' };
841
845
  }
842
846
  const [payload, membership] = await Promise.all([
843
- requireProviderBytes(
844
- this.provider,
845
- aggregateParticipantPayloadKey(fence, index),
846
- signal
847
- ),
848
- requireProviderBytes(
849
- this.provider,
850
- aggregateParticipantMembershipKey(fence, index),
851
- signal
852
- )
847
+ requireProviderBytes(this.provider, aggregateParticipantPayloadKey(fence, index), signal),
848
+ requireProviderBytes(this.provider, aggregateParticipantMembershipKey(fence, index), signal)
853
849
  ]);
854
850
  if (
855
- sha256Hex(payload) !== entry.authorityPayloadSha256
856
- || sha256Hex(membership) !== entry.membershipMutationSha256
851
+ sha256Hex(payload) !== entry.authorityPayloadSha256 ||
852
+ sha256Hex(membership) !== entry.membershipMutationSha256
857
853
  ) {
858
854
  throw new Error('Aggregate participant staging checksum does not match inventory.');
859
855
  }
@@ -874,11 +870,8 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
874
870
  this.provider.read(targetLeaseKey, signal)
875
871
  ]);
876
872
  if (
877
- liveTargetDescriptor(
878
- descriptorRead,
879
- leaseRead,
880
- aggregateTargetFromRecord(aggregate)
881
- ) === undefined
873
+ liveTargetDescriptor(descriptorRead, leaseRead, aggregateTargetFromRecord(aggregate)) ===
874
+ undefined
882
875
  ) {
883
876
  return { kind: 'stale' };
884
877
  }
@@ -939,44 +932,44 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
939
932
  bytes: encodeJson(capacity)
940
933
  });
941
934
  }
942
- const published = await this.provider.write({
943
- conditions: [
944
- { kind: 'version', key: rowKey, expected: aggregateRead.value.version },
945
- versionCondition(targetDescriptorKey, descriptorRead),
946
- versionCondition(targetLeaseKey, leaseRead),
947
- ...[...capacityReads.entries()].map(([value, read]) => ({
948
- kind: 'version' as const,
949
- key: capacityKeys.get(value)!,
950
- expected: read.value.version
951
- }))
952
- ],
953
- mutations: [
954
- {
955
- kind: 'put',
956
- key: rowKey,
957
- bytes: encodeJson({ ...aggregate, state: 'committed' } satisfies AggregateRecord)
958
- },
959
- ...capacityMutations
960
- ]
961
- }, signal);
935
+ const published = await this.provider.write(
936
+ {
937
+ conditions: [
938
+ { kind: 'version', key: rowKey, expected: aggregateRead.value.version },
939
+ versionCondition(targetDescriptorKey, descriptorRead),
940
+ versionCondition(targetLeaseKey, leaseRead),
941
+ ...[...capacityReads.entries()].map(([value, read]) => ({
942
+ kind: 'version' as const,
943
+ key: capacityKeys.get(value)!,
944
+ expected: read.value.version
945
+ }))
946
+ ],
947
+ mutations: [
948
+ {
949
+ kind: 'put',
950
+ key: rowKey,
951
+ bytes: encodeJson({ ...aggregate, state: 'committed' } satisfies AggregateRecord)
952
+ },
953
+ ...capacityMutations
954
+ ]
955
+ },
956
+ signal
957
+ );
962
958
  if (published.kind === 'conflict') {
963
959
  aggregateRead = await this.provider.read(rowKey, signal);
964
960
  if (aggregateRead.kind === 'missing') return { kind: 'stale' };
965
961
  aggregate = decodeJson<AggregateRecord>(aggregateRead.value.bytes);
966
- if (aggregate.state === 'prepared'
967
- && retryAttempt < MAX_AGGREGATE_COMMIT_CONFLICT_RETRIES
968
- && performance.now() < retryDeadlineAtMs) {
962
+ if (
963
+ aggregate.state === 'prepared' &&
964
+ retryAttempt < MAX_AGGREGATE_COMMIT_CONFLICT_RETRIES &&
965
+ performance.now() < retryDeadlineAtMs
966
+ ) {
969
967
  // The commit CAS also fences the target's live owner lease, descriptor,
970
968
  // and capacity rows. Re-read the whole prepared fence after an
971
969
  // auxiliary-row race; a changed aggregate or participant fence exits
972
970
  // through the normal stale checks on the next attempt.
973
971
  await waitForAggregateCommitRetry(retryAttempt, retryDeadlineAtMs, signal);
974
- return await this.commitAggregateCore(
975
- fence,
976
- retryAttempt + 1,
977
- retryDeadlineAtMs,
978
- signal
979
- );
972
+ return await this.commitAggregateCore(fence, retryAttempt + 1, retryDeadlineAtMs, signal);
980
973
  }
981
974
  if (aggregate.state !== 'committed') return { kind: 'stale' };
982
975
  } else {
@@ -1001,16 +994,20 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1001
994
  return { kind: 'alreadyAborted' };
1002
995
  }
1003
996
  if (aggregate.state === 'committed') return { kind: 'stale' };
1004
- const conditions: ZLinkStoreCondition[] = [{
1005
- kind: 'version',
1006
- key: rowKey,
1007
- expected: current.value.version
1008
- }];
1009
- const mutations: ZLinkStoreWriteRequest['mutations'][number][] = [{
1010
- kind: 'put',
1011
- key: rowKey,
1012
- bytes: encodeJson({ ...aggregate, state: 'aborted' } satisfies AggregateRecord)
1013
- }];
997
+ const conditions: ZLinkStoreCondition[] = [
998
+ {
999
+ kind: 'version',
1000
+ key: rowKey,
1001
+ expected: current.value.version
1002
+ }
1003
+ ];
1004
+ const mutations: ZLinkStoreWriteRequest['mutations'][number][] = [
1005
+ {
1006
+ kind: 'put',
1007
+ key: rowKey,
1008
+ bytes: encodeJson({ ...aggregate, state: 'aborted' } satisfies AggregateRecord)
1009
+ }
1010
+ ];
1014
1011
  if (aggregate.state === 'prepared') {
1015
1012
  const targetCapacityKey = capacityKey(
1016
1013
  aggregate.targetDescriptor.meshName,
@@ -1044,19 +1041,13 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1044
1041
  request: ZLinkObjectReserveRequest,
1045
1042
  signal?: AbortSignal
1046
1043
  ): Promise<ZLinkObjectReserveResult> {
1047
- const encodedAuthorityKey = encodeAuthorityKey(
1048
- request.key.kind,
1049
- request.key.globalId
1050
- );
1044
+ const encodedAuthorityKey = encodeAuthorityKey(request.key.kind, request.key.globalId);
1051
1045
  for (;;) {
1052
1046
  signal?.throwIfAborted();
1053
1047
  const rowKey = authorityKey(encodedAuthorityKey.value);
1054
1048
  const descriptorKey = meshKey(request.target.meshName, request.target.nodeRid);
1055
1049
  const leaseKey = ownerKey(request.target.owner.ownerId);
1056
- const capacityRowKey = capacityKey(
1057
- request.target.meshName,
1058
- String(request.target.nodeRid)
1059
- );
1050
+ const capacityRowKey = capacityKey(request.target.meshName, String(request.target.nodeRid));
1060
1051
  const [
1061
1052
  current,
1062
1053
  descriptorRead,
@@ -1064,15 +1055,14 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1064
1055
  capacityRead,
1065
1056
  objectGenerationRead,
1066
1057
  authorityOwnerGenerationRead
1067
- ] =
1068
- await Promise.all([
1069
- this.provider.read(rowKey, signal),
1070
- this.provider.read(descriptorKey, signal),
1071
- this.provider.read(leaseKey, signal),
1072
- this.provider.read(capacityRowKey, signal),
1073
- this.provider.read(OBJECT_COUNTER_KEY, signal),
1074
- this.provider.read(AUTHORITY_OWNER_COUNTER_KEY, signal)
1075
- ]);
1058
+ ] = await Promise.all([
1059
+ this.provider.read(rowKey, signal),
1060
+ this.provider.read(descriptorKey, signal),
1061
+ this.provider.read(leaseKey, signal),
1062
+ this.provider.read(capacityRowKey, signal),
1063
+ this.provider.read(OBJECT_COUNTER_KEY, signal),
1064
+ this.provider.read(AUTHORITY_OWNER_COUNTER_KEY, signal)
1065
+ ]);
1076
1066
  if (current.kind === 'found') {
1077
1067
  const record = decodeAuthorityRecord(current.value.bytes);
1078
1068
  const snapshot = authoritySnapshot(
@@ -1081,16 +1071,18 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1081
1071
  current.value.storeNow
1082
1072
  );
1083
1073
  if (
1084
- snapshot.allocation.objectKind !== request.key.kind
1085
- || snapshot.allocation.stableType !== request.intent.stableType
1074
+ snapshot.allocation.objectKind !== request.key.kind ||
1075
+ snapshot.allocation.stableType !== request.intent.stableType
1086
1076
  ) {
1087
1077
  return { kind: 'typeMismatch', current: snapshot };
1088
1078
  }
1089
1079
  if (snapshot.allocation.state === 'active') {
1090
1080
  return { kind: 'alreadyExists', current: snapshot };
1091
1081
  }
1092
- if (record.aggregate !== undefined
1093
- || isCanonicalAuthorityPayload(record.snapshot.payload)) {
1082
+ if (
1083
+ record.aggregate !== undefined ||
1084
+ isCanonicalAuthorityPayload(record.snapshot.payload)
1085
+ ) {
1094
1086
  // A relocation record carries its own recovery protocol. Reserve
1095
1087
  // may reclaim only an unfinished plain creation.
1096
1088
  return { kind: 'conflict', current: snapshot };
@@ -1107,8 +1099,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1107
1099
  this.provider.read(staleOwnerKey, signal),
1108
1100
  this.provider.read(staleCapacityKey, signal)
1109
1101
  ]);
1110
- if (staleOwnerRead.kind === 'found'
1111
- && staleOwnerRead.value.expiresAt === undefined) {
1102
+ if (staleOwnerRead.kind === 'found' && staleOwnerRead.value.expiresAt === undefined) {
1112
1103
  // A lease is always written with a positive TTL, so a missing
1113
1104
  // expiry is a corrupt record. Reclaiming deletes authority state,
1114
1105
  // so refuse rather than read the absence as expiry.
@@ -1117,43 +1108,44 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1117
1108
  if (sameLiveOwner(staleOwnerRead, record.snapshot)) {
1118
1109
  return { kind: 'conflict', current: snapshot };
1119
1110
  }
1120
- const staleCapacity = staleCapacityRead.kind === 'missing'
1121
- ? emptyCapacityRecord()
1122
- : decodeJson<CapacityRecord>(staleCapacityRead.value.bytes);
1123
- await this.provider.write({
1124
- conditions: [
1125
- { kind: 'version', key: rowKey, expected: current.value.version },
1126
- versionCondition(staleOwnerKey, staleOwnerRead),
1127
- conditionFor(staleCapacityKey, staleCapacityRead)
1128
- ],
1129
- mutations: [
1130
- { kind: 'delete', key: rowKey },
1131
- {
1132
- kind: 'put',
1133
- key: staleCapacityKey,
1134
- bytes: encodeJson({
1135
- active: staleCapacity.active,
1136
- pending: subtractCapacity(
1137
- staleCapacity.pending,
1138
- record.snapshot.allocation.capacity
1139
- )
1140
- } satisfies CapacityRecord)
1141
- }
1142
- ]
1143
- }, signal);
1111
+ const staleCapacity =
1112
+ staleCapacityRead.kind === 'missing'
1113
+ ? emptyCapacityRecord()
1114
+ : decodeJson<CapacityRecord>(staleCapacityRead.value.bytes);
1115
+ await this.provider.write(
1116
+ {
1117
+ conditions: [
1118
+ { kind: 'version', key: rowKey, expected: current.value.version },
1119
+ versionCondition(staleOwnerKey, staleOwnerRead),
1120
+ conditionFor(staleCapacityKey, staleCapacityRead)
1121
+ ],
1122
+ mutations: [
1123
+ { kind: 'delete', key: rowKey },
1124
+ {
1125
+ kind: 'put',
1126
+ key: staleCapacityKey,
1127
+ bytes: encodeJson({
1128
+ active: staleCapacity.active,
1129
+ pending: subtractCapacity(
1130
+ staleCapacity.pending,
1131
+ record.snapshot.allocation.capacity
1132
+ )
1133
+ } satisfies CapacityRecord)
1134
+ }
1135
+ ]
1136
+ },
1137
+ signal
1138
+ );
1144
1139
  continue;
1145
1140
  }
1146
- const descriptor = liveTargetDescriptor(
1147
- descriptorRead,
1148
- leaseRead,
1149
- request.target
1150
- );
1141
+ const descriptor = liveTargetDescriptor(descriptorRead, leaseRead, request.target);
1151
1142
  if (descriptor === undefined) {
1152
1143
  return { kind: 'conflict', current: { kind: 'missing', storeNow: current.storeNow } };
1153
1144
  }
1154
- const capacity = capacityRead.kind === 'missing'
1155
- ? emptyCapacityRecord()
1156
- : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1145
+ const capacity =
1146
+ capacityRead.kind === 'missing'
1147
+ ? emptyCapacityRecord()
1148
+ : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1157
1149
  if (!capacityAvailable(descriptor, request.capacity, capacity)) {
1158
1150
  return { kind: 'placementCapacityExhausted' };
1159
1151
  }
@@ -1193,40 +1185,42 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1193
1185
  }
1194
1186
  }
1195
1187
  };
1196
- const result = await this.provider.write({
1197
- conditions: [
1198
- { kind: 'missing', key: rowKey },
1199
- versionCondition(descriptorKey, descriptorRead),
1200
- versionCondition(leaseKey, leaseRead),
1201
- conditionFor(capacityRowKey, capacityRead),
1202
- conditionFor(OBJECT_COUNTER_KEY, objectGenerationRead),
1203
- conditionFor(AUTHORITY_OWNER_COUNTER_KEY, authorityOwnerGenerationRead)
1204
- ],
1205
- mutations: [
1206
- { kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(record) },
1207
- {
1208
- kind: 'put',
1209
- key: capacityRowKey,
1210
- bytes: encodeJson({
1211
- active: capacity.active,
1212
- pending: addCapacity(capacity.pending, request.capacity)
1213
- } satisfies CapacityRecord)
1214
- },
1215
- {
1216
- kind: 'put',
1217
- key: OBJECT_COUNTER_KEY,
1218
- bytes: encodeText((generation + 1n).toString())
1219
- },
1220
- {
1221
- kind: 'put',
1222
- key: AUTHORITY_OWNER_COUNTER_KEY,
1223
- bytes: encodeText((authorityOwnerGeneration + 1n).toString())
1224
- }
1225
- ]
1226
- }, signal);
1188
+ const result = await this.provider.write(
1189
+ {
1190
+ conditions: [
1191
+ { kind: 'missing', key: rowKey },
1192
+ versionCondition(descriptorKey, descriptorRead),
1193
+ versionCondition(leaseKey, leaseRead),
1194
+ conditionFor(capacityRowKey, capacityRead),
1195
+ conditionFor(OBJECT_COUNTER_KEY, objectGenerationRead),
1196
+ conditionFor(AUTHORITY_OWNER_COUNTER_KEY, authorityOwnerGenerationRead)
1197
+ ],
1198
+ mutations: [
1199
+ { kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(record) },
1200
+ {
1201
+ kind: 'put',
1202
+ key: capacityRowKey,
1203
+ bytes: encodeJson({
1204
+ active: capacity.active,
1205
+ pending: addCapacity(capacity.pending, request.capacity)
1206
+ } satisfies CapacityRecord)
1207
+ },
1208
+ {
1209
+ kind: 'put',
1210
+ key: OBJECT_COUNTER_KEY,
1211
+ bytes: encodeText((generation + 1n).toString())
1212
+ },
1213
+ {
1214
+ kind: 'put',
1215
+ key: AUTHORITY_OWNER_COUNTER_KEY,
1216
+ bytes: encodeText((authorityOwnerGeneration + 1n).toString())
1217
+ }
1218
+ ]
1219
+ },
1220
+ signal
1221
+ );
1227
1222
  if (result.kind === 'conflict') continue;
1228
- const version = result.putVersions.find(entry =>
1229
- entry.key.value === rowKey.value)?.version;
1223
+ const version = result.putVersions.find((entry) => entry.key.value === rowKey.value)?.version;
1230
1224
  if (version === undefined) throw new Error('Authority reserve did not return a row version.');
1231
1225
  return {
1232
1226
  kind: 'reserved',
@@ -1248,9 +1242,9 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1248
1242
  if (current.kind === 'missing') return { kind: 'stale' };
1249
1243
  const record = decodeAuthorityRecord(current.value.bytes);
1250
1244
  if (
1251
- record.terminal === 'committed'
1252
- && record.snapshot.pendingCreation === undefined
1253
- && record.snapshot.allocation.state === 'active'
1245
+ record.terminal === 'committed' &&
1246
+ record.snapshot.pendingCreation === undefined &&
1247
+ record.snapshot.allocation.state === 'active'
1254
1248
  ) {
1255
1249
  return {
1256
1250
  kind: 'alreadyCommitted',
@@ -1258,10 +1252,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1258
1252
  };
1259
1253
  }
1260
1254
  if (
1261
- record.snapshot.pendingCreation?.reservationId !== request.reservationId
1262
- || current.value.version.value !== request.expectedStoreVersion
1263
- || record.snapshot.allocation.state !== 'reserved'
1264
- || !sameCreationTarget(record.snapshot, request.target)
1255
+ record.snapshot.pendingCreation?.reservationId !== request.reservationId ||
1256
+ current.value.version.value !== request.expectedStoreVersion ||
1257
+ record.snapshot.allocation.state !== 'reserved' ||
1258
+ !sameCreationTarget(record.snapshot, request.target)
1265
1259
  ) {
1266
1260
  return { kind: 'stale' };
1267
1261
  }
@@ -1276,9 +1270,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1276
1270
  if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined) {
1277
1271
  return { kind: 'stale' };
1278
1272
  }
1279
- const capacity = capacityRead.kind === 'missing'
1280
- ? emptyCapacityRecord()
1281
- : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1273
+ const capacity =
1274
+ capacityRead.kind === 'missing'
1275
+ ? emptyCapacityRecord()
1276
+ : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1282
1277
  const ready: AuthorityRecord = {
1283
1278
  terminal: 'committed',
1284
1279
  snapshot: {
@@ -1288,28 +1283,30 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1288
1283
  pendingCreation: undefined
1289
1284
  }
1290
1285
  };
1291
- const result = await this.provider.write({
1292
- conditions: [
1293
- { kind: 'version', key: rowKey, expected: current.value.version },
1294
- versionCondition(descriptorKey, descriptorRead),
1295
- versionCondition(leaseKey, leaseRead),
1296
- conditionFor(capacityRowKey, capacityRead)
1297
- ],
1298
- mutations: [
1299
- { kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(ready) },
1300
- {
1301
- kind: 'put',
1302
- key: capacityRowKey,
1303
- bytes: encodeJson({
1304
- active: addCapacity(capacity.active, record.snapshot.allocation.capacity),
1305
- pending: subtractCapacity(capacity.pending, record.snapshot.allocation.capacity)
1306
- } satisfies CapacityRecord)
1307
- }
1308
- ]
1309
- }, signal);
1286
+ const result = await this.provider.write(
1287
+ {
1288
+ conditions: [
1289
+ { kind: 'version', key: rowKey, expected: current.value.version },
1290
+ versionCondition(descriptorKey, descriptorRead),
1291
+ versionCondition(leaseKey, leaseRead),
1292
+ conditionFor(capacityRowKey, capacityRead)
1293
+ ],
1294
+ mutations: [
1295
+ { kind: 'put', key: rowKey, bytes: encodeAuthorityRecord(ready) },
1296
+ {
1297
+ kind: 'put',
1298
+ key: capacityRowKey,
1299
+ bytes: encodeJson({
1300
+ active: addCapacity(capacity.active, record.snapshot.allocation.capacity),
1301
+ pending: subtractCapacity(capacity.pending, record.snapshot.allocation.capacity)
1302
+ } satisfies CapacityRecord)
1303
+ }
1304
+ ]
1305
+ },
1306
+ signal
1307
+ );
1310
1308
  if (result.kind === 'conflict') continue;
1311
- const version = result.putVersions.find(entry =>
1312
- entry.key.value === rowKey.value)?.version;
1309
+ const version = result.putVersions.find((entry) => entry.key.value === rowKey.value)?.version;
1313
1310
  if (version === undefined) throw new Error('Authority commit did not return a row version.');
1314
1311
  return {
1315
1312
  kind: 'committed',
@@ -1330,18 +1327,15 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1330
1327
  if (current.kind === 'missing') return { kind: 'stale' };
1331
1328
  const record = decodeAuthorityRecord(current.value.bytes);
1332
1329
  if (
1333
- record.snapshot.pendingCreation?.reservationId !== request.reservationId
1334
- || current.value.version.value !== request.expectedStoreVersion
1335
- || record.snapshot.allocation.state !== 'reserved'
1336
- || !sameCreationTarget(record.snapshot, request.target)
1330
+ record.snapshot.pendingCreation?.reservationId !== request.reservationId ||
1331
+ current.value.version.value !== request.expectedStoreVersion ||
1332
+ record.snapshot.allocation.state !== 'reserved' ||
1333
+ !sameCreationTarget(record.snapshot, request.target)
1337
1334
  ) {
1338
1335
  return { kind: 'stale' };
1339
1336
  }
1340
1337
  const leaseKey = ownerKey(request.target.owner.ownerId);
1341
- const capacityRowKey = capacityKey(
1342
- request.target.meshName,
1343
- String(request.target.nodeRid)
1344
- );
1338
+ const capacityRowKey = capacityKey(request.target.meshName, String(request.target.nodeRid));
1345
1339
  const [leaseRead, capacityRead] = await Promise.all([
1346
1340
  this.provider.read(leaseKey, signal),
1347
1341
  this.provider.read(capacityRowKey, signal)
@@ -1353,30 +1347,31 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1353
1347
  throw new Error('Location Store owner lease record is invalid.');
1354
1348
  }
1355
1349
  if (!sameLiveOwner(leaseRead, record.snapshot)) return { kind: 'stale' };
1356
- const capacity = capacityRead.kind === 'missing'
1357
- ? emptyCapacityRecord()
1358
- : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1359
- const result = await this.provider.write({
1360
- conditions: [
1361
- { kind: 'version', key: rowKey, expected: current.value.version },
1362
- versionCondition(leaseKey, leaseRead),
1363
- conditionFor(capacityRowKey, capacityRead)
1364
- ],
1365
- mutations: [
1366
- { kind: 'delete', key: rowKey },
1367
- {
1368
- kind: 'put',
1369
- key: capacityRowKey,
1370
- bytes: encodeJson({
1371
- active: capacity.active,
1372
- pending: subtractCapacity(
1373
- capacity.pending,
1374
- record.snapshot.allocation.capacity
1375
- )
1376
- } satisfies CapacityRecord)
1377
- }
1378
- ]
1379
- }, signal);
1350
+ const capacity =
1351
+ capacityRead.kind === 'missing'
1352
+ ? emptyCapacityRecord()
1353
+ : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1354
+ const result = await this.provider.write(
1355
+ {
1356
+ conditions: [
1357
+ { kind: 'version', key: rowKey, expected: current.value.version },
1358
+ versionCondition(leaseKey, leaseRead),
1359
+ conditionFor(capacityRowKey, capacityRead)
1360
+ ],
1361
+ mutations: [
1362
+ { kind: 'delete', key: rowKey },
1363
+ {
1364
+ kind: 'put',
1365
+ key: capacityRowKey,
1366
+ bytes: encodeJson({
1367
+ active: capacity.active,
1368
+ pending: subtractCapacity(capacity.pending, record.snapshot.allocation.capacity)
1369
+ } satisfies CapacityRecord)
1370
+ }
1371
+ ]
1372
+ },
1373
+ signal
1374
+ );
1380
1375
  if (result.kind === 'conflict') continue;
1381
1376
  return { kind: 'aborted' };
1382
1377
  }
@@ -1389,13 +1384,8 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1389
1384
  if (request.key.kind !== 'actor') {
1390
1385
  throw new TypeError('completeCreation is reserved for Actor creation.');
1391
1386
  }
1392
- const terminal = createTerminalRecord(
1393
- request,
1394
- this.nowProvider()
1395
- );
1396
- const rowKey = authorityKey(
1397
- encodeAuthorityKey(request.key.kind, request.key.globalId).value
1398
- );
1387
+ const terminal = createTerminalRecord(request, this.nowProvider());
1388
+ const rowKey = authorityKey(encodeAuthorityKey(request.key.kind, request.key.globalId).value);
1399
1389
  const terminalRowKey = creationTerminalKey(terminal.operation);
1400
1390
  for (;;) {
1401
1391
  signal?.throwIfAborted();
@@ -1417,10 +1407,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1417
1407
  if (current.kind === 'missing') return { kind: 'stale' };
1418
1408
  const record = decodeAuthorityRecord(current.value.bytes);
1419
1409
  if (
1420
- record.snapshot.pendingCreation?.reservationId !== request.reservationId
1421
- || current.value.version.value !== request.expectedStoreVersion
1422
- || record.snapshot.allocation.state !== 'reserved'
1423
- || !sameCreationTarget(record.snapshot, request.target)
1410
+ record.snapshot.pendingCreation?.reservationId !== request.reservationId ||
1411
+ current.value.version.value !== request.expectedStoreVersion ||
1412
+ record.snapshot.allocation.state !== 'reserved' ||
1413
+ !sameCreationTarget(record.snapshot, request.target)
1424
1414
  ) {
1425
1415
  return { kind: 'stale' };
1426
1416
  }
@@ -1435,73 +1425,77 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1435
1425
  if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined) {
1436
1426
  return { kind: 'stale' };
1437
1427
  }
1438
- const capacity = capacityRead.kind === 'missing'
1439
- ? emptyCapacityRecord()
1440
- : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1428
+ const capacity =
1429
+ capacityRead.kind === 'missing'
1430
+ ? emptyCapacityRecord()
1431
+ : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1441
1432
  const terminalAtStore = {
1442
1433
  ...terminal,
1443
1434
  storeNow: current.value.storeNow
1444
1435
  };
1445
- const retentionMs = terminalAtStore.expiresAt.getTime()
1446
- - current.value.storeNow.getTime();
1436
+ const retentionMs = terminalAtStore.expiresAt.getTime() - current.value.storeNow.getTime();
1447
1437
  if (retentionMs <= 0) {
1448
1438
  throw new RangeError(
1449
1439
  'Creation terminal expiry must be the live operation deadline plus five minutes.'
1450
1440
  );
1451
1441
  }
1452
- const mutations = request.completion.kind === 'created'
1453
- ? [
1454
- {
1455
- kind: 'put' as const,
1456
- key: rowKey,
1457
- bytes: encodeAuthorityRecord({
1458
- terminal: 'committed',
1459
- snapshot: {
1460
- ...record.snapshot,
1461
- payload: Buffer.from(request.completion.readyPayload),
1462
- allocation: { ...record.snapshot.allocation, state: 'active' },
1463
- pendingCreation: undefined
1464
- }
1465
- } satisfies AuthorityRecord)
1466
- },
1442
+ const mutations =
1443
+ request.completion.kind === 'created'
1444
+ ? [
1445
+ {
1446
+ kind: 'put' as const,
1447
+ key: rowKey,
1448
+ bytes: encodeAuthorityRecord({
1449
+ terminal: 'committed',
1450
+ snapshot: {
1451
+ ...record.snapshot,
1452
+ payload: Buffer.from(request.completion.readyPayload),
1453
+ allocation: { ...record.snapshot.allocation, state: 'active' },
1454
+ pendingCreation: undefined
1455
+ }
1456
+ } satisfies AuthorityRecord)
1457
+ },
1458
+ {
1459
+ kind: 'put' as const,
1460
+ key: capacityRowKey,
1461
+ bytes: encodeJson({
1462
+ active: addCapacity(capacity.active, record.snapshot.allocation.capacity),
1463
+ pending: subtractCapacity(capacity.pending, record.snapshot.allocation.capacity)
1464
+ } satisfies CapacityRecord)
1465
+ }
1466
+ ]
1467
+ : [
1468
+ { kind: 'delete' as const, key: rowKey },
1469
+ {
1470
+ kind: 'put' as const,
1471
+ key: capacityRowKey,
1472
+ bytes: encodeJson({
1473
+ active: capacity.active,
1474
+ pending: subtractCapacity(capacity.pending, record.snapshot.allocation.capacity)
1475
+ } satisfies CapacityRecord)
1476
+ }
1477
+ ];
1478
+ const result = await this.provider.write(
1479
+ {
1480
+ conditions: [
1481
+ { kind: 'version', key: rowKey, expected: current.value.version },
1482
+ { kind: 'missing', key: terminalRowKey },
1483
+ versionCondition(descriptorKey, descriptorRead),
1484
+ versionCondition(leaseKey, leaseRead),
1485
+ conditionFor(capacityRowKey, capacityRead)
1486
+ ],
1487
+ mutations: [
1488
+ ...mutations,
1467
1489
  {
1468
- kind: 'put' as const,
1469
- key: capacityRowKey,
1470
- bytes: encodeJson({
1471
- active: addCapacity(capacity.active, record.snapshot.allocation.capacity),
1472
- pending: subtractCapacity(capacity.pending, record.snapshot.allocation.capacity)
1473
- } satisfies CapacityRecord)
1490
+ kind: 'put',
1491
+ key: terminalRowKey,
1492
+ bytes: terminalAtStore.terminalEnvelope,
1493
+ retentionMs
1474
1494
  }
1475
1495
  ]
1476
- : [
1477
- { kind: 'delete' as const, key: rowKey },
1478
- {
1479
- kind: 'put' as const,
1480
- key: capacityRowKey,
1481
- bytes: encodeJson({
1482
- active: capacity.active,
1483
- pending: subtractCapacity(capacity.pending, record.snapshot.allocation.capacity)
1484
- } satisfies CapacityRecord)
1485
- }
1486
- ];
1487
- const result = await this.provider.write({
1488
- conditions: [
1489
- { kind: 'version', key: rowKey, expected: current.value.version },
1490
- { kind: 'missing', key: terminalRowKey },
1491
- versionCondition(descriptorKey, descriptorRead),
1492
- versionCondition(leaseKey, leaseRead),
1493
- conditionFor(capacityRowKey, capacityRead)
1494
- ],
1495
- mutations: [
1496
- ...mutations,
1497
- {
1498
- kind: 'put',
1499
- key: terminalRowKey,
1500
- bytes: terminalAtStore.terminalEnvelope,
1501
- retentionMs
1502
- }
1503
- ]
1504
- }, signal);
1496
+ },
1497
+ signal
1498
+ );
1505
1499
  if (result.kind === 'conflict') continue;
1506
1500
  const publishedTerminal = {
1507
1501
  ...terminalAtStore,
@@ -1510,8 +1504,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1510
1504
  if (request.completion.kind !== 'created') {
1511
1505
  return { kind: request.completion.kind, terminal: publishedTerminal };
1512
1506
  }
1513
- const version = result.putVersions.find(entry =>
1514
- entry.key.value === rowKey.value)?.version;
1507
+ const version = result.putVersions.find((entry) => entry.key.value === rowKey.value)?.version;
1515
1508
  if (version === undefined) {
1516
1509
  throw new Error('Actor creation completion did not return an authority row version.');
1517
1510
  }
@@ -1571,22 +1564,25 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1571
1564
  ? { kind: 'missing', key: OWNER_COUNTER_KEY }
1572
1565
  : { kind: 'version', key: OWNER_COUNTER_KEY, expected: counter.value.version }
1573
1566
  ];
1574
- const result = await this.provider.write({
1575
- conditions,
1576
- mutations: [
1577
- {
1578
- kind: 'put',
1579
- key: ownerKey(ownerId),
1580
- bytes: encodeOwnerRecord(ownerId, generation),
1581
- retentionMs: leaseTtlMs
1582
- },
1583
- {
1584
- kind: 'put',
1585
- key: OWNER_COUNTER_KEY,
1586
- bytes: encodeText((generation + 1n).toString())
1587
- }
1588
- ]
1589
- }, signal);
1567
+ const result = await this.provider.write(
1568
+ {
1569
+ conditions,
1570
+ mutations: [
1571
+ {
1572
+ kind: 'put',
1573
+ key: ownerKey(ownerId),
1574
+ bytes: encodeOwnerRecord(ownerId, generation),
1575
+ retentionMs: leaseTtlMs
1576
+ },
1577
+ {
1578
+ kind: 'put',
1579
+ key: OWNER_COUNTER_KEY,
1580
+ bytes: encodeText((generation + 1n).toString())
1581
+ }
1582
+ ]
1583
+ },
1584
+ signal
1585
+ );
1590
1586
  if (result.kind === 'conflict') continue;
1591
1587
  return {
1592
1588
  kind: 'claimed',
@@ -1626,15 +1622,20 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1626
1622
  if (current.kind === 'missing') return { kind: 'stale' };
1627
1623
  const record = decodeOwnerRecord(current.value.bytes);
1628
1624
  if (BigInt(record.leaseGeneration) !== token.leaseGeneration) return { kind: 'stale' };
1629
- const result = await this.provider.write({
1630
- conditions: [{ kind: 'version', key, expected: current.value.version }],
1631
- mutations: [{
1632
- kind: 'put',
1633
- key,
1634
- bytes: current.value.bytes,
1635
- retentionMs: leaseTtlMs
1636
- }]
1637
- }, signal);
1625
+ const result = await this.provider.write(
1626
+ {
1627
+ conditions: [{ kind: 'version', key, expected: current.value.version }],
1628
+ mutations: [
1629
+ {
1630
+ kind: 'put',
1631
+ key,
1632
+ bytes: current.value.bytes,
1633
+ retentionMs: leaseTtlMs
1634
+ }
1635
+ ]
1636
+ },
1637
+ signal
1638
+ );
1638
1639
  if (result.kind === 'conflict') return { kind: 'stale' };
1639
1640
  return {
1640
1641
  kind: 'renewed',
@@ -1652,10 +1653,13 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1652
1653
  if (current.kind === 'missing') return 'stale';
1653
1654
  const record = decodeOwnerRecord(current.value.bytes);
1654
1655
  if (BigInt(record.leaseGeneration) !== token.leaseGeneration) return 'stale';
1655
- const result = await this.provider.write({
1656
- conditions: [{ kind: 'version', key, expected: current.value.version }],
1657
- mutations: [{ kind: 'delete', key }]
1658
- }, signal);
1656
+ const result = await this.provider.write(
1657
+ {
1658
+ conditions: [{ kind: 'version', key, expected: current.value.version }],
1659
+ mutations: [{ kind: 'delete', key }]
1660
+ },
1661
+ signal
1662
+ );
1659
1663
  return result.kind === 'applied' ? 'released' : 'stale';
1660
1664
  }
1661
1665
 
@@ -1683,15 +1687,22 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1683
1687
  const rowKey = meshKey(key.meshName, key.rid);
1684
1688
  const current = await this.provider.read(rowKey, signal);
1685
1689
  if (current.kind === 'missing') return WriteStatus.IgnoredStale;
1686
- const descriptor = reviveMeshDescriptor(decodeCanonicalDescriptorRecord<ZLinkMeshNodeDescriptor>(current.value.bytes).descriptor);
1687
- if (descriptor.ownerId !== owner.ownerId
1688
- || descriptor.leaseGeneration !== owner.leaseGeneration) {
1690
+ const descriptor = reviveMeshDescriptor(
1691
+ decodeCanonicalDescriptorRecord<ZLinkMeshNodeDescriptor>(current.value.bytes).descriptor
1692
+ );
1693
+ if (
1694
+ descriptor.ownerId !== owner.ownerId ||
1695
+ descriptor.leaseGeneration !== owner.leaseGeneration
1696
+ ) {
1689
1697
  return WriteStatus.IgnoredStale;
1690
1698
  }
1691
- const result = await this.provider.write({
1692
- conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
1693
- mutations: [{ kind: 'delete', key: rowKey }]
1694
- }, signal);
1699
+ const result = await this.provider.write(
1700
+ {
1701
+ conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
1702
+ mutations: [{ kind: 'delete', key: rowKey }]
1703
+ },
1704
+ signal
1705
+ );
1695
1706
  return result.kind === 'applied' ? WriteStatus.Stored : WriteStatus.IgnoredStale;
1696
1707
  }
1697
1708
 
@@ -1700,55 +1711,62 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1700
1711
  page: ZLinkPageRequest = {},
1701
1712
  signal?: AbortSignal
1702
1713
  ): Promise<ZLinkLocationPage<ZLinkMeshNodeDescriptor>> {
1703
- const result = await this.provider.scan({
1704
- prefix: meshPrefix(meshName),
1705
- cursor: page.continuationToken === undefined
1706
- ? undefined
1707
- : ({ value: page.continuationToken } as ZLinkStoreScanCursor),
1708
- limit: page.pageSize ?? 100
1709
- }, signal);
1714
+ const result = await this.provider.scan(
1715
+ {
1716
+ prefix: meshPrefix(meshName),
1717
+ cursor:
1718
+ page.continuationToken === undefined
1719
+ ? undefined
1720
+ : ({ value: page.continuationToken } as ZLinkStoreScanCursor),
1721
+ limit: page.pageSize ?? 100
1722
+ },
1723
+ signal
1724
+ );
1710
1725
  if (result.kind === 'expired') {
1711
1726
  throw new Error('Location Store scan snapshot expired.');
1712
1727
  }
1713
- const items = await Promise.all(result.value.items.map(async item => {
1714
- const descriptor = reviveMeshDescriptor(
1715
- decodeCanonicalDescriptorRecord<ZLinkMeshNodeDescriptor>(item.value.bytes).descriptor
1716
- );
1717
- const capacityRead = await this.provider.read(
1718
- capacityKey(descriptor.meshName, String(descriptor.rid)),
1719
- signal
1720
- );
1721
- const capacity = capacityRead.kind === 'missing'
1722
- ? emptyCapacityRecord()
1723
- : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1724
- return {
1725
- ...descriptor,
1726
- populationCapacity: {
1727
- actors: {
1728
- ...descriptor.populationCapacity.actors,
1729
- active: capacity.active.actors,
1730
- reserved: capacity.pending.actors
1731
- },
1732
- spots: {
1733
- ...descriptor.populationCapacity.spots,
1734
- active: capacity.active.spots,
1735
- reserved: capacity.pending.spots
1736
- },
1737
- spotTypes: descriptor.populationCapacity.spotTypes.map(value => {
1738
- const key = capacityTypeKey({
1739
- objectKind: value.objectKind,
1740
- stableType: value.stableType,
1741
- count: 0
1742
- });
1743
- return {
1744
- ...value,
1745
- active: capacity.active.spotTypes[key] ?? 0,
1746
- reserved: capacity.pending.spotTypes[key] ?? 0
1747
- };
1748
- })
1749
- }
1750
- };
1751
- }));
1728
+ const items = await Promise.all(
1729
+ result.value.items.map(async (item) => {
1730
+ const descriptor = reviveMeshDescriptor(
1731
+ decodeCanonicalDescriptorRecord<ZLinkMeshNodeDescriptor>(item.value.bytes).descriptor
1732
+ );
1733
+ const capacityRead = await this.provider.read(
1734
+ capacityKey(descriptor.meshName, String(descriptor.rid)),
1735
+ signal
1736
+ );
1737
+ const capacity =
1738
+ capacityRead.kind === 'missing'
1739
+ ? emptyCapacityRecord()
1740
+ : decodeJson<CapacityRecord>(capacityRead.value.bytes);
1741
+ return {
1742
+ ...descriptor,
1743
+ populationCapacity: {
1744
+ actors: {
1745
+ ...descriptor.populationCapacity.actors,
1746
+ active: capacity.active.actors,
1747
+ reserved: capacity.pending.actors
1748
+ },
1749
+ spots: {
1750
+ ...descriptor.populationCapacity.spots,
1751
+ active: capacity.active.spots,
1752
+ reserved: capacity.pending.spots
1753
+ },
1754
+ spotTypes: descriptor.populationCapacity.spotTypes.map((value) => {
1755
+ const key = capacityTypeKey({
1756
+ objectKind: value.objectKind,
1757
+ stableType: value.stableType,
1758
+ count: 0
1759
+ });
1760
+ return {
1761
+ ...value,
1762
+ active: capacity.active.spotTypes[key] ?? 0,
1763
+ reserved: capacity.pending.spotTypes[key] ?? 0
1764
+ };
1765
+ })
1766
+ }
1767
+ };
1768
+ })
1769
+ );
1752
1770
  return {
1753
1771
  items,
1754
1772
  continuationToken: result.value.nextCursor?.value
@@ -1835,12 +1853,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1835
1853
  page: ZLinkPageRequest = {},
1836
1854
  signal?: AbortSignal
1837
1855
  ): Promise<ZLinkLocationPage<ZLinkFanoutPublisherDescriptor>> {
1838
- return this.listDescriptors(
1839
- fanoutPrefix(channelName),
1840
- page,
1841
- reviveFanoutDescriptor,
1842
- signal
1843
- );
1856
+ return this.listDescriptors(fanoutPrefix(channelName), page, reviveFanoutDescriptor, signal);
1844
1857
  }
1845
1858
 
1846
1859
  override async updateSpot(
@@ -1861,11 +1874,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1861
1874
  owner: ZLinkLocationOwnerToken,
1862
1875
  signal?: AbortSignal
1863
1876
  ): Promise<ZLinkLocationWriteStatus> {
1864
- return this.removeOwnedLocation(
1865
- spotKey(key.meshName, String(key.spotId)),
1866
- owner,
1867
- signal
1868
- );
1877
+ return this.removeOwnedLocation(spotKey(key.meshName, String(key.spotId)), owner, signal);
1869
1878
  }
1870
1879
 
1871
1880
  override async resolveSpot(
@@ -1888,7 +1897,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1888
1897
  `${PREFIX}spot:`,
1889
1898
  page,
1890
1899
  normalizeSpot,
1891
- value => matchesSpot(value, filter),
1900
+ (value) => matchesSpot(value, filter),
1892
1901
  signal
1893
1902
  );
1894
1903
  }
@@ -1934,7 +1943,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1934
1943
  `${PREFIX}actor:`,
1935
1944
  page,
1936
1945
  normalizeActor,
1937
- value => matchesActor(value, filter),
1946
+ (value) => matchesActor(value, filter),
1938
1947
  signal
1939
1948
  );
1940
1949
  }
@@ -1962,9 +1971,11 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1962
1971
  updatedAt: current.value.storeNow
1963
1972
  };
1964
1973
  }
1965
- } else if (intent === 2
1966
- && (stored.ownerId !== normalized.ownerId
1967
- || normalized.generation !== 0n && stored.generation !== normalized.generation)) {
1974
+ } else if (
1975
+ intent === 2 &&
1976
+ (stored.ownerId !== normalized.ownerId ||
1977
+ (normalized.generation !== 0n && stored.generation !== normalized.generation))
1978
+ ) {
1968
1979
  return {
1969
1980
  status: WriteStatus.IgnoredStale,
1970
1981
  generation,
@@ -1977,17 +1988,22 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
1977
1988
  return rejected(new Date());
1978
1989
  }
1979
1990
  const stored = { ...normalized, generation };
1980
- const result = await this.provider.write({
1981
- conditions: [condition],
1982
- mutations: [{
1983
- kind: 'put',
1984
- key: rowKey,
1985
- bytes: encodeJson<DescriptorRecord<ZLinkRouteLocation>>({
1986
- generation: generation.toString(),
1987
- descriptor: stored
1988
- })
1989
- }]
1990
- }, signal);
1991
+ const result = await this.provider.write(
1992
+ {
1993
+ conditions: [condition],
1994
+ mutations: [
1995
+ {
1996
+ kind: 'put',
1997
+ key: rowKey,
1998
+ bytes: encodeJson<DescriptorRecord<ZLinkRouteLocation>>({
1999
+ generation: generation.toString(),
2000
+ descriptor: stored
2001
+ })
2002
+ }
2003
+ ]
2004
+ },
2005
+ signal
2006
+ );
1991
2007
  return result.kind === 'applied'
1992
2008
  ? { status: WriteStatus.Stored, generation, updatedAt: result.storeNow }
1993
2009
  : rejected(result.storeNow);
@@ -2002,20 +2018,29 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2002
2018
  const current = await this.provider.read(rowKey, signal);
2003
2019
  if (current.kind === 'missing') return rejected(current.storeNow);
2004
2020
  const record = decodeJson<DescriptorRecord<ZLinkRouteLocation>>(current.value.bytes);
2005
- if (record.descriptor.ownerId !== owner.ownerId
2006
- || record.descriptor.generation !== owner.leaseGeneration) {
2021
+ if (
2022
+ record.descriptor.ownerId !== owner.ownerId ||
2023
+ record.descriptor.generation !== owner.leaseGeneration
2024
+ ) {
2007
2025
  return {
2008
2026
  status: WriteStatus.IgnoredStale,
2009
2027
  generation: BigInt(record.generation),
2010
2028
  updatedAt: current.value.storeNow
2011
2029
  };
2012
2030
  }
2013
- const result = await this.provider.write({
2014
- conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
2015
- mutations: [{ kind: 'delete', key: rowKey }]
2016
- }, signal);
2031
+ const result = await this.provider.write(
2032
+ {
2033
+ conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
2034
+ mutations: [{ kind: 'delete', key: rowKey }]
2035
+ },
2036
+ signal
2037
+ );
2017
2038
  return result.kind === 'applied'
2018
- ? { status: WriteStatus.Stored, generation: BigInt(record.generation), updatedAt: result.storeNow }
2039
+ ? {
2040
+ status: WriteStatus.Stored,
2041
+ generation: BigInt(record.generation),
2042
+ updatedAt: result.storeNow
2043
+ }
2019
2044
  : rejected(result.storeNow);
2020
2045
  }
2021
2046
 
@@ -2039,7 +2064,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2039
2064
  `${PREFIX}route:`,
2040
2065
  page,
2041
2066
  normalizeRoute,
2042
- value => matchesRoute(value, filter),
2067
+ (value) => matchesRoute(value, filter),
2043
2068
  signal
2044
2069
  );
2045
2070
  }
@@ -2094,7 +2119,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2094
2119
  signal
2095
2120
  );
2096
2121
  }
2097
- return removed + await super.removeAllByOwner(owner);
2122
+ return removed + (await super.removeAllByOwner(owner));
2098
2123
  }
2099
2124
 
2100
2125
  private async removeOwnedAuthorities(
@@ -2106,12 +2131,15 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2106
2131
  const pageCandidates: OwnerCleanupCandidate[] = [];
2107
2132
  let cursor: ZLinkStoreScanCursor | undefined;
2108
2133
  let expired = false;
2109
- do {
2110
- const result = await this.provider.scan({
2111
- prefix: AUTHORITY_PREIMAGE_PREFIX,
2112
- cursor,
2113
- limit: 1_000
2114
- }, signal);
2134
+ do {
2135
+ const result = await this.provider.scan(
2136
+ {
2137
+ prefix: AUTHORITY_PREIMAGE_PREFIX,
2138
+ cursor,
2139
+ limit: 1_000
2140
+ },
2141
+ signal
2142
+ );
2115
2143
  if (result.kind === 'expired') {
2116
2144
  expired = true;
2117
2145
  break;
@@ -2133,14 +2161,15 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2133
2161
  for (const candidate of candidates) {
2134
2162
  signal?.throwIfAborted();
2135
2163
  const current = await this.provider.read(candidate.key, signal);
2136
- if (current.kind === 'missing'
2137
- || current.value.version.value !== candidate.scanVersion.value) continue;
2164
+ if (current.kind === 'missing' || current.value.version.value !== candidate.scanVersion.value)
2165
+ continue;
2138
2166
  const record = decodeAuthorityRecord(current.value.bytes);
2139
2167
  if (
2140
- record.snapshot.ownerId !== owner.ownerId
2141
- || record.snapshot.ownerLeaseGeneration !== owner.leaseGeneration
2142
- || record.aggregate !== undefined
2143
- ) continue;
2168
+ record.snapshot.ownerId !== owner.ownerId ||
2169
+ record.snapshot.ownerLeaseGeneration !== owner.leaseGeneration ||
2170
+ record.aggregate !== undefined
2171
+ )
2172
+ continue;
2144
2173
  const encodedAuthority = authorityContractValueFromPreimage(candidate.key.value);
2145
2174
  const identity = decodeAuthorityKey({ value: encodedAuthority } as ZLinkAuthorityKey);
2146
2175
  if (record.snapshot.allocation.state === 'active') {
@@ -2155,21 +2184,23 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2155
2184
  }
2156
2185
  const reservationId = record.snapshot.pendingCreation?.reservationId;
2157
2186
  if (reservationId === undefined) continue;
2158
- const aborted = await this.abort({
2159
- key: identity,
2160
- reservationId,
2161
- expectedStoreVersion: current.value.version.value,
2162
- target: {
2163
- meshName: record.snapshot.allocation.descriptor.meshName,
2164
- nodeRid: record.snapshot.allocation.descriptor.rid,
2165
- nodeLifecycleGeneration:
2166
- record.snapshot.allocation.descriptorLifecycleGeneration,
2167
- owner: {
2168
- ownerId: record.snapshot.ownerId,
2169
- leaseGeneration: record.snapshot.ownerLeaseGeneration
2187
+ const aborted = await this.abort(
2188
+ {
2189
+ key: identity,
2190
+ reservationId,
2191
+ expectedStoreVersion: current.value.version.value,
2192
+ target: {
2193
+ meshName: record.snapshot.allocation.descriptor.meshName,
2194
+ nodeRid: record.snapshot.allocation.descriptor.rid,
2195
+ nodeLifecycleGeneration: record.snapshot.allocation.descriptorLifecycleGeneration,
2196
+ owner: {
2197
+ ownerId: record.snapshot.ownerId,
2198
+ leaseGeneration: record.snapshot.ownerLeaseGeneration
2199
+ }
2170
2200
  }
2171
- }
2172
- }, signal);
2201
+ },
2202
+ signal
2203
+ );
2173
2204
  if (aborted.kind === 'aborted') removed += 1n;
2174
2205
  }
2175
2206
  return removed;
@@ -2183,20 +2214,25 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2183
2214
  ): Promise<bigint> {
2184
2215
  if (candidates.length === 0) return 0n;
2185
2216
 
2186
- const currentRows = await Promise.all(candidates.map(candidate =>
2187
- this.provider.read(candidate.key, signal)));
2217
+ const currentRows = await Promise.all(
2218
+ candidates.map((candidate) => this.provider.read(candidate.key, signal))
2219
+ );
2188
2220
  const unchangedOwnedRows: OwnerCleanupCandidate[] = [];
2189
2221
  for (let index = 0; index < candidates.length; index += 1) {
2190
2222
  const candidate = candidates[index]!;
2191
2223
  const current = currentRows[index]!;
2192
- if (current.kind === 'missing'
2193
- || current.value.version.value !== candidate.scanVersion.value) {
2224
+ if (
2225
+ current.kind === 'missing' ||
2226
+ current.value.version.value !== candidate.scanVersion.value
2227
+ ) {
2194
2228
  continue;
2195
2229
  }
2196
2230
  const record = decodeJson<OwnerCleanupRecord>(current.value.bytes);
2197
2231
  const descriptor = record.descriptor;
2198
- if (descriptor.ownerId !== owner.ownerId
2199
- || descriptorOwnerLeaseGeneration(descriptor) !== owner.leaseGeneration) {
2232
+ if (
2233
+ descriptor.ownerId !== owner.ownerId ||
2234
+ descriptorOwnerLeaseGeneration(descriptor) !== owner.leaseGeneration
2235
+ ) {
2200
2236
  continue;
2201
2237
  }
2202
2238
  unchangedOwnedRows.push({
@@ -2207,24 +2243,29 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2207
2243
  if (unchangedOwnedRows.length === 0) return 0n;
2208
2244
 
2209
2245
  const currentLease = await this.provider.read(leaseKey, signal);
2210
- if (currentLease.kind === 'missing'
2211
- || liveOwnerLeaseGeneration(currentLease) !== owner.leaseGeneration) {
2246
+ if (
2247
+ currentLease.kind === 'missing' ||
2248
+ liveOwnerLeaseGeneration(currentLease) !== owner.leaseGeneration
2249
+ ) {
2212
2250
  return 0n;
2213
2251
  }
2214
- const result = await this.provider.write({
2215
- conditions: [
2216
- { kind: 'version', key: leaseKey, expected: currentLease.value.version },
2217
- ...unchangedOwnedRows.map(row => ({
2218
- kind: 'version' as const,
2219
- key: row.key,
2220
- expected: row.scanVersion
2252
+ const result = await this.provider.write(
2253
+ {
2254
+ conditions: [
2255
+ { kind: 'version', key: leaseKey, expected: currentLease.value.version },
2256
+ ...unchangedOwnedRows.map((row) => ({
2257
+ kind: 'version' as const,
2258
+ key: row.key,
2259
+ expected: row.scanVersion
2260
+ }))
2261
+ ],
2262
+ mutations: unchangedOwnedRows.map((row) => ({
2263
+ kind: 'delete' as const,
2264
+ key: row.key
2221
2265
  }))
2222
- ],
2223
- mutations: unchangedOwnedRows.map(row => ({
2224
- kind: 'delete' as const,
2225
- key: row.key
2226
- }))
2227
- }, signal);
2266
+ },
2267
+ signal
2268
+ );
2228
2269
  if (result.kind === 'applied') return BigInt(unchangedOwnedRows.length);
2229
2270
 
2230
2271
  // A row may have changed while the page was being prepared. Split the
@@ -2263,11 +2304,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2263
2304
  this.provider.read(rowKey, signal)
2264
2305
  ]);
2265
2306
  if (lease.kind === 'missing') return rejected(lease.storeNow);
2266
- if (!matchesLiveOwnerLease(
2267
- lease,
2268
- descriptor.ownerId,
2269
- descriptor.leaseGeneration
2270
- )) {
2307
+ if (!matchesLiveOwnerLease(lease, descriptor.ownerId, descriptor.leaseGeneration)) {
2271
2308
  return rejected(lease.value.storeNow);
2272
2309
  }
2273
2310
 
@@ -2330,16 +2367,20 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2330
2367
  let currentRow = predecessor;
2331
2368
 
2332
2369
  for (let attempt = 0; attempt <= MAX_DESCRIPTOR_WRITE_RETRIES; attempt += 1) {
2333
- const rowCondition: ZLinkStoreCondition = currentRow.kind === 'found'
2334
- ? { kind: 'version', key: rowKey, expected: currentRow.value.version }
2335
- : { kind: 'missing', key: rowKey };
2336
- const result = await this.provider.write({
2337
- conditions: [
2338
- { kind: 'version', key: leaseKey, expected: currentLease.value.version },
2339
- rowCondition
2340
- ],
2341
- mutations: [{ kind: 'put', key: rowKey, bytes: encodedDescriptor }]
2342
- }, signal);
2370
+ const rowCondition: ZLinkStoreCondition =
2371
+ currentRow.kind === 'found'
2372
+ ? { kind: 'version', key: rowKey, expected: currentRow.value.version }
2373
+ : { kind: 'missing', key: rowKey };
2374
+ const result = await this.provider.write(
2375
+ {
2376
+ conditions: [
2377
+ { kind: 'version', key: leaseKey, expected: currentLease.value.version },
2378
+ rowCondition
2379
+ ],
2380
+ mutations: [{ kind: 'put', key: rowKey, bytes: encodedDescriptor }]
2381
+ },
2382
+ signal
2383
+ );
2343
2384
  if (result.kind === 'applied') {
2344
2385
  return { status: WriteStatus.Stored, generation, updatedAt: result.storeNow };
2345
2386
  }
@@ -2349,9 +2390,11 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2349
2390
  this.provider.read(leaseKey, signal),
2350
2391
  this.provider.read(rowKey, signal)
2351
2392
  ]);
2352
- if (refreshedLease.kind === 'missing'
2353
- || !matchesLiveOwnerLease(refreshedLease, ownerId, leaseGeneration)
2354
- || !sameDescriptorPredecessor(predecessor, refreshedRow)) {
2393
+ if (
2394
+ refreshedLease.kind === 'missing' ||
2395
+ !matchesLiveOwnerLease(refreshedLease, ownerId, leaseGeneration) ||
2396
+ !sameDescriptorPredecessor(predecessor, refreshedRow)
2397
+ ) {
2355
2398
  return ignoredStale(result.storeNow);
2356
2399
  }
2357
2400
 
@@ -2369,16 +2412,20 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2369
2412
  ): Promise<ZLinkLocationWriteStatus> {
2370
2413
  const current = await this.provider.read(rowKey, signal);
2371
2414
  if (current.kind === 'missing') return WriteStatus.IgnoredStale;
2372
- const descriptor = revive(
2373
- decodeCanonicalDescriptorRecord<T>(current.value.bytes).descriptor);
2374
- if (descriptor.ownerId !== owner.ownerId
2375
- || descriptor.leaseGeneration !== owner.leaseGeneration) {
2415
+ const descriptor = revive(decodeCanonicalDescriptorRecord<T>(current.value.bytes).descriptor);
2416
+ if (
2417
+ descriptor.ownerId !== owner.ownerId ||
2418
+ descriptor.leaseGeneration !== owner.leaseGeneration
2419
+ ) {
2376
2420
  return WriteStatus.IgnoredStale;
2377
2421
  }
2378
- const result = await this.provider.write({
2379
- conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
2380
- mutations: [{ kind: 'delete', key: rowKey }]
2381
- }, signal);
2422
+ const result = await this.provider.write(
2423
+ {
2424
+ conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
2425
+ mutations: [{ kind: 'delete', key: rowKey }]
2426
+ },
2427
+ signal
2428
+ );
2382
2429
  return result.kind === 'applied' ? WriteStatus.Stored : WriteStatus.IgnoredStale;
2383
2430
  }
2384
2431
 
@@ -2388,19 +2435,24 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2388
2435
  revive: (descriptor: T) => T,
2389
2436
  signal?: AbortSignal
2390
2437
  ): Promise<ZLinkLocationPage<T>> {
2391
- const result = await this.provider.scan({
2392
- prefix,
2393
- cursor: page.continuationToken === undefined
2394
- ? undefined
2395
- : ({ value: page.continuationToken } as ZLinkStoreScanCursor),
2396
- limit: page.pageSize ?? 100
2397
- }, signal);
2438
+ const result = await this.provider.scan(
2439
+ {
2440
+ prefix,
2441
+ cursor:
2442
+ page.continuationToken === undefined
2443
+ ? undefined
2444
+ : ({ value: page.continuationToken } as ZLinkStoreScanCursor),
2445
+ limit: page.pageSize ?? 100
2446
+ },
2447
+ signal
2448
+ );
2398
2449
  if (result.kind === 'expired') {
2399
2450
  throw new Error('Location Store scan snapshot expired.');
2400
2451
  }
2401
2452
  return {
2402
- items: result.value.items.map(item =>
2403
- revive(decodeCanonicalDescriptorRecord<T>(item.value.bytes).descriptor)),
2453
+ items: result.value.items.map((item) =>
2454
+ revive(decodeCanonicalDescriptorRecord<T>(item.value.bytes).descriptor)
2455
+ ),
2404
2456
  continuationToken: result.value.nextCursor?.value
2405
2457
  };
2406
2458
  }
@@ -2428,8 +2480,10 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2428
2480
  generation = BigInt(record.generation);
2429
2481
  const stored = record.descriptor;
2430
2482
  if (intent === 2) {
2431
- if (stored.ownerId !== location.ownerId
2432
- || locationOwnerGeneration(stored) !== locationOwnerGeneration(location)) {
2483
+ if (
2484
+ stored.ownerId !== location.ownerId ||
2485
+ locationOwnerGeneration(stored) !== locationOwnerGeneration(location)
2486
+ ) {
2433
2487
  return {
2434
2488
  status: WriteStatus.IgnoredStale,
2435
2489
  generation,
@@ -2461,20 +2515,25 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2461
2515
  return rejected(lease.value.storeNow);
2462
2516
  }
2463
2517
 
2464
- const result = await this.provider.write({
2465
- conditions: [
2466
- { kind: 'version', key: leaseKey, expected: lease.value.version },
2467
- rowCondition
2468
- ],
2469
- mutations: [{
2470
- kind: 'put',
2471
- key: rowKey,
2472
- bytes: encodeJson<DescriptorRecord<T>>({
2473
- generation: generation.toString(),
2474
- descriptor: location
2475
- })
2476
- }]
2477
- }, signal);
2518
+ const result = await this.provider.write(
2519
+ {
2520
+ conditions: [
2521
+ { kind: 'version', key: leaseKey, expected: lease.value.version },
2522
+ rowCondition
2523
+ ],
2524
+ mutations: [
2525
+ {
2526
+ kind: 'put',
2527
+ key: rowKey,
2528
+ bytes: encodeJson<DescriptorRecord<T>>({
2529
+ generation: generation.toString(),
2530
+ descriptor: location
2531
+ })
2532
+ }
2533
+ ]
2534
+ },
2535
+ signal
2536
+ );
2478
2537
  return result.kind === 'applied'
2479
2538
  ? { status: WriteStatus.Stored, generation, updatedAt: result.storeNow }
2480
2539
  : rejected(result.storeNow);
@@ -2493,14 +2552,16 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2493
2552
  readonly leaseGeneration?: bigint;
2494
2553
  };
2495
2554
  const leaseGeneration = descriptor.leaseGeneration ?? BigInt(record.generation);
2496
- if (descriptor.ownerId !== owner.ownerId
2497
- || leaseGeneration !== owner.leaseGeneration) {
2555
+ if (descriptor.ownerId !== owner.ownerId || leaseGeneration !== owner.leaseGeneration) {
2498
2556
  return WriteStatus.IgnoredStale;
2499
2557
  }
2500
- const result = await this.provider.write({
2501
- conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
2502
- mutations: [{ kind: 'delete', key: rowKey }]
2503
- }, signal);
2558
+ const result = await this.provider.write(
2559
+ {
2560
+ conditions: [{ kind: 'version', key: rowKey, expected: current.value.version }],
2561
+ mutations: [{ kind: 'delete', key: rowKey }]
2562
+ },
2563
+ signal
2564
+ );
2504
2565
  return result.kind === 'applied' ? WriteStatus.Stored : WriteStatus.IgnoredStale;
2505
2566
  }
2506
2567
 
@@ -2522,22 +2583,25 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2522
2583
  signal?: AbortSignal
2523
2584
  ): Promise<ZLinkLocationPage<T>> {
2524
2585
  const requested = page.pageSize ?? 100;
2525
- let cursor = page.continuationToken === undefined
2526
- ? undefined
2527
- : ({ value: page.continuationToken } as ZLinkStoreScanCursor);
2586
+ let cursor =
2587
+ page.continuationToken === undefined
2588
+ ? undefined
2589
+ : ({ value: page.continuationToken } as ZLinkStoreScanCursor);
2528
2590
  const items: T[] = [];
2529
2591
  do {
2530
- const result = await this.provider.scan({
2531
- prefix,
2532
- cursor,
2533
- limit: requested
2534
- }, signal);
2592
+ const result = await this.provider.scan(
2593
+ {
2594
+ prefix,
2595
+ cursor,
2596
+ limit: requested
2597
+ },
2598
+ signal
2599
+ );
2535
2600
  if (result.kind === 'expired') {
2536
2601
  throw new Error('Location Store scan snapshot expired.');
2537
2602
  }
2538
2603
  for (const item of result.value.items) {
2539
- const value = revive(
2540
- decodeJson<DescriptorRecord<T>>(item.value.bytes).descriptor);
2604
+ const value = revive(decodeJson<DescriptorRecord<T>>(item.value.bytes).descriptor);
2541
2605
  if (matches(value)) items.push(value);
2542
2606
  if (items.length === requested) {
2543
2607
  return {
@@ -2568,10 +2632,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2568
2632
  );
2569
2633
  }
2570
2634
  const aggregateRead = await this.provider.read(
2571
- aggregateKey(aggregateFence(
2572
- aggregateId(marker.aggregateId),
2573
- marker.aggregateGeneration
2574
- )),
2635
+ aggregateKey(aggregateFence(aggregateId(marker.aggregateId), marker.aggregateGeneration)),
2575
2636
  signal
2576
2637
  );
2577
2638
  if (aggregateRead.kind === 'missing') {
@@ -2585,10 +2646,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2585
2646
  storeNow
2586
2647
  );
2587
2648
  }
2588
- const fence = aggregateFence(
2589
- aggregateId(marker.aggregateId),
2590
- marker.aggregateGeneration
2591
- );
2649
+ const fence = aggregateFence(aggregateId(marker.aggregateId), marker.aggregateGeneration);
2592
2650
  const payload = await requireProviderBytes(
2593
2651
  this.provider,
2594
2652
  aggregateParticipantPayloadKey(fence, marker.index),
@@ -2597,25 +2655,25 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2597
2655
  if (sha256Hex(payload) !== marker.authorityPayloadSha256) {
2598
2656
  throw new Error('Committed aggregate participant payload checksum is invalid.');
2599
2657
  }
2600
- const projected: StoredAuthoritySnapshot = marker.ownerTransition === 'newOwner'
2601
- ? {
2602
- payload: Buffer.from(payload),
2603
- objectGeneration: record.snapshot.objectGeneration,
2604
- authorityOwnerGeneration: marker.targetAuthorityOwnerGeneration,
2605
- ownerId: aggregate.targetOwner.ownerId,
2606
- ownerLeaseGeneration: aggregate.targetOwner.leaseGeneration,
2607
- allocation: {
2608
- ...record.snapshot.allocation,
2609
- descriptor: { ...aggregate.targetDescriptor },
2610
- descriptorLifecycleGeneration:
2611
- aggregate.targetDescriptorLifecycleGeneration,
2612
- capacity: cloneCapacity(record.snapshot.allocation.capacity)
2658
+ const projected: StoredAuthoritySnapshot =
2659
+ marker.ownerTransition === 'newOwner'
2660
+ ? {
2661
+ payload: Buffer.from(payload),
2662
+ objectGeneration: record.snapshot.objectGeneration,
2663
+ authorityOwnerGeneration: marker.targetAuthorityOwnerGeneration,
2664
+ ownerId: aggregate.targetOwner.ownerId,
2665
+ ownerLeaseGeneration: aggregate.targetOwner.leaseGeneration,
2666
+ allocation: {
2667
+ ...record.snapshot.allocation,
2668
+ descriptor: { ...aggregate.targetDescriptor },
2669
+ descriptorLifecycleGeneration: aggregate.targetDescriptorLifecycleGeneration,
2670
+ capacity: cloneCapacity(record.snapshot.allocation.capacity)
2671
+ }
2613
2672
  }
2614
- }
2615
- : {
2616
- ...record.snapshot,
2617
- payload: Buffer.from(payload)
2618
- };
2673
+ : {
2674
+ ...record.snapshot,
2675
+ payload: Buffer.from(payload)
2676
+ };
2619
2677
  return authoritySnapshot(projected, version, storeNow);
2620
2678
  }
2621
2679
 
@@ -2640,11 +2698,13 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2640
2698
  if (record.aggregate === undefined) {
2641
2699
  if (
2642
2700
  !Buffer.from(record.snapshot.payload).equals(
2643
- Buffer.from(await requireProviderBytes(
2644
- this.provider,
2645
- aggregateParticipantPayloadKey(fence, index),
2646
- signal
2647
- ))
2701
+ Buffer.from(
2702
+ await requireProviderBytes(
2703
+ this.provider,
2704
+ aggregateParticipantPayloadKey(fence, index),
2705
+ signal
2706
+ )
2707
+ )
2648
2708
  )
2649
2709
  ) {
2650
2710
  throw new Error('Normalized aggregate participant payload changed.');
@@ -2667,15 +2727,13 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2667
2727
  ? {
2668
2728
  payload: Buffer.from(payload),
2669
2729
  objectGeneration: record.snapshot.objectGeneration,
2670
- authorityOwnerGeneration:
2671
- record.aggregate.targetAuthorityOwnerGeneration,
2730
+ authorityOwnerGeneration: record.aggregate.targetAuthorityOwnerGeneration,
2672
2731
  ownerId: aggregate.targetOwner.ownerId,
2673
2732
  ownerLeaseGeneration: aggregate.targetOwner.leaseGeneration,
2674
2733
  allocation: {
2675
2734
  ...record.snapshot.allocation,
2676
2735
  descriptor: { ...aggregate.targetDescriptor },
2677
- descriptorLifecycleGeneration:
2678
- aggregate.targetDescriptorLifecycleGeneration,
2736
+ descriptorLifecycleGeneration: aggregate.targetDescriptorLifecycleGeneration,
2679
2737
  capacity: cloneCapacity(record.snapshot.allocation.capacity)
2680
2738
  }
2681
2739
  }
@@ -2689,18 +2747,25 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2689
2747
  aggregate: undefined,
2690
2748
  visibleStoreVersion: undefined
2691
2749
  };
2692
- const result = await this.provider.write({
2693
- conditions: [{
2694
- kind: 'version',
2695
- key: rowKey,
2696
- expected: current.value.version
2697
- }],
2698
- mutations: [{
2699
- kind: 'put',
2700
- key: rowKey,
2701
- bytes: encodeAuthorityRecord(normalized)
2702
- }]
2703
- }, signal);
2750
+ const result = await this.provider.write(
2751
+ {
2752
+ conditions: [
2753
+ {
2754
+ kind: 'version',
2755
+ key: rowKey,
2756
+ expected: current.value.version
2757
+ }
2758
+ ],
2759
+ mutations: [
2760
+ {
2761
+ kind: 'put',
2762
+ key: rowKey,
2763
+ bytes: encodeAuthorityRecord(normalized)
2764
+ }
2765
+ ]
2766
+ },
2767
+ signal
2768
+ );
2704
2769
  if (result.kind === 'applied') return;
2705
2770
  }
2706
2771
  });
@@ -2714,16 +2779,16 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2714
2779
  if (bytes.byteLength > 1024 * 1024) {
2715
2780
  throw new RangeError('Aggregate participant staging value exceeds 1 MiB.');
2716
2781
  }
2717
- const result = await this.provider.write({
2718
- conditions: [{ kind: 'missing', key }],
2719
- mutations: [{ kind: 'put', key, bytes: Buffer.from(bytes) }]
2720
- }, signal);
2782
+ const result = await this.provider.write(
2783
+ {
2784
+ conditions: [{ kind: 'missing', key }],
2785
+ mutations: [{ kind: 'put', key, bytes: Buffer.from(bytes) }]
2786
+ },
2787
+ signal
2788
+ );
2721
2789
  if (result.kind === 'applied') return;
2722
2790
  const current = await this.provider.read(key, signal);
2723
- if (
2724
- current.kind !== 'found'
2725
- || !Buffer.from(current.value.bytes).equals(Buffer.from(bytes))
2726
- ) {
2791
+ if (current.kind !== 'found' || !Buffer.from(current.value.bytes).equals(Buffer.from(bytes))) {
2727
2792
  throw new Error(`Immutable aggregate participant value changed: ${key.value}.`);
2728
2793
  }
2729
2794
  }
@@ -2742,14 +2807,19 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2742
2807
  return;
2743
2808
  }
2744
2809
  if (record.state !== 'staging') return;
2745
- const result = await this.provider.write({
2746
- conditions: [{ kind: 'version', key, expected: current.value.version }],
2747
- mutations: [{
2748
- kind: 'put',
2749
- key,
2750
- bytes: encodeJson({ ...record, state: 'aborted' } satisfies AggregateRecord)
2751
- }]
2752
- }, signal);
2810
+ const result = await this.provider.write(
2811
+ {
2812
+ conditions: [{ kind: 'version', key, expected: current.value.version }],
2813
+ mutations: [
2814
+ {
2815
+ kind: 'put',
2816
+ key,
2817
+ bytes: encodeJson({ ...record, state: 'aborted' } satisfies AggregateRecord)
2818
+ }
2819
+ ]
2820
+ },
2821
+ signal
2822
+ );
2753
2823
  if (result.kind === 'applied') {
2754
2824
  await this.clearAggregateMarkersByScan(fence, signal);
2755
2825
  return;
@@ -2765,7 +2835,7 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2765
2835
  }[],
2766
2836
  signal?: AbortSignal
2767
2837
  ): Promise<void> {
2768
- await parallelForEach(installed, 64, async value => {
2838
+ await parallelForEach(installed, 64, async (value) => {
2769
2839
  await this.clearAggregateMarker(fence, value.key, signal);
2770
2840
  });
2771
2841
  }
@@ -2776,21 +2846,26 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2776
2846
  ): Promise<void> {
2777
2847
  let cursor: ZLinkStoreScanCursor | undefined;
2778
2848
  for (;;) {
2779
- const result = await this.provider.scan({
2780
- prefix: AUTHORITY_PREIMAGE_PREFIX,
2781
- cursor,
2782
- limit: 1_000
2783
- }, signal);
2849
+ const result = await this.provider.scan(
2850
+ {
2851
+ prefix: AUTHORITY_PREIMAGE_PREFIX,
2852
+ cursor,
2853
+ limit: 1_000
2854
+ },
2855
+ signal
2856
+ );
2784
2857
  if (result.kind === 'expired') {
2785
2858
  cursor = undefined;
2786
2859
  continue;
2787
2860
  }
2788
- const matching = result.value.items.filter(item => {
2861
+ const matching = result.value.items.filter((item) => {
2789
2862
  const record = decodeAuthorityRecord(item.value.bytes);
2790
- return record.aggregate?.aggregateId === fence.aggregateId.value
2791
- && record.aggregate.aggregateGeneration === fence.aggregateGeneration;
2863
+ return (
2864
+ record.aggregate?.aggregateId === fence.aggregateId.value &&
2865
+ record.aggregate.aggregateGeneration === fence.aggregateGeneration
2866
+ );
2792
2867
  });
2793
- await parallelForEach(matching, 64, async item => {
2868
+ await parallelForEach(matching, 64, async (item) => {
2794
2869
  await this.clearAggregateMarker(fence, item.key, signal);
2795
2870
  });
2796
2871
  if (result.value.nextCursor === undefined) return;
@@ -2808,20 +2883,28 @@ export class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationStore {
2808
2883
  if (current.kind === 'missing') return;
2809
2884
  const record = decodeAuthorityRecord(current.value.bytes);
2810
2885
  if (
2811
- record.aggregate === undefined
2812
- || record.aggregate.aggregateId !== fence.aggregateId.value
2813
- || record.aggregate.aggregateGeneration !== fence.aggregateGeneration
2886
+ record.aggregate === undefined ||
2887
+ record.aggregate.aggregateId !== fence.aggregateId.value ||
2888
+ record.aggregate.aggregateGeneration !== fence.aggregateGeneration
2814
2889
  ) {
2815
2890
  return;
2816
2891
  }
2817
- const result = await this.provider.write({
2818
- conditions: [{ kind: 'version', key, expected: current.value.version }],
2819
- mutations: [{
2820
- kind: 'put',
2821
- key,
2822
- bytes: encodeAuthorityRecord({ ...record, aggregate: undefined } satisfies AuthorityRecord)
2823
- }]
2824
- }, signal);
2892
+ const result = await this.provider.write(
2893
+ {
2894
+ conditions: [{ kind: 'version', key, expected: current.value.version }],
2895
+ mutations: [
2896
+ {
2897
+ kind: 'put',
2898
+ key,
2899
+ bytes: encodeAuthorityRecord({
2900
+ ...record,
2901
+ aggregate: undefined
2902
+ } satisfies AuthorityRecord)
2903
+ }
2904
+ ]
2905
+ },
2906
+ signal
2907
+ );
2825
2908
  if (result.kind === 'applied') return;
2826
2909
  }
2827
2910
  }
@@ -2846,10 +2929,7 @@ class AmbiguousWriteReconcilingLocationStore implements ZLinkLocationStore {
2846
2929
  return this.inner.read(key, signal);
2847
2930
  }
2848
2931
 
2849
- scan(
2850
- request: ZLinkStoreScanRequest,
2851
- signal?: AbortSignal
2852
- ): Promise<ZLinkStoreScanResult> {
2932
+ scan(request: ZLinkStoreScanRequest, signal?: AbortSignal): Promise<ZLinkStoreScanResult> {
2853
2933
  return this.inner.scan(request, signal);
2854
2934
  }
2855
2935
 
@@ -2868,18 +2948,14 @@ class AmbiguousWriteReconcilingLocationStore implements ZLinkLocationStore {
2868
2948
  }
2869
2949
  }
2870
2950
 
2871
- private async reconcile(
2872
- request: ZLinkStoreWriteRequest
2873
- ): Promise<ZLinkStoreWriteResult> {
2951
+ private async reconcile(request: ZLinkStoreWriteRequest): Promise<ZLinkStoreWriteResult> {
2874
2952
  if (request.mutations.length === 0) {
2875
2953
  throw new Error('Cannot reconcile an opaque Store write without mutations.');
2876
2954
  }
2877
- const reconciliationSignal = AbortSignal.timeout(
2878
- AMBIGUOUS_WRITE_RECONCILIATION_TIMEOUT_MS
2955
+ const reconciliationSignal = AbortSignal.timeout(AMBIGUOUS_WRITE_RECONCILIATION_TIMEOUT_MS);
2956
+ const reads = await Promise.all(
2957
+ request.mutations.map((mutation) => this.inner.read(mutation.key, reconciliationSignal))
2879
2958
  );
2880
- const reads = await Promise.all(request.mutations.map(
2881
- mutation => this.inner.read(mutation.key, reconciliationSignal)
2882
- ));
2883
2959
  const putVersions: Array<{
2884
2960
  readonly key: ZLinkStoreKey;
2885
2961
  readonly version: ZLinkStoreVersion;
@@ -2889,17 +2965,20 @@ class AmbiguousWriteReconcilingLocationStore implements ZLinkLocationStore {
2889
2965
  for (let index = 0; index < request.mutations.length; index += 1) {
2890
2966
  const mutation = request.mutations[index];
2891
2967
  const read = reads[index];
2892
- storeNow = read.kind === 'found'
2893
- ? latestDate(storeNow, read.value.storeNow)
2894
- : latestDate(storeNow, read.storeNow);
2968
+ storeNow =
2969
+ read.kind === 'found'
2970
+ ? latestDate(storeNow, read.value.storeNow)
2971
+ : latestDate(storeNow, read.storeNow);
2895
2972
 
2896
2973
  if (mutation.kind === 'delete') {
2897
2974
  if (read.kind !== 'missing') return { kind: 'conflict', storeNow };
2898
2975
  continue;
2899
2976
  }
2900
- if (read.kind !== 'found'
2901
- || !Buffer.from(read.value.bytes).equals(Buffer.from(mutation.bytes))
2902
- || !versionAdvanced(request.conditions, mutation.key, read.value.version)) {
2977
+ if (
2978
+ read.kind !== 'found' ||
2979
+ !Buffer.from(read.value.bytes).equals(Buffer.from(mutation.bytes)) ||
2980
+ !versionAdvanced(request.conditions, mutation.key, read.value.version)
2981
+ ) {
2903
2982
  return { kind: 'conflict', storeNow };
2904
2983
  }
2905
2984
  putVersions.push({ key: mutation.key, version: read.value.version });
@@ -2914,7 +2993,7 @@ function versionAdvanced(
2914
2993
  key: ZLinkStoreKey,
2915
2994
  current: ZLinkStoreVersion
2916
2995
  ): boolean {
2917
- const condition = conditions.find(candidate => candidate.key.value === key.value);
2996
+ const condition = conditions.find((candidate) => candidate.key.value === key.value);
2918
2997
  return condition?.kind !== 'version' || condition.expected.value !== current.value;
2919
2998
  }
2920
2999
 
@@ -2923,9 +3002,7 @@ function latestDate(left: Date, right: Date): Date {
2923
3002
  }
2924
3003
 
2925
3004
  type OwnedDescriptor =
2926
- | ZLinkMeshNodeDescriptor
2927
- | ZLinkClientServerServerDescriptor
2928
- | ZLinkFanoutPublisherDescriptor;
3005
+ ZLinkMeshNodeDescriptor | ZLinkClientServerServerDescriptor | ZLinkFanoutPublisherDescriptor;
2929
3006
 
2930
3007
  type LeaseOwnedLocation = ZLinkSpotLocation | ZLinkActorLocation;
2931
3008
  type StoredLocation = LeaseOwnedLocation | ZLinkRouteLocation;
@@ -2939,10 +3016,10 @@ function validateProviderAggregateRequest(request: ZLinkAggregatePrepareRequest)
2939
3016
  if (request.inventoryDigest.byteLength !== 32) {
2940
3017
  throw new TypeError('Aggregate inventory digest must contain 32 bytes.');
2941
3018
  }
2942
- const keys = request.participants.map(value => value.authorityKey.value);
3019
+ const keys = request.participants.map((value) => value.authorityKey.value);
2943
3020
  if (
2944
- new Set(keys).size !== keys.length
2945
- || keys.some((key, index) => index > 0 && keys[index - 1]!.localeCompare(key) >= 0)
3021
+ new Set(keys).size !== keys.length ||
3022
+ keys.some((key, index) => index > 0 && keys[index - 1]!.localeCompare(key) >= 0)
2946
3023
  ) {
2947
3024
  throw new TypeError('Aggregate participants must be unique and canonically sorted.');
2948
3025
  }
@@ -2950,8 +3027,8 @@ function validateProviderAggregateRequest(request: ZLinkAggregatePrepareRequest)
2950
3027
  requireText(participant.authorityKey.value, 'aggregate authority key');
2951
3028
  requireText(participant.expectedStoreVersion.value, 'aggregate expected Store version');
2952
3029
  if (
2953
- participant.authorityPayload.byteLength > 1024 * 1024
2954
- || participant.membershipMutation.byteLength > 1024 * 1024
3030
+ participant.authorityPayload.byteLength > 1024 * 1024 ||
3031
+ participant.membershipMutation.byteLength > 1024 * 1024
2955
3032
  ) {
2956
3033
  throw new RangeError('Aggregate participant value exceeds 1 MiB.');
2957
3034
  }
@@ -2976,8 +3053,7 @@ function aggregateRecord(
2976
3053
  participantCount: request.participants.length,
2977
3054
  inventoryDigest: Buffer.from(request.inventoryDigest),
2978
3055
  targetDescriptor: { ...request.targetDescriptor },
2979
- targetDescriptorLifecycleGeneration:
2980
- request.targetDescriptorLifecycleGeneration,
3056
+ targetDescriptorLifecycleGeneration: request.targetDescriptorLifecycleGeneration,
2981
3057
  capacity: cloneCapacity(request.capacity),
2982
3058
  targetOwner: { ...request.targetOwner }
2983
3059
  };
@@ -3001,12 +3077,14 @@ function sameAggregateMarker(
3001
3077
  index: number,
3002
3078
  participant: ZLinkAggregatePrepareRequest['participants'][number]
3003
3079
  ): boolean {
3004
- return marker !== undefined
3005
- && marker.aggregateId === fence.aggregateId.value
3006
- && marker.aggregateGeneration === fence.aggregateGeneration
3007
- && marker.index === index
3008
- && marker.expectedStoreVersion === participant.expectedStoreVersion.value
3009
- && marker.ownerTransition === participant.ownerTransition;
3080
+ return (
3081
+ marker !== undefined &&
3082
+ marker.aggregateId === fence.aggregateId.value &&
3083
+ marker.aggregateGeneration === fence.aggregateGeneration &&
3084
+ marker.index === index &&
3085
+ marker.expectedStoreVersion === participant.expectedStoreVersion.value &&
3086
+ marker.ownerTransition === participant.ownerTransition
3087
+ );
3010
3088
  }
3011
3089
 
3012
3090
  function sameAggregateMarkerEntry(
@@ -3020,14 +3098,16 @@ function sameAggregateMarkerEntry(
3020
3098
  readonly membershipMutationSha256: string;
3021
3099
  }
3022
3100
  ): boolean {
3023
- return marker !== undefined
3024
- && marker.aggregateId === fence.aggregateId.value
3025
- && marker.aggregateGeneration === fence.aggregateGeneration
3026
- && marker.index === index
3027
- && marker.expectedStoreVersion === entry.expectedStoreVersion
3028
- && marker.ownerTransition === entry.ownerTransition
3029
- && marker.authorityPayloadSha256 === entry.authorityPayloadSha256
3030
- && marker.membershipMutationSha256 === entry.membershipMutationSha256;
3101
+ return (
3102
+ marker !== undefined &&
3103
+ marker.aggregateId === fence.aggregateId.value &&
3104
+ marker.aggregateGeneration === fence.aggregateGeneration &&
3105
+ marker.index === index &&
3106
+ marker.expectedStoreVersion === entry.expectedStoreVersion &&
3107
+ marker.ownerTransition === entry.ownerTransition &&
3108
+ marker.authorityPayloadSha256 === entry.authorityPayloadSha256 &&
3109
+ marker.membershipMutationSha256 === entry.membershipMutationSha256
3110
+ );
3031
3111
  }
3032
3112
 
3033
3113
  function aggregateTarget(
@@ -3041,9 +3121,7 @@ function aggregateTarget(
3041
3121
  };
3042
3122
  }
3043
3123
 
3044
- function aggregateTargetFromRecord(
3045
- record: AggregateRecord
3046
- ): ZLinkObjectCommitRequest['target'] {
3124
+ function aggregateTargetFromRecord(record: AggregateRecord): ZLinkObjectCommitRequest['target'] {
3047
3125
  return {
3048
3126
  meshName: record.targetDescriptor.meshName,
3049
3127
  nodeRid: record.targetDescriptor.rid,
@@ -3059,11 +3137,9 @@ function addCapacityVector(
3059
3137
  let spotType = left.spotType;
3060
3138
  if (right.spotType !== undefined) {
3061
3139
  if (
3062
- spotType !== undefined
3063
- && (
3064
- spotType.objectKind !== right.spotType.objectKind
3065
- || spotType.stableType !== right.spotType.stableType
3066
- )
3140
+ spotType !== undefined &&
3141
+ (spotType.objectKind !== right.spotType.objectKind ||
3142
+ spotType.stableType !== right.spotType.stableType)
3067
3143
  ) {
3068
3144
  throw new TypeError('Aggregate capacity contains more than one Spot type.');
3069
3145
  }
@@ -3097,15 +3173,14 @@ async function parallelForEach<T>(
3097
3173
  operation: (value: T, index: number) => Promise<void>
3098
3174
  ): Promise<void> {
3099
3175
  let next = 0;
3100
- await Promise.all(Array.from(
3101
- { length: Math.min(concurrency, values.length) },
3102
- async () => {
3176
+ await Promise.all(
3177
+ Array.from({ length: Math.min(concurrency, values.length) }, async () => {
3103
3178
  while (next < values.length) {
3104
3179
  const index = next++;
3105
3180
  await operation(values[index]!, index);
3106
3181
  }
3107
- }
3108
- ));
3182
+ })
3183
+ );
3109
3184
  }
3110
3185
 
3111
3186
  async function waitForAggregateCommitRetry(
@@ -3160,11 +3235,7 @@ function authorityPreimage(value: string): string {
3160
3235
  // §2.3: Entry|User|Instance Spot kinds share one segment ("spot") -- one
3161
3236
  // Id has exactly one authority row regardless of spot kind.
3162
3237
  const segment = decoded.kind === 'actor' ? 'actor' : 'spot';
3163
- return opaqueRecordPreimage(
3164
- 'authority',
3165
- segment,
3166
- requireNoNul(decoded.globalId, 'Authority Id')
3167
- );
3238
+ return opaqueRecordPreimage('authority', segment, requireNoNul(decoded.globalId, 'Authority Id'));
3168
3239
  }
3169
3240
 
3170
3241
  // Reverses authorityPreimage(): recovers the framework-internal zla1-encoded
@@ -3200,10 +3271,7 @@ function aggregateId(value: string): ZLinkAggregateId {
3200
3271
  return { value } as ZLinkAggregateId;
3201
3272
  }
3202
3273
 
3203
- function aggregateFence(
3204
- id: ZLinkAggregateId,
3205
- generation: bigint
3206
- ): ZLinkAggregateFence {
3274
+ function aggregateFence(id: ZLinkAggregateId, generation: bigint): ZLinkAggregateFence {
3207
3275
  return { aggregateId: id, aggregateGeneration: generation };
3208
3276
  }
3209
3277
 
@@ -3213,13 +3281,10 @@ function aggregateKey(fence: ZLinkAggregateFence): ZLinkStoreKey {
3213
3281
  );
3214
3282
  }
3215
3283
 
3216
- function aggregateParticipantPayloadKey(
3217
- fence: ZLinkAggregateFence,
3218
- index: number
3219
- ): ZLinkStoreKey {
3284
+ function aggregateParticipantPayloadKey(fence: ZLinkAggregateFence, index: number): ZLinkStoreKey {
3220
3285
  return storeKey(
3221
- `${PREFIX}aggregate-participant:${encodeURIComponent(fence.aggregateId.value)}:`
3222
- + `${fence.aggregateGeneration}:${index}:authority`
3286
+ `${PREFIX}aggregate-participant:${encodeURIComponent(fence.aggregateId.value)}:` +
3287
+ `${fence.aggregateGeneration}:${index}:authority`
3223
3288
  );
3224
3289
  }
3225
3290
 
@@ -3228,8 +3293,8 @@ function aggregateParticipantMembershipKey(
3228
3293
  index: number
3229
3294
  ): ZLinkStoreKey {
3230
3295
  return storeKey(
3231
- `${PREFIX}aggregate-participant:${encodeURIComponent(fence.aggregateId.value)}:`
3232
- + `${fence.aggregateGeneration}:${index}:membership`
3296
+ `${PREFIX}aggregate-participant:${encodeURIComponent(fence.aggregateId.value)}:` +
3297
+ `${fence.aggregateGeneration}:${index}:membership`
3233
3298
  );
3234
3299
  }
3235
3300
 
@@ -3249,56 +3314,53 @@ function meshPrefix(meshName: string): string {
3249
3314
  }
3250
3315
 
3251
3316
  function meshKey(meshName: string, nodeRid: RoutingId) {
3252
- return storeKey(opaqueRecordPreimage(
3253
- 'mesh-node',
3254
- requireNoNul(meshName, 'MeshName'),
3255
- routingIdHexSegment(nodeRid)
3256
- ));
3317
+ return storeKey(
3318
+ opaqueRecordPreimage(
3319
+ 'mesh-node',
3320
+ requireNoNul(meshName, 'MeshName'),
3321
+ routingIdHexSegment(nodeRid)
3322
+ )
3323
+ );
3257
3324
  }
3258
3325
 
3259
3326
  function clientServerPrefix(channelName: string): string {
3260
- return `${opaqueRecordPreimage(
3261
- 'client-server',
3262
- requireNoNul(channelName, 'ChannelName')
3263
- )}\0`;
3327
+ return `${opaqueRecordPreimage('client-server', requireNoNul(channelName, 'ChannelName'))}\0`;
3264
3328
  }
3265
3329
 
3266
3330
  function clientServerKey(channelName: string, serverRid: RoutingId) {
3267
- return storeKey(opaqueRecordPreimage(
3268
- 'client-server',
3269
- requireNoNul(channelName, 'ChannelName'),
3270
- routingIdHexSegment(serverRid)
3271
- ));
3331
+ return storeKey(
3332
+ opaqueRecordPreimage(
3333
+ 'client-server',
3334
+ requireNoNul(channelName, 'ChannelName'),
3335
+ routingIdHexSegment(serverRid)
3336
+ )
3337
+ );
3272
3338
  }
3273
3339
 
3274
3340
  function fanoutPrefix(channelName: string): string {
3275
- return `${opaqueRecordPreimage(
3276
- 'fanout-publisher',
3277
- requireNoNul(channelName, 'ChannelName')
3278
- )}\0`;
3341
+ return `${opaqueRecordPreimage('fanout-publisher', requireNoNul(channelName, 'ChannelName'))}\0`;
3279
3342
  }
3280
3343
 
3281
3344
  function fanoutKey(channelName: string, publisherRid: RoutingId) {
3282
- return storeKey(opaqueRecordPreimage(
3283
- 'fanout-publisher',
3284
- requireNoNul(channelName, 'ChannelName'),
3285
- routingIdHexSegment(publisherRid)
3286
- ));
3345
+ return storeKey(
3346
+ opaqueRecordPreimage(
3347
+ 'fanout-publisher',
3348
+ requireNoNul(channelName, 'ChannelName'),
3349
+ routingIdHexSegment(publisherRid)
3350
+ )
3351
+ );
3287
3352
  }
3288
3353
 
3289
3354
  function spotKey(meshName: string, spotId: string) {
3290
- return storeKey(
3291
- `${PREFIX}spot:${encodeURIComponent(meshName)}:${encodeURIComponent(spotId)}`);
3355
+ return storeKey(`${PREFIX}spot:${encodeURIComponent(meshName)}:${encodeURIComponent(spotId)}`);
3292
3356
  }
3293
3357
 
3294
3358
  function actorKey(meshName: string, actorId: string) {
3295
- return storeKey(
3296
- `${PREFIX}actor:${encodeURIComponent(meshName)}:${encodeURIComponent(actorId)}`);
3359
+ return storeKey(`${PREFIX}actor:${encodeURIComponent(meshName)}:${encodeURIComponent(actorId)}`);
3297
3360
  }
3298
3361
 
3299
3362
  function routeKey(routeKind: string, value: string) {
3300
- return storeKey(
3301
- `${PREFIX}route:${encodeURIComponent(routeKind)}:${encodeURIComponent(value)}`);
3363
+ return storeKey(`${PREFIX}route:${encodeURIComponent(routeKind)}:${encodeURIComponent(value)}`);
3302
3364
  }
3303
3365
 
3304
3366
  function encodeText(value: string): Uint8Array {
@@ -3324,24 +3386,28 @@ function counterNextValue(counter: ZLinkStoreReadResult): bigint {
3324
3386
  }
3325
3387
 
3326
3388
  function encodeJson<T>(value: T): Uint8Array {
3327
- return Buffer.from(JSON.stringify(value, (key, candidate) => {
3328
- if (typeof candidate === 'bigint') return { $bigint: candidate.toString() };
3329
- if (candidate instanceof Uint8Array) {
3330
- return { $bytes: Buffer.from(candidate).toString('base64') };
3331
- }
3332
- if (
3333
- key === 'spotTypes'
3334
- && candidate !== null
3335
- && typeof candidate === 'object'
3336
- && !Array.isArray(candidate)
3337
- ) {
3338
- return Object.fromEntries(
3339
- Object.entries(candidate as Record<string, unknown>)
3340
- .sort(([left], [right]) => compareUtf16Ordinal(left, right))
3341
- );
3342
- }
3343
- return candidate;
3344
- }), 'utf8');
3389
+ return Buffer.from(
3390
+ JSON.stringify(value, (key, candidate) => {
3391
+ if (typeof candidate === 'bigint') return { $bigint: candidate.toString() };
3392
+ if (candidate instanceof Uint8Array) {
3393
+ return { $bytes: Buffer.from(candidate).toString('base64') };
3394
+ }
3395
+ if (
3396
+ key === 'spotTypes' &&
3397
+ candidate !== null &&
3398
+ typeof candidate === 'object' &&
3399
+ !Array.isArray(candidate)
3400
+ ) {
3401
+ return Object.fromEntries(
3402
+ Object.entries(candidate as Record<string, unknown>).sort(([left], [right]) =>
3403
+ compareUtf16Ordinal(left, right)
3404
+ )
3405
+ );
3406
+ }
3407
+ return candidate;
3408
+ }),
3409
+ 'utf8'
3410
+ );
3345
3411
  }
3346
3412
 
3347
3413
  function compareUtf16Ordinal(left: string, right: string): number {
@@ -3350,16 +3416,20 @@ function compareUtf16Ordinal(left: string, right: string): number {
3350
3416
 
3351
3417
  function decodeJson<T>(value: Uint8Array): T {
3352
3418
  return JSON.parse(decodeText(value), (_key, candidate) => {
3353
- if (candidate !== null
3354
- && typeof candidate === 'object'
3355
- && Object.keys(candidate).length === 1
3356
- && typeof candidate.$bigint === 'string') {
3419
+ if (
3420
+ candidate !== null &&
3421
+ typeof candidate === 'object' &&
3422
+ Object.keys(candidate).length === 1 &&
3423
+ typeof candidate.$bigint === 'string'
3424
+ ) {
3357
3425
  return BigInt(candidate.$bigint);
3358
3426
  }
3359
- if (candidate !== null
3360
- && typeof candidate === 'object'
3361
- && Object.keys(candidate).length === 1
3362
- && typeof candidate.$bytes === 'string') {
3427
+ if (
3428
+ candidate !== null &&
3429
+ typeof candidate === 'object' &&
3430
+ Object.keys(candidate).length === 1 &&
3431
+ typeof candidate.$bytes === 'string'
3432
+ ) {
3363
3433
  return Buffer.from(candidate.$bytes, 'base64');
3364
3434
  }
3365
3435
  return candidate;
@@ -3367,8 +3437,11 @@ function decodeJson<T>(value: Uint8Array): T {
3367
3437
  }
3368
3438
 
3369
3439
  function requireRecordVersion(value: unknown, kind: string): void {
3370
- if (value === null || typeof value !== 'object'
3371
- || (value as { recordVersion?: unknown }).recordVersion !== 1) {
3440
+ if (
3441
+ value === null ||
3442
+ typeof value !== 'object' ||
3443
+ (value as { recordVersion?: unknown }).recordVersion !== 1
3444
+ ) {
3372
3445
  throw new Error(`Location Store ${kind} record has an unrecognized recordVersion.`);
3373
3446
  }
3374
3447
  }
@@ -3379,21 +3452,33 @@ function canonicalize(value: unknown): unknown {
3379
3452
  if (value instanceof Date) return value.toISOString();
3380
3453
  if (Array.isArray(value)) return value.map(canonicalize);
3381
3454
  if (value !== null && typeof value === 'object') {
3382
- return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, canonicalize(item)]));
3455
+ return Object.fromEntries(
3456
+ Object.entries(value).map(([key, item]) => [key, canonicalize(item)])
3457
+ );
3383
3458
  }
3384
3459
  return value;
3385
3460
  }
3386
3461
 
3387
3462
  function reviveCanonical(value: unknown, key = ''): unknown {
3388
3463
  const generationKeys = new Set([
3389
- 'generation', 'leaseGeneration', 'ownerLeaseGeneration', 'objectGeneration',
3390
- 'authorityOwnerGeneration', 'aggregateGeneration', 'lifecycleGeneration', 'descriptorRevision',
3391
- 'nodeGeneration', 'applicationVersion', 'requestEncodedSize'
3464
+ 'generation',
3465
+ 'leaseGeneration',
3466
+ 'ownerLeaseGeneration',
3467
+ 'objectGeneration',
3468
+ 'authorityOwnerGeneration',
3469
+ 'aggregateGeneration',
3470
+ 'lifecycleGeneration',
3471
+ 'descriptorRevision',
3472
+ 'nodeGeneration',
3473
+ 'applicationVersion',
3474
+ 'requestEncodedSize'
3392
3475
  ]);
3393
3476
  if (typeof value === 'string' && generationKeys.has(key)) return BigInt(value);
3394
- if (Array.isArray(value)) return value.map(item => reviveCanonical(item));
3477
+ if (Array.isArray(value)) return value.map((item) => reviveCanonical(item));
3395
3478
  if (value !== null && typeof value === 'object') {
3396
- return Object.fromEntries(Object.entries(value).map(([name, item]) => [name, reviveCanonical(item, name)]));
3479
+ return Object.fromEntries(
3480
+ Object.entries(value).map(([name, item]) => [name, reviveCanonical(item, name)])
3481
+ );
3397
3482
  }
3398
3483
  return value;
3399
3484
  }
@@ -3405,7 +3490,11 @@ function decodeOwnerRecord(bytes: Uint8Array): OwnerRecord {
3405
3490
  }
3406
3491
 
3407
3492
  function encodeOwnerRecord(ownerId: string, leaseGeneration: bigint): Uint8Array {
3408
- return encodeJson<OwnerRecord>({ recordVersion: 1, ownerId, leaseGeneration: leaseGeneration.toString() });
3493
+ return encodeJson<OwnerRecord>({
3494
+ recordVersion: 1,
3495
+ ownerId,
3496
+ leaseGeneration: leaseGeneration.toString()
3497
+ });
3409
3498
  }
3410
3499
 
3411
3500
  function encodeCanonicalDescriptorRecord<T extends OwnedDescriptor>(
@@ -3416,16 +3505,21 @@ function encodeCanonicalDescriptorRecord<T extends OwnedDescriptor>(
3416
3505
  // cmsgpack version is the interoperable row version, so it is deliberately
3417
3506
  // not serialized (21-location-runtime §2.4).
3418
3507
  void generation;
3419
- return Buffer.from(JSON.stringify({
3420
- recordVersion: 1,
3421
- ownerId: descriptor.ownerId,
3422
- leaseGeneration: descriptor.leaseGeneration.toString(),
3423
- descriptorRevision: descriptor.descriptorRevision.toString(),
3424
- descriptor: canonicalDescriptor(descriptor)
3425
- } satisfies CanonicalDescriptorRecord<unknown>), 'utf8');
3508
+ return Buffer.from(
3509
+ JSON.stringify({
3510
+ recordVersion: 1,
3511
+ ownerId: descriptor.ownerId,
3512
+ leaseGeneration: descriptor.leaseGeneration.toString(),
3513
+ descriptorRevision: descriptor.descriptorRevision.toString(),
3514
+ descriptor: canonicalDescriptor(descriptor)
3515
+ } satisfies CanonicalDescriptorRecord<unknown>),
3516
+ 'utf8'
3517
+ );
3426
3518
  }
3427
3519
 
3428
- function decodeCanonicalDescriptorRecord<T extends OwnedDescriptor>(bytes: Uint8Array): CanonicalDescriptorRecord<T> {
3520
+ function decodeCanonicalDescriptorRecord<T extends OwnedDescriptor>(
3521
+ bytes: Uint8Array
3522
+ ): CanonicalDescriptorRecord<T> {
3429
3523
  const record = JSON.parse(decodeText(bytes)) as CanonicalDescriptorRecord<unknown>;
3430
3524
  requireRecordVersion(record, 'descriptor');
3431
3525
  return reviveCanonical(record) as CanonicalDescriptorRecord<T>;
@@ -3440,19 +3534,20 @@ function descriptorStoreGeneration(
3440
3534
 
3441
3535
  function canonicalDescriptor(descriptor: OwnedDescriptor): Record<string, unknown> {
3442
3536
  if ('rid' in descriptor) return canonicalMeshDescriptor(descriptor);
3443
- if ('serverRid' in descriptor) return {
3444
- channelName: descriptor.channelName,
3445
- serverRoutingIdHex: encodeRoutingIdStorageHex(descriptor.serverRid),
3446
- lifecycleGeneration: descriptor.lifecycleGeneration.toString(),
3447
- descriptorRevision: descriptor.descriptorRevision.toString(),
3448
- endpoint: descriptor.endpoint,
3449
- weight: descriptor.weight,
3450
- state: canonicalRuntimeState(descriptor.state),
3451
- securityIdentity: descriptor.securityIdentity,
3452
- ownerId: descriptor.ownerId,
3453
- leaseGeneration: descriptor.leaseGeneration.toString(),
3454
- updatedAtEpochMs: descriptor.updatedAt.getTime().toString()
3455
- };
3537
+ if ('serverRid' in descriptor)
3538
+ return {
3539
+ channelName: descriptor.channelName,
3540
+ serverRoutingIdHex: encodeRoutingIdStorageHex(descriptor.serverRid),
3541
+ lifecycleGeneration: descriptor.lifecycleGeneration.toString(),
3542
+ descriptorRevision: descriptor.descriptorRevision.toString(),
3543
+ endpoint: descriptor.endpoint,
3544
+ weight: descriptor.weight,
3545
+ state: canonicalRuntimeState(descriptor.state),
3546
+ securityIdentity: descriptor.securityIdentity,
3547
+ ownerId: descriptor.ownerId,
3548
+ leaseGeneration: descriptor.leaseGeneration.toString(),
3549
+ updatedAtEpochMs: descriptor.updatedAt.getTime().toString()
3550
+ };
3456
3551
  const publisher = descriptor as ZLinkFanoutPublisherDescriptor;
3457
3552
  return {
3458
3553
  channelName: publisher.channelName,
@@ -3478,7 +3573,7 @@ function canonicalMeshDescriptor(descriptor: ZLinkMeshNodeDescriptor): Record<st
3478
3573
  entrySpotId: descriptor.entrySpotId ?? null,
3479
3574
  channelWeights: descriptor.channelWeights,
3480
3575
  applicationVersion: descriptor.applicationVersion.toString(),
3481
- objectCapabilities: descriptor.objectCapabilities.map(capability => ({
3576
+ objectCapabilities: descriptor.objectCapabilities.map((capability) => ({
3482
3577
  ...capability,
3483
3578
  objectKind: canonicalObjectKind(capability.objectKind),
3484
3579
  policy: capability.policy === 'disabled' ? 'disabled' : capability.policy
@@ -3488,7 +3583,7 @@ function canonicalMeshDescriptor(descriptor: ZLinkMeshNodeDescriptor): Record<st
3488
3583
  capacity: {
3489
3584
  actors: descriptor.populationCapacity.actors,
3490
3585
  spots: descriptor.populationCapacity.spots,
3491
- spotTypes: descriptor.populationCapacity.spotTypes.map(capacity => ({
3586
+ spotTypes: descriptor.populationCapacity.spotTypes.map((capacity) => ({
3492
3587
  ...capacity,
3493
3588
  objectKind: canonicalObjectKind(capacity.objectKind)
3494
3589
  }))
@@ -3503,19 +3598,23 @@ function canonicalMeshDescriptor(descriptor: ZLinkMeshNodeDescriptor): Record<st
3503
3598
  };
3504
3599
  }
3505
3600
 
3506
- function reviveCanonicalCapacity(value: Record<string, unknown>): ZLinkMeshNodeDescriptor['populationCapacity'] {
3601
+ function reviveCanonicalCapacity(
3602
+ value: Record<string, unknown>
3603
+ ): ZLinkMeshNodeDescriptor['populationCapacity'] {
3507
3604
  return {
3508
3605
  actors: value.actors as ZLinkMeshNodeDescriptor['populationCapacity']['actors'],
3509
3606
  spots: value.spots as ZLinkMeshNodeDescriptor['populationCapacity']['spots'],
3510
- spotTypes: (value.spotTypes as readonly Record<string, unknown>[]).map(capacity => ({
3607
+ spotTypes: (value.spotTypes as readonly Record<string, unknown>[]).map((capacity) => ({
3511
3608
  ...capacity,
3512
3609
  objectKind: runtimeSpotObjectKind(String(capacity.objectKind))
3513
3610
  })) as unknown as ZLinkMeshNodeDescriptor['populationCapacity']['spotTypes']
3514
3611
  };
3515
3612
  }
3516
3613
 
3517
- function reviveCanonicalCapabilities(value: unknown): ZLinkMeshNodeDescriptor['objectCapabilities'] {
3518
- return (value as readonly Record<string, unknown>[]).map(capability => ({
3614
+ function reviveCanonicalCapabilities(
3615
+ value: unknown
3616
+ ): ZLinkMeshNodeDescriptor['objectCapabilities'] {
3617
+ return (value as readonly Record<string, unknown>[]).map((capability) => ({
3519
3618
  ...capability,
3520
3619
  objectKind: runtimeObjectKind(String(capability.objectKind))
3521
3620
  })) as unknown as ZLinkMeshNodeDescriptor['objectCapabilities'];
@@ -3534,17 +3633,30 @@ function runtimeObjectKind(kind: string): 'actor' | 'user_spot' | 'instance_spot
3534
3633
 
3535
3634
  function runtimeSpotObjectKind(kind: string): 'user_spot' | 'instance_spot' {
3536
3635
  const result = runtimeObjectKind(kind);
3537
- if (result === 'actor') throw new TypeError('Location Store spot capacity cannot have actor objectKind.');
3636
+ if (result === 'actor')
3637
+ throw new TypeError('Location Store spot capacity cannot have actor objectKind.');
3538
3638
  return result;
3539
3639
  }
3540
3640
 
3541
3641
  function canonicalRuntimeState(state: ZLinkFrameworkRuntimeState): string {
3542
- return ['preparing', 'serving', 'relocating', 'relocated', 'draining', 'stopped', 'error'][state]
3543
- ?? (() => { throw new TypeError(`Location Store descriptor has invalid state '${state}'.`); })();
3642
+ return (
3643
+ ['preparing', 'serving', 'relocating', 'relocated', 'draining', 'stopped', 'error'][state] ??
3644
+ (() => {
3645
+ throw new TypeError(`Location Store descriptor has invalid state '${state}'.`);
3646
+ })()
3647
+ );
3544
3648
  }
3545
3649
 
3546
3650
  function runtimeState(state: string): ZLinkFrameworkRuntimeState {
3547
- const index = ['preparing', 'serving', 'relocating', 'relocated', 'draining', 'stopped', 'error'].indexOf(state);
3651
+ const index = [
3652
+ 'preparing',
3653
+ 'serving',
3654
+ 'relocating',
3655
+ 'relocated',
3656
+ 'draining',
3657
+ 'stopped',
3658
+ 'error'
3659
+ ].indexOf(state);
3548
3660
  if (index < 0) throw new TypeError(`Location Store descriptor has invalid state '${state}'.`);
3549
3661
  return index as ZLinkFrameworkRuntimeState;
3550
3662
  }
@@ -3570,19 +3682,23 @@ function encodeAuthorityRecord(record: AuthorityRecord): Uint8Array {
3570
3682
  descriptorLifecycleGeneration: allocation.descriptorLifecycleGeneration.toString(),
3571
3683
  capacity: canonicalAuthorityCapacity(allocation.capacity)
3572
3684
  },
3573
- pendingCreation: snapshot.pendingCreation === undefined ? null : {
3574
- reservationId: snapshot.pendingCreation.reservationId,
3575
- requestContentReference: snapshot.pendingCreation.requestContentReference,
3576
- requestSha256: Buffer.from(snapshot.pendingCreation.requestSha256).toString('hex'),
3577
- requestEncodedSize: Number(snapshot.pendingCreation.requestEncodedSize)
3578
- }
3685
+ pendingCreation:
3686
+ snapshot.pendingCreation === undefined
3687
+ ? null
3688
+ : {
3689
+ reservationId: snapshot.pendingCreation.reservationId,
3690
+ requestContentReference: snapshot.pendingCreation.requestContentReference,
3691
+ requestSha256: Buffer.from(snapshot.pendingCreation.requestSha256).toString('hex'),
3692
+ requestEncodedSize: Number(snapshot.pendingCreation.requestEncodedSize)
3693
+ }
3579
3694
  };
3580
3695
  // These fields gate Node-only creation/aggregate recovery. They are absent
3581
3696
  // from normal authority values (including the golden vector), while the
3582
3697
  // interoperable envelope above remains byte-canonical.
3583
3698
  if (record.terminal !== undefined) envelope.terminal = record.terminal;
3584
3699
  if (record.aggregate !== undefined) envelope.aggregate = canonicalize(record.aggregate);
3585
- if (record.visibleStoreVersion !== undefined) envelope.visibleStoreVersion = record.visibleStoreVersion;
3700
+ if (record.visibleStoreVersion !== undefined)
3701
+ envelope.visibleStoreVersion = record.visibleStoreVersion;
3586
3702
  return Buffer.from(JSON.stringify(envelope), 'utf8');
3587
3703
  }
3588
3704
 
@@ -3596,11 +3712,12 @@ function decodeAuthorityRecord(bytes: Uint8Array): AuthorityRecord {
3596
3712
  const objectKind = runtimePlacementObjectKind(String(allocation.objectKind));
3597
3713
  return {
3598
3714
  terminal: value.terminal as AuthorityRecord['terminal'],
3599
- aggregate: value.aggregate === undefined
3600
- ? undefined
3601
- : reviveCanonical(value.aggregate) as AggregateParticipantFenceRecord,
3602
- visibleStoreVersion: typeof value.visibleStoreVersion === 'string'
3603
- ? value.visibleStoreVersion : undefined,
3715
+ aggregate:
3716
+ value.aggregate === undefined
3717
+ ? undefined
3718
+ : (reviveCanonical(value.aggregate) as AggregateParticipantFenceRecord),
3719
+ visibleStoreVersion:
3720
+ typeof value.visibleStoreVersion === 'string' ? value.visibleStoreVersion : undefined,
3604
3721
  snapshot: {
3605
3722
  payload: Buffer.from(String(value.payload), 'base64'),
3606
3723
  objectGeneration: BigInt(String(value.objectGeneration)),
@@ -3613,44 +3730,52 @@ function decodeAuthorityRecord(bytes: Uint8Array): AuthorityRecord {
3613
3730
  stableType: String(allocation.stableType),
3614
3731
  descriptor: {
3615
3732
  meshName: String(descriptor.meshName),
3616
- rid: decodeRoutingId(
3617
- String(descriptor.routingIdHex),
3618
- descriptor.routingIdHex
3619
- )
3733
+ rid: decodeRoutingId(String(descriptor.routingIdHex), descriptor.routingIdHex)
3620
3734
  },
3621
3735
  descriptorLifecycleGeneration: BigInt(String(allocation.descriptorLifecycleGeneration)),
3622
3736
  capacity: {
3623
3737
  actors: Number(capacity.actors),
3624
3738
  spots: Number(capacity.spots),
3625
- spotType: capacity.spotType === null
3626
- ? undefined
3627
- : decodeAuthoritySpotType(capacity.spotType)
3739
+ spotType:
3740
+ capacity.spotType === null ? undefined : decodeAuthoritySpotType(capacity.spotType)
3628
3741
  }
3629
3742
  },
3630
- pendingCreation: pending === null ? undefined : {
3631
- reservationId: String(pending.reservationId),
3632
- requestContentReference: String(pending.requestContentReference),
3633
- requestSha256: Buffer.from(String(pending.requestSha256), 'hex'),
3634
- requestEncodedSize: BigInt(String(pending.requestEncodedSize))
3635
- }
3743
+ pendingCreation:
3744
+ pending === null
3745
+ ? undefined
3746
+ : {
3747
+ reservationId: String(pending.reservationId),
3748
+ requestContentReference: String(pending.requestContentReference),
3749
+ requestSha256: Buffer.from(String(pending.requestSha256), 'hex'),
3750
+ requestEncodedSize: BigInt(String(pending.requestEncodedSize))
3751
+ }
3636
3752
  }
3637
3753
  };
3638
3754
  }
3639
3755
 
3640
3756
  function canonicalPlacementObjectKind(kind: ZLinkPlacementAllocation['objectKind']): string {
3641
3757
  switch (kind) {
3642
- case 'actor': return 'actor';
3643
- case 'user_spot': return 'userSpot';
3644
- case 'instance_spot': return 'instanceSpot';
3758
+ case 'actor':
3759
+ return 'actor';
3760
+ case 'user_spot':
3761
+ return 'userSpot';
3762
+ case 'instance_spot':
3763
+ return 'instanceSpot';
3645
3764
  }
3646
3765
  }
3647
3766
 
3648
3767
  function runtimePlacementObjectKind(kind: string): ZLinkPlacementAllocation['objectKind'] {
3649
3768
  switch (kind) {
3650
- case 'actor': return 'actor';
3651
- case 'userSpot': return 'user_spot';
3652
- case 'instanceSpot': return 'instance_spot';
3653
- default: throw new Error(`Location Store authority record has an invalid allocation objectKind '${kind}'.`);
3769
+ case 'actor':
3770
+ return 'actor';
3771
+ case 'userSpot':
3772
+ return 'user_spot';
3773
+ case 'instanceSpot':
3774
+ return 'instance_spot';
3775
+ default:
3776
+ throw new Error(
3777
+ `Location Store authority record has an invalid allocation objectKind '${kind}'.`
3778
+ );
3654
3779
  }
3655
3780
  }
3656
3781
 
@@ -3658,13 +3783,14 @@ function canonicalAuthorityCapacity(capacity: ZLinkCapacityVector): Record<strin
3658
3783
  return {
3659
3784
  actors: capacity.actors,
3660
3785
  spots: capacity.spots,
3661
- spotType: capacity.spotType === undefined
3662
- ? null
3663
- : {
3664
- objectKind: canonicalPlacementObjectKind(capacity.spotType.objectKind),
3665
- stableType: capacity.spotType.stableType,
3666
- count: capacity.spotType.count
3667
- }
3786
+ spotType:
3787
+ capacity.spotType === undefined
3788
+ ? null
3789
+ : {
3790
+ objectKind: canonicalPlacementObjectKind(capacity.spotType.objectKind),
3791
+ stableType: capacity.spotType.stableType,
3792
+ count: capacity.spotType.count
3793
+ }
3668
3794
  };
3669
3795
  }
3670
3796
 
@@ -3699,9 +3825,9 @@ function createTerminalRecord(
3699
3825
  const deadlineMs = publication.operationDeadline.getTime();
3700
3826
  const expiresAtMs = deadlineMs + CREATION_TERMINAL_RETENTION_MS;
3701
3827
  if (
3702
- !Number.isSafeInteger(deadlineMs)
3703
- || !Number.isSafeInteger(expiresAtMs)
3704
- || expiresAtMs <= now.getTime()
3828
+ !Number.isSafeInteger(deadlineMs) ||
3829
+ !Number.isSafeInteger(expiresAtMs) ||
3830
+ expiresAtMs <= now.getTime()
3705
3831
  ) {
3706
3832
  throw new RangeError(
3707
3833
  'Creation terminal expiry must be the live operation deadline plus five minutes.'
@@ -3752,13 +3878,13 @@ function validateCreationOperation(operation: ZLinkCreationOperationIdentity): v
3752
3878
  );
3753
3879
  }
3754
3880
  if (
3755
- operation.sourceNodeGeneration < 1n
3756
- || operation.sourceNodeGeneration > MAX_U64
3757
- || operation.operationId.high < 0n
3758
- || operation.operationId.high > MAX_U64
3759
- || operation.operationId.low < 0n
3760
- || operation.operationId.low > MAX_U64
3761
- || (operation.operationId.high === 0n && operation.operationId.low === 0n)
3881
+ operation.sourceNodeGeneration < 1n ||
3882
+ operation.sourceNodeGeneration > MAX_U64 ||
3883
+ operation.operationId.high < 0n ||
3884
+ operation.operationId.high > MAX_U64 ||
3885
+ operation.operationId.low < 0n ||
3886
+ operation.operationId.low > MAX_U64 ||
3887
+ (operation.operationId.high === 0n && operation.operationId.low === 0n)
3762
3888
  ) {
3763
3889
  throw new RangeError('Creation terminal source generation and operation ID are invalid.');
3764
3890
  }
@@ -3786,12 +3912,13 @@ function authoritySnapshot(
3786
3912
  kind: 'snapshot',
3787
3913
  ...snapshot,
3788
3914
  payload: Buffer.from(snapshot.payload),
3789
- pendingCreation: snapshot.pendingCreation === undefined
3790
- ? undefined
3791
- : {
3792
- ...snapshot.pendingCreation,
3793
- requestSha256: Buffer.from(snapshot.pendingCreation.requestSha256)
3794
- },
3915
+ pendingCreation:
3916
+ snapshot.pendingCreation === undefined
3917
+ ? undefined
3918
+ : {
3919
+ ...snapshot.pendingCreation,
3920
+ requestSha256: Buffer.from(snapshot.pendingCreation.requestSha256)
3921
+ },
3795
3922
  storeVersion: { value: storeVersion.value } as ZLinkAuthorityStoreVersion,
3796
3923
  storeNow
3797
3924
  };
@@ -3812,34 +3939,28 @@ function liveTargetDescriptor(
3812
3939
  decodeCanonicalDescriptorRecord<ZLinkMeshNodeDescriptor>(descriptorRead.value.bytes).descriptor
3813
3940
  );
3814
3941
  const lease = decodeOwnerRecord(leaseRead.value.bytes);
3815
- return descriptor.meshName === target.meshName
3816
- && String(descriptor.rid) === String(target.nodeRid)
3817
- && descriptor.lifecycleGeneration === target.nodeLifecycleGeneration
3818
- && descriptor.ownerId === target.owner.ownerId
3819
- && descriptor.leaseGeneration === target.owner.leaseGeneration
3820
- && descriptor.objectRole === ZLinkObjectRole.Server
3821
- && descriptor.state === ZLinkFrameworkRuntimeState.Serving
3822
- && lease.ownerId === target.owner.ownerId
3823
- && BigInt(lease.leaseGeneration) === target.owner.leaseGeneration
3824
- && leaseRead.value.expiresAt !== undefined
3825
- && leaseRead.value.expiresAt.getTime() > leaseRead.value.storeNow.getTime()
3826
- ? descriptor
3827
- : undefined;
3828
- }
3829
-
3830
- function conditionFor(
3831
- key: ZLinkStoreKey,
3832
- read: ZLinkStoreReadResult
3833
- ): ZLinkStoreCondition {
3942
+ return descriptor.meshName === target.meshName &&
3943
+ String(descriptor.rid) === String(target.nodeRid) &&
3944
+ descriptor.lifecycleGeneration === target.nodeLifecycleGeneration &&
3945
+ descriptor.ownerId === target.owner.ownerId &&
3946
+ descriptor.leaseGeneration === target.owner.leaseGeneration &&
3947
+ descriptor.objectRole === ZLinkObjectRole.Server &&
3948
+ descriptor.state === ZLinkFrameworkRuntimeState.Serving &&
3949
+ lease.ownerId === target.owner.ownerId &&
3950
+ BigInt(lease.leaseGeneration) === target.owner.leaseGeneration &&
3951
+ leaseRead.value.expiresAt !== undefined &&
3952
+ leaseRead.value.expiresAt.getTime() > leaseRead.value.storeNow.getTime()
3953
+ ? descriptor
3954
+ : undefined;
3955
+ }
3956
+
3957
+ function conditionFor(key: ZLinkStoreKey, read: ZLinkStoreReadResult): ZLinkStoreCondition {
3834
3958
  return read.kind === 'missing'
3835
3959
  ? { kind: 'missing', key }
3836
3960
  : { kind: 'version', key, expected: read.value.version };
3837
3961
  }
3838
3962
 
3839
- function versionCondition(
3840
- key: ZLinkStoreKey,
3841
- read: ZLinkStoreReadResult
3842
- ): ZLinkStoreCondition {
3963
+ function versionCondition(key: ZLinkStoreKey, read: ZLinkStoreReadResult): ZLinkStoreCondition {
3843
3964
  if (read.kind === 'missing') {
3844
3965
  throw new Error(`Required provider row '${key}' is missing.`);
3845
3966
  }
@@ -3859,24 +3980,30 @@ function capacityAvailable(
3859
3980
  capacity: CapacityRecord
3860
3981
  ): boolean {
3861
3982
  const spotType = requested.spotType;
3862
- const typeCapacity = spotType === undefined
3863
- ? undefined
3864
- : descriptor.populationCapacity.spotTypes.find(candidate =>
3865
- candidate.objectKind === spotType.objectKind
3866
- && candidate.stableType === spotType.stableType);
3983
+ const typeCapacity =
3984
+ spotType === undefined
3985
+ ? undefined
3986
+ : descriptor.populationCapacity.spotTypes.find(
3987
+ (candidate) =>
3988
+ candidate.objectKind === spotType.objectKind &&
3989
+ candidate.stableType === spotType.stableType
3990
+ );
3867
3991
  const typeKey = spotType === undefined ? undefined : capacityTypeKey(spotType);
3868
- return (descriptor.populationCapacity.actors.limit === 0
3869
- || capacity.active.actors + capacity.pending.actors + requested.actors
3870
- <= descriptor.populationCapacity.actors.limit)
3871
- && (descriptor.populationCapacity.spots.limit === 0
3872
- || capacity.active.spots + capacity.pending.spots + requested.spots
3873
- <= descriptor.populationCapacity.spots.limit)
3874
- && (spotType === undefined
3875
- || typeCapacity !== undefined
3876
- && (typeCapacity.limit === 0
3877
- || (capacity.active.spotTypes[typeKey!] ?? 0)
3878
- + (capacity.pending.spotTypes[typeKey!] ?? 0)
3879
- + spotType.count <= typeCapacity.limit));
3992
+ return (
3993
+ (descriptor.populationCapacity.actors.limit === 0 ||
3994
+ capacity.active.actors + capacity.pending.actors + requested.actors <=
3995
+ descriptor.populationCapacity.actors.limit) &&
3996
+ (descriptor.populationCapacity.spots.limit === 0 ||
3997
+ capacity.active.spots + capacity.pending.spots + requested.spots <=
3998
+ descriptor.populationCapacity.spots.limit) &&
3999
+ (spotType === undefined ||
4000
+ (typeCapacity !== undefined &&
4001
+ (typeCapacity.limit === 0 ||
4002
+ (capacity.active.spotTypes[typeKey!] ?? 0) +
4003
+ (capacity.pending.spotTypes[typeKey!] ?? 0) +
4004
+ spotType.count <=
4005
+ typeCapacity.limit)))
4006
+ );
3880
4007
  }
3881
4008
 
3882
4009
  function addCapacity(usage: CapacityUsage, delta: ZLinkCapacityVector): CapacityUsage {
@@ -3906,9 +4033,7 @@ function adjustCapacity(
3906
4033
  return { actors, spots, spotTypes };
3907
4034
  }
3908
4035
 
3909
- function capacityTypeKey(
3910
- value: NonNullable<ZLinkCapacityVector['spotType']>
3911
- ): string {
4036
+ function capacityTypeKey(value: NonNullable<ZLinkCapacityVector['spotType']>): string {
3912
4037
  return `${value.objectKind}\0${value.stableType}`;
3913
4038
  }
3914
4039
 
@@ -3921,46 +4046,42 @@ function cloneCapacity(value: ZLinkCapacityVector): ZLinkCapacityVector {
3921
4046
  }
3922
4047
 
3923
4048
  function sameCapacityVector(left: ZLinkCapacityVector, right: ZLinkCapacityVector): boolean {
3924
- return left.actors === right.actors
3925
- && left.spots === right.spots
3926
- && left.spotType?.objectKind === right.spotType?.objectKind
3927
- && left.spotType?.stableType === right.spotType?.stableType
3928
- && left.spotType?.count === right.spotType?.count;
4049
+ return (
4050
+ left.actors === right.actors &&
4051
+ left.spots === right.spots &&
4052
+ left.spotType?.objectKind === right.spotType?.objectKind &&
4053
+ left.spotType?.stableType === right.spotType?.stableType &&
4054
+ left.spotType?.count === right.spotType?.count
4055
+ );
3929
4056
  }
3930
4057
 
3931
4058
  function sameCreationTarget(
3932
4059
  snapshot: StoredAuthoritySnapshot,
3933
4060
  target: ZLinkObjectCommitRequest['target']
3934
4061
  ): boolean {
3935
- return snapshot.allocation.descriptor.meshName === target.meshName
3936
- && String(snapshot.allocation.descriptor.rid) === String(target.nodeRid)
3937
- && snapshot.allocation.descriptorLifecycleGeneration
3938
- === target.nodeLifecycleGeneration
3939
- && snapshot.ownerId === target.owner.ownerId
3940
- && snapshot.ownerLeaseGeneration === target.owner.leaseGeneration;
4062
+ return (
4063
+ snapshot.allocation.descriptor.meshName === target.meshName &&
4064
+ String(snapshot.allocation.descriptor.rid) === String(target.nodeRid) &&
4065
+ snapshot.allocation.descriptorLifecycleGeneration === target.nodeLifecycleGeneration &&
4066
+ snapshot.ownerId === target.owner.ownerId &&
4067
+ snapshot.ownerLeaseGeneration === target.owner.leaseGeneration
4068
+ );
3941
4069
  }
3942
4070
 
3943
4071
  const CANONICAL_AUTHORITY_MAGIC = Buffer.from('ZLAU');
3944
4072
 
3945
4073
  function isCanonicalAuthorityPayload(payload: Uint8Array): boolean {
3946
- return payload.byteLength >= CANONICAL_AUTHORITY_MAGIC.byteLength
3947
- && Buffer.from(
3948
- payload.buffer,
3949
- payload.byteOffset,
3950
- CANONICAL_AUTHORITY_MAGIC.byteLength
3951
- ).equals(CANONICAL_AUTHORITY_MAGIC);
4074
+ return (
4075
+ payload.byteLength >= CANONICAL_AUTHORITY_MAGIC.byteLength &&
4076
+ Buffer.from(payload.buffer, payload.byteOffset, CANONICAL_AUTHORITY_MAGIC.byteLength).equals(
4077
+ CANONICAL_AUTHORITY_MAGIC
4078
+ )
4079
+ );
3952
4080
  }
3953
4081
 
3954
- function sameLiveOwner(
3955
- lease: ZLinkStoreReadResult,
3956
- snapshot: StoredAuthoritySnapshot
3957
- ): boolean {
4082
+ function sameLiveOwner(lease: ZLinkStoreReadResult, snapshot: StoredAuthoritySnapshot): boolean {
3958
4083
  if (lease.kind === 'missing') return false;
3959
- return matchesLiveOwnerLease(
3960
- lease,
3961
- snapshot.ownerId,
3962
- snapshot.ownerLeaseGeneration
3963
- );
4084
+ return matchesLiveOwnerLease(lease, snapshot.ownerId, snapshot.ownerLeaseGeneration);
3964
4085
  }
3965
4086
 
3966
4087
  function matchesLiveOwnerLease(
@@ -3968,13 +4089,14 @@ function matchesLiveOwnerLease(
3968
4089
  ownerId: string,
3969
4090
  leaseGeneration: bigint
3970
4091
  ): boolean {
3971
- if (lease.value.expiresAt === undefined
3972
- || lease.value.expiresAt.getTime() <= lease.value.storeNow.getTime()) {
4092
+ if (
4093
+ lease.value.expiresAt === undefined ||
4094
+ lease.value.expiresAt.getTime() <= lease.value.storeNow.getTime()
4095
+ ) {
3973
4096
  return false;
3974
4097
  }
3975
4098
  const owner = decodeOwnerRecord(lease.value.bytes);
3976
- return owner.ownerId === ownerId
3977
- && BigInt(owner.leaseGeneration) === leaseGeneration;
4099
+ return owner.ownerId === ownerId && BigInt(owner.leaseGeneration) === leaseGeneration;
3978
4100
  }
3979
4101
 
3980
4102
  function sameDescriptorPredecessor(
@@ -3987,12 +4109,12 @@ function sameDescriptorPredecessor(
3987
4109
  return Buffer.from(expected.value.bytes).equals(Buffer.from(current.value.bytes));
3988
4110
  }
3989
4111
 
3990
- function liveOwnerLeaseGeneration(
3991
- lease: ZLinkStoreReadResult
3992
- ): bigint | undefined {
3993
- if (lease.kind === 'missing'
3994
- || lease.value.expiresAt === undefined
3995
- || lease.value.expiresAt.getTime() <= lease.value.storeNow.getTime()) {
4112
+ function liveOwnerLeaseGeneration(lease: ZLinkStoreReadResult): bigint | undefined {
4113
+ if (
4114
+ lease.kind === 'missing' ||
4115
+ lease.value.expiresAt === undefined ||
4116
+ lease.value.expiresAt.getTime() <= lease.value.storeNow.getTime()
4117
+ ) {
3996
4118
  return undefined;
3997
4119
  }
3998
4120
  return BigInt(decodeOwnerRecord(lease.value.bytes).leaseGeneration);
@@ -4015,9 +4137,11 @@ function canTakeOverStoredLocation(
4015
4137
  return false;
4016
4138
  }
4017
4139
  if (liveLeaseGeneration === undefined) return true;
4018
- return currentOwnerId === nextOwnerId
4019
- && currentLeaseGeneration !== nextLeaseGeneration
4020
- && liveLeaseGeneration === nextLeaseGeneration;
4140
+ return (
4141
+ currentOwnerId === nextOwnerId &&
4142
+ currentLeaseGeneration !== nextLeaseGeneration &&
4143
+ liveLeaseGeneration === nextLeaseGeneration
4144
+ );
4021
4145
  }
4022
4146
 
4023
4147
  function persistMeshDescriptor(descriptor: ZLinkMeshNodeDescriptor): ZLinkMeshNodeDescriptor {
@@ -4035,15 +4159,18 @@ function reviveMeshDescriptor(descriptor: ZLinkMeshNodeDescriptor): ZLinkMeshNod
4035
4159
  descriptorRevision: BigInt(String(value.descriptorRevision)),
4036
4160
  endpoint: String(value.endpoint),
4037
4161
  objectRole: value.objectRole as ZLinkObjectRole,
4038
- entrySpotId: value.entrySpotId === null ? undefined : value.entrySpotId as string | undefined,
4162
+ entrySpotId:
4163
+ value.entrySpotId === null ? undefined : (value.entrySpotId as string | undefined),
4039
4164
  placementWeight: Number(value.placementWeight),
4040
4165
  populationCapacity: reviveCanonicalCapacity(capacity),
4041
- activationConcurrency: value.activationConcurrency as ZLinkMeshNodeDescriptor['activationConcurrency'],
4166
+ activationConcurrency:
4167
+ value.activationConcurrency as ZLinkMeshNodeDescriptor['activationConcurrency'],
4042
4168
  channelWeights: value.channelWeights as Readonly<Record<string, number>>,
4043
4169
  applicationVersion: BigInt(String(value.applicationVersion)),
4044
4170
  spotTypes: [],
4045
4171
  objectCapabilities: reviveCanonicalCapabilities(value.objectCapabilities),
4046
- maintenanceWave: value.maintenanceWave === null ? undefined : value.maintenanceWave as string | undefined,
4172
+ maintenanceWave:
4173
+ value.maintenanceWave === null ? undefined : (value.maintenanceWave as string | undefined),
4047
4174
  state: runtimeState(String(value.state)),
4048
4175
  securityIdentity: String(value.securityIdentity),
4049
4176
  ownerId: String(value.ownerId),
@@ -4054,9 +4181,8 @@ function reviveMeshDescriptor(descriptor: ZLinkMeshNodeDescriptor): ZLinkMeshNod
4054
4181
  return {
4055
4182
  ...descriptor,
4056
4183
  rid: descriptor.rid,
4057
- updatedAt: descriptor.updatedAt instanceof Date
4058
- ? descriptor.updatedAt
4059
- : new Date(descriptor.updatedAt)
4184
+ updatedAt:
4185
+ descriptor.updatedAt instanceof Date ? descriptor.updatedAt : new Date(descriptor.updatedAt)
4060
4186
  };
4061
4187
  }
4062
4188
 
@@ -4093,7 +4219,10 @@ function reviveFanoutDescriptor(
4093
4219
  if ('publisherRoutingIdHex' in value) {
4094
4220
  return {
4095
4221
  channelName: String(value.channelName),
4096
- publisherRid: decodeRoutingId(String(value.publisherRoutingIdHex), value.publisherRoutingIdHex),
4222
+ publisherRid: decodeRoutingId(
4223
+ String(value.publisherRoutingIdHex),
4224
+ value.publisherRoutingIdHex
4225
+ ),
4097
4226
  lifecycleGeneration: BigInt(String(value.lifecycleGeneration)),
4098
4227
  descriptorRevision: BigInt(String(value.descriptorRevision)),
4099
4228
  endpoint: String(value.endpoint),
@@ -4147,24 +4276,30 @@ function normalizeRoute(value: ZLinkRouteLocation): ZLinkRouteLocation {
4147
4276
  }
4148
4277
 
4149
4278
  function matchesSpot(value: ZLinkSpotLocation, filter: ZLinkSpotLocationFilter): boolean {
4150
- return (filter.meshName === undefined || value.meshName === filter.meshName)
4151
- && (filter.spotType === undefined || value.spotType === filter.spotType)
4152
- && (filter.nodeRid === undefined || String(value.ownerNodeRid) === String(filter.nodeRid))
4153
- && (filter.spotKind === undefined || value.spotKind === filter.spotKind);
4279
+ return (
4280
+ (filter.meshName === undefined || value.meshName === filter.meshName) &&
4281
+ (filter.spotType === undefined || value.spotType === filter.spotType) &&
4282
+ (filter.nodeRid === undefined || String(value.ownerNodeRid) === String(filter.nodeRid)) &&
4283
+ (filter.spotKind === undefined || value.spotKind === filter.spotKind)
4284
+ );
4154
4285
  }
4155
4286
 
4156
4287
  function matchesActor(value: ZLinkActorLocation, filter: ZLinkActorLocationFilter): boolean {
4157
- return (filter.actorType === undefined || value.actorType === filter.actorType)
4158
- && (filter.nodeRid === undefined || String(value.ownerNodeRid) === String(filter.nodeRid))
4159
- && (filter.spotId === undefined || String(value.spotId) === String(filter.spotId))
4160
- && (filter.locationKind === undefined || value.spotKind === filter.locationKind);
4288
+ return (
4289
+ (filter.actorType === undefined || value.actorType === filter.actorType) &&
4290
+ (filter.nodeRid === undefined || String(value.ownerNodeRid) === String(filter.nodeRid)) &&
4291
+ (filter.spotId === undefined || String(value.spotId) === String(filter.spotId)) &&
4292
+ (filter.locationKind === undefined || value.spotKind === filter.locationKind)
4293
+ );
4161
4294
  }
4162
4295
 
4163
4296
  function matchesRoute(value: ZLinkRouteLocation, filter: ZLinkRouteLocationFilter): boolean {
4164
- return (filter.routeKind === undefined || value.routeKind === filter.routeKind)
4165
- && (filter.ownerNodeRid === undefined
4166
- || String(value.ownerNodeRid) === String(filter.ownerNodeRid))
4167
- && (filter.ownerId === undefined || value.ownerId === filter.ownerId);
4297
+ return (
4298
+ (filter.routeKind === undefined || value.routeKind === filter.routeKind) &&
4299
+ (filter.ownerNodeRid === undefined ||
4300
+ String(value.ownerNodeRid) === String(filter.ownerNodeRid)) &&
4301
+ (filter.ownerId === undefined || value.ownerId === filter.ownerId)
4302
+ );
4168
4303
  }
4169
4304
 
4170
4305
  function locationOwnerGeneration(value: LeaseOwnedLocation): bigint {
@@ -4178,9 +4313,7 @@ function descriptorOwnerLeaseGeneration(value: OwnedStoreRecord): bigint | undef
4178
4313
  : BigInt(value.leaseGeneration);
4179
4314
  }
4180
4315
  if ('generation' in value) {
4181
- return typeof value.generation === 'bigint'
4182
- ? value.generation
4183
- : BigInt(value.generation);
4316
+ return typeof value.generation === 'bigint' ? value.generation : BigInt(value.generation);
4184
4317
  }
4185
4318
  return undefined;
4186
4319
  }
@@ -4190,7 +4323,8 @@ function sameMeshDescriptor(
4190
4323
  right: ZLinkMeshNodeDescriptor
4191
4324
  ): boolean {
4192
4325
  return Buffer.from(encodeJson(persistMeshDescriptor(left))).equals(
4193
- Buffer.from(encodeJson(persistMeshDescriptor(right))));
4326
+ Buffer.from(encodeJson(persistMeshDescriptor(right)))
4327
+ );
4194
4328
  }
4195
4329
 
4196
4330
  function sameClientServerDescriptor(
@@ -4207,44 +4341,43 @@ function sameFanoutDescriptor(
4207
4341
  return descriptorFingerprint(left, ['updatedAt']) === descriptorFingerprint(right, ['updatedAt']);
4208
4342
  }
4209
4343
 
4210
- function canRenewMesh(
4211
- current: ZLinkMeshNodeDescriptor,
4212
- next: ZLinkMeshNodeDescriptor
4213
- ): boolean {
4214
- return sameOwnerGeneration(current, next)
4215
- && next.descriptorRevision > current.descriptorRevision;
4344
+ function canRenewMesh(current: ZLinkMeshNodeDescriptor, next: ZLinkMeshNodeDescriptor): boolean {
4345
+ return sameOwnerGeneration(current, next) && next.descriptorRevision > current.descriptorRevision;
4216
4346
  }
4217
4347
 
4218
4348
  function canRenewClientServer(
4219
4349
  current: ZLinkClientServerServerDescriptor,
4220
4350
  next: ZLinkClientServerServerDescriptor
4221
4351
  ): boolean {
4222
- return sameOwnerGeneration(current, next)
4223
- && next.descriptorRevision > current.descriptorRevision
4224
- && descriptorFingerprint(current, ['descriptorRevision', 'weight', 'state', 'updatedAt'])
4225
- === descriptorFingerprint(next, ['descriptorRevision', 'weight', 'state', 'updatedAt']);
4352
+ return (
4353
+ sameOwnerGeneration(current, next) &&
4354
+ next.descriptorRevision > current.descriptorRevision &&
4355
+ descriptorFingerprint(current, ['descriptorRevision', 'weight', 'state', 'updatedAt']) ===
4356
+ descriptorFingerprint(next, ['descriptorRevision', 'weight', 'state', 'updatedAt'])
4357
+ );
4226
4358
  }
4227
4359
 
4228
4360
  function canRenewFanout(
4229
4361
  current: ZLinkFanoutPublisherDescriptor,
4230
4362
  next: ZLinkFanoutPublisherDescriptor
4231
4363
  ): boolean {
4232
- return sameOwnerGeneration(current, next)
4233
- && next.descriptorRevision > current.descriptorRevision
4234
- && descriptorFingerprint(current, ['descriptorRevision', 'state', 'updatedAt'])
4235
- === descriptorFingerprint(next, ['descriptorRevision', 'state', 'updatedAt']);
4364
+ return (
4365
+ sameOwnerGeneration(current, next) &&
4366
+ next.descriptorRevision > current.descriptorRevision &&
4367
+ descriptorFingerprint(current, ['descriptorRevision', 'state', 'updatedAt']) ===
4368
+ descriptorFingerprint(next, ['descriptorRevision', 'state', 'updatedAt'])
4369
+ );
4236
4370
  }
4237
4371
 
4238
4372
  function sameOwnerGeneration(left: OwnedDescriptor, right: OwnedDescriptor): boolean {
4239
- return left.ownerId === right.ownerId
4240
- && left.leaseGeneration === right.leaseGeneration
4241
- && left.lifecycleGeneration === right.lifecycleGeneration;
4373
+ return (
4374
+ left.ownerId === right.ownerId &&
4375
+ left.leaseGeneration === right.leaseGeneration &&
4376
+ left.lifecycleGeneration === right.lifecycleGeneration
4377
+ );
4242
4378
  }
4243
4379
 
4244
- function descriptorFingerprint(
4245
- descriptor: OwnedDescriptor,
4246
- omitted: readonly string[]
4247
- ): string {
4380
+ function descriptorFingerprint(descriptor: OwnedDescriptor, omitted: readonly string[]): string {
4248
4381
  // Descriptor rows are canonicalized through routing-id hex. Comparing the
4249
4382
  // in-memory shape here would distinguish a binding RoutingId instance from
4250
4383
  // the equivalent ID revived from a canonical row, incorrectly rejecting a
@@ -4257,13 +4390,16 @@ function descriptorFingerprint(
4257
4390
  }
4258
4391
 
4259
4392
  function validateClientServerDescriptor(descriptor: ZLinkClientServerServerDescriptor): void {
4260
- validateDescriptorIdentity([
4261
- descriptor.channelName,
4262
- String(descriptor.serverRid),
4263
- descriptor.endpoint,
4264
- descriptor.securityIdentity,
4265
- descriptor.ownerId
4266
- ], 'ClientServer');
4393
+ validateDescriptorIdentity(
4394
+ [
4395
+ descriptor.channelName,
4396
+ String(descriptor.serverRid),
4397
+ descriptor.endpoint,
4398
+ descriptor.securityIdentity,
4399
+ descriptor.ownerId
4400
+ ],
4401
+ 'ClientServer'
4402
+ );
4267
4403
  validateDescriptorGenerations(descriptor, 'ClientServer');
4268
4404
  if (!Number.isInteger(descriptor.weight) || descriptor.weight < 0 || descriptor.weight > 10_000) {
4269
4405
  throw new RangeError('ClientServer descriptor weight must be an integer in 0..10000.');
@@ -4271,26 +4407,34 @@ function validateClientServerDescriptor(descriptor: ZLinkClientServerServerDescr
4271
4407
  }
4272
4408
 
4273
4409
  function validateFanoutPublisherDescriptor(descriptor: ZLinkFanoutPublisherDescriptor): void {
4274
- validateDescriptorIdentity([
4275
- descriptor.channelName,
4276
- String(descriptor.publisherRid),
4277
- descriptor.endpoint,
4278
- descriptor.securityIdentity,
4279
- descriptor.ownerId
4280
- ], 'Fanout publisher');
4410
+ validateDescriptorIdentity(
4411
+ [
4412
+ descriptor.channelName,
4413
+ String(descriptor.publisherRid),
4414
+ descriptor.endpoint,
4415
+ descriptor.securityIdentity,
4416
+ descriptor.ownerId
4417
+ ],
4418
+ 'Fanout publisher'
4419
+ );
4281
4420
  validateDescriptorGenerations(descriptor, 'Fanout publisher');
4282
4421
  }
4283
4422
 
4284
4423
  function validateDescriptorIdentity(values: readonly string[], kind: string): void {
4285
- if (values.some(value => Buffer.byteLength(value, 'utf8') < 1 || value.includes('\0'))) {
4424
+ if (values.some((value) => Buffer.byteLength(value, 'utf8') < 1 || value.includes('\0'))) {
4286
4425
  throw new TypeError(`${kind} descriptor identity and endpoint are required.`);
4287
4426
  }
4288
4427
  }
4289
4428
 
4290
4429
  function validateDescriptorGenerations(descriptor: OwnedDescriptor, kind: string): void {
4291
- if (descriptor.lifecycleGeneration < 1n || descriptor.lifecycleGeneration > MAX_GENERATION
4292
- || descriptor.descriptorRevision < 1n || descriptor.descriptorRevision > MAX_GENERATION
4293
- || descriptor.leaseGeneration < 1n || descriptor.leaseGeneration > MAX_GENERATION) {
4430
+ if (
4431
+ descriptor.lifecycleGeneration < 1n ||
4432
+ descriptor.lifecycleGeneration > MAX_GENERATION ||
4433
+ descriptor.descriptorRevision < 1n ||
4434
+ descriptor.descriptorRevision > MAX_GENERATION ||
4435
+ descriptor.leaseGeneration < 1n ||
4436
+ descriptor.leaseGeneration > MAX_GENERATION
4437
+ ) {
4294
4438
  throw new RangeError(`${kind} descriptor generations are invalid.`);
4295
4439
  }
4296
4440
  }