@zlink-systems/framework 0.30.3 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (398) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Actors/ZLinkActor.d.ts +2 -0
  3. package/dist/contracts/Actors/ZLinkSessionBindingIdentity.d.ts +6 -0
  4. package/dist/contracts/Actors/ZLinkSessionBindingIdentity.js +2 -0
  5. package/dist/contracts/Actors/index.d.ts +1 -0
  6. package/dist/contracts/Actors/index.js +1 -0
  7. package/dist/contracts/Common/CoreTypes.d.ts +1 -0
  8. package/dist/contracts/Common/HandlerMessageType.d.ts +8 -0
  9. package/dist/contracts/Common/HandlerMessageType.js +41 -0
  10. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +1 -1
  11. package/dist/contracts/Common/ZLinkEncodedPayload.js +12 -20
  12. package/dist/contracts/Common/ZLinkMessage.js +11 -7
  13. package/dist/contracts/Common/encoded-payload-storage.d.ts +0 -2
  14. package/dist/contracts/Common/encoded-payload-storage.js +4 -16
  15. package/dist/contracts/Common/index.d.ts +1 -1
  16. package/dist/contracts/Common/payload-slab.d.ts +4 -0
  17. package/dist/contracts/Common/payload-slab.js +30 -0
  18. package/dist/contracts/Configuration/RegistrationBuilders.js +15 -9
  19. package/dist/contracts/Configuration/RegistrationTypes.d.ts +19 -0
  20. package/dist/contracts/Handlers/Contexts.d.ts +1 -0
  21. package/dist/contracts/Locations/Authority.d.ts +2 -0
  22. package/dist/internal.d.ts +9 -0
  23. package/dist/internal.js +23 -1
  24. package/dist/nest-integration.d.ts +1 -0
  25. package/dist/nest-integration.js +3 -1
  26. package/dist/runtime/actors/actor-client.d.ts +6 -2
  27. package/dist/runtime/actors/actor-client.js +120 -82
  28. package/dist/runtime/actors/actor-context.js +16 -5
  29. package/dist/runtime/actors/actor-execution-context.js +2 -2
  30. package/dist/runtime/actors/actor-handoff.d.ts +12 -1
  31. package/dist/runtime/actors/actor-handoff.js +79 -34
  32. package/dist/runtime/actors/actor-join-deferred-scope.js +6 -6
  33. package/dist/runtime/actors/actor-local-native-join.d.ts +2 -2
  34. package/dist/runtime/actors/actor-local-native-join.js +19 -17
  35. package/dist/runtime/actors/actor-mailbox.d.ts +1 -1
  36. package/dist/runtime/actors/actor-remote-joiner.d.ts +2 -2
  37. package/dist/runtime/actors/actor-remote-joiner.js +4 -4
  38. package/dist/runtime/actors/actor-routed-join-transport.d.ts +9 -3
  39. package/dist/runtime/actors/actor-routed-json-request.d.ts +3 -0
  40. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -2
  41. package/dist/runtime/actors/actor-runtime-state.d.ts +1 -1
  42. package/dist/runtime/actors/spot-actor-dispatch.d.ts +9 -5
  43. package/dist/runtime/actors/spot-actor-dispatch.js +60 -38
  44. package/dist/runtime/admission.d.ts +6 -4
  45. package/dist/runtime/admission.js +21 -10
  46. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +1 -0
  47. package/dist/runtime/application-jobs/application-ingress-record-owner.js +3 -0
  48. package/dist/runtime/backend/contracts/index.d.ts +26 -10
  49. package/dist/runtime/backend/mesh-completion-table.d.ts +7 -1
  50. package/dist/runtime/backend/mesh-completion-table.js +84 -20
  51. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +19 -6
  52. package/dist/runtime/backend/mesh-dispatch-pump.js +246 -147
  53. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -2
  54. package/dist/runtime/backend/node/node-backend-adapter-support.js +27 -19
  55. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +5 -2
  56. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +70 -13
  57. package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
  58. package/dist/runtime/backend/node/node-event-loop-poller.js +4 -3
  59. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +5 -1
  60. package/dist/runtime/backend/node/node-raw-binding-port.d.ts +7 -2
  61. package/dist/runtime/backend/node/node-raw-binding-port.js +99 -63
  62. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +34 -16
  63. package/dist/runtime/backend/node/node-raw-mesh-backend.js +210 -106
  64. package/dist/runtime/backend/node/node-socket-backend-adapter.js +20 -6
  65. package/dist/runtime/backend/raw-binding-port.d.ts +6 -3
  66. package/dist/runtime/channels/channel-clients.js +3 -3
  67. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +11 -7
  68. package/dist/runtime/channels/channel-dispatch-pipeline.js +40 -22
  69. package/dist/runtime/channels/channel-dispatch-services.d.ts +3 -1
  70. package/dist/runtime/channels/channel-dispatch-services.js +7 -6
  71. package/dist/runtime/channels/channel-dispatchers.d.ts +13 -6
  72. package/dist/runtime/channels/channel-dispatchers.js +57 -36
  73. package/dist/runtime/channels/channel-envelope.d.ts +2 -2
  74. package/dist/runtime/channels/channel-envelope.js +609 -83
  75. package/dist/runtime/channels/channel-multipart.d.ts +1 -0
  76. package/dist/runtime/channels/channel-multipart.js +10 -6
  77. package/dist/runtime/channels/channel-outbound-operations.d.ts +6 -9
  78. package/dist/runtime/channels/channel-outbound-operations.js +107 -105
  79. package/dist/runtime/channels/channel-receive-loops.d.ts +9 -7
  80. package/dist/runtime/channels/channel-receive-loops.js +126 -90
  81. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +23 -6
  82. package/dist/runtime/channels/channel-runtime-lifecycle.js +47 -38
  83. package/dist/runtime/channels/channel-runtime-manager.d.ts +13 -6
  84. package/dist/runtime/channels/channel-runtime-manager.js +32 -14
  85. package/dist/runtime/channels/channel-socket-registry.d.ts +28 -4
  86. package/dist/runtime/channels/channel-socket-registry.js +9 -1
  87. package/dist/runtime/channels/channel-transports.d.ts +23 -16
  88. package/dist/runtime/channels/channel-transports.js +139 -119
  89. package/dist/runtime/channels/dispatch-error-reporter.d.ts +4 -4
  90. package/dist/runtime/channels/dispatch-error-reporter.js +5 -5
  91. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  92. package/dist/runtime/channels/local-spot-route-transport.d.ts +5 -2
  93. package/dist/runtime/channels/local-spot-route-transport.js +15 -18
  94. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +6 -3
  95. package/dist/runtime/channels/router-socket-spot-route-transport.js +33 -19
  96. package/dist/runtime/channels/source-spot-router.d.ts +6 -3
  97. package/dist/runtime/channels/source-spot-router.js +34 -23
  98. package/dist/runtime/channels/spot-node-route-transport.d.ts +6 -3
  99. package/dist/runtime/channels/spot-node-route-transport.js +23 -17
  100. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +6 -3
  101. package/dist/runtime/channels/spot-route-bridge-transport.js +38 -24
  102. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +8 -4
  103. package/dist/runtime/channels/spot-route-dispatch-strategy.js +36 -23
  104. package/dist/runtime/diagnostics/dispatch-error-details.js +9 -3
  105. package/dist/runtime/diagnostics/message-flow-bootstrap.d.ts +1 -0
  106. package/dist/runtime/diagnostics/message-flow-bootstrap.js +8 -0
  107. package/dist/runtime/diagnostics/message-flow-delivery.d.ts +47 -0
  108. package/dist/runtime/diagnostics/message-flow-delivery.js +149 -0
  109. package/dist/runtime/diagnostics/message-flow-record.d.ts +50 -0
  110. package/dist/runtime/diagnostics/message-flow-record.js +228 -0
  111. package/dist/runtime/diagnostics/message-flow-worker.d.ts +1 -0
  112. package/dist/runtime/diagnostics/message-flow-worker.js +118 -0
  113. package/dist/runtime/diagnostics/message-flow.d.ts +7 -19
  114. package/dist/runtime/diagnostics/message-flow.js +42 -290
  115. package/dist/runtime/diagnostics/runtime-metrics.d.ts +4 -3
  116. package/dist/runtime/diagnostics/runtime-metrics.js +8 -4
  117. package/dist/runtime/execution/index.d.ts +1 -0
  118. package/dist/runtime/execution/index.js +6 -3
  119. package/dist/runtime/execution/serial-execution-queue.d.ts +26 -13
  120. package/dist/runtime/execution/serial-execution-queue.js +75 -71
  121. package/dist/runtime/foundation/durable-service-request.d.ts +12 -3
  122. package/dist/runtime/foundation/durable-service-request.js +158 -73
  123. package/dist/runtime/foundation/operation-registry.d.ts +33 -3
  124. package/dist/runtime/foundation/operation-registry.js +272 -33
  125. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +62 -23
  126. package/dist/runtime/foundation/raw-service-mesh-runtime.js +373 -194
  127. package/dist/runtime/foundation/request-runtime.d.ts +17 -0
  128. package/dist/runtime/foundation/request-runtime.js +163 -0
  129. package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
  130. package/dist/runtime/foundation/service-discovery-registry.js +6 -0
  131. package/dist/runtime/foundation/service-liveness-registry.d.ts +1 -1
  132. package/dist/runtime/foundation/service-mailbox.d.ts +4 -2
  133. package/dist/runtime/foundation/service-mailbox.js +4 -1
  134. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -2
  135. package/dist/runtime/foundation/service-relocation-object-owner.js +12 -5
  136. package/dist/runtime/foundation/service-runtime-contracts.d.ts +7 -2
  137. package/dist/runtime/foundation/service-stateful-registry.d.ts +6 -2
  138. package/dist/runtime/foundation/service-stateful-registry.js +38 -17
  139. package/dist/runtime/foundation/service-stateful-runtime.d.ts +91 -26
  140. package/dist/runtime/foundation/service-stateful-runtime.js +245 -120
  141. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -0
  142. package/dist/runtime/foundation/service-stateful-wire-codec.js +15 -0
  143. package/dist/runtime/foundation/service-topology-registry.d.ts +2 -0
  144. package/dist/runtime/foundation/service-topology-registry.js +13 -3
  145. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  146. package/dist/runtime/foundation/service-wire-constants.generated.js +12 -0
  147. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +5 -1
  148. package/dist/runtime/foundation/service-wire-m6a-codec.js +50 -15
  149. package/dist/runtime/host/actor-packet-relay.d.ts +5 -6
  150. package/dist/runtime/host/actor-packet-relay.js +58 -57
  151. package/dist/runtime/host/actor-placement-coordinator.d.ts +1 -1
  152. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
  153. package/dist/runtime/host/actor-runtime-options-factory.js +3 -2
  154. package/dist/runtime/host/actor-transfer-runtime.d.ts +3 -3
  155. package/dist/runtime/host/application-job-queue.d.ts +7 -5
  156. package/dist/runtime/host/application-job-queue.js +33 -21
  157. package/dist/runtime/host/bound-session-relay.js +0 -1
  158. package/dist/runtime/host/channel-runtime-options-factory.d.ts +2 -0
  159. package/dist/runtime/host/channel-runtime-options-factory.js +1 -0
  160. package/dist/runtime/host/entry-actor-runtime.d.ts +5 -2
  161. package/dist/runtime/host/entry-actor-runtime.js +2 -2
  162. package/dist/runtime/host/index.d.ts +106 -37
  163. package/dist/runtime/host/index.js +303 -151
  164. package/dist/runtime/host/location-runtime-owner.d.ts +2 -2
  165. package/dist/runtime/host/location-runtime-owner.js +1 -1
  166. package/dist/runtime/host/service-relocation-host-runtime.d.ts +195 -45
  167. package/dist/runtime/host/service-relocation-host-runtime.js +257 -144
  168. package/dist/runtime/host/spot-address-transport.d.ts +3 -0
  169. package/dist/runtime/host/spot-address-transport.js +73 -76
  170. package/dist/runtime/host/spot-runtime-options-factory.js +2 -0
  171. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -1
  172. package/dist/runtime/host/user-spot-creation-coordinator.js +49 -21
  173. package/dist/runtime/internal-observation.d.ts +1 -0
  174. package/dist/runtime/internal-observation.js +5 -0
  175. package/dist/runtime/locations/actor-location-claims.d.ts +1 -1
  176. package/dist/runtime/locations/actor-location-claims.js +15 -6
  177. package/dist/runtime/locations/auto-connect-loop.d.ts +0 -1
  178. package/dist/runtime/locations/auto-connect-loop.js +25 -19
  179. package/dist/runtime/locations/auto-connect-planner.js +2 -5
  180. package/dist/runtime/locations/auto-connect-reconciler.d.ts +1 -0
  181. package/dist/runtime/locations/auto-connect-reconciler.js +35 -23
  182. package/dist/runtime/locations/in-memory-authority-store.d.ts +1 -0
  183. package/dist/runtime/locations/in-memory-authority-store.js +15 -5
  184. package/dist/runtime/locations/in-memory-location-store.d.ts +0 -2
  185. package/dist/runtime/locations/in-memory-location-store.js +1 -38
  186. package/dist/runtime/locations/lifecycle.d.ts +1 -1
  187. package/dist/runtime/locations/lifecycle.js +2 -2
  188. package/dist/runtime/locations/location-store-repository.d.ts +0 -1
  189. package/dist/runtime/locations/location-store-repository.js +163 -246
  190. package/dist/runtime/locations/resolvers.d.ts +8 -1
  191. package/dist/runtime/locations/resolvers.js +16 -2
  192. package/dist/runtime/locations/runtime.d.ts +3 -3
  193. package/dist/runtime/locations/runtime.js +12 -16
  194. package/dist/runtime/messaging/creation-payload-codec.js +8 -7
  195. package/dist/runtime/messaging/framework-json-v1.d.ts +1 -1
  196. package/dist/runtime/messaging/framework-json-v1.js +6 -2
  197. package/dist/runtime/messaging/payload-codec.js +21 -35
  198. package/dist/runtime/messaging/request-deadline.d.ts +4 -2
  199. package/dist/runtime/messaging/request-deadline.js +40 -25
  200. package/dist/runtime/messaging/request-result.d.ts +14 -1
  201. package/dist/runtime/messaging/request-result.js +74 -13
  202. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +4 -0
  203. package/dist/runtime/protocol/service_wire_codec.generated.js +17 -7
  204. package/dist/runtime/spots/index.d.ts +28 -7
  205. package/dist/runtime/spots/index.js +31 -6
  206. package/dist/runtime/spots/spot-activation-registry.d.ts +3 -2
  207. package/dist/runtime/spots/spot-activation-registry.js +13 -8
  208. package/dist/runtime/spots/spot-activation-state.d.ts +2 -0
  209. package/dist/runtime/spots/spot-activation-state.js +1 -0
  210. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +9 -4
  211. package/dist/runtime/spots/spot-actor-admission-coordinator.js +33 -12
  212. package/dist/runtime/spots/spot-actor-ingress-admission.d.ts +40 -0
  213. package/dist/runtime/spots/spot-actor-ingress-admission.js +78 -0
  214. package/dist/runtime/spots/spot-actor-membership.js +3 -3
  215. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +16 -43
  216. package/dist/runtime/spots/spot-actor-packet-dispatch.js +56 -113
  217. package/dist/runtime/spots/spot-actor-packet-drain.d.ts +1 -0
  218. package/dist/runtime/spots/spot-actor-packet-drain.js +12 -5
  219. package/dist/runtime/spots/spot-entry-activation.d.ts +4 -3
  220. package/dist/runtime/spots/spot-entry-activation.js +7 -12
  221. package/dist/runtime/spots/spot-handler-registry.d.ts +5 -1
  222. package/dist/runtime/spots/spot-handler-registry.js +31 -15
  223. package/dist/runtime/spots/spot-manager-public.js +3 -2
  224. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +11 -6
  225. package/dist/runtime/spots/spot-node-runtime-manager.js +6 -1
  226. package/dist/runtime/spots/spot-outbound.d.ts +8 -2
  227. package/dist/runtime/spots/spot-outbound.js +5 -5
  228. package/dist/runtime/spots/spot-route-packet-dispatch.js +13 -8
  229. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +3 -3
  230. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +9 -5
  231. package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -2
  232. package/dist/runtime/spots/spot-serial-executor.d.ts +2 -1
  233. package/dist/runtime/spots/spot-serial-turn-executor.js +20 -26
  234. package/dist/runtime/spots/spot-subscription-dispatch.js +5 -2
  235. package/dist/runtime/spots/spot-timer.d.ts +1 -1
  236. package/dist/runtime/streams/actor-session-binding-registry.d.ts +11 -3
  237. package/dist/runtime/streams/actor-session-binding-registry.js +28 -0
  238. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -2
  239. package/dist/runtime/streams/bound-actor-relay-sender.js +3 -4
  240. package/dist/runtime/streams/bound-session-service.js +6 -7
  241. package/dist/runtime/streams/index.d.ts +3 -3
  242. package/dist/runtime/streams/index.js +22 -2
  243. package/dist/runtime/streams/managed-stream.js +2 -1
  244. package/dist/runtime/streams/session-calls.d.ts +1 -1
  245. package/dist/runtime/streams/session-calls.js +3 -9
  246. package/dist/runtime/streams/session-context.d.ts +2 -2
  247. package/dist/runtime/streams/session-context.js +2 -2
  248. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -0
  249. package/dist/runtime/streams/stream-session-runtime.js +64 -33
  250. package/package.json +3 -3
  251. package/src/contracts/Actors/ZLinkActor.ts +6 -0
  252. package/src/contracts/Actors/ZLinkSessionBindingIdentity.ts +7 -0
  253. package/src/contracts/Actors/index.ts +1 -0
  254. package/src/contracts/Common/CoreTypes.ts +1 -0
  255. package/src/contracts/Common/HandlerMessageType.ts +50 -0
  256. package/src/contracts/Common/ZLinkEncodedPayload.ts +13 -25
  257. package/src/contracts/Common/ZLinkMessage.ts +11 -7
  258. package/src/contracts/Common/encoded-payload-storage.ts +4 -16
  259. package/src/contracts/Common/index.ts +1 -1
  260. package/src/contracts/Common/payload-slab.ts +29 -0
  261. package/src/contracts/Configuration/RegistrationBuilders.ts +29 -15
  262. package/src/contracts/Configuration/RegistrationTypes.ts +19 -0
  263. package/src/contracts/Handlers/Contexts.ts +1 -0
  264. package/src/contracts/Locations/Authority.ts +7 -1
  265. package/src/internal.ts +17 -0
  266. package/src/nest-integration.ts +1 -0
  267. package/src/runtime/actors/actor-client.ts +257 -163
  268. package/src/runtime/actors/actor-context.ts +26 -14
  269. package/src/runtime/actors/actor-execution-context.ts +2 -2
  270. package/src/runtime/actors/actor-handoff.ts +86 -51
  271. package/src/runtime/actors/actor-join-deferred-scope.ts +6 -6
  272. package/src/runtime/actors/actor-local-native-join.ts +38 -17
  273. package/src/runtime/actors/actor-mailbox.ts +1 -1
  274. package/src/runtime/actors/actor-remote-joiner.ts +8 -4
  275. package/src/runtime/actors/actor-routed-join-transport.ts +13 -5
  276. package/src/runtime/actors/actor-routed-json-request.ts +3 -0
  277. package/src/runtime/actors/actor-runtime-contracts.ts +4 -2
  278. package/src/runtime/actors/actor-runtime-state.ts +1 -1
  279. package/src/runtime/actors/spot-actor-dispatch.ts +70 -68
  280. package/src/runtime/admission.ts +42 -15
  281. package/src/runtime/application-jobs/application-ingress-record-owner.ts +4 -0
  282. package/src/runtime/backend/contracts/index.ts +77 -10
  283. package/src/runtime/backend/mesh-completion-table.ts +106 -15
  284. package/src/runtime/backend/mesh-dispatch-pump.ts +294 -146
  285. package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -32
  286. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +91 -34
  287. package/src/runtime/backend/node/node-event-loop-poller.ts +14 -5
  288. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +5 -1
  289. package/src/runtime/backend/node/node-raw-binding-port.ts +180 -69
  290. package/src/runtime/backend/node/node-raw-mesh-backend.ts +386 -157
  291. package/src/runtime/backend/node/node-socket-backend-adapter.ts +56 -11
  292. package/src/runtime/backend/raw-binding-port.ts +13 -5
  293. package/src/runtime/channels/channel-clients.ts +26 -11
  294. package/src/runtime/channels/channel-dispatch-pipeline.ts +77 -65
  295. package/src/runtime/channels/channel-dispatch-services.ts +7 -12
  296. package/src/runtime/channels/channel-dispatchers.ts +93 -39
  297. package/src/runtime/channels/channel-envelope.ts +680 -144
  298. package/src/runtime/channels/channel-multipart.ts +17 -13
  299. package/src/runtime/channels/channel-outbound-operations.ts +204 -178
  300. package/src/runtime/channels/channel-receive-loops.ts +160 -107
  301. package/src/runtime/channels/channel-runtime-lifecycle.ts +64 -59
  302. package/src/runtime/channels/channel-runtime-manager.ts +74 -27
  303. package/src/runtime/channels/channel-socket-registry.ts +20 -5
  304. package/src/runtime/channels/channel-transports.ts +414 -287
  305. package/src/runtime/channels/dispatch-error-reporter.ts +4 -9
  306. package/src/runtime/channels/local-spot-route-transport.ts +27 -29
  307. package/src/runtime/channels/router-socket-spot-route-transport.ts +63 -32
  308. package/src/runtime/channels/source-spot-router.ts +75 -38
  309. package/src/runtime/channels/spot-node-route-transport.ts +67 -37
  310. package/src/runtime/channels/spot-route-bridge-transport.ts +62 -30
  311. package/src/runtime/channels/spot-route-dispatch-strategy.ts +105 -34
  312. package/src/runtime/diagnostics/dispatch-error-details.ts +10 -2
  313. package/src/runtime/diagnostics/message-flow-bootstrap.ts +6 -0
  314. package/src/runtime/diagnostics/message-flow-delivery.ts +171 -0
  315. package/src/runtime/diagnostics/message-flow-record.ts +295 -0
  316. package/src/runtime/diagnostics/message-flow-worker.ts +146 -0
  317. package/src/runtime/diagnostics/message-flow.ts +49 -362
  318. package/src/runtime/diagnostics/runtime-metrics.ts +10 -4
  319. package/src/runtime/execution/index.ts +6 -0
  320. package/src/runtime/execution/serial-execution-queue.ts +94 -96
  321. package/src/runtime/foundation/durable-service-request.ts +212 -89
  322. package/src/runtime/foundation/operation-registry.ts +287 -38
  323. package/src/runtime/foundation/raw-service-mesh-runtime.ts +617 -292
  324. package/src/runtime/foundation/request-runtime.ts +227 -0
  325. package/src/runtime/foundation/service-discovery-registry.ts +7 -0
  326. package/src/runtime/foundation/service-liveness-registry.ts +1 -1
  327. package/src/runtime/foundation/service-mailbox.ts +7 -2
  328. package/src/runtime/foundation/service-relocation-object-owner.ts +21 -6
  329. package/src/runtime/foundation/service-runtime-contracts.ts +12 -2
  330. package/src/runtime/foundation/service-stateful-registry.ts +52 -19
  331. package/src/runtime/foundation/service-stateful-runtime.ts +365 -198
  332. package/src/runtime/foundation/service-stateful-wire-codec.ts +18 -0
  333. package/src/runtime/foundation/service-topology-registry.ts +21 -3
  334. package/src/runtime/foundation/service-wire-constants.generated.ts +10 -0
  335. package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -17
  336. package/src/runtime/host/actor-packet-relay.ts +160 -156
  337. package/src/runtime/host/actor-placement-coordinator.ts +1 -1
  338. package/src/runtime/host/actor-runtime-options-factory.ts +7 -2
  339. package/src/runtime/host/actor-transfer-runtime.ts +3 -3
  340. package/src/runtime/host/application-job-queue.ts +56 -27
  341. package/src/runtime/host/bound-session-relay.ts +0 -1
  342. package/src/runtime/host/channel-runtime-options-factory.ts +3 -0
  343. package/src/runtime/host/entry-actor-runtime.ts +14 -6
  344. package/src/runtime/host/index.ts +388 -113
  345. package/src/runtime/host/location-runtime-owner.ts +3 -3
  346. package/src/runtime/host/service-relocation-host-runtime.ts +380 -252
  347. package/src/runtime/host/spot-address-transport.ts +110 -95
  348. package/src/runtime/host/spot-runtime-options-factory.ts +3 -0
  349. package/src/runtime/host/user-spot-creation-coordinator.ts +69 -22
  350. package/src/runtime/internal-observation.ts +2 -0
  351. package/src/runtime/locations/actor-location-claims.ts +42 -16
  352. package/src/runtime/locations/auto-connect-loop.ts +24 -16
  353. package/src/runtime/locations/auto-connect-planner.ts +2 -5
  354. package/src/runtime/locations/auto-connect-reconciler.ts +37 -24
  355. package/src/runtime/locations/in-memory-authority-store.ts +27 -7
  356. package/src/runtime/locations/in-memory-location-store.ts +1 -74
  357. package/src/runtime/locations/lifecycle.ts +4 -2
  358. package/src/runtime/locations/location-store-repository.ts +228 -308
  359. package/src/runtime/locations/resolvers.ts +20 -8
  360. package/src/runtime/locations/runtime.ts +16 -28
  361. package/src/runtime/messaging/creation-payload-codec.ts +12 -10
  362. package/src/runtime/messaging/framework-json-v1.ts +10 -1
  363. package/src/runtime/messaging/payload-codec.ts +50 -75
  364. package/src/runtime/messaging/request-deadline.ts +47 -39
  365. package/src/runtime/messaging/request-result.ts +88 -17
  366. package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
  367. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
  368. package/src/runtime/spots/index.ts +57 -10
  369. package/src/runtime/spots/spot-activation-registry.ts +12 -8
  370. package/src/runtime/spots/spot-activation-state.ts +2 -0
  371. package/src/runtime/spots/spot-actor-admission-coordinator.ts +62 -37
  372. package/src/runtime/spots/spot-actor-ingress-admission.ts +157 -0
  373. package/src/runtime/spots/spot-actor-membership.ts +8 -5
  374. package/src/runtime/spots/spot-actor-packet-dispatch.ts +122 -206
  375. package/src/runtime/spots/spot-actor-packet-drain.ts +21 -6
  376. package/src/runtime/spots/spot-entry-activation.ts +25 -35
  377. package/src/runtime/spots/spot-handler-registry.ts +72 -15
  378. package/src/runtime/spots/spot-manager-public.ts +4 -2
  379. package/src/runtime/spots/spot-node-runtime-manager.ts +16 -7
  380. package/src/runtime/spots/spot-outbound.ts +26 -10
  381. package/src/runtime/spots/spot-route-packet-dispatch.ts +18 -8
  382. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +14 -8
  383. package/src/runtime/spots/spot-runtime-ports.ts +5 -2
  384. package/src/runtime/spots/spot-serial-executor.ts +1 -1
  385. package/src/runtime/spots/spot-serial-turn-executor.ts +25 -40
  386. package/src/runtime/spots/spot-subscription-dispatch.ts +9 -2
  387. package/src/runtime/spots/spot-timer.ts +1 -1
  388. package/src/runtime/streams/actor-session-binding-registry.ts +46 -3
  389. package/src/runtime/streams/bound-actor-relay-sender.ts +16 -5
  390. package/src/runtime/streams/bound-session-service.ts +10 -7
  391. package/src/runtime/streams/index.ts +30 -4
  392. package/src/runtime/streams/managed-stream.ts +2 -1
  393. package/src/runtime/streams/session-calls.ts +9 -14
  394. package/src/runtime/streams/session-context.ts +6 -11
  395. package/src/runtime/streams/stream-session-runtime.ts +79 -40
  396. package/dist/runtime/spots/spot-lifecycle-metrics.d.ts +0 -8
  397. package/dist/runtime/spots/spot-lifecycle-metrics.js +0 -17
  398. package/src/runtime/spots/spot-lifecycle-metrics.ts +0 -16
