@zlink-systems/framework 0.29.1 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/LICENSE +150 -68
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
  4. package/dist/contracts/Channels/Calls.d.ts +2 -1
  5. package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  7. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  8. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  9. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  10. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  11. package/dist/contracts/Configuration/index.d.ts +1 -1
  12. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  13. package/dist/contracts/Handlers/Attributes.js +7 -11
  14. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  15. package/dist/contracts/Handlers/JsonContract.js +4 -153
  16. package/dist/contracts/Spots/Contracts.d.ts +2 -1
  17. package/dist/internal.d.ts +1 -0
  18. package/dist/internal.js +3 -1
  19. package/dist/nest-integration.d.ts +1 -1
  20. package/dist/nest-integration.js +2 -1
  21. package/dist/runtime/actors/actor-client.d.ts +1 -1
  22. package/dist/runtime/actors/actor-client.js +14 -12
  23. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  24. package/dist/runtime/actors/actor-handoff.js +15 -7
  25. package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
  26. package/dist/runtime/actors/actor-local-native-join.js +9 -12
  27. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  28. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  29. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  30. package/dist/runtime/actors/index.d.ts +2 -1
  31. package/dist/runtime/actors/index.js +18 -6
  32. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  33. package/dist/runtime/admission.d.ts +1 -1
  34. package/dist/runtime/admission.js +15 -5
  35. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +9 -9
  36. package/dist/runtime/application-jobs/application-ingress-record-owner.js +45 -23
  37. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +5 -2
  38. package/dist/runtime/application-jobs/application-job-queue-scope.js +41 -21
  39. package/dist/runtime/application-jobs/contracts.d.ts +15 -2
  40. package/dist/runtime/backend/contracts/index.d.ts +27 -27
  41. package/dist/runtime/backend/mesh-completion-table.d.ts +15 -5
  42. package/dist/runtime/backend/mesh-completion-table.js +160 -50
  43. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
  44. package/dist/runtime/backend/mesh-dispatch-pump.js +53 -36
  45. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  46. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  47. package/dist/runtime/backend/node/node-backend-adapter-support.js +33 -31
  48. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  49. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  50. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  51. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  52. package/dist/runtime/backend/node/node-raw-binding-port.js +50 -25
  53. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +22 -16
  54. package/dist/runtime/backend/node/node-raw-mesh-backend.js +133 -149
  55. package/dist/runtime/backend/node/node-socket-backend-adapter.js +15 -10
  56. package/dist/runtime/backend/raw-binding-port.d.ts +10 -3
  57. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  58. package/dist/runtime/backend/runtime-message.js +5 -0
  59. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  60. package/dist/runtime/backend/runtime-values.js +2 -1
  61. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  62. package/dist/runtime/channels/channel-clients.js +58 -21
  63. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
  64. package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
  65. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  66. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  67. package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
  68. package/dist/runtime/channels/channel-dispatchers.js +27 -26
  69. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  70. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  71. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  72. package/dist/runtime/channels/channel-envelope.js +83 -8
  73. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  74. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  75. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  76. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  77. package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
  78. package/dist/runtime/channels/channel-runtime-manager.js +12 -12
  79. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  80. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  81. package/dist/runtime/channels/channel-transports.d.ts +18 -15
  82. package/dist/runtime/channels/channel-transports.js +48 -31
  83. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  84. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  85. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  86. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  87. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  88. package/dist/runtime/channels/source-spot-router.js +4 -4
  89. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  90. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  91. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  92. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  93. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  94. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  95. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  96. package/dist/runtime/diagnostics/message-flow.js +3 -3
  97. package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
  98. package/dist/runtime/execution/serial-execution-queue.js +1 -0
  99. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  100. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  101. package/dist/runtime/foundation/durable-service-request.js +98 -0
  102. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  103. package/dist/runtime/foundation/operation-identity.js +5 -1
  104. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +37 -6
  105. package/dist/runtime/foundation/raw-service-mesh-runtime.js +473 -220
  106. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  107. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  108. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  109. package/dist/runtime/foundation/service-mailbox.js +2 -1
  110. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
  111. package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
  112. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  113. package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
  114. package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
  115. package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -9
  116. package/dist/runtime/foundation/service-stateful-runtime.js +78 -126
  117. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -7
  118. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  119. package/dist/runtime/foundation/service-topology-registry.d.ts +16 -4
  120. package/dist/runtime/foundation/service-topology-registry.js +69 -30
  121. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
  122. package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
  123. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  124. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  125. package/dist/runtime/host/actor-packet-relay.js +7 -7
  126. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  127. package/dist/runtime/host/application-job-queue.d.ts +28 -9
  128. package/dist/runtime/host/application-job-queue.js +214 -50
  129. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  130. package/dist/runtime/host/entry-actor-runtime.js +4 -1
  131. package/dist/runtime/host/index.d.ts +7 -1
  132. package/dist/runtime/host/index.js +154 -126
  133. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  134. package/dist/runtime/host/instance-activation-authority.js +89 -25
  135. package/dist/runtime/host/remote-bound-session-relay.js +2 -18
  136. package/dist/runtime/host/route-mesh-runtime.js +1 -1
  137. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  138. package/dist/runtime/host/service-relocation-control.js +10 -4
  139. package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
  140. package/dist/runtime/host/service-relocation-host-runtime.js +215 -243
  141. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  142. package/dist/runtime/host/spot-address-transport.js +28 -14
  143. package/dist/runtime/host/spot-runtime-options-factory.js +3 -2
  144. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  145. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  146. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  147. package/dist/runtime/locations/actor-location-claims.js +34 -19
  148. package/dist/runtime/locations/domain-store-contract.d.ts +2 -2
  149. package/dist/runtime/locations/in-memory-authority-store.d.ts +4 -2
  150. package/dist/runtime/locations/in-memory-authority-store.js +80 -8
  151. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  152. package/dist/runtime/locations/in-memory-location-store.js +19 -3
  153. package/dist/runtime/locations/internal-location-contracts.d.ts +3 -0
  154. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  155. package/dist/runtime/locations/lifecycle.js +2 -5
  156. package/dist/runtime/locations/location-store-repository.d.ts +3 -2
  157. package/dist/runtime/locations/location-store-repository.js +165 -22
  158. package/dist/runtime/locations/resolvers.d.ts +2 -1
  159. package/dist/runtime/locations/resolvers.js +10 -1
  160. package/dist/runtime/locations/runtime.d.ts +1 -1
  161. package/dist/runtime/locations/runtime.js +24 -23
  162. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  163. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  164. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  165. package/dist/runtime/messaging/packet-name.js +8 -24
  166. package/dist/runtime/messaging/request-result.d.ts +2 -0
  167. package/dist/runtime/messaging/request-result.js +54 -0
  168. package/dist/runtime/messaging/submission-result.d.ts +2 -1
  169. package/dist/runtime/messaging/submission-result.js +7 -4
  170. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
  171. package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
  172. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
  173. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
  174. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +9 -2
  175. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
  176. package/dist/runtime/spots/index.d.ts +7 -3
  177. package/dist/runtime/spots/index.js +23 -16
  178. package/dist/runtime/spots/spot-activation.d.ts +3 -1
  179. package/dist/runtime/spots/spot-activation.js +21 -12
  180. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  181. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  182. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  183. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  184. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  185. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  186. package/dist/runtime/spots/spot-entry-activation.js +9 -3
  187. package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
  188. package/dist/runtime/spots/spot-handler-registry.js +18 -8
  189. package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
  190. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +2 -1
  191. package/dist/runtime/spots/spot-node-runtime-manager.js +4 -11
  192. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  193. package/dist/runtime/spots/spot-outbound.js +24 -15
  194. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  195. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  196. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  197. package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -1
  198. package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
  199. package/dist/runtime/spots/spot-timer.js +1 -0
  200. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  201. package/dist/runtime/streams/stream-session-runtime.js +14 -28
  202. package/package.json +3 -3
  203. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  204. package/src/contracts/Channels/Calls.ts +2 -1
  205. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  206. package/src/contracts/Configuration/Builders.ts +1 -2
  207. package/src/contracts/Configuration/Configs.ts +0 -6
  208. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  209. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  210. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  211. package/src/contracts/Configuration/index.ts +1 -6
  212. package/src/contracts/Handlers/Attributes.ts +14 -21
  213. package/src/contracts/Handlers/JsonContract.ts +8 -216
  214. package/src/contracts/Spots/Contracts.ts +2 -1
  215. package/src/internal.ts +1 -0
  216. package/src/nest-integration.ts +1 -0
  217. package/src/runtime/actors/actor-client.ts +40 -16
  218. package/src/runtime/actors/actor-handoff.ts +22 -8
  219. package/src/runtime/actors/actor-join-relocation.ts +1 -0
  220. package/src/runtime/actors/actor-local-native-join.ts +17 -26
  221. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  222. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  223. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  224. package/src/runtime/actors/index.ts +19 -5
  225. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  226. package/src/runtime/admission.ts +18 -5
  227. package/src/runtime/application-jobs/application-ingress-record-owner.ts +53 -27
  228. package/src/runtime/application-jobs/application-job-queue-scope.ts +56 -22
  229. package/src/runtime/application-jobs/contracts.ts +28 -2
  230. package/src/runtime/backend/contracts/index.ts +63 -32
  231. package/src/runtime/backend/mesh-completion-table.ts +175 -59
  232. package/src/runtime/backend/mesh-dispatch-pump.ts +59 -32
  233. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  234. package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -31
  235. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  236. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  237. package/src/runtime/backend/node/node-raw-binding-port.ts +73 -37
  238. package/src/runtime/backend/node/node-raw-mesh-backend.ts +209 -176
  239. package/src/runtime/backend/node/node-socket-backend-adapter.ts +32 -13
  240. package/src/runtime/backend/raw-binding-port.ts +18 -3
  241. package/src/runtime/backend/runtime-message.ts +6 -0
  242. package/src/runtime/backend/runtime-values.ts +1 -0
  243. package/src/runtime/channels/channel-clients.ts +90 -41
  244. package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
  245. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  246. package/src/runtime/channels/channel-dispatchers.ts +29 -27
  247. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  248. package/src/runtime/channels/channel-envelope.ts +133 -8
  249. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  250. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  251. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  252. package/src/runtime/channels/channel-runtime-manager.ts +29 -12
  253. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  254. package/src/runtime/channels/channel-transports.ts +128 -60
  255. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  256. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  257. package/src/runtime/channels/source-spot-router.ts +8 -4
  258. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  259. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  260. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  261. package/src/runtime/diagnostics/message-flow.ts +1 -1
  262. package/src/runtime/execution/serial-execution-queue.ts +2 -0
  263. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  264. package/src/runtime/foundation/durable-service-request.ts +137 -0
  265. package/src/runtime/foundation/operation-identity.ts +5 -1
  266. package/src/runtime/foundation/raw-service-mesh-runtime.ts +642 -253
  267. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  268. package/src/runtime/foundation/service-mailbox.ts +7 -1
  269. package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
  270. package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
  271. package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
  272. package/src/runtime/foundation/service-stateful-runtime.ts +128 -160
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -84
  274. package/src/runtime/foundation/service-topology-registry.ts +103 -42
  275. package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
  276. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  277. package/src/runtime/host/actor-packet-relay.ts +7 -0
  278. package/src/runtime/host/actor-runtime-options-factory.ts +14 -2
  279. package/src/runtime/host/application-job-queue.ts +249 -48
  280. package/src/runtime/host/entry-actor-runtime.ts +5 -0
  281. package/src/runtime/host/index.ts +224 -160
  282. package/src/runtime/host/instance-activation-authority.ts +132 -27
  283. package/src/runtime/host/remote-bound-session-relay.ts +2 -23
  284. package/src/runtime/host/route-mesh-runtime.ts +1 -1
  285. package/src/runtime/host/service-relocation-control.ts +11 -5
  286. package/src/runtime/host/service-relocation-host-runtime.ts +317 -291
  287. package/src/runtime/host/spot-address-transport.ts +49 -24
  288. package/src/runtime/host/spot-runtime-options-factory.ts +4 -0
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  290. package/src/runtime/locations/actor-location-claims.ts +52 -30
  291. package/src/runtime/locations/domain-store-contract.ts +6 -2
  292. package/src/runtime/locations/in-memory-authority-store.ts +113 -9
  293. package/src/runtime/locations/in-memory-location-store.ts +25 -3
  294. package/src/runtime/locations/internal-location-contracts.ts +4 -0
  295. package/src/runtime/locations/lifecycle.ts +8 -26
  296. package/src/runtime/locations/location-store-repository.ts +220 -15
  297. package/src/runtime/locations/resolvers.ts +25 -2
  298. package/src/runtime/locations/runtime.ts +28 -24
  299. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  300. package/src/runtime/messaging/packet-name.ts +5 -25
  301. package/src/runtime/messaging/request-result.ts +58 -0
  302. package/src/runtime/messaging/submission-result.ts +7 -3
  303. package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
  304. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  305. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +45 -23
  306. package/src/runtime/spots/index.ts +30 -2
  307. package/src/runtime/spots/spot-activation.ts +33 -10
  308. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  309. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  310. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  311. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  312. package/src/runtime/spots/spot-entry-activation.ts +12 -2
  313. package/src/runtime/spots/spot-handler-registry.ts +41 -8
  314. package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
  315. package/src/runtime/spots/spot-node-runtime-manager.ts +7 -12
  316. package/src/runtime/spots/spot-outbound.ts +36 -16
  317. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  318. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  319. package/src/runtime/spots/spot-runtime-ports.ts +3 -0
  320. package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
  321. package/src/runtime/spots/spot-timer.ts +5 -1
  322. package/src/runtime/streams/stream-session-runtime.ts +13 -30
