@zlink-systems/framework 0.30.1 → 0.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
  3. package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
  4. package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
  5. package/dist/contracts/Common/encoded-payload-storage.js +5 -2
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -1
  7. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
  8. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
  9. package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
  10. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  11. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
  12. package/dist/contracts/Locations/Rows.d.ts +2 -0
  13. package/dist/contracts/Spots/Contracts.d.ts +4 -0
  14. package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
  15. package/dist/runtime/abort.d.ts +5 -0
  16. package/dist/runtime/abort.js +10 -0
  17. package/dist/runtime/actors/actor-authority-publication.js +3 -2
  18. package/dist/runtime/actors/actor-client.d.ts +0 -1
  19. package/dist/runtime/actors/actor-client.js +38 -45
  20. package/dist/runtime/actors/actor-context.d.ts +2 -0
  21. package/dist/runtime/actors/actor-context.js +46 -9
  22. package/dist/runtime/actors/actor-handoff.d.ts +7 -3
  23. package/dist/runtime/actors/actor-handoff.js +212 -88
  24. package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
  25. package/dist/runtime/actors/actor-local-native-join.js +4 -0
  26. package/dist/runtime/actors/actor-mailbox.js +27 -1
  27. package/dist/runtime/actors/actor-remote-joiner.js +3 -1
  28. package/dist/runtime/actors/actor-reply.d.ts +4 -0
  29. package/dist/runtime/actors/actor-reply.js +29 -0
  30. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
  31. package/dist/runtime/actors/actor-runtime-state.js +2 -20
  32. package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
  33. package/dist/runtime/actors/index.d.ts +6 -2
  34. package/dist/runtime/actors/index.js +37 -21
  35. package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
  36. package/dist/runtime/actors/session-disconnected-wire.js +48 -0
  37. package/dist/runtime/admission.d.ts +9 -1
  38. package/dist/runtime/admission.js +55 -32
  39. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
  40. package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
  41. package/dist/runtime/application-jobs/contracts.d.ts +2 -0
  42. package/dist/runtime/backend/contracts/index.d.ts +19 -3
  43. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
  44. package/dist/runtime/backend/mesh-completion-table.js +5 -0
  45. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
  46. package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
  47. package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
  48. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
  49. package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
  50. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
  51. package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
  52. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  53. package/dist/runtime/channels/channel-clients.js +20 -5
  54. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
  55. package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
  56. package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
  57. package/dist/runtime/channels/channel-dispatchers.js +44 -37
  58. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  59. package/dist/runtime/channels/channel-envelope.js +74 -31
  60. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
  61. package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
  62. package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
  63. package/dist/runtime/channels/channel-runtime-manager.js +4 -4
  64. package/dist/runtime/channels/channel-transports.d.ts +0 -1
  65. package/dist/runtime/channels/channel-transports.js +35 -33
  66. package/dist/runtime/channels/client-server-location-runtime.js +5 -4
  67. package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
  68. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  69. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  70. package/dist/runtime/channels/fanout-location-runtime.js +3 -3
  71. package/dist/runtime/diagnostics/flow-context.js +19 -7
  72. package/dist/runtime/diagnostics/index.js +4 -9
  73. package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
  74. package/dist/runtime/diagnostics/message-flow.js +35 -5
  75. package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
  76. package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
  77. package/dist/runtime/execution/index.d.ts +4 -2
  78. package/dist/runtime/execution/index.js +33 -10
  79. package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
  80. package/dist/runtime/execution/serial-execution-queue.js +21 -2
  81. package/dist/runtime/execution/state-lane.d.ts +2 -0
  82. package/dist/runtime/execution/state-lane.js +5 -0
  83. package/dist/runtime/foundation/operation-registry.d.ts +25 -1
  84. package/dist/runtime/foundation/operation-registry.js +86 -18
  85. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
  86. package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
  87. package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
  88. package/dist/runtime/foundation/service-liveness-registry.js +38 -0
  89. package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
  90. package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
  91. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
  92. package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
  93. package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
  94. package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
  95. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
  96. package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
  97. package/dist/runtime/foundation/service-stateful-registry.js +24 -26
  98. package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
  99. package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
  100. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
  101. package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
  102. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
  103. package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
  104. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  105. package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
  106. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
  107. package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
  108. package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
  109. package/dist/runtime/host/actor-packet-relay.js +59 -72
  110. package/dist/runtime/host/actor-placement-coordinator.js +25 -8
  111. package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
  112. package/dist/runtime/host/actor-transfer-runtime.js +85 -331
  113. package/dist/runtime/host/application-job-queue.d.ts +24 -3
  114. package/dist/runtime/host/application-job-queue.js +28 -41
  115. package/dist/runtime/host/index.d.ts +5 -1
  116. package/dist/runtime/host/index.js +171 -97
  117. package/dist/runtime/host/location-runtime-owner.js +2 -6
  118. package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
  119. package/dist/runtime/host/mesh-router-resolver.js +14 -6
  120. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
  121. package/dist/runtime/host/remote-bound-session-relay.js +71 -190
  122. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
  123. package/dist/runtime/host/route-mesh-runtime.js +5 -3
  124. package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
  125. package/dist/runtime/host/runtime-shutdown.js +3 -2
  126. package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
  127. package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
  128. package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
  129. package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
  130. package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
  131. package/dist/runtime/locations/auto-connect-loop.js +22 -14
  132. package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
  133. package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
  134. package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
  135. package/dist/runtime/locations/descriptor-publication.js +11 -0
  136. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  137. package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
  138. package/dist/runtime/locations/in-memory-authority-store.js +56 -19
  139. package/dist/runtime/locations/in-memory-location-store.js +1 -10
  140. package/dist/runtime/locations/index.d.ts +1 -0
  141. package/dist/runtime/locations/index.js +1 -0
  142. package/dist/runtime/locations/lease-tracker.js +1 -6
  143. package/dist/runtime/locations/location-store-repository.d.ts +51 -1
  144. package/dist/runtime/locations/location-store-repository.js +363 -139
  145. package/dist/runtime/locations/relocation-blob.d.ts +18 -1
  146. package/dist/runtime/locations/relocation-blob.js +52 -1
  147. package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
  148. package/dist/runtime/locations/request-source-resolver.js +80 -0
  149. package/dist/runtime/locations/resolvers.js +1 -1
  150. package/dist/runtime/locations/runtime.d.ts +6 -2
  151. package/dist/runtime/locations/runtime.js +37 -30
  152. package/dist/runtime/messaging/payload-codec.d.ts +7 -1
  153. package/dist/runtime/messaging/payload-codec.js +7 -6
  154. package/dist/runtime/messaging/request-result.js +29 -26
  155. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
  156. package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
  157. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
  158. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
  159. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
  160. package/dist/runtime/spots/index.d.ts +18 -11
  161. package/dist/runtime/spots/index.js +234 -176
  162. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  163. package/dist/runtime/spots/spot-activation-registry.js +21 -11
  164. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  165. package/dist/runtime/spots/spot-activation-state.js +7 -7
  166. package/dist/runtime/spots/spot-activation.d.ts +6 -3
  167. package/dist/runtime/spots/spot-activation.js +123 -44
  168. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
  169. package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
  170. package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
  171. package/dist/runtime/spots/spot-actor-membership.js +0 -8
  172. package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
  173. package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
  174. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
  175. package/dist/runtime/spots/spot-entry-activation.js +14 -9
  176. package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
  177. package/dist/runtime/spots/spot-handler-registry.js +6 -2
  178. package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
  179. package/dist/runtime/spots/spot-manager-public.js +2 -2
  180. package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
  181. package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
  182. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
  183. package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
  184. package/dist/runtime/spots/spot-outbound.js +3 -3
  185. package/dist/runtime/spots/spot-remote-codec.js +5 -1
  186. package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
  187. package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
  188. package/dist/runtime/spots/spot-serial-executor.js +61 -8
  189. package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
  190. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
  191. package/dist/runtime/spots/spot-timer.d.ts +57 -5
  192. package/dist/runtime/spots/spot-timer.js +287 -103
  193. package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
  194. package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
  195. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
  196. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
  197. package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
  198. package/dist/runtime/streams/bound-session-service.d.ts +1 -1
  199. package/dist/runtime/streams/bound-session-service.js +6 -11
  200. package/dist/runtime/streams/index.d.ts +3 -2
  201. package/dist/runtime/streams/index.js +6 -4
  202. package/dist/runtime/streams/managed-stream.js +3 -2
  203. package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
  204. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
  205. package/dist/runtime/streams/session-actor-coordinator.js +15 -32
  206. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
  207. package/dist/runtime/streams/stream-session-runtime.js +1 -4
  208. package/dist/runtime/workers/index.js +1 -1
  209. package/package.json +3 -3
  210. package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
  211. package/src/contracts/Common/encoded-payload-storage.ts +6 -3
  212. package/src/contracts/Configuration/Builders.ts +4 -1
  213. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
  214. package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
  215. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  216. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
  217. package/src/contracts/Locations/Rows.ts +2 -0
  218. package/src/contracts/Spots/Contracts.ts +8 -0
  219. package/src/contracts/Spots/ZLinkSpot.ts +3 -3
  220. package/src/runtime/abort.ts +12 -0
  221. package/src/runtime/actors/actor-authority-publication.ts +3 -2
  222. package/src/runtime/actors/actor-client.ts +61 -70
  223. package/src/runtime/actors/actor-context.ts +49 -9
  224. package/src/runtime/actors/actor-handoff.ts +282 -106
  225. package/src/runtime/actors/actor-join-relocation.ts +2 -0
  226. package/src/runtime/actors/actor-local-native-join.ts +4 -0
  227. package/src/runtime/actors/actor-mailbox.ts +40 -2
  228. package/src/runtime/actors/actor-remote-joiner.ts +6 -1
  229. package/src/runtime/actors/actor-reply.ts +42 -0
  230. package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
  231. package/src/runtime/actors/actor-runtime-state.ts +2 -20
  232. package/src/runtime/actors/actor-source-transfer.ts +1 -34
  233. package/src/runtime/actors/index.ts +41 -27
  234. package/src/runtime/actors/session-disconnected-wire.ts +66 -0
  235. package/src/runtime/admission.ts +69 -34
  236. package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
  237. package/src/runtime/application-jobs/contracts.ts +2 -0
  238. package/src/runtime/backend/contracts/index.ts +39 -4
  239. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
  240. package/src/runtime/backend/mesh-completion-table.ts +4 -0
  241. package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
  242. package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
  243. package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
  244. package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
  245. package/src/runtime/channels/channel-clients.ts +49 -24
  246. package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
  247. package/src/runtime/channels/channel-dispatchers.ts +116 -72
  248. package/src/runtime/channels/channel-envelope.ts +105 -36
  249. package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
  250. package/src/runtime/channels/channel-runtime-manager.ts +12 -5
  251. package/src/runtime/channels/channel-transports.ts +49 -58
  252. package/src/runtime/channels/client-server-location-runtime.ts +11 -10
  253. package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
  254. package/src/runtime/channels/fanout-location-runtime.ts +17 -9
  255. package/src/runtime/diagnostics/flow-context.ts +20 -7
  256. package/src/runtime/diagnostics/index.ts +1 -7
  257. package/src/runtime/diagnostics/message-flow.ts +47 -9
  258. package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
  259. package/src/runtime/execution/index.ts +40 -14
  260. package/src/runtime/execution/serial-execution-queue.ts +31 -4
  261. package/src/runtime/execution/state-lane.ts +7 -0
  262. package/src/runtime/foundation/operation-registry.ts +98 -20
  263. package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
  264. package/src/runtime/foundation/service-liveness-registry.ts +39 -0
  265. package/src/runtime/foundation/service-mailbox.ts +8 -0
  266. package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
  267. package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
  268. package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
  269. package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
  270. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
  271. package/src/runtime/foundation/service-stateful-registry.ts +38 -35
  272. package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
  274. package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
  275. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  276. package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
  277. package/src/runtime/host/actor-packet-relay.ts +113 -94
  278. package/src/runtime/host/actor-placement-coordinator.ts +31 -8
  279. package/src/runtime/host/actor-transfer-runtime.ts +104 -430
  280. package/src/runtime/host/application-job-queue.ts +29 -44
  281. package/src/runtime/host/index.ts +286 -129
  282. package/src/runtime/host/location-runtime-owner.ts +2 -6
  283. package/src/runtime/host/mesh-router-resolver.ts +13 -5
  284. package/src/runtime/host/remote-bound-session-relay.ts +86 -248
  285. package/src/runtime/host/route-mesh-runtime.ts +11 -5
  286. package/src/runtime/host/runtime-shutdown.ts +15 -4
  287. package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
  288. package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
  290. package/src/runtime/locations/auto-connect-loop.ts +22 -14
  291. package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
  292. package/src/runtime/locations/auto-connect-types.ts +0 -1
  293. package/src/runtime/locations/descriptor-publication.ts +7 -0
  294. package/src/runtime/locations/domain-store-contract.ts +5 -0
  295. package/src/runtime/locations/in-memory-authority-store.ts +85 -23
  296. package/src/runtime/locations/in-memory-location-store.ts +1 -12
  297. package/src/runtime/locations/index.ts +1 -0
  298. package/src/runtime/locations/lease-tracker.ts +2 -9
  299. package/src/runtime/locations/location-store-repository.ts +628 -152
  300. package/src/runtime/locations/relocation-blob.ts +75 -1
  301. package/src/runtime/locations/request-source-resolver.ts +138 -0
  302. package/src/runtime/locations/resolvers.ts +2 -2
  303. package/src/runtime/locations/runtime.ts +70 -40
  304. package/src/runtime/messaging/payload-codec.ts +8 -11
  305. package/src/runtime/messaging/request-result.ts +33 -29
  306. package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
  307. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
  308. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
  309. package/src/runtime/spots/index.ts +375 -281
  310. package/src/runtime/spots/spot-activation-registry.ts +25 -13
  311. package/src/runtime/spots/spot-activation-state.ts +12 -19
  312. package/src/runtime/spots/spot-activation.ts +170 -86
  313. package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
  314. package/src/runtime/spots/spot-actor-membership.ts +0 -15
  315. package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
  316. package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
  317. package/src/runtime/spots/spot-entry-activation.ts +24 -19
  318. package/src/runtime/spots/spot-handler-registry.ts +15 -4
  319. package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
  320. package/src/runtime/spots/spot-manager-public.ts +2 -2
  321. package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
  322. package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
  323. package/src/runtime/spots/spot-outbound.ts +3 -3
  324. package/src/runtime/spots/spot-remote-codec.ts +9 -2
  325. package/src/runtime/spots/spot-runtime-ports.ts +0 -1
  326. package/src/runtime/spots/spot-serial-executor.ts +97 -25
  327. package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
  328. package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
  329. package/src/runtime/spots/spot-timer.ts +413 -157
  330. package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
  331. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
  332. package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
  333. package/src/runtime/streams/bound-session-service.ts +7 -10
  334. package/src/runtime/streams/index.ts +12 -6
  335. package/src/runtime/streams/managed-stream.ts +4 -2
  336. package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
  337. package/src/runtime/streams/session-actor-coordinator.ts +39 -88
  338. package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
  339. package/src/runtime/streams/stream-session-runtime.ts +1 -5
  340. package/src/runtime/workers/index.ts +1 -1