@@ -1,3 +1,6 @@
1
+ import type { MeshOperationSubmission } from '../mesh-completion-table';
2
+ import type { RequestRuntime } from '../../foundation/request-runtime';
3
+ import type { PendingOperation } from '../../foundation/operation-registry';
1
4
  import { routingIdsEqual } from '../../routing-id';
2
5
  import { requestDurableService } from '../../foundation/durable-service-request';
3
6
  import { encodeRoutingIdStorageHex, toBackendRoutingId } from '../../routing-id';
@@ -126,6 +129,7 @@ import {
126
129
  decodeMultipartApplicationParts,
127
130
  decodeMultipartParts,
128
131
  encodeMultipartApplicationPayload,
132
+ encodeMultipartPayload,
129
133
  ServiceWireProtocolError,
130
134
  type ServiceApplicationPayload
131
135
  } from '../../foundation/service-wire-m6a-codec';
@@ -151,10 +155,6 @@ const UNSTARTED_DIAGNOSTIC_ENDPOINT = 'inproc://not-started';
151
155
  const MULTIPART_PACKET_NAME = SERVICE_FRAMEWORK_MULTIPART_PACKET_NAME;
152
156
  const MULTIPART_CONTENT_TYPE = SERVICE_FRAMEWORK_MULTIPART_CONTENT_TYPE;