@@ -3,7 +3,6 @@ import type { Socket } from '@zlink-systems/zlink';
3
3
  import type { ZLinkBackendObject } from '../contracts';
4
4
  import {
5
5
  closeBindingHandle,
6
- disableSocketLinger,
7
6
  isBindingNotFound,
8
7
  isContextTerminatedError,
9
8
  isRouteRecvRetryable,
@@ -36,10 +35,12 @@ export function wrapSocket<T extends { close(): void }>(
36
35
  recvTimeout?: number;
37
36
  sendTimeout?: number;
38
37
  noDrop?: boolean;
38
+ linger?: number;
39
39
  maxMsgSize?: bigint;
40
40
  lastEndpoint?: string;
41
41
  };
42
42
  };
43
+ if (socket.options !== undefined) socket.options.linger = 0;
43
44
  const hasRequest = typeof (nativeInstance as { request?: unknown }).request === 'function';
44
45
  const hasRoutedPeer =
45
46
  hasRequest && typeof (nativeInstance as { reply?: unknown }).reply === 'function';
@@ -50,9 +51,10 @@ export function wrapSocket<T extends { close(): void }>(
50
51
  : new ZLinkNodeEventLoopPoller(nativeInstance as unknown as Socket, pollCompletion, () => {});
51
52
  const adapter = {
52
53
  nativeInstance,
54
+ receiveAdmission: undefined as
55
+ import('../../foundation/service-liveness-registry').ServiceLivenessConnection | undefined,
53
56
  async dispose(): Promise<void> {
54
57
  eventLoopPoller?.dispose();
55
- disableSocketLinger(nativeInstance);
56
58
  closeBindingHandle(nativeInstance);
57
59
  },
58
60
  close(): void {
@@ -76,11 +78,6 @@ export function wrapSocket<T extends { close(): void }>(
76
78
  .setChannelName;
77
79
  setChannelName?.call(nativeInstance, channelName);
78
80
  },
79
- setReceiveFlowState(state: 0 | 1): void {
80
- (nativeInstance as T & { setReceiveFlowState(value: 0 | 1): void }).setReceiveFlowState(
81
- state
82
- );
83
- },
84
81
  setProbe(enabled: boolean): void {
85
82
  requireSocketOptions(socket).probe = enabled;
86
83
  },
@@ -114,6 +111,12 @@ export function wrapSocket<T extends { close(): void }>(
114
111
  toNativeRoutingId(routingId)
115
112
  );
116
113
  },
114
+ get lingerMs(): number {
115
+ return requireSocketOptions(socket).linger!;
116
+ },
117
+ set lingerMs(value: number) {
118
+ requireSocketOptions(socket).linger = value;
119
+ },
117
120
  get peerWeight(): number {
118
121
  return socket.options?.peerWeight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT;
119
122
  },
@@ -205,21 +208,34 @@ export function wrapSocket<T extends { close(): void }>(
205
208
  },
206
209
  request(...args: unknown[]): unknown {
207
210
  if (hasRoutedPeer) {
208
- const [routingId, payload, timeoutMs] = args as [unknown, unknown, number | undefined];
211
+ const [routingId, payload, timeoutMs, onAdmitted] = args as [
212
+ unknown,
213
+ unknown,
214
+ number | undefined,
215
+ (() => void) | undefined
216
+ ];
209
217
  return submitBindingRequest(
210
218
  (
211
219
  nativeInstance as T & { request(routingId: unknown): ZLinkBindingRequestOperation }
212
220
  ).request(toNativeRoutingId(routingId)),
213
221
  payload,
214
- timeoutMs
222
+ timeoutMs,
223
+ undefined,
224
+ onAdmitted
215
225
  );
216
226
  }
217
227
  if (hasRequest) {
218
- const [payload, timeoutMs] = args as [unknown, number | undefined];
228
+ const [payload, timeoutMs, onAdmitted] = args as [
229
+ unknown,
230
+ number | undefined,
231
+ (() => void) | undefined
232
+ ];
219
233
  return submitBindingRequest(
220
234
  (nativeInstance as T & { request(): ZLinkBindingRequestOperation }).request(),
221
235
  payload,
222
- timeoutMs
236
+ timeoutMs,
237
+ adapter.receiveAdmission?.recordReceived,
238
+ onAdmitted
223
239
  );
224
240
  }
225
241
  throw new TypeError('Backend request requires a DEALER or ROUTER socket.');
@@ -298,7 +314,8 @@ export function wrapSocket<T extends { close(): void }>(
298
314
  targetRid: unknown,
299
315
  targetSpot: unknown,
300
316
  payload: unknown,
301
- timeoutMs?: number
317
+ timeoutMs?: number,
318
+ onAdmitted?: () => void
302
319
  ): Promise<readonly unknown[]> {
303
320
  return submitBindingRequest(
304
321
  (
@@ -307,7 +324,9 @@ export function wrapSocket<T extends { close(): void }>(
307
324
  }
308
325
  ).requestToSpot(toNativeRoutingId(targetRid), toNativeRoutingId(targetSpot)),
309
326
  payload,
310
- timeoutMs
327
+ timeoutMs,
328
+ undefined,
329
+ onAdmitted
311
330
  );
312
331
  },
313
332
  disconnectPeer(routingId: unknown): void {
@@ -1,3 +1,10 @@
1
+ import type { SubmitResult } from './runtime-values';
2
+
3
+ export interface ZLinkRawSendSubmission {
4
+ readonly result: typeof SubmitResult.Ok | typeof SubmitResult.Backpressured;
5
+ readonly admitted: Promise<void>;
6
+ }
7
+
1
8
  export interface ZLinkRawReceivedRecord {
2
9
  readonly sourceRid: string;
3
10
  readonly sourceRoute: Uint8Array;
@@ -31,7 +38,6 @@ export interface ZLinkRawSocketPort {
31
38
  unbind(endpoint: string): void;
32
39
  connect(endpoint: string): void;
33
40
  disconnect(endpoint: string): void;
34
- setReceiveFlowState(state: 'running' | 'paused'): void;
35
41
  monitor(): ZLinkRawMonitorPort;
36
42
  close(): void;
37
43
  }
@@ -49,6 +55,9 @@ export interface ZLinkRawRouterRoute {
49
55
  }
50
56
 
51
57
  export interface ZLinkRawRouterPort extends ZLinkRawSocketPort {
58
+ setReceiveFlowState(state: 'running' | 'paused'): void;
59
+ /** Reports Core submit synchronously; admitted observes only pending admission. */
60
+ submitSend(targetRid: string, parts: readonly Uint8Array[]): ZLinkRawSendSubmission;
52
61
  disconnectRid?(routingId: string): void;
53
62
  localEndpoint(): string;
54
63
  setRoutingId(routingId: string): void;
@@ -57,7 +66,9 @@ export interface ZLinkRawRouterPort extends ZLinkRawSocketPort {
57
66
  request(
58
67
  targetRid: string,
59
68
  parts: readonly Uint8Array[],
60
- timeoutMs: number
69
+ timeoutMs: number,
70
+ recordReceived?: () => void,
71
+ onAdmitted?: () => void
61
72
  ): Promise<readonly Buffer[]>;
62
73
  receive(dontWait?: boolean): ZLinkRawReceivedRecord | undefined;
63
74
  /** The selected route of every RID. The socket's one route observer calls it. */
@@ -67,7 +78,11 @@ export interface ZLinkRawRouterPort extends ZLinkRawSocketPort {
67
78
  export interface ZLinkRawDealerPort extends ZLinkRawSocketPort {
68
79
  setRoutingId(routingId: string): void;
69
80
  send(parts: readonly Uint8Array[]): Promise<void>;
70
- request(parts: readonly Uint8Array[], timeoutMs: number): Promise<readonly Buffer[]>;
81
+ request(
82
+ parts: readonly Uint8Array[],
83
+ timeoutMs: number,
84
+ onAdmitted?: () => void
85
+ ): Promise<readonly Buffer[]>;
71
86
  receive(dontWait?: boolean): ZLinkRawReceivedRecord | undefined;
72
87
  }
73
88
 
@@ -17,6 +17,12 @@ export class ZLinkBufferMessage implements Message {
17
17
  return new ZLinkBufferMessage(bytes);
18
18
  }
19
19
 
20
+ static retainPayload(message: Message): Buffer {
21
+ // Binding data() Buffers retain their storage after the message handle closes.
22
+ // Preserve that ownership at runtime boundaries without copying the payload.
23
+ return message.data();
24
+ }
25
+
20
26
  data(): Buffer {
21
27
  return this.bytes;
22
28
  }
@@ -39,6 +39,7 @@ export type SubmitResult = (typeof SubmitResult)[keyof typeof SubmitResult];
39
39
  export type ZLinkBackendSendFlags = number;
40
40
  export type ZLinkBackendRecvFlags = number;
41
41
  export const ZLINK_BACKEND_SEND_NONE: ZLinkBackendSendFlags = 0;
42
+ export const ZLINK_BACKEND_SEND_DONT_WAIT: ZLinkBackendSendFlags = 1;
42
43
  export const ZLINK_BACKEND_RECV_DONT_WAIT: ZLinkBackendRecvFlags = 1;
43
44
 
44
45
  export class ZLinkBackendResultError extends Error {
@@ -1,4 +1,6 @@
1
1
  import { DEFAULT_REQUEST_TIMEOUT_MS } from '../../contracts/Configuration/Registration';
2
+ import { createZLinkRequest } from '../messaging/request-result';
3
+ import type { ZLinkRequest } from '../../contracts/Handlers/Attributes';
2
4
  import type {
3
5
  ZLinkChannelClient,
4
6
  ZLinkChannelRequestCall,
@@ -23,6 +25,7 @@ import {
23
25
  requireClassicFanoutCompletion,
24
26
  throwAlreadySubmitted,
25
27
  ZLinkSubmitStatus,
28
+ submittedResult,
26
29
  type ZLinkSubmitResult
27
30
  } from '../messaging/submission-result';
28
31
  import type {
@@ -165,7 +168,17 @@ export class DefaultZLinkFanoutClient implements ZLinkFanoutClient {
165
168
  }
166
169
  }
167
170
 
171
+ interface PreparedNodeSend {
172
+ readonly validate: () => void;
173
+ readonly submit: (
174
+ packetName: string | undefined,
175
+ metadata: ReadonlyMap<string, string>,
176
+ message?: unknown
177
+ ) => ZLinkSubmitResult | Promise<ZLinkSubmitResult>;
178
+ }
179
+
168
180
  export class DefaultZLinkRouteClient implements ZLinkRouteClient {
181
+ private readonly nodeSends = new Map<string, Map<string, PreparedNodeSend>>();
169
182
  constructor(
170
183
  private readonly registration: ZLinkFrameworkRegistration,
171
184
  private readonly transport?: ZLinkRouteClientTransport,
@@ -175,25 +188,28 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
175
188
  ) {}
176
189
 
177
190
  sendToNode(meshName: string, targetNodeRid: string, message: unknown): ZLinkSendCall {
178
- return new DefaultZLinkSendCall(
179
- () => this.requireMesh(meshName),
180
- async (packetName, metadata) =>
181
- normalizeSubmitResult(
182
- await this.requireTransport().submit(
183
- meshName,
184
- targetNodeRid,
185
- packetName,
186
- message,
187
- metadata
191
+ let targets = this.nodeSends.get(meshName);
192
+ if (targets === undefined) this.nodeSends.set(meshName, (targets = new Map()));
193
+ let prepared = targets.get(targetNodeRid);
194
+ if (prepared === undefined) {
195
+ prepared = {
196
+ validate: () => {
197
+ this.requireMesh(meshName);
198
+ },
199
+ submit: (packetName, metadata, payload) =>
200
+ normalizeSubmitResult(
201
+ this.requireTransport().submit(meshName, targetNodeRid, packetName, payload, metadata)
188
202
  )
189
- )
190
- );
203
+ };
204
+ targets.set(targetNodeRid, prepared);
205
+ }
206
+ return new DefaultZLinkSendCall(prepared.validate, prepared.submit, message);
191
207
  }
192
208
 
193
209
  requestToNode(meshName: string, targetNodeRid: string, request: unknown): ZLinkRequestCall {
194
210
  return new DefaultZLinkRequestCall(
195
211
  () => this.requireMesh(meshName),
196
- (packetName, timeoutMs, metadata, signal) =>
212
+ (packetName, timeoutMs, metadata, signal, onAdmitted) =>
197
213
  this.requireTransport().request(
198
214
  meshName,
199
215
  targetNodeRid,
@@ -201,7 +217,8 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
201
217
  request,
202
218
  timeoutMs,
203
219
  signal,
204
- metadata
220
+ metadata,
221
+ onAdmitted
205
222
  ),
206
223
  this.defaultRequestTimeout(meshName)
207
224
  );
@@ -233,7 +250,7 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
233
250
  requestToChannel(channelName: string, request: unknown): ZLinkChannelRequestCall {
234
251
  return new DefaultZLinkRequestCall(
235
252
  () => this.requireChannelRoute(channelName),
236
- (packetName, timeoutMs, metadata, signal) => {
253
+ (packetName, timeoutMs, metadata, signal, onAdmitted) => {
237
254
  const route = this.requireChannelRoute(channelName);
238
255
  if (route.kind === 'route-mesh') {
239
256
  return this.requireTransport().requestToChannel(
@@ -243,7 +260,8 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
243
260
  request,
244
261
  timeoutMs,
245
262
  signal,
246
- metadata
263
+ metadata,
264
+ onAdmitted
247
265
  );
248
266
  }
249
267
  return this.requireChannelTransport().request(
@@ -252,7 +270,8 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
252
270
  request,
253
271
  timeoutMs,
254
272
  signal,
255
- metadata
273
+ metadata,
274
+ onAdmitted
256
275
  );
257
276
  },
258
277
  this.defaultRequestTimeoutForChannel(channelName)
@@ -279,11 +298,12 @@ export class DefaultZLinkRouteClient implements ZLinkRouteClient {
279
298
  () => {
280
299
  this.requireSpotTransport();
281
300
  },
282
- (_packetName, timeoutMs, metadata, signal) =>
301
+ (_packetName, timeoutMs, metadata, signal, onAdmitted) =>
283
302
  requestToSpotHandle(this.requireSpotTransport(), spot, request, {
284
303
  timeoutMs,
285
304
  signal,
286
305
  metadata,
306
+ onAdmitted,
287
307
  spotRouterChannelIdForMesh: this.spotRouterChannelIdForMesh
288
308
  }),
289
309
  this.registration.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS
@@ -416,21 +436,24 @@ export class DefaultZLinkSpotPublisherClient implements ZLinkSpotPublisherClient
416
436
  }
417
437
 
418
438
  class DefaultZLinkSendCall implements ZLinkSendCall {
419
- private readonly selectedMetadata = new Map<string, string>();
439
+ private selectedMetadata?: Map<string, string>;
420
440
  private executed = false;
421
441
 
422
442
  constructor(
423
443
  private readonly validate: () => void,
424
444
  private readonly submitter: (
425
445
  packetName: string | undefined,
426
- metadata: ReadonlyMap<string, string>
427
- ) => Promise<ZLinkSubmitResult>
446
+ metadata: ReadonlyMap<string, string>,
447
+ message?: unknown
448
+ ) => ZLinkSubmitResult | Promise<ZLinkSubmitResult>,
449
+ private readonly message?: unknown
428
450
  ) {}
429
451
 
430
452
  metadata(key: string, value: string): this;
431
453
  metadata(metadata: ZLinkMessageMetadata): this;
432
454
  metadata(keyOrMetadata: string | ZLinkMessageMetadata, value?: string): this {
433
455
  ensureNotExecuted(this.executed);
456
+ this.selectedMetadata ??= new Map<string, string>();
434
457
  if (typeof keyOrMetadata === 'string') {
435
458
  this.selectedMetadata.set(keyOrMetadata, value!);
436
459
  } else {
@@ -441,12 +464,22 @@ class DefaultZLinkSendCall implements ZLinkSendCall {
441
464
  return this;
442
465
  }
443
466
 
444
- async submit(): Promise<void> {
445
- ensureNotExecuted(this.executed);
446
- this.validate();
447
- this.executed = true;
448
- const result = await this.submitter(undefined, new Map(this.selectedMetadata));
449
- requireOneWayCompletion(result, 'One-way send');
467
+ submit(): Promise<void> {
468
+ try {
469
+ ensureNotExecuted(this.executed);
470
+ this.validate();
471
+ this.executed = true;
472
+ const result = this.submitter(
473
+ undefined,
474
+ this.selectedMetadata ?? EMPTY_CALL_METADATA,
475
+ this.message
476
+ );
477
+ if (result instanceof Promise) return result.then(completeOneWaySend);
478
+ completeOneWaySend(result);
479
+ return completedOneWaySend;
480
+ } catch (error) {
481
+ return Promise.reject(error);
482
+ }
450
483
  }
451
484
  }
452
485
 
@@ -456,13 +489,24 @@ function ensureNotExecuted(executed: boolean): void {
456
489
  }
457
490
  }
458
491
 
459
- function normalizeSubmitResult(result: void | ZLinkSubmitResult): ZLinkSubmitResult {
460
- return result ?? { status: ZLinkSubmitStatus.Submitted };
492
+ const EMPTY_CALL_METADATA: ReadonlyMap<string, string> = new Map();
493
+ const completedOneWaySend = Promise.resolve();
494
+
495
+ function completeOneWaySend(result: ZLinkSubmitResult): void {
496
+ requireOneWayCompletion(result, 'One-way send');
497
+ }
498
+
499
+ function normalizeSubmitResult(
500
+ result: void | ZLinkSubmitResult | Promise<void | ZLinkSubmitResult>
501
+ ): ZLinkSubmitResult | Promise<ZLinkSubmitResult> {
502
+ return result instanceof Promise
503
+ ? result.then((value) => value ?? submittedResult)
504
+ : (result ?? submittedResult);
461
505
  }
462
506
 
463
507
  class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
464
508
  private timeoutMs?: number;
465
- private readonly selectedMetadata = new Map<string, string>();
509
+ private selectedMetadata?: Map<string, string>;
466
510
  private readonly turn: ZLinkSpotSerialTurn | undefined = captureZLinkSpotSerialTurn();
467
511
 
468
512
  constructor(
@@ -471,7 +515,8 @@ class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
471
515
  packetName: string | undefined,
472
516
  timeoutMs: number | undefined,
473
517
  metadata: ReadonlyMap<string, string>,
474
- signal?: AbortSignal
518
+ signal?: AbortSignal,
519
+ onAdmitted?: () => void
475
520
  ) => Promise<TReply>,
476
521
  private readonly defaultRequestTimeoutMs?: number
477
522
  ) {}
@@ -479,6 +524,7 @@ class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
479
524
  metadata(key: string, value: string): this;
480
525
  metadata(metadata: ZLinkMessageMetadata): this;
481
526
  metadata(keyOrMetadata: string | ZLinkMessageMetadata, value?: string): this {
527
+ this.selectedMetadata ??= new Map<string, string>();
482
528
  if (typeof keyOrMetadata === 'string') {
483
529
  this.selectedMetadata.set(keyOrMetadata, value!);
484
530
  } else {
@@ -494,15 +540,18 @@ class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
494
540
  return this;
495
541
  }
496
542
 
497
- async submit<TReply>(signal?: AbortSignal): Promise<TReply> {
498
- throwIfAborted(signal);
499
- this.validate();
500
- return this.submitter<TReply>(
501
- undefined,
502
- this.timeoutMs ?? this.defaultRequestTimeoutMs,
503
- new Map(this.selectedMetadata),
504
- signal
505
- );
543
+ submit<TReply>(signal?: AbortSignal): ZLinkRequest<TReply> {
544
+ return createZLinkRequest((onAdmitted) => {
545
+ throwIfAborted(signal);
546
+ this.validate();
547
+ return this.submitter<TReply>(
548
+ undefined,
549
+ this.timeoutMs ?? this.defaultRequestTimeoutMs,
550
+ this.selectedMetadata === undefined ? EMPTY_CALL_METADATA : new Map(this.selectedMetadata),
551
+ signal,
552
+ onAdmitted
553
+ );
554
+ });
506
555
  }
507
556
 
508
557
  async yield<TReply>(signal?: AbortSignal): Promise<TReply> {
@@ -512,7 +561,7 @@ class DefaultZLinkRequestCall implements ZLinkChannelRequestCall {
512
561
  const pending = this.submitter<TReply>(
513
562
  undefined,
514
563
  this.timeoutMs ?? this.defaultRequestTimeoutMs,
515
- new Map(this.selectedMetadata),
564
+ this.selectedMetadata === undefined ? EMPTY_CALL_METADATA : new Map(this.selectedMetadata),
516
565
  signal
517
566
  );
518
567
  return turn.yieldPromise(pending);
@@ -26,7 +26,6 @@ import {
26
26
  import { invokeZLinkHandlerFilters } from '../handlers';
27
27
  import {
28
28
  decodeChannelPayload,
29
- ZLinkChannelMessageKind,
30
29
  type ZLinkChannelEnvelope,
31
30
  type ZLinkChannelEnvelopeCodecRegistry
32
31
  } from './channel-envelope';
@@ -74,8 +73,8 @@ interface ZLinkRequestDispatch<TContext extends ZLinkMessageContext> {
74
73
  readonly context: TContext;
75
74
  readonly signal?: AbortSignal;
76
75
  readonly missingHandlerMessage: string;
77
- readonly writeReply: (reply: unknown) => Promise<void>;
78
- readonly writeError: (error: unknown) => Promise<void>;
76
+ readonly writeReply: (reply: unknown) => void | Promise<void>;
77
+ readonly writeError: (error: unknown) => void | Promise<void>;
79
78
  }
80
79
 
81
80
  export class ZLinkChannelDispatchPipeline {
@@ -113,17 +112,27 @@ export class ZLinkChannelDispatchPipeline {
113
112
  this.options.dispatchErrors.flow.flowCreationEnabled(),
114
113
  undefined
115
114
  );
116
- const invocation = await runWithFlow(flow, () =>
117
- this.invoke(
118
- dispatch.envelope,
119
- dispatch.codecs,
120
- dispatch.handler!,
121
- dispatch.context,
122
- dispatch.fields,
123
- dispatch.signal
124
- )
125
- );
126
- if (invocation.handlerInvoked) {
115
+ const invocation = await (flow === undefined
116
+ ? this.invoke(
117
+ dispatch.envelope,
118
+ dispatch.codecs,
119
+ dispatch.handler,
120
+ dispatch.context,
121
+ dispatch.fields,
122
+ dispatch.signal
123
+ )
124
+ : runWithFlow(flow, () =>
125
+ this.invoke(
126
+ dispatch.envelope,
127
+ dispatch.codecs,
128
+ dispatch.handler!,
129
+ dispatch.context,
130
+ dispatch.fields,
131
+ dispatch.signal
132
+ )
133
+ ));
134
+
135
+ if (invocation !== HANDLER_FILTER_REJECTED) {
127
136
  this.trace(ZLinkMessageFlowOutcome.Completed, dispatch.fields);
128
137
  }
129
138
  } catch (error) {
@@ -165,23 +174,33 @@ export class ZLinkChannelDispatchPipeline {
165
174
  this.options.dispatchErrors.flow.flowCreationEnabled(),
166
175
  undefined
167
176
  );
168
- const invocation = await runWithFlow(flow, () =>
169
- this.invoke(
170
- dispatch.envelope,
171
- dispatch.codecs,
172
- dispatch.handler!,
173
- dispatch.context,
174
- dispatch.fields,
175
- dispatch.signal
176
- )
177
- );
178
- if (!invocation.handlerInvoked) {
177
+ const invocation = await (flow === undefined
178
+ ? this.invoke(
179
+ dispatch.envelope,
180
+ dispatch.codecs,
181
+ dispatch.handler,
182
+ dispatch.context,
183
+ dispatch.fields,
184
+ dispatch.signal
185
+ )
186
+ : runWithFlow(flow, () =>
187
+ this.invoke(
188
+ dispatch.envelope,
189
+ dispatch.codecs,
190
+ dispatch.handler!,
191
+ dispatch.context,
192
+ dispatch.fields,
193
+ dispatch.signal
194
+ )
195
+ ));
196
+
197
+ if (invocation === HANDLER_FILTER_REJECTED) {
179
198
  throw createInternalFrameworkException(
180
199
  ZLinkFrameworkInternalErrorKind.RequestRejected,
181
200
  `A handler filter rejected '${this.options.channelName}:${dispatch.fields.packetName}'.`
182
201
  );
183
202
  }
184
- reply = invocation.value;
203
+ reply = invocation;
185
204
  } catch (error) {
186
205
  try {
187
206
  await dispatch.writeError(error);
@@ -206,7 +225,8 @@ export class ZLinkChannelDispatchPipeline {
206
225
  }
207
226
 
208
227
  try {
209
- await dispatch.writeReply(reply);
228
+ const written = dispatch.writeReply(reply);
229
+ if (written !== undefined) await written;
210
230
  this.trace(ZLinkMessageFlowOutcome.Replied, dispatch.fields);
211
231
  } catch (error) {
212
232
  // Spec 26 §3.1: a failed reply write means the reply delivery path is
@@ -240,9 +260,7 @@ export class ZLinkChannelDispatchPipeline {
240
260
  readonly writeProtocolError?: (error: ZLinkFrameworkException) => Promise<void>;
241
261
  }): Promise<void> {
242
262
  const { info } = input;
243
- const isRequest =
244
- info.kind === ZLinkChannelMessageKind.Request ||
245
- (info.kind === undefined && input.transportRequest);
263
+ const isRequest = input.transportRequest;
246
264
  let replied = false;
247
265
  if (isRequest && input.writeProtocolError !== undefined && info.correlationId !== undefined) {
248
266
  const protocolError = new ZLinkFrameworkException(
@@ -271,22 +289,37 @@ export class ZLinkChannelDispatchPipeline {
271
289
  });
272
290
  }
273
291
 
274
- private async invoke<TContext extends ZLinkMessageContext, TResult>(
292
+ private invoke<TContext extends ZLinkMessageContext, TResult>(
275
293
  envelope: ZLinkChannelEnvelope,
276
294
  codecs: ZLinkChannelEnvelopeCodecRegistry | undefined,
277
295
  handler: ZLinkChannelDispatchHandler<TContext, TResult>,
278
296
  context: TContext,
279
297
  fields: ZLinkChannelDispatchFields,
280
298
  signal?: AbortSignal
281
- ): Promise<{ readonly handlerInvoked: boolean; readonly value?: TResult }> {
299
+ ):
300
+ | TResult
301
+ | undefined
302
+ | typeof HANDLER_FILTER_REJECTED
303
+ | Promise<TResult | undefined | typeof HANDLER_FILTER_REJECTED> {
282
304
  releaseApplicationJobPermitBeforeHandler();
283
305
  if (this.filters.length === 0) {
284
306
  // Fast path for the dominant unfiltered dispatch: skip the filter
285
307
  // context object and chain machinery entirely.
286
308
  const payload = decodeChannelPayload(envelope, codecs);
287
309
  this.trace(ZLinkMessageFlowOutcome.Dispatched, fields);
288
- return { handlerInvoked: true, value: await handler.handle(payload, context) };
310
+ return handler.handle(payload, context);
289
311
  }
312
+ return this.invokeFiltered(envelope, codecs, handler, context, fields, signal);
313
+ }
314
+
315
+ private async invokeFiltered<TContext extends ZLinkMessageContext, TResult>(
316
+ envelope: ZLinkChannelEnvelope,
317
+ codecs: ZLinkChannelEnvelopeCodecRegistry | undefined,
318
+ handler: ZLinkChannelDispatchHandler<TContext, TResult>,
319
+ context: TContext,
320
+ fields: ZLinkChannelDispatchFields,
321
+ signal?: AbortSignal
322
+ ): Promise<TResult | undefined | typeof HANDLER_FILTER_REJECTED> {
290
323
  let value: TResult | undefined;
291
324
  const handlerInvoked = await invokeZLinkHandlerFilters(
292
325
  this.filters,
@@ -300,7 +333,7 @@ export class ZLinkChannelDispatchPipeline {
300
333
  },
301
334
  signal
302
335
  );
303
- return { handlerInvoked, value };
336
+ return handlerInvoked ? value : HANDLER_FILTER_REJECTED;
304
337
  }
305
338
 
306
339
  private createFilterContext(
@@ -401,6 +434,8 @@ export class ZLinkChannelDispatchPipeline {
401
434
  }
402
435
  }
403
436
 
437
+ const HANDLER_FILTER_REJECTED = Symbol('handler-filter-rejected');
438
+
404
439
  const DEFAULT_UNHANDLED_DISPATCH: ZLinkUnhandledDispatchOptions = {
405
440
  request: ZLinkUnhandledDispatchAction.ReplyError,
406
441
  send: ZLinkUnhandledDispatchAction.LogAndDrop,