@@ -8,8 +8,10 @@ import {
8
8
  import { runZLinkActorExecution } from './actor-execution-context';
9
9
  import {
10
10
  bindApplicationJobPermit,
11
- hasApplicationJobPermit
11
+ currentApplicationJobPermit,
12
+ runWithApplicationJobPermit
12
13
  } from '../application-jobs/application-job-queue-scope';
14
+ import type { ApplicationJobPermitPort } from '../application-jobs/contracts';
13
15
 
14
16
  export class ZLinkActorSerialExecutor {
15
17
  private readonly scheduler: ZLinkSerialExecutionQueue;
@@ -28,10 +30,46 @@ export class ZLinkActorSerialExecutor {
28
30
  }
29
31
 
30
32
  execute<T>(operation: () => Promise<T> | T, workOptions?: ZLinkSerialWorkOptions): Promise<T> {
33
+ const initial = currentApplicationJobPermit();
34
+ if (
35
+ initial !== undefined &&
36
+ workOptions?.lane !== 'lifecycle' &&
37
+ this.scheduler.hasPendingDurableApplication
38
+ ) {
39
+ let prepared: ApplicationJobPermitPort | undefined;
40
+ const cancel = (): void => {
41
+ prepared?.releaseAfterInternalProcessing();
42
+ prepared = undefined;
43
+ };
44
+ const terminal = this.scheduler.admitDurablePrefix(
45
+ () =>
46
+ runWithApplicationJobPermit(prepared!, () =>
47
+ runZLinkActorExecution(this.actorId, this.sourceSpotId, operation)
48
+ ),
49
+ workOptions,
50
+ undefined,
51
+ {
52
+ prepare: async (signal) => {
53
+ if (initial.reacquire === undefined) {
54
+ throw new Error('Durable Actor ingress requires its host permit source.');
55
+ }
56
+ prepared = await initial.reacquire(signal);
57
+ if (signal.aborted) {
58
+ cancel();
59
+ throw signal.reason;
60
+ }
61
+ prepared.markApplicationQueued();
62
+ },
63
+ cancel
64
+ }
65
+ );
66
+ initial.releaseAfterInternalProcessing();
67
+ return terminal;
68
+ }
31
69
  const boundOperation = bindApplicationJobPermit(() =>
32
70
  runZLinkActorExecution(this.actorId, this.sourceSpotId, operation)
33
71
  );
34
- return hasApplicationJobPermit()
72
+ return initial !== undefined
35
73
  ? this.scheduler.submitPreAdmitted(boundOperation, workOptions)
36
74
  : this.scheduler.submit(boundOperation, workOptions);
37
75
  }
@@ -164,7 +164,12 @@ export class ZLinkActorNativeJoinCoordinator implements ZLinkActorJoinCoordinato
164
164
  result: ZLinkActorJoinRuntimeResult<Message>,
165
165
  operationId: import('../../contracts').ZLinkActorJoinOperationId | undefined
166
166
  ): ZLinkActorJoinRuntimeResult<Message> {
167
- if (operationId === undefined || this.options.sourceTransfer === undefined) return result;
167
+ if (
168
+ result.sourceCleanup !== undefined ||
169
+ operationId === undefined ||
170
+ this.options.sourceTransfer === undefined
171
+ )
172
+ return result;
168
173
  return {
169
174
  ...result,
170
175
  finalizeDeferredJoin: async () => {
@@ -0,0 +1,42 @@
1
+ import { encodeFrameworkPayload } from '../messaging/payload-codec';
2
+ import {
3
+ decodeStreamHeader,
4
+ encodeStreamFrame,
5
+ streamCodecForContentType,
6
+ ZLinkStreamHeaderFlags,
7
+ ZLinkStreamMessageKind
8
+ } from '../streams/protocol';
9
+
10
+ /** Ordinary dispatch and relocation use the same typed Actor reply envelope. */
11
+ export function encodeActorReply(
12
+ requestHeaderBytes: Uint8Array,
13
+ kind: ZLinkStreamMessageKind.Response | ZLinkStreamMessageKind.Error,
14
+ payload: unknown,
15
+ serializers: Parameters<typeof encodeFrameworkPayload>[1],
16
+ flowEnabled: boolean
17
+ ): readonly Buffer[] {
18
+ const requestHeader = decodeStreamHeader(requestHeaderBytes, flowEnabled);
19
+ const encoded =
20
+ kind === ZLinkStreamMessageKind.Response
21
+ ? encodeFrameworkPayload(payload, serializers, requestHeader.name, 'reply')
22
+ : encodeFrameworkPayload(payload);
23
+ try {
24
+ const frame = encodeStreamFrame(
25
+ {
26
+ kind,
27
+ codec: streamCodecForContentType(encoded.contentType),
28
+ flags: ZLinkStreamHeaderFlags.None,
29
+ requestSeq: requestHeader.requestSeq,
30
+ name: '',
31
+ metadata: new Map(),
32
+ correlationId: requestHeader.correlationId,
33
+ flowId: requestHeader.flowId,
34
+ flowOrigin: requestHeader.flowOrigin
35
+ },
36
+ encoded.message.data()
37
+ );
38
+ return [Buffer.from(frame.buffer, frame.byteOffset, frame.byteLength)];
39
+ } finally {
40
+ encoded.message.close();
41
+ }
42
+ }
@@ -19,6 +19,8 @@ import type { ZLinkRuntimeAdmissionGate } from '../admission';
19
19
  import type { ZLinkActivationAdmission } from '../activation-admission';
20
20
 
21
21
  export interface ZLinkActorJoinRuntimeResult<TReply> {
22
+ /** Relay-ready transferred completion; this continuation only releases source work. */
23
+ readonly sourceCleanup?: () => Promise<void>;
22
24
  readonly accepted: boolean;
23
25
  readonly actor?: import('../../contracts').ActorRef;
24
26
  readonly reply?: TReply;
@@ -94,14 +94,8 @@ function sameRemoteSessionOwnerLifecycle(
94
94
  right.sessionNodeRid !== undefined &&
95
95
  left.sessionOwnerNodeGeneration !== undefined &&
96
96
  right.sessionOwnerNodeGeneration !== undefined &&
97
- left.sessionOwnerId !== undefined &&
98
- right.sessionOwnerId !== undefined &&
99
- left.sessionOwnerLeaseGeneration !== undefined &&
100
- right.sessionOwnerLeaseGeneration !== undefined &&
101
97
  routingIdsEqual(left.sessionNodeRid, right.sessionNodeRid) &&
102
- left.sessionOwnerNodeGeneration === right.sessionOwnerNodeGeneration &&
103
- left.sessionOwnerId === right.sessionOwnerId &&
104
- left.sessionOwnerLeaseGeneration === right.sessionOwnerLeaseGeneration
98
+ left.sessionOwnerNodeGeneration === right.sessionOwnerNodeGeneration
105
99
  );
106
100
  }
107
101
 
@@ -495,19 +489,7 @@ export class ZLinkActorRuntimeState {
495
489
  ) {
496
490
  throw new TypeError('An installed bound Session target requires its binding identity.');
497
491
  }
498
- const current = this.boundSessionValue;
499
- if (current !== undefined && sameRemoteSessionOwnerLifecycle(current, target)) {
500
- // A duplicate or late older command for the exact physical Session
501
- // leaves the current binding; a newer generation of the same Session
502
- // replaces it. A different Session in the same owner lifecycle must
503
- // advance that lifecycle's generation; a late equal/lower one is stale.
504
- const advances =
505
- current.bindingGeneration === undefined ||
506
- target.bindingGeneration > current.bindingGeneration;
507
- if (!advances) return sameRemoteSessionOwner(current, target);
508
- }
509
- // Binding generations are scoped to a Session-owner lifecycle. A restarted
510
- // owner can legitimately reset its counter below the predecessor value.
492
+ // The service registry accepted this identity in the Actor owner turn.
511
493
  this.boundSessionValue = boundSessionIdentity(target);
512
494
  return true;
513
495
  }
@@ -1,35 +1,10 @@
1
- import type { ActorRef, ZLinkActor, ZLinkMessage } from '../../contracts';
1
+ import type { ActorRef, ZLinkActor } from '../../contracts';
2
2
  import type { ZLinkSpotRouteTarget } from '../spots/spot-routing-internal';
3
3
  import type { ZLinkActorRuntimeState } from './actor-runtime-state';
4
- import type { ZLinkActorHandoffPacket, ZLinkActorHandoffResult } from './actor-handoff';
5
- import type { ServiceWireOperationId } from '../foundation/service-stateful-wire-codec';
6
-
7
- export interface ZLinkPreparedActorSource {
8
- readonly adapterKey?: string;
9
- readonly state: ZLinkMessage;
10
- readonly handoffBacklog: readonly ZLinkActorHandoffPacket[];
11
- readonly sourceLeaveCompletion?: Promise<void>;
12
- readonly sourceLeaveSubmitted?: Promise<void>;
13
- onSourceLeaveSubmitted(notify: () => Promise<void>): void;
14
- observeTargetAuthority(
15
- target: ZLinkSpotRouteTarget,
16
- targetActorRef: ActorRef,
17
- signal?: AbortSignal
18
- ): Promise<void>;
19
- commit(
20
- target: ZLinkSpotRouteTarget,
21
- targetActorRef: ActorRef,
22
- results: readonly ZLinkActorHandoffResult[],
23
- releaseLocation?: boolean
24
- ): void;
25
- rollback(): Promise<void>;
26
- }
27
4
 
28
5
  export interface ZLinkActorSourceTransfer {
29
6
  /** Starts the ingress handoff before target route lookup. */
30
7
  beginDeferredActorHandoff?(actor: ZLinkActor, state: ZLinkActorRuntimeState): void;
31
- /** Changes a provisional ingress fence into a relocation handoff. */
32
- promoteDeferredActorHandoff?(actor: ZLinkActor, state: ZLinkActorRuntimeState): void;
33
8
  /** Finishes a same-node deferred Join handoff after completion callback. */
34
9
  completeDeferredActorHandoff?(
35
10
  actor: ZLinkActor,
@@ -38,12 +13,4 @@ export interface ZLinkActorSourceTransfer {
38
13
  ): Promise<void>;
39
14
  /** Releases an early handoff when Join cannot commit. */
40
15
  cancelDeferredActorHandoff?(actor: ZLinkActor, state: ZLinkActorRuntimeState): Promise<void>;
41
- prepareSource(
42
- actor: ZLinkActor,
43
- state: ZLinkActorRuntimeState,
44
- signal?: AbortSignal,
45
- lifecycleAuthority?: 'framework' | 'core',
46
- deferredJoin?: boolean,
47
- relocation?: ServiceWireOperationId
48
- ): Promise<ZLinkPreparedActorSource>;
49
16
  }
@@ -42,11 +42,7 @@ import { ZLinkTransferredActorRollbackCoordinator } from './transferred-actor-ro
42
42
  const ACTOR_CREATION_RETRY_INTERVAL_MS = 5;
43
43
  const LOCAL_DIAGNOSTIC_NODE_RID = 'local';
44
44
 
45
- export {
46
- DefaultZLinkActorClient,
47
- forwardEncodedActorPacket,
48
- type ZLinkActorClientOptions
49
- } from './actor-client';
45
+ export { DefaultZLinkActorClient, type ZLinkActorClientOptions } from './actor-client';
50
46
  export { DefaultZLinkActorContext, ZLINK_ACTOR_JOIN_ENTRY_SPOT_RUNTIME } from './actor-context';
51
47
  export { ZLinkActorSerialExecutor } from './actor-mailbox';
52
48
  export {
@@ -400,6 +396,11 @@ export class DefaultZLinkActorManager implements ZLinkActorManager {
400
396
 
401
397
  async findActor(actorId: string, signal?: AbortSignal): Promise<ZLinkActor | undefined> {
402
398
  throwIfAborted(signal);
399
+ return this.resolveLocalActor(actorId);
400
+ }
401
+
402
+ /** @internal Uses the relocation owner's publication boundary for local dispatch. */
403
+ resolveLocalActor(actorId: string): ZLinkActor | undefined {
403
404
  if (this.relocationStaged.has(actorId)) return undefined;
404
405
  return this.states.get(actorId)?.actor;
405
406
  }
@@ -474,7 +475,7 @@ export class DefaultZLinkActorManager implements ZLinkActorManager {
474
475
  if (nativeRef !== undefined) node.discardRelocatedActor?.(nativeRef);
475
476
  this.relocationStaged.delete(actorId);
476
477
  const failedState = this.states.get(actorId);
477
- await this.finalizeActorState(actorId, failedState);
478
+ await this.finalizeActorState(failedState);
478
479
  throw error;
479
480
  }
480
481
  }
@@ -497,6 +498,13 @@ export class DefaultZLinkActorManager implements ZLinkActorManager {
497
498
  await this.releaseLocalActor(actorId, sourceActorRef);
498
499
  }
499
500
 
501
+ /** Commit removes current ownership; a Join profile may still own its leave callback. */
502
+ detachRelocationSource(state: ZLinkActorRuntimeState): void {
503
+ if (this.detachActorStateRegistration(state)) {
504
+ this.discardNativeRelocationSource(state.nativeActorRef);
505
+ }
506
+ }
507
+
500
508
  async releaseSpotActorMembers(meshName: string, spotId?: RoutingId): Promise<void> {
501
509
  const results = await Promise.allSettled(
502
510
  [...this.states.values()]
@@ -515,18 +523,15 @@ export class DefaultZLinkActorManager implements ZLinkActorManager {
515
523
  exactNativeActorRef?: ZLinkBackendActorRef
516
524
  ): Promise<void> {
517
525
  const state = this.states.get(actorId);
518
- const node = this.options.nativeActorNodeProvider?.() ?? this.options.nativeActorNode;
519
- const nativeActorRef = exactNativeActorRef ?? state?.nativeActorRef;
526
+ if (state === undefined) return;
520
527
  const failures: unknown[] = [];
521
528
  try {
522
- if (nativeActorRef !== undefined) {
523
- node?.discardRelocatedActor?.(nativeActorRef);
524
- }
529
+ this.discardNativeRelocationSource(exactNativeActorRef ?? state.nativeActorRef);
525
530
  } catch (error) {
526
531
  failures.push(error);
527
532
  }
528
533
  try {
529
- await this.completeCoreRelocationSource(actorId);
534
+ await this.completeCoreRelocationSource(actorId, state);
530
535
  } catch (error) {
531
536
  failures.push(error);
532
537
  }
@@ -537,29 +542,38 @@ export class DefaultZLinkActorManager implements ZLinkActorManager {
537
542
  }
538
543
  }
539
544
 
540
- async completeCoreRelocationSource(actorId: string): Promise<void> {
541
- const state = this.states.get(actorId);
542
- await this.finalizeActorState(actorId, state);
543
- }
544
-
545
- private async finalizeActorState(
545
+ async completeCoreRelocationSource(
546
546
  actorId: string,
547
- state: ZLinkActorRuntimeState | undefined
547
+ state = this.states.get(actorId)
548
548
  ): Promise<void> {
549
- if (state === undefined || this.states.get(actorId) !== state) return;
549
+ await this.finalizeActorState(state);
550
+ }
551
+
552
+ private discardNativeRelocationSource(nativeActorRef: ZLinkBackendActorRef | undefined): void {
553
+ if (nativeActorRef === undefined) return;
554
+ const node = this.options.nativeActorNodeProvider?.() ?? this.options.nativeActorNode;
555
+ node?.discardRelocatedActor?.(nativeActorRef);
556
+ }
557
+
558
+ private async finalizeActorState(state: ZLinkActorRuntimeState | undefined): Promise<void> {
559
+ if (state === undefined) return;
550
560
  try {
551
561
  if (state.actor !== undefined)
552
562
  await disposeLifecycleHandlers(state.actor, this.detachedTaskRunner);
553
563
  } finally {
554
564
  state.clearAfterDestroy();
555
- if (this.states.get(actorId) === state) {
556
- this.states.delete(actorId);
557
- this.actorMeshNames.delete(actorId);
558
- this.relocationStaged.delete(actorId);
559
- }
565
+ this.detachActorStateRegistration(state);
560
566
  }
561
567
  }
562
568
 
569
+ private detachActorStateRegistration(state: ZLinkActorRuntimeState): boolean {
570
+ if (this.states.get(state.actorId) !== state) return false;
571
+ this.states.delete(state.actorId);
572
+ this.actorMeshNames.delete(state.actorId);
573
+ this.relocationStaged.delete(state.actorId);
574
+ return true;
575
+ }
576
+
563
577
  private async finalizeDestroyedActor(
564
578
  actorId: string,
565
579
  state: ZLinkActorRuntimeState
@@ -568,7 +582,7 @@ export class DefaultZLinkActorManager implements ZLinkActorManager {
568
582
  try {
569
583
  this.options.actorDestroyedCleanup?.(actorId);
570
584
  } finally {
571
- await this.finalizeActorState(actorId, state);
585
+ await this.finalizeActorState(state);
572
586
  this.options.metrics?.change(METRIC_NAMES.ActorCount, -1);
573
587
  }
574
588
  }
@@ -944,7 +958,7 @@ class ZLinkActorCreateCallRuntime implements ZLinkActorCreateCall {
944
958
  yield(signal?: AbortSignal): Promise<ZLinkActorCreateResult> {
945
959
  const turn = requireZLinkYieldTurn(this.turn);
946
960
  const pending = this.executeOnce(signal);
947
- return turn.yieldPromise(pending);
961
+ return turn.yieldFrameworkPromise(pending);
948
962
  }
949
963
 
950
964
  private executeOnce(signal?: AbortSignal): Promise<ZLinkActorCreateResult> {
@@ -0,0 +1,66 @@
1
+ import type { RoutingId } from '../../contracts';
2
+ import { ZLINK_MAX_ROUTING_ID_BYTES } from '../../contracts/Common/CoreTypes';
3
+ import { ZLinkFrameworkErrorKind, ZLinkFrameworkException } from '../../contracts';
4
+ import { decodeRoutingId, encodeRoutingIdStorageHex } from '../routing-id';
5
+
6
+ const RID_LENGTH_BYTES = 1;
7
+ const GENERATION_BYTES = 8;
8
+ const GENERATIONS_BYTES = GENERATION_BYTES * 2;
9
+
10
+ export interface SessionDisconnectedIdentity {
11
+ readonly sessionOwnerNodeRid: RoutingId;
12
+ readonly sessionOwnerNodeGeneration: bigint;
13
+ readonly bindingGeneration: bigint;
14
+ }
15
+
16
+ export function encodeSessionDisconnected(
17
+ sessionOwnerNodeRid: RoutingId | undefined,
18
+ sessionOwnerNodeGeneration: bigint | undefined,
19
+ bindingGeneration: bigint | undefined
20
+ ): Buffer {
21
+ if (
22
+ sessionOwnerNodeRid === undefined ||
23
+ sessionOwnerNodeGeneration === undefined ||
24
+ sessionOwnerNodeGeneration === 0n ||
25
+ bindingGeneration === undefined ||
26
+ bindingGeneration === 0n
27
+ ) {
28
+ throw new ZLinkFrameworkException(
29
+ ZLinkFrameworkErrorKind.ProtocolError,
30
+ 'Session disconnect requires an exact binding identity.'
31
+ );
32
+ }
33
+ const rid = Buffer.from(encodeRoutingIdStorageHex(sessionOwnerNodeRid), 'hex');
34
+ if (rid.length === 0 || rid.length > ZLINK_MAX_ROUTING_ID_BYTES) {
35
+ throw new ZLinkFrameworkException(
36
+ ZLinkFrameworkErrorKind.ProtocolError,
37
+ 'Invalid Session owner Node RID length.'
38
+ );
39
+ }
40
+ const payload = Buffer.allocUnsafe(RID_LENGTH_BYTES + rid.length + GENERATIONS_BYTES);
41
+ payload[0] = rid.length;
42
+ rid.copy(payload, RID_LENGTH_BYTES);
43
+ payload.writeBigUInt64BE(sessionOwnerNodeGeneration, RID_LENGTH_BYTES + rid.length);
44
+ payload.writeBigUInt64BE(bindingGeneration, RID_LENGTH_BYTES + rid.length + GENERATION_BYTES);
45
+ return payload;
46
+ }
47
+
48
+ export function decodeSessionDisconnected(
49
+ bytes: Uint8Array
50
+ ): SessionDisconnectedIdentity | undefined {
51
+ const payload = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
52
+ if (payload.length < RID_LENGTH_BYTES + 1 + GENERATIONS_BYTES) return undefined;
53
+ const ridLength = payload[0];
54
+ if (ridLength === 0 || payload.length !== RID_LENGTH_BYTES + ridLength + GENERATIONS_BYTES)
55
+ return undefined;
56
+ const offset = RID_LENGTH_BYTES + ridLength;
57
+ const sessionOwnerNodeGeneration = payload.readBigUInt64BE(offset);
58
+ const bindingGeneration = payload.readBigUInt64BE(offset + GENERATION_BYTES);
59
+ if (sessionOwnerNodeGeneration === 0n || bindingGeneration === 0n) return undefined;
60
+ const hex = payload.subarray(RID_LENGTH_BYTES, offset).toString('hex');
61
+ return {
62
+ sessionOwnerNodeRid: decodeRoutingId(hex, hex),
63
+ sessionOwnerNodeGeneration,
64
+ bindingGeneration
65
+ };
66
+ }
@@ -2,8 +2,15 @@ import {
2
2
  ZLinkFrameworkInternalErrorKind,
3
3
  createInternalFrameworkException
4
4
  } from './framework-errors-internal';
5
+ import { isPromiseLike } from './abort';
5
6
  const BACKING_ARRAY_COMPACTION_MIN_HEAD = 1024;
6
7
 
8
+ /** Runs host admission inside the domain's request completion boundary. */
9
+ export type ZLinkMeshDispatchAdmission = (
10
+ dispatch: () => void | Promise<void>,
11
+ onRejected?: (error: unknown) => void | Promise<void>
12
+ ) => void | Promise<void>;
13
+
7
14
  /** 소비한 배열 prefix가 정리 조건에 도달했는지 판정합니다. */
8
15
  export function shouldCompactBackingArray(head: number, length: number): boolean {
9
16
  return head >= BACKING_ARRAY_COMPACTION_MIN_HEAD && head * 2 >= length;
@@ -64,21 +71,63 @@ export class ZLinkRuntimeAdmissionGate {
64
71
  }
65
72
 
66
73
  claim(meshName: string, operation: string): ZLinkApplicationWorkClaim {
74
+ const state = this.enter(meshName, operation);
75
+ let closed = false;
76
+ return {
77
+ close: () => {
78
+ if (closed) return;
79
+ closed = true;
80
+ exitAdmission(state);
81
+ }
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Runs one admitted unit of work. Work that completes synchronously leaves
87
+ * admission in the same turn; asynchronous work leaves it from the single
88
+ * continuation on its result.
89
+ */
90
+ run<T>(
91
+ meshName: string,
92
+ operation: string,
93
+ work: () => T | Promise<T>,
94
+ onRejected?: (error: unknown) => T | Promise<T>
95
+ ): T | Promise<T> {
96
+ let state: ZLinkMeshAdmissionState;
97
+ let result: T | Promise<T>;
98
+ try {
99
+ state = this.enter(meshName, operation);
100
+ } catch (error) {
101
+ // The domain owns admission rejection completion, just as it owns handler failure.
102
+ return onRejected === undefined ? Promise.reject(error) : onRejected(error);
103
+ }
104
+ try {
105
+ result = work();
106
+ } catch (error) {
107
+ exitAdmission(state);
108
+ return Promise.reject(error);
109
+ }
110
+ if (!isPromiseLike(result)) {
111
+ exitAdmission(state);
112
+ return result;
113
+ }
114
+ return Promise.resolve(result).then(
115
+ (value) => {
116
+ exitAdmission(state);
117
+ return value;
118
+ },
119
+ (error: unknown) => {
120
+ exitAdmission(state);
121
+ throw error;
122
+ }
123
+ );
124
+ }
125
+
126
+ private enter(meshName: string, operation: string): ZLinkMeshAdmissionState {
67
127
  const state = this.requireState(meshName);
68
128
  if (this.ownerAdmissionOpen() && !state.sealed) {
69
129
  state.active += 1;
70
- let closed = false;
71
- return {
72
- close: () => {
73
- if (closed) return;
74
- closed = true;
75
- state.active -= 1;
76
- if (state.active === 0) {
77
- let resolve: (() => void) | undefined;
78
- while ((resolve = takeWaiter(state)) !== undefined) resolve();
79
- }
80
- }
81
- };
130
+ return state;
82
131
  }
83
132
  throw createInternalFrameworkException(
84
133
  state.sealedReason,
@@ -86,28 +135,6 @@ export class ZLinkRuntimeAdmissionGate {
86
135
  );
87
136
  }
88
137
 
89
- run<T>(meshName: string, operation: string, work: () => T | Promise<T>): Promise<T> {
90
- let claim: ZLinkApplicationWorkClaim | undefined;
91
- try {
92
- claim = this.claim(meshName, operation);
93
- const result = work();
94
- const close = claim.close;
95
- return Promise.resolve(result).then(
96
- (value) => {
97
- close();
98
- return value;
99
- },
100
- (error) => {
101
- close();
102
- throw error;
103
- }
104
- );
105
- } catch (error) {
106
- claim?.close();
107
- return Promise.reject(error);
108
- }
109
- }
110
-
111
138
  awaitZero(meshName: string, signal?: AbortSignal): Promise<void> {
112
139
  const state = this.requireState(meshName);
113
140
  if (state.active === 0) return Promise.resolve();
@@ -191,6 +218,14 @@ interface ZLinkMeshAdmissionState {
191
218
  waiterCount: number;
192
219
  }
193
220
 
221
+ function exitAdmission(state: ZLinkMeshAdmissionState): void {
222
+ state.active -= 1;
223
+ if (state.active === 0) {
224
+ let resolve: (() => void) | undefined;
225
+ while ((resolve = takeWaiter(state)) !== undefined) resolve();
226
+ }
227
+ }
228
+
194
229
  function takeWaiter(state: ZLinkMeshAdmissionState): (() => void) | undefined {
195
230
  advanceWaiterHead(state);
196
231
  const waiter = state.waiters[state.waiterHead];
@@ -5,11 +5,38 @@ import type { ApplicationJobOrigin, ApplicationJobPermitPort } from './contracts
5
5
  const applicationJobPermitScope = new AsyncLocalStorage<ApplicationJobPermitPort | undefined>();
6
6
 
7
7
  function releasePermitTurn(): void {
8
- const permit = applicationJobPermitScope.getStore();
8
+ releaseApplicationJobPermitTurn(applicationJobPermitScope.getStore());
9
+ }
10
+
11
+ /** Ends the internal processing of one record turn unless its handler detached the permit. */
12
+ export function releaseApplicationJobPermitTurn(
13
+ permit: ApplicationJobPermitPort | undefined
14
+ ): void {
9
15
  if (permit !== undefined && !permit.detachedForHandlerTurn)
10
16
  permit.releaseAfterInternalProcessing();
11
17
  }
12
18
 
19
+ /**
20
+ * Makes `permit` the current record's permit for the synchronous part of a
21
+ * dispatch. The caller restores the returned previous scope with
22
+ * {@link leaveApplicationJobPermitScope} and releases the turn itself, so a
23
+ * dispatcher that already continues on the handler result needs no second
24
+ * continuation here.
25
+ */
26
+ export function enterApplicationJobPermitScope(
27
+ permit: ApplicationJobPermitPort
28
+ ): ApplicationJobPermitPort | undefined {
29
+ const previous = applicationJobPermitScope.getStore();
30
+ applicationJobPermitScope.enterWith(permit);
31
+ return previous;
32
+ }
33
+
34
+ export function leaveApplicationJobPermitScope(
35
+ previous: ApplicationJobPermitPort | undefined
36
+ ): void {
37
+ applicationJobPermitScope.enterWith(previous);
38
+ }
39
+
13
40
  function releasePermitSuccess<TResult>(value: TResult): TResult {
14
41
  releasePermitTurn();
15
42
  return value;
@@ -72,6 +99,11 @@ export function hasApplicationJobPermit(): boolean {
72
99
  return applicationJobPermitScope.getStore() !== undefined;
73
100
  }
74
101
 
102
+ /** The current ingress reservation; capacity remains owned by its host queue. */
103
+ export function currentApplicationJobPermit(): ApplicationJobPermitPort | undefined {
104
+ return applicationJobPermitScope.getStore();
105
+ }
106
+
75
107
  /** Keeps the ingress origin when a durable record later reacquires its permit. */
76
108
  export function currentApplicationJobOrigin(): ApplicationJobOrigin {
77
109
  return applicationJobPermitScope.getStore()!.origin;
@@ -1,6 +1,8 @@
1
1
  export type ApplicationJobOrigin = 'local' | 'remote';
2
2
 
3
3
  export interface ApplicationJobPermitPort {
4
+ /** Reacquires this record's host supply after durable FIFO ownership. */
5
+ reacquire?(signal: AbortSignal): Promise<ApplicationJobPermitPort>;
4
6
  readonly origin: ApplicationJobOrigin;
5
7
  readonly detachedForHandlerTurn: boolean;
6
8
  markApplicationQueued(): void;