153
157
  const MAX_DRAIN_RECORDS = 64;
154
- // The maintenance timer runs at the nearest management deadline and never
155
- // sooner than this. Only the binding readable handler admits receive work;
156
- // this timer never probes the socket.
157
- const MESH_BACKEND_MAINTENANCE_INTERVAL_MS = 1;
158
158
  /** The longest single timer delay Node accepts. */
159
159
  const MESH_BACKEND_MAINTENANCE_MAX_DELAY_MS = 2 ** 31 - 1;
160
160
  // Spec 08 §4.2 bounds the combined turn. Raw gets one equal share; stateful
@@ -182,6 +182,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
182
182
  readonly endpoint: string;
183
183
  readonly nodeRoutingId?: string;
184
184
  readonly lifecycleGeneration?: bigint;
185
+ readonly securityIdentity?: string;
185
186
  }
186
187
  >();
187
188
  private completionHandler?: ZLinkMeshCompletionHandler;
@@ -189,16 +190,21 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
189
190
  private readonly lifecycleGeneration: bigint;
190
191
  private bindEndpoint?: string;
191
192
  private advertiseHost?: string;
192
- private runtime?: RawServiceMeshRuntime;
193
+ runtime?: RawServiceMeshRuntime;
193
194
  private stateful?: ServiceStatefulRuntime;
194
195
  private readyHandler?: (domains: number) => number;
195
196
  private maintenanceTimer?: NodeJS.Timeout;
196
197
  private maintenanceDueMs = Number.POSITIVE_INFINITY;
197
198
  private pumpTask?: Promise<void>;
198
199
  private readable = 0;
199
- private readonly onReadable = (receiveReady: boolean, routeReady: boolean): void => {
200
+ private readonly onReadable = (
201
+ receiveReady: boolean,
202
+ routeReady: boolean,
203
+ connectReady: boolean
204
+ ): void => {
200
205
  if (receiveReady) this.readable |= 1;
201
206
  if (routeReady) this.readable |= 2;
207
+ if (connectReady) this.readable |= 4;
202
208
  this.pump();
203
209
  };
204
210
  private readonly onMaintenance = (): void => {
@@ -238,8 +244,8 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
238
244
  record: import('../../foundation/service-stateful-wire-codec').ServiceMessageFollowRecord
239
245
  ) => void;
240
246
  private dispatchErrors?: ZLinkDispatchErrorReporter;
241
- private sessionOwnerDescriptors?: ServiceSessionOwnerDescriptors;
242
247
  private requestSourceAcceptance?: import('../contracts').ZLinkBackendRequestSourceAcceptance;
248
+ private sessionOwnerDescriptors?: ServiceSessionOwnerDescriptors;
243
249
  private readonly peerDisconnectedHandlers = new Set<(endpoint: string) => void>();
244
250
  constructor(
245
251
  private readonly meshName: string,
@@ -248,7 +254,11 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
248
254
  private readonly applicationJobQueue?: ApplicationJobQueuePort,
249
255
  private readonly applicationJobReceiveFlowFailureSink?: (error: unknown) => void,
250
256
  private readonly peerAdmissionSealed?: () => boolean,
251
- private readonly infrastructureTaskRunner?: import('../../spots/spot-actor-join-dispatch').ZLinkDetachedTaskRunner
257
+ private readonly infrastructureTaskRunner?: import('../../spots/spot-actor-join-dispatch').ZLinkDetachedTaskRunner,
258
+ runtimeDependencies?: {
259
+ readonly raw?: RawServiceMeshRuntime;
260
+ readonly stateful?: ServiceStatefulRuntime;
261
+ }
252
262
  ) {
253
263
  if (meshName.length === 0) throw new TypeError('MeshName must be non-empty.');
254
264
  if (routingId === undefined || routingId.length === 0) {
@@ -256,6 +266,8 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
256
266
  }
257
267
  this.routingId = routingId;
258
268
  this.lifecycleGeneration = createLifecycleGeneration();
269
+ this.runtime = runtimeDependencies?.raw;
270
+ this.stateful = runtimeDependencies?.stateful;
259
271
  }
260
272
 
261
273
  configureObjectPlacement(options: {
@@ -365,17 +377,18 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
365
377
  deadlineUnixMs: bigint,
366
378
  sourceSpotId?: string,
367
379
  metadata?: ReadonlyMap<string, string>,
368
- onAdmitted?: () => void
380
+ onAdmitted?: () => void,
381
+ requestOperation?: PendingOperation<unknown>
369
382
  ): MeshOperationId {
370
- return this.observeStateful(
371
- OperationKind.InstanceSpotRequest,
383
+ return this.observeStatefulRequest(OperationKind.InstanceSpotRequest, requestOperation, () =>
372
384
  this.requireStateful().requestToMissingInstanceSpotFrame(
373
385
  target,
374
386
  encodeMultipartApplicationFrame(parts),
375
387
  deadlineUnixMs,
376
388
  sourceSpotId,
377
389
  metadata === undefined ? undefined : encodeServiceMetadataFrame(metadata),
378
- onAdmitted
390
+ onAdmitted,
391
+ requestOperation
379
392
  )
380
393
  );
381
394
  }
@@ -398,6 +411,13 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
398
411
  this.advertiseHost = host;
399
412
  }
400
413
 
414
+ private requests?: RequestRuntime;
415
+
416
+ setRequestRuntime(requests: RequestRuntime): void {
417
+ this.requireNotStarted();
418
+ this.requests = requests;
419
+ }
420
+
401
421
  start(): void {
402
422
  if (this.runtime !== undefined) return;
403
423
  if (this.closed) throw new Error('MeshNode is closed.');
@@ -405,12 +425,13 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
405
425
  throw new Error('MeshNode bind endpoint is not configured.');
406
426
  const descriptor = this.createDescriptor();
407
427
  const runtime = new RawServiceMeshRuntime({
428
+ requests: this.requests,
408
429
  onPendingOperationsChanged: this.onPendingOperationsChanged,
409
430
  descriptor,
410
431
  resolveAdvertisedEndpoint: (boundEndpoint) => this.resolveAdvertisedEndpoint(boundEndpoint),
411
432
  bindingPort: this.bindingPort,
412
433
  applicationJobQueue: this.requireApplicationJobQueue(),
413
- onReceiveReady: () => this.onReadable(true, false),
434
+ onReceiveReady: () => this.onReadable(true, false, false),
414
435
  infrastructureTaskRunner: this.infrastructureTaskRunner,
415
436
  peerAdmissionSealed: this.peerAdmissionSealed,
416
437
  onReceiveFlowConfigFailure: this.applicationJobReceiveFlowFailureSink,
@@ -444,7 +465,8 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
444
465
  runtime,
445
466
  descriptor.nodeRoutingId,
446
467
  descriptor.lifecycleGeneration,
447
- this.onPendingOperationsChanged
468
+ this.onPendingOperationsChanged,
469
+ this.requests
448
470
  );
449
471
  if (this.dispatchErrors !== undefined) {
450
472
  this.stateful.setDispatchErrorReporter(this.dispatchErrors, this.meshName);
@@ -550,19 +572,34 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
550
572
  const runtime = this.requireRuntime();
551
573
  const nodeRoutingId =
552
574
  options.expectedRid === undefined ? undefined : String(options.expectedRid);
575
+ const securityIdentity =
576
+ options.expectedSecurityIdentity ?? runtime.topology.localDescriptor().securityIdentity;
577
+ for (const [id, existing] of this.peerIntents) {
578
+ if (existing.endpoint !== options.endpoint) continue;
579
+ if (
580
+ existing.nodeRoutingId === nodeRoutingId &&
581
+ existing.securityIdentity === securityIdentity &&
582
+ existing.lifecycleGeneration === options.expectedLifecycleGeneration
583
+ ) {
584
+ return id;
585
+ }
586
+ runtime.disconnectPeerEndpoint(existing.endpoint);
587
+ this.peerIntents.delete(id);
588
+ }
553
589
  if (nodeRoutingId === undefined) {
554
590
  runtime.connectPeerEndpoint(options.endpoint);
555
591
  } else {
556
592
  runtime.connectPeerByRoutingId(
557
593
  options.endpoint,
558
594
  nodeRoutingId,
559
- options.expectedSecurityIdentity ?? runtime.topology.localDescriptor().securityIdentity,
595
+ securityIdentity,
560
596
  options.expectedLifecycleGeneration
561
597
  );
562
598
  }
563
599
  const intent = this.nextPeerIntent++;
564
600
  this.peerIntents.set(intent, {
565
601
  endpoint: options.endpoint,
602
+ securityIdentity,
566
603
  ...(nodeRoutingId === undefined
567
604
  ? {}
568
605
  : {
@@ -592,6 +629,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
592
629
  peer.securityIdentity,
593
630
  peer.lifecycleGeneration
594
631
  );
632
+ this.scheduleMaintenance();
595
633
  }
596
634
 
597
635
  removePeerConnection(intentId: bigint): void {
@@ -741,63 +779,106 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
741
779
  frames: readonly Uint8Array[],
742
780
  options?: {
743
781
  readonly timeoutMs?: number;
782
+ readonly requestOperation?: PendingOperation<unknown>;
744
783
  readonly signal?: AbortSignal;
745
784
  readonly onSubmitted?: (signal: AbortSignal) => Promise<void>;
746
785
  }
747
786
  ): Promise<readonly Uint8Array[]> {
748
- return requestDurableService(
749
- this.requireRuntime(),
787
+ const runtime = this.requireRuntime();
788
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
789
+ const pending =
790
+ options?.requestOperation ?? runtime.beginInfrastructureRequest(timeoutMs, options?.signal);
791
+ if (options?.requestOperation !== undefined) {
792
+ return requestDurableService(
793
+ runtime,
794
+ String(targetRid),
795
+ frames,
796
+ pending,
797
+ 'relocation control',
798
+ options.signal,
799
+ options.onSubmitted
800
+ );
801
+ }
802
+ const completed = (reply: readonly Buffer[]) => {
803
+ pending.complete(reply);
804
+ };
805
+ const failed = (error: unknown) => {
806
+ pending.fail(error);
807
+ };
808
+ void requestDurableService(
809
+ runtime,
750
810
  String(targetRid),
751
811
  frames,
752
- performance.now() + (options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS),
812
+ pending,
753
813
  'relocation control',
754
814
  options?.signal,
755
815
  options?.onSubmitted
756
- );
816
+ ).then(completed, failed);
817
+ return pending.promise as Promise<readonly Uint8Array[]>;
757
818
  }
758
819
 
759
820
  requestToNode(
760
821
  targetRid: unknown,
761
822
  parts: MessageLike | readonly MessageLike[],
762
- options?: { readonly timeoutMs?: number; readonly onAdmitted?: () => void }
823
+ options?: {
824
+ readonly timeoutMs?: number;
825
+ readonly requestOperation?: PendingOperation<unknown>;
826
+ readonly onAdmitted?: () => void;
827
+ },
828
+ completion?: import('../mesh-completion-table').ZLinkMeshCompletionHandler
763
829
  ): MeshOperationId {
764
830
  const pending = this.requireRuntime().requestToNode(
765
831
  String(targetRid),
766
832
  encodeMultipartApplicationFrame(parts),
767
833
  options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
768
834
  options?.onAdmitted,
769
- this.requestObserver,
770
- OperationKind.NodeRequest
835
+ this.requestObserverFor(completion),
836
+ OperationKind.NodeRequest,
837
+ options?.requestOperation
771
838
  );
772
839
  return this.observedOperation(pending, OperationKind.NodeRequest);
773
840
  }
774
841
 
775
- async sendToChannel(
842
+ sendToChannel(
776
843
  channelName: string,
777
844
  parts: MessageLike | readonly MessageLike[]
778
845
  ): Promise<SubmitResultValue> {
779
- return this.requireRuntime().sendToChannel(channelName, encodeMultipartApplicationFrame(parts));
846
+ try {
847
+ return Promise.resolve(
848
+ this.requireRuntime().sendToChannel(channelName, encodeMultipartApplicationFrame(parts))
849
+ );
850
+ } catch (error) {
851
+ return Promise.reject(error);
852
+ }
780
853
  }
781
854
 
782
855
  requestToChannel(
783
856
  channelName: string,
784
857
  parts: MessageLike | readonly MessageLike[],
785
- options?: { readonly timeoutMs?: number; readonly onAdmitted?: () => void }
858
+ options?: {
859
+ readonly timeoutMs?: number;
860
+ readonly requestOperation?: PendingOperation<unknown>;
861
+ readonly onAdmitted?: () => void;
862
+ },
863
+ completion?: import('../mesh-completion-table').ZLinkMeshCompletionHandler
786
864
  ): MeshOperationId {
787
865
  const pending = this.requireRuntime().requestToChannel(
788
866
  channelName,
789
867
  encodeMultipartApplicationFrame(parts),
790
868
  options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
791
869
  options?.onAdmitted,
792
- this.requestObserver,
793
- OperationKind.ChannelRequest
870
+ this.requestObserverFor(completion),
871
+ OperationKind.ChannelRequest,
872
+ options?.requestOperation
794
873
  );
795
874
  return this.observedOperation(pending, OperationKind.ChannelRequest);
796
875
  }
797
876
 
798
877
  status() {
799
878
  const descriptor = this.runtime?.topology.localDescriptor() ?? this.createDescriptor();
800
- const peers = this.runtime?.topology.peers() ?? [];
879
+ const peers = (this.runtime?.topology.peers() ?? []).filter(
880
+ (peer) => this.runtime?.isPeerRouteReady(peer.descriptor.nodeRoutingId) === true
881
+ );
801
882
  return {
802
883
  state: stateCode(descriptor.state),
803
884
  routingId: descriptor.nodeRoutingId as RoutingId,
@@ -1255,19 +1336,26 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
1255
1336
  sourceSpotId?: string,
1256
1337
  metadata?: ReadonlyMap<string, string>,
1257
1338
  instanceIntent = false,
1258
- onAdmitted?: () => void
1339
+ onAdmitted?: () => void,
1340
+ requestOperation?: PendingOperation<unknown>,
1341
+ completion?: import('../mesh-completion-table').ZLinkMeshCompletionHandler
1259
1342
  ): MeshOperationId {
1260
- return this.observeStateful(
1343
+ return this.observeStatefulRequest(
1261
1344
  OperationKind.InstanceSpotRequest,
1262
- this.requireStateful().requestToInstanceSpot(
1263
- route,
1264
- encodeMultipart(parts),
1265
- timeoutMs,
1266
- sourceSpotId,
1267
- metadata === undefined ? undefined : encodeServiceMetadataFrame(metadata),
1268
- instanceIntent,
1269
- onAdmitted
1270
- )
1345
+ requestOperation,
1346
+ (receiver) =>
1347
+ this.requireStateful().requestToInstanceSpot(
1348
+ route,
1349
+ encodeMultipart(parts),
1350
+ timeoutMs,
1351
+ sourceSpotId,
1352
+ metadata === undefined ? undefined : encodeServiceMetadataFrame(metadata),
1353
+ instanceIntent,
1354
+ onAdmitted,
1355
+ requestOperation,
1356
+ receiver
1357
+ ),
1358
+ completion
1271
1359
  );
1272
1360
  }
1273
1361
 
@@ -1418,21 +1506,28 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
1418
1506
  parts: MessageLike | readonly MessageLike[],
1419
1507
  options?: {
1420
1508
  readonly timeoutMs?: number;
1509
+ readonly requestOperation?: PendingOperation<unknown>;
1421
1510
  readonly onAdmitted?: () => void;
1422
1511
  readonly routeFence?: import('../../foundation/service-stateful-wire-codec').ServiceActorRouteFence;
1423
- }
1512
+ },
1513
+ completion?: import('../mesh-completion-table').ZLinkMeshCompletionHandler
1424
1514
  ): MeshOperationId {
1425
- return this.observeStateful(
1515
+ return this.observeStatefulRequest(
1426
1516
  OperationKind.ActorRequest,
1427
- this.requireStateful().requestToActor(
1428
- actor,
1429
- encodeMultipart(parts),
1430
- options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
1431
- undefined,
1432
- undefined,
1433
- options?.onAdmitted,
1434
- options?.routeFence
1435
- )
1517
+ options?.requestOperation,
1518
+ (receiver) =>
1519
+ this.requireStateful().requestToActor(
1520
+ actor,
1521
+ encodeMultipart(parts),
1522
+ options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
1523
+ undefined,
1524
+ undefined,
1525
+ options?.onAdmitted,
1526
+ options?.routeFence,
1527
+ options?.requestOperation,
1528
+ receiver
1529
+ ),
1530
+ completion
1436
1531
  );
1437
1532
  }
1438
1533
 
@@ -1460,17 +1555,22 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
1460
1555
  source: ZLinkBackendActorRef,
1461
1556
  target: ZLinkBackendActorRef,
1462
1557
  parts: MessageLike | readonly MessageLike[],
1463
- options?: { readonly timeoutMs?: number; readonly onAdmitted?: () => void }
1558
+ options?: {
1559
+ readonly timeoutMs?: number;
1560
+ readonly requestOperation?: PendingOperation<unknown>;
1561
+ readonly onAdmitted?: () => void;
1562
+ }
1464
1563
  ): MeshOperationId {
1465
- return this.observeStateful(
1466
- OperationKind.ActorRequest,
1564
+ return this.observeStatefulRequest(OperationKind.ActorRequest, options?.requestOperation, () =>
1467
1565
  this.requireStateful().requestToActor(
1468
1566
  target,
1469
1567
  encodeMultipart(parts),
1470
1568
  options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
1471
1569
  source,
1472
1570
  undefined,
1473
- options?.onAdmitted
1571
+ options?.onAdmitted,
1572
+ undefined,
1573
+ options?.requestOperation
1474
1574
  )
1475
1575
  );
1476
1576
  }
@@ -1535,17 +1635,24 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
1535
1635
  target: ServiceDirectSpotRouteFence,
1536
1636
  parts: MessageLike | readonly MessageLike[],
1537
1637
  timeoutMs: number,
1538
- onAdmitted?: () => void
1638
+ onAdmitted?: () => void,
1639
+ requestOperation?: PendingOperation<unknown>,
1640
+ completion?: import('../mesh-completion-table').ZLinkMeshCompletionHandler
1539
1641
  ): MeshOperationId {
1540
- return this.observeStateful(
1642
+ return this.observeStatefulRequest(
1541
1643
  OperationKind.SpotRequest,
1542
- this.requireStateful().requestToSpot(
1543
- source.ref.spotId,
1544
- target,
1545
- encodeMultipart(parts),
1546
- timeoutMs,
1547
- onAdmitted
1548
- )
1644
+ requestOperation,
1645
+ (receiver) =>
1646
+ this.requireStateful().requestToSpot(
1647
+ source.ref.spotId,
1648
+ target,
1649
+ encodeMultipart(parts),
1650
+ timeoutMs,
1651
+ onAdmitted,
1652
+ requestOperation,
1653
+ receiver
1654
+ ),
1655
+ completion
1549
1656
  );
1550
1657
  }
1551
1658
 
@@ -1584,7 +1691,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
1584
1691
  this.requireStateful().clearSubscriptions(state.ref.spotId);
1585
1692
  }
1586
1693
 
1587
- private createDescriptor(): ServiceNodeDescriptor {
1694
+ createDescriptor(): ServiceNodeDescriptor {
1588
1695
  const channels: ServiceChannelDescriptor[] = [...this.channels]
1589
1696
  .map(([name, weight]) => ({ name, weight }))
1590
1697
  .sort((left, right) => left.name.localeCompare(right.name));
@@ -1623,22 +1730,17 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
1623
1730
  /**
1624
1731
  * Arms the one maintenance timer for the nearest management deadline
1625
1732
  * (spec 08 §4.2): request expiry, liveness, or a pending peer handshake.
1626
- * An earlier deadline re-arms it; a later one keeps the armed time.
1733
+ * The timer follows changes to the index visit or the other management deadlines.
1627
1734
  */
1628
1735
  private scheduleMaintenance(): void {
1629
1736
  if (this.closed) return;
1630
1737
  const nowMs = performance.now();
1631
- const dueMs = Math.max(
1632
- nowMs + MESH_BACKEND_MAINTENANCE_INTERVAL_MS,
1633
- Math.min(
1634
- this.runtime?.nextMaintenanceDeadlineMs(nowMs) ?? Number.POSITIVE_INFINITY,
1635
- this.stateful?.nextMaintenanceDeadlineMs() ?? Number.POSITIVE_INFINITY
1636
- )
1738
+ const dueMs = Math.min(
1739
+ this.runtime?.nextMaintenanceDeadlineMs(nowMs) ?? Number.POSITIVE_INFINITY,
1740
+ this.stateful?.nextMaintenanceDeadlineMs() ?? Number.POSITIVE_INFINITY
1637
1741
  );
1638
1742
  if (dueMs === Number.POSITIVE_INFINITY) {
1639
- if (this.maintenanceTimer !== undefined) clearTimeout(this.maintenanceTimer);
1640
- this.maintenanceTimer = undefined;
1641
- this.maintenanceDueMs = dueMs;
1743
+ this.maintenanceTimer?.unref();
1642
1744
  return;
1643
1745
  }
1644
1746
  if (this.maintenanceTimer === undefined || dueMs < this.maintenanceDueMs) {
@@ -1661,29 +1763,92 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
1661
1763
 
1662
1764
  private pump(): void {
1663
1765
  if (this.closed || this.pumpTask !== undefined) return;
1664
- this.pumpTask = this.runPump(this.requireRuntime());
1766
+ const runtime = this.requireRuntime();
1767
+ let complete!: () => void;
1768
+ let fail!: (error: unknown) => void;
1769
+ // Publish the join owner before receive can signal readiness or start close.
1770
+ // The receive turn itself needs no startup Promise continuation.
1771
+ this.pumpTask = new Promise<void>((resolve, reject) => {
1772
+ complete = resolve;
1773
+ fail = reject;
1774
+ });
1775
+ this.runPump(runtime, complete, fail);
1665
1776
  }
1666
1777
 
1667
- private async runPump(runtime: RawServiceMeshRuntime): Promise<void> {
1668
- // Publish pumpTask before any callback can signal readiness or begin close.
1669
- await Promise.resolve();
1778
+ private runPump(
1779
+ runtime: RawServiceMeshRuntime,
1780
+ complete: () => void,
1781
+ fail: (error: unknown) => void
1782
+ ): void {
1670
1783
  try {
1671
1784
  do {
1672
- const ready = this.readable;
1673
- this.readable = 0;
1674
- const more = await runtime.pumpBatch((ready & 1) !== 0, (ready & 2) !== 0);
1785
+ const batch = this.pumpReceiveBatch(runtime);
1786
+ if (batch !== false) {
1787
+ // Only suspended work needs an async continuation. A completed receive
1788
+ // rotation uses the published join without allocating another Promise.
1789
+ void this.resumePump(runtime, batch, complete, fail);
1790
+ return;
1791
+ }
1792
+ } while (this.hasPumpReadiness());
1793
+ } catch (error) {
1794
+ this.finishPump(complete, fail, runtime, error);
1795
+ return;
1796
+ }
1797
+ this.finishPump(complete, fail);
1798
+ }
1799
+
1800
+ private async resumePump(
1801
+ runtime: RawServiceMeshRuntime,
1802
+ batch: boolean | Promise<boolean>,
1803
+ complete: () => void,
1804
+ fail: (error: unknown) => void
1805
+ ): Promise<void> {
1806
+ try {
1807
+ for (;;) {
1808
+ const more = batch instanceof Promise ? await batch : batch;
1675
1809
  if (more) {
1676
1810
  // Yield only after actual progress, retaining readiness across the
1677
1811
  // existing batch limits until receive reports no data.
1678
1812
  this.readable |= 1;
1679
1813
  await yieldToIO();
1680
1814
  }
1681
- } while (!this.closed && this.readable !== 0);
1815
+ if (!this.hasPumpReadiness()) break;
1816
+ batch = this.pumpReceiveBatch(runtime);
1817
+ }
1682
1818
  } catch (error) {
1683
- runtime.reportInfrastructureFailure(error);
1684
- } finally {
1685
- this.pumpTask = undefined;
1686
- this.scheduleMaintenance();
1819
+ this.finishPump(complete, fail, runtime, error);
1820
+ return;
1821
+ }
1822
+ this.finishPump(complete, fail);
1823
+ }
1824
+
1825
+ private pumpReceiveBatch(runtime: RawServiceMeshRuntime): boolean | Promise<boolean> {
1826
+ const ready = this.readable;
1827
+ this.readable = 0;
1828
+ return runtime.pumpBatch((ready & 1) !== 0, (ready & 2) !== 0, (ready & 4) !== 0);
1829
+ }
1830
+
1831
+ private hasPumpReadiness(): boolean {
1832
+ return !this.closed && this.readable !== 0;
1833
+ }
1834
+
1835
+ private finishPump(
1836
+ complete: () => void,
1837
+ fail: (error: unknown) => void,
1838
+ failedRuntime?: RawServiceMeshRuntime,
1839
+ error?: unknown
1840
+ ): void {
1841
+ try {
1842
+ try {
1843
+ if (failedRuntime !== undefined) failedRuntime.reportInfrastructureFailure(error);
1844
+ } finally {
1845
+ this.pumpTask = undefined;
1846
+ this.scheduleMaintenance();
1847
+ }
1848
+ complete();
1849
+ } catch (error) {
1850
+ // Forward reporting and maintenance failures to the published join owner.
1851
+ fail(error);
1687
1852
  }
1688
1853
  }
1689
1854
 
@@ -1700,57 +1865,121 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
1700
1865
  }
1701
1866
 
1702
1867
  /**
1703
- * The raw registry takes a remote request's terminal and hands it here,
1704
- * where the Framework completion owner receives it in the same turn.
1868
+ * Publishes native results after submission returns and the completion slot has its id.
1869
+ * A caller-owned entry is completed after the result is mapped.
1705
1870
  */
1706
1871
  private readonly requestObserver: RawServiceRequestObserver = {
1707
1872
  operationCompleted: (id, result, operationKind) =>
1708
- this.deliverCompletion({ high: 1n, low: id }, operationKind ?? 0, result),
1873
+ queueMicrotask(() =>
1874
+ this.deliverCompletion({ high: 1n, low: id }, operationKind ?? 0, result)
1875
+ ),
1709
1876
  operationFailed: (id, error, operationKind) =>
1710
- this.deliverCompletion({ high: 1n, low: id }, operationKind ?? 0, requestFailureResult(error))
1877
+ queueMicrotask(() =>
1878
+ this.deliverCompletion(
1879
+ { high: 1n, low: id },
1880
+ operationKind ?? 0,
1881
+ requestFailureResult(error)
1882
+ )
1883
+ )
1711
1884
  };
1712
1885
 
1886
+ private requestObserverFor(
1887
+ completion?: import('../mesh-completion-table').ZLinkMeshCompletionHandler
1888
+ ): RawServiceRequestObserver {
1889
+ if (completion === undefined) return this.requestObserver;
1890
+ return {
1891
+ operationCompleted: (id, result, operationKind) =>
1892
+ queueMicrotask(() =>
1893
+ this.deliverCompletion({ high: 1n, low: id }, operationKind ?? 0, result, completion)
1894
+ ),
1895
+ operationFailed: (id, error, operationKind) =>
1896
+ queueMicrotask(() =>
1897
+ this.deliverCompletion(
1898
+ { high: 1n, low: id },
1899
+ operationKind ?? 0,
1900
+ requestFailureResult(error),
1901
+ completion
1902
+ )
1903
+ )
1904
+ };
1905
+ }
1906
+
1713
1907
  private observedOperation(
1714
1908
  pending: RawServiceObservedRequest,
1715
1909
  operationKind: number
1716
- ): MeshOperationId {
1717
- return pending.promise === undefined
1718
- ? { high: 1n, low: pending.id }
1719
- : this.observeCompletion(pending.id, operationKind, pending.promise);
1720
- }
1721
-
1722
- private observeCompletion(
1723
- low: bigint,
1724
- operationKind: number,
1725
- promise: Promise<RawServiceRequestResult>
1726
- ): MeshOperationId {
1727
- const id = { high: 1n, low };
1728
- void promise.then(
1729
- (result) => this.deliverCompletion(id, operationKind, result),
1730
- (error) => this.deliverCompletion(id, operationKind, requestFailureResult(error))
1731
- );
1732
- return id;
1910
+ ): MeshOperationSubmission {
1911
+ const id = { high: 1n, low: pending.id };
1912
+ if (pending.promise !== undefined && !pending.hasObserver()) {
1913
+ void pending.promise.then(
1914
+ (result) => this.deliverCompletion(id, operationKind, result),
1915
+ (error) => this.deliverCompletion(id, operationKind, requestFailureResult(error))
1916
+ );
1917
+ }
1918
+ return this.requestSubmission(id, pending);
1919
+ }
1920
+
1921
+ private observeStatefulRequest(
1922
+ kind: number,
1923
+ entry: PendingOperation<unknown> | undefined,
1924
+ submit: (
1925
+ receiver?: import('../../foundation/operation-registry').OperationObserver<unknown, unknown>
1926
+ ) => ServiceStatefulPendingOperation,
1927
+ completion?: import('../mesh-completion-table').ZLinkMeshCompletionHandler
1928
+ ): MeshOperationSubmission {
1929
+ if (entry === undefined) return this.observeStateful(kind, submit(), completion);
1930
+ const id = { high: ZLINK_NATIVE_CORRELATION_OPERATION_NAMESPACE, low: entry.id };
1931
+ const receiver: import('../../foundation/operation-registry').OperationObserver<
1932
+ unknown,
1933
+ unknown
1934
+ > = {
1935
+ operationCompleted: (_operationId, value) =>
1936
+ queueMicrotask(() =>
1937
+ this.deliverCompletion(id, kind, value as ServiceStatefulResult, completion)
1938
+ ),
1939
+ operationFailed: (_operationId, error) =>
1940
+ queueMicrotask(() =>
1941
+ this.deliverCompletion(id, kind, requestFailureResult(error), completion)
1942
+ )
1943
+ };
1944
+ if (completion === undefined) {
1945
+ entry.setObserver(receiver);
1946
+ submit();
1947
+ } else submit(receiver);
1948
+ return this.requestSubmission(id, entry);
1733
1949
  }
1734
1950
 
1735
1951
  private observeStateful(
1736
1952
  operationKind: number,
1737
- pending: ServiceStatefulPendingOperation
1738
- ): MeshOperationId {
1953
+ pending: ServiceStatefulPendingOperation,
1954
+ completion?: import('../mesh-completion-table').ZLinkMeshCompletionHandler
1955
+ ): MeshOperationSubmission {
1739
1956
  const id = { high: ZLINK_NATIVE_CORRELATION_OPERATION_NAMESPACE, low: pending.id };
1740
1957
  void pending.promise.then(
1741
- (result) => this.deliverCompletion(id, operationKind, result),
1742
- (error) => this.deliverCompletion(id, operationKind, requestFailureResult(error))
1958
+ (result) => this.deliverCompletion(id, operationKind, result, completion),
1959
+ (error) => this.deliverCompletion(id, operationKind, requestFailureResult(error), completion)
1743
1960
  );
1744
- return id;
1961
+ return this.requestSubmission(id, pending);
1962
+ }
1963
+
1964
+ private requestSubmission(
1965
+ id: MeshOperationId,
1966
+ requestOperation: RawServiceObservedRequest | PendingOperation<unknown>
1967
+ ): MeshOperationSubmission {
1968
+ return Object.defineProperty({ ...id }, 'requestOperation', {
1969
+ value: requestOperation,
1970
+ configurable: true
1971
+ });
1745
1972
  }
1746
1973
 
1747
1974
  private deliverCompletion(
1748
1975
  operationId: MeshOperationId,
1749
1976
  operationKind: number,
1750
- result: RawServiceRequestResult | ServiceStatefulResult
1977
+ result: RawServiceRequestResult | ServiceStatefulResult,
1978
+ completion: import('../mesh-completion-table').ZLinkMeshCompletionHandler | undefined = this
1979
+ .completionHandler
1751
1980
  ): void {
1752
- if (this.completionHandler !== undefined) {
1753
- this.completionHandler({ operationId, terminalResult: result.terminalResult }, () =>
1981
+ if (completion !== undefined) {
1982
+ completion({ operationId, terminalResult: result.terminalResult }, () =>
1754
1983
  completionRecord(operationId, operationKind, result)
1755
1984
  );
1756
1985
  return;
@@ -1844,14 +2073,18 @@ class RawServiceSpot implements ServiceSpot {
1844
2073
  };
1845
2074
  }
1846
2075
 
1847
- async sendToChannel(
2076
+ sendToChannel(
1848
2077
  channelName: string,
1849
2078
  parts: MessageLike | readonly MessageLike[],
1850
2079
  options?: { readonly flags?: number }
1851
2080
  ): Promise<SubmitResultValue> {
1852
- this.requireOpen();
1853
- void options;
1854
- return this.backend.sendToChannel(channelName, parts);
2081
+ try {
2082
+ this.requireOpen();
2083
+ void options;
2084
+ return this.backend.sendToChannel(channelName, parts);
2085
+ } catch (error) {
2086
+ return Promise.reject(error);
2087
+ }
1855
2088
  }
1856
2089
 
1857
2090
  requestToChannel(
@@ -1860,6 +2093,7 @@ class RawServiceSpot implements ServiceSpot {
1860
2093
  options?: {
1861
2094
  readonly flags?: number;
1862
2095
  readonly timeoutMs?: number;
2096
+ readonly requestOperation?: PendingOperation<unknown>;
1863
2097
  readonly onAdmitted?: () => void;
1864
2098
  }
1865
2099
  ): MeshOperationId {
@@ -1897,10 +2131,12 @@ class RawServiceSpot implements ServiceSpot {
1897
2131
  parts: MessageLike | readonly MessageLike[],
1898
2132
  options?: {
1899
2133
  readonly timeoutMs?: number;
2134
+ readonly requestOperation?: PendingOperation<unknown>;
1900
2135
  readonly onAdmitted?: () => void;
1901
2136
  readonly routeFence?: ServiceDirectSpotRouteFence;
1902
2137
  readonly entrySpot?: boolean;
1903
- }
2138
+ },
2139
+ completion?: import('../mesh-completion-table').ZLinkMeshCompletionHandler
1904
2140
  ): MeshOperationId {
1905
2141
  this.requireOpen();
1906
2142
  const routeFence = requireDirectSpotRouteFence(
@@ -1917,7 +2153,9 @@ class RawServiceSpot implements ServiceSpot {
1917
2153
  routeFence,
1918
2154
  parts,
1919
2155
  options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS,
1920
- options?.onAdmitted
2156
+ options?.onAdmitted,
2157
+ options?.requestOperation,
2158
+ completion
1921
2159
  );
1922
2160
  }
1923
2161
 
@@ -2322,14 +2560,17 @@ function completionRecord(
2322
2560
  kindData: 'kindData' in result ? (result.kindData ?? null) : null,
2323
2561
  terminalResult: result.terminalResult,
2324
2562
  failureErrno: result.failureCode,
2563
+ ...('failureMessage' in result && result.failureMessage !== undefined
2564
+ ? { failureMessage: result.failureMessage }
2565
+ : {}),
2325
2566
  parts:
2326
2567
  payload === undefined
2327
2568
  ? []
2328
2569
  : payload.contentType === MULTIPART_CONTENT_TYPE
2329
2570
  ? decodeMultipart(payload.payload)
2330
2571
  : [ZLinkBufferMessage.from(payload.payload)],
2331
- reply: () => SubmitResult.InvalidState,
2332
- replyActorJoin: () => SubmitResult.NotSupported
2572
+ reply: replyInvalidState,
2573
+ replyActorJoin: replyActorJoinNotSupported
2333
2574
  };
2334
2575
  }
2335
2576
 
@@ -2380,17 +2621,12 @@ function decodeMultipartRecord(
2380
2621
  const values = Array.isArray(parts) ? parts : [parts];
2381
2622
  if (values.length === 0) return SubmitResult.InvalidState;
2382
2623
  runtime.replyService(
2383
- {
2384
- sourceRoutingId: record.sourceRoutingId!,
2385
- ...(record.sourceRoute === undefined ? {} : { sourceRoute: record.sourceRoute }),
2386
- requestSequence: record.requestSequence!,
2387
- ...(record.reply === undefined ? {} : { reply: record.reply })
2388
- },
2389
- values.map((value) => Buffer.from(messageBytesView(value)))
2624
+ record as Parameters<RawServiceMeshRuntime['replyService']>[0],
2625
+ values.map(messagePayloadView)
2390
2626
  );
2391
2627
  return SubmitResult.Ok;
2392
2628
  },
2393
- replyActorJoin: () => SubmitResult.NotSupported
2629
+ replyActorJoin: replyActorJoinNotSupported
2394
2630
  };
2395
2631
  }
2396
2632
  const header = record.parts[0]!;
@@ -2463,6 +2699,10 @@ function releaseRecordApplicationJob(this: {
2463
2699
  )?.close();
2464
2700
  }
2465
2701
 
2702
+ function replyInvalidState(): SubmitResultValue {
2703
+ return SubmitResult.InvalidState;
2704
+ }
2705
+
2466
2706
  function replyActorJoinNotSupported(): SubmitResultValue {
2467
2707
  return SubmitResult.NotSupported;
2468
2708
  }
@@ -2572,9 +2812,9 @@ function decodeStatefulRecord(
2572
2812
  });
2573
2813
  return accepted ? SubmitResult.Ok : SubmitResult.InvalidState;
2574
2814
  },
2575
- replyFailure(terminalResult, failureCode) {
2815
+ replyFailure(terminalResult, failureCode, tail) {
2576
2816
  if (stateful.reply === undefined) return SubmitResult.InvalidState;
2577
- return stateful.reply(terminalResult, failureCode)
2817
+ return stateful.reply(terminalResult, failureCode, undefined, tail)
2578
2818
  ? SubmitResult.Ok
2579
2819
  : SubmitResult.InvalidState;
2580
2820
  }
@@ -2582,16 +2822,20 @@ function decodeStatefulRecord(
2582
2822
  }
2583
2823
 
2584
2824
  function receiveIngressLifecycle(record: ServiceMailboxRecord): {
2825
+ readonly receivedAt?: Date;
2585
2826
  readonly applicationJobPermit?: import('../../application-jobs/contracts').ApplicationJobPermitPort;
2586
2827
  readonly releaseRetainedIngress?: () => void;
2587
2828
  } {
2588
2829
  const applicationJob = record.applicationJob;
2589
- return applicationJob === undefined
2590
- ? {}
2591
- : {
2592
- applicationJobPermit: applicationJob,
2593
- releaseRetainedIngress: () => applicationJob.close()
2594
- };
2830
+ return {
2831
+ ...(record.receivedAt === undefined ? {} : { receivedAt: record.receivedAt }),
2832
+ ...(applicationJob === undefined
2833
+ ? {}
2834
+ : {
2835
+ applicationJobPermit: applicationJob,
2836
+ releaseRetainedIngress: () => applicationJob.close()
2837
+ })
2838
+ };
2595
2839
  }
2596
2840
 
2597
2841
  function prepareStatefulMailboxDispatch(
@@ -2696,24 +2940,10 @@ export function requestFailureResult(error: unknown): RawServiceRequestResult {
2696
2940
  function encodeMultipart(parts: MessageLike | readonly MessageLike[]) {
2697
2941
  const values = Array.isArray(parts) ? parts : [parts];
2698
2942
  if (values.length === 0) throw new TypeError('Multipart payload must contain at least one part.');
2699
- // messageBytesView aliases the caller's buffer; the parts are consumed
2700
- // synchronously by the copy loop below and never retained.
2701
- const bytes = values.map(messageBytesView);
2702
- let size = 4;
2703
- for (const part of bytes) size += 4 + part.byteLength;
2704
- const payload = Buffer.alloc(size);
2705
- payload.writeUInt32BE(bytes.length, 0);
2706
- let offset = 4;
2707
- for (const part of bytes) {
2708
- payload.writeUInt32BE(part.byteLength, offset);
2709
- offset += 4;
2710
- payload.set(part, offset);
2711
- offset += part.byteLength;
2712
- }
2713
2943
  return {
2714
2944
  packetName: MULTIPART_PACKET_NAME,
2715
2945
  contentType: MULTIPART_CONTENT_TYPE,
2716
- payload
2946
+ payload: encodeMultipartPayload(values.map(messagePayloadView))
2717
2947
  };
2718
2948
  }
2719
2949
 
@@ -2721,7 +2951,7 @@ function encodeMultipartApplicationFrame(parts: MessageLike | readonly MessageLi
2721
2951
  const values = Array.isArray(parts) ? parts : [parts];
2722
2952
  if (values.length === 0) throw new TypeError('Multipart payload must contain at least one part.');
2723
2953
  return encodeMultipartApplicationPayload(
2724
- values.map(messageBytesView),
2954
+ values.map(messagePayloadView),
2725
2955
  MULTIPART_PACKET_NAME,
2726
2956
  MULTIPART_CONTENT_TYPE
2727
2957
  );
@@ -2739,11 +2969,10 @@ function borrowMultipartPart(part: Buffer): Buffer {
2739
2969
  return part;
2740
2970
  }
2741
2971
 
2742
- function messageBytesView(value: MessageLike): Uint8Array {
2972
+ function messagePayloadView(value: MessageLike): Uint8Array | string {
2743
2973
  if (typeof value === 'object' && 'data' in value) {
2744
2974
  return value.data();
2745
2975
  }
2746
- if (typeof value === 'string') return Buffer.from(value);
2747
2976
  return value;
2748
2977
  }
2749
2978