@zlink-systems/framework 0.30.0 → 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 (245) 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/Handlers/Attributes.d.ts +5 -13
  7. package/dist/contracts/Handlers/Attributes.js +7 -11
  8. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  9. package/dist/contracts/Handlers/JsonContract.js +4 -153
  10. package/dist/contracts/Spots/Contracts.d.ts +2 -1
  11. package/dist/nest-integration.d.ts +1 -1
  12. package/dist/nest-integration.js +2 -1
  13. package/dist/runtime/actors/actor-client.d.ts +1 -1
  14. package/dist/runtime/actors/actor-client.js +14 -12
  15. package/dist/runtime/actors/actor-handoff.d.ts +1 -1
  16. package/dist/runtime/actors/actor-handoff.js +7 -4
  17. package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
  18. package/dist/runtime/actors/actor-local-native-join.js +9 -12
  19. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  20. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  21. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  22. package/dist/runtime/actors/index.d.ts +2 -1
  23. package/dist/runtime/actors/index.js +18 -6
  24. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  25. package/dist/runtime/admission.d.ts +1 -1
  26. package/dist/runtime/admission.js +15 -5
  27. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
  28. package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
  29. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +2 -1
  30. package/dist/runtime/application-jobs/application-job-queue-scope.js +37 -22
  31. package/dist/runtime/application-jobs/contracts.d.ts +10 -1
  32. package/dist/runtime/backend/contracts/index.d.ts +18 -9
  33. package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
  34. package/dist/runtime/backend/mesh-completion-table.js +149 -49
  35. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
  36. package/dist/runtime/backend/mesh-dispatch-pump.js +32 -11
  37. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
  38. package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
  39. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  40. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  41. package/dist/runtime/backend/node/node-raw-binding-port.js +42 -22
  42. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +13 -5
  43. package/dist/runtime/backend/node/node-raw-mesh-backend.js +69 -51
  44. package/dist/runtime/backend/node/node-socket-backend-adapter.js +6 -6
  45. package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
  46. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  47. package/dist/runtime/backend/runtime-message.js +5 -0
  48. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  49. package/dist/runtime/backend/runtime-values.js +2 -1
  50. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  51. package/dist/runtime/channels/channel-clients.js +58 -21
  52. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
  53. package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
  54. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  55. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  56. package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
  57. package/dist/runtime/channels/channel-dispatchers.js +27 -26
  58. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  59. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  60. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  61. package/dist/runtime/channels/channel-envelope.js +83 -8
  62. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  63. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  64. package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
  65. package/dist/runtime/channels/channel-runtime-manager.js +12 -12
  66. package/dist/runtime/channels/channel-transports.d.ts +18 -15
  67. package/dist/runtime/channels/channel-transports.js +48 -31
  68. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  69. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  70. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  71. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  72. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  73. package/dist/runtime/channels/source-spot-router.js +4 -4
  74. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  75. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  76. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  77. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  78. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  79. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  80. package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
  81. package/dist/runtime/execution/serial-execution-queue.js +1 -0
  82. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  83. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  84. package/dist/runtime/foundation/durable-service-request.js +98 -0
  85. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  86. package/dist/runtime/foundation/operation-identity.js +5 -1
  87. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +22 -5
  88. package/dist/runtime/foundation/raw-service-mesh-runtime.js +356 -232
  89. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
  90. package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
  91. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  92. package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
  93. package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
  94. package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -4
  95. package/dist/runtime/foundation/service-stateful-runtime.js +44 -103
  96. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +0 -5
  97. package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
  98. package/dist/runtime/foundation/service-topology-registry.js +61 -27
  99. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
  100. package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
  101. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  102. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  103. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  104. package/dist/runtime/host/application-job-queue.d.ts +19 -7
  105. package/dist/runtime/host/application-job-queue.js +150 -42
  106. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  107. package/dist/runtime/host/entry-actor-runtime.js +3 -0
  108. package/dist/runtime/host/index.d.ts +7 -1
  109. package/dist/runtime/host/index.js +142 -118
  110. package/dist/runtime/host/remote-bound-session-relay.js +2 -18
  111. package/dist/runtime/host/route-mesh-runtime.js +1 -1
  112. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  113. package/dist/runtime/host/service-relocation-control.js +10 -4
  114. package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
  115. package/dist/runtime/host/service-relocation-host-runtime.js +213 -241
  116. package/dist/runtime/host/spot-address-transport.js +3 -2
  117. package/dist/runtime/host/spot-runtime-options-factory.js +1 -0
  118. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  119. package/dist/runtime/locations/actor-location-claims.js +34 -19
  120. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  121. package/dist/runtime/locations/lifecycle.js +2 -5
  122. package/dist/runtime/locations/runtime.d.ts +1 -1
  123. package/dist/runtime/locations/runtime.js +24 -23
  124. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  125. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  126. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  127. package/dist/runtime/messaging/packet-name.js +8 -24
  128. package/dist/runtime/messaging/request-result.d.ts +2 -0
  129. package/dist/runtime/messaging/request-result.js +54 -0
  130. package/dist/runtime/messaging/submission-result.d.ts +1 -0
  131. package/dist/runtime/messaging/submission-result.js +5 -2
  132. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
  133. package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
  134. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
  135. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
  136. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
  137. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
  138. package/dist/runtime/spots/index.d.ts +3 -0
  139. package/dist/runtime/spots/index.js +9 -2
  140. package/dist/runtime/spots/spot-activation.d.ts +1 -0
  141. package/dist/runtime/spots/spot-activation.js +17 -8
  142. package/dist/runtime/spots/spot-entry-activation.js +6 -2
  143. package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
  144. package/dist/runtime/spots/spot-handler-registry.js +18 -8
  145. package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
  146. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  147. package/dist/runtime/spots/spot-outbound.js +24 -15
  148. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  149. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  150. package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -0
  151. package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
  152. package/dist/runtime/spots/spot-timer.js +1 -0
  153. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  154. package/dist/runtime/streams/stream-session-runtime.js +13 -27
  155. package/package.json +2 -2
  156. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  157. package/src/contracts/Channels/Calls.ts +2 -1
  158. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  159. package/src/contracts/Handlers/Attributes.ts +14 -21
  160. package/src/contracts/Handlers/JsonContract.ts +8 -216
  161. package/src/contracts/Spots/Contracts.ts +2 -1
  162. package/src/nest-integration.ts +1 -0
  163. package/src/runtime/actors/actor-client.ts +40 -16
  164. package/src/runtime/actors/actor-handoff.ts +9 -4
  165. package/src/runtime/actors/actor-join-relocation.ts +1 -0
  166. package/src/runtime/actors/actor-local-native-join.ts +17 -26
  167. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  168. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  169. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  170. package/src/runtime/actors/index.ts +19 -5
  171. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  172. package/src/runtime/admission.ts +18 -5
  173. package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
  174. package/src/runtime/application-jobs/application-job-queue-scope.ts +51 -22
  175. package/src/runtime/application-jobs/contracts.ts +14 -1
  176. package/src/runtime/backend/contracts/index.ts +53 -14
  177. package/src/runtime/backend/mesh-completion-table.ts +156 -57
  178. package/src/runtime/backend/mesh-dispatch-pump.ts +40 -10
  179. package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
  180. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  181. package/src/runtime/backend/node/node-raw-binding-port.ts +57 -30
  182. package/src/runtime/backend/node/node-raw-mesh-backend.ts +128 -65
  183. package/src/runtime/backend/node/node-socket-backend-adapter.ts +21 -6
  184. package/src/runtime/backend/raw-binding-port.ts +7 -2
  185. package/src/runtime/backend/runtime-message.ts +6 -0
  186. package/src/runtime/backend/runtime-values.ts +1 -0
  187. package/src/runtime/channels/channel-clients.ts +90 -41
  188. package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
  189. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  190. package/src/runtime/channels/channel-dispatchers.ts +29 -27
  191. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  192. package/src/runtime/channels/channel-envelope.ts +133 -8
  193. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  194. package/src/runtime/channels/channel-runtime-manager.ts +29 -12
  195. package/src/runtime/channels/channel-transports.ts +128 -60
  196. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  197. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  198. package/src/runtime/channels/source-spot-router.ts +8 -4
  199. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  200. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  201. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  202. package/src/runtime/execution/serial-execution-queue.ts +2 -0
  203. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  204. package/src/runtime/foundation/durable-service-request.ts +137 -0
  205. package/src/runtime/foundation/operation-identity.ts +5 -1
  206. package/src/runtime/foundation/raw-service-mesh-runtime.ts +484 -293
  207. package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
  208. package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
  209. package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
  210. package/src/runtime/foundation/service-stateful-runtime.ts +67 -125
  211. package/src/runtime/foundation/service-stateful-wire-codec.ts +0 -5
  212. package/src/runtime/foundation/service-topology-registry.ts +91 -36
  213. package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
  214. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  215. package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
  216. package/src/runtime/host/application-job-queue.ts +175 -41
  217. package/src/runtime/host/entry-actor-runtime.ts +4 -0
  218. package/src/runtime/host/index.ts +201 -156
  219. package/src/runtime/host/remote-bound-session-relay.ts +2 -23
  220. package/src/runtime/host/route-mesh-runtime.ts +1 -1
  221. package/src/runtime/host/service-relocation-control.ts +11 -5
  222. package/src/runtime/host/service-relocation-host-runtime.ts +315 -291
  223. package/src/runtime/host/spot-address-transport.ts +4 -2
  224. package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
  225. package/src/runtime/locations/actor-location-claims.ts +52 -30
  226. package/src/runtime/locations/lifecycle.ts +8 -26
  227. package/src/runtime/locations/runtime.ts +28 -24
  228. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  229. package/src/runtime/messaging/packet-name.ts +5 -25
  230. package/src/runtime/messaging/request-result.ts +58 -0
  231. package/src/runtime/messaging/submission-result.ts +5 -1
  232. package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
  233. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  234. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +43 -23
  235. package/src/runtime/spots/index.ts +14 -2
  236. package/src/runtime/spots/spot-activation.ts +28 -10
  237. package/src/runtime/spots/spot-entry-activation.ts +9 -2
  238. package/src/runtime/spots/spot-handler-registry.ts +41 -8
  239. package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
  240. package/src/runtime/spots/spot-outbound.ts +36 -16
  241. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  242. package/src/runtime/spots/spot-runtime-ports.ts +1 -0
  243. package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
  244. package/src/runtime/spots/spot-timer.ts +5 -1
  245. package/src/runtime/streams/stream-session-runtime.ts +12 -29
@@ -4,12 +4,109 @@ exports.ZLinkMeshCompletionTable = void 0;
4
4
  exports.closeMeshCompletion = closeMeshCompletion;
5
5
  const runtime_message_1 = require("./runtime-message");
6
6
  const operation_identity_1 = require("../foundation/operation-identity");
7
+ const COMPLETION_SLOT_BLOCK_SIZE = 64;
8
+ const COMPLETION_HASH_BUCKETS_PER_SLOT = 2;
9
+ const COMPLETION_HASH_WORD_SCALE = 0x1_0000;
10
+ const COMPLETION_HASH_MULTIPLIER = 0x9e37_79b1;
11
+ const COMPLETION_ABORT_OPTIONS = Object.freeze({ once: true });
12
+ class CompletionSlot {
13
+ abort;
14
+ generation = 0;
15
+ next = -1;
16
+ high;
17
+ low;
18
+ hashNext = -1;
19
+ resolve;
20
+ reject;
21
+ signal;
22
+ constructor(abort) {
23
+ this.abort = abort;
24
+ }
25
+ }
7
26
  class ZLinkMeshCompletionTable {
8
27
  onDiagnostic;
9
- pending = new Map();
28
+ buckets = new Int32Array(0);
29
+ slots = [];
30
+ free = -1;
31
+ activeCount = 0;
10
32
  disposed = false;
11
33
  constructor(onDiagnostic) {
12
34
  this.onDiagnostic = onDiagnostic;
35
+ this.prepareSlots();
36
+ }
37
+ prepareSlots() {
38
+ const start = this.slots.length;
39
+ for (let index = start; index < start + COMPLETION_SLOT_BLOCK_SIZE; index++) {
40
+ const slot = new CompletionSlot(() => {
41
+ const reject = slot.reject;
42
+ const signal = slot.signal;
43
+ if (reject === undefined)
44
+ return;
45
+ this.releaseSlot(index);
46
+ reject(signal?.reason ?? new DOMException('The operation was aborted.', 'AbortError'));
47
+ });
48
+ slot.next = this.free;
49
+ this.slots.push(slot);
50
+ this.free = index;
51
+ }
52
+ const minimumBuckets = this.slots.length * COMPLETION_HASH_BUCKETS_PER_SLOT;
53
+ this.buckets = new Int32Array(2 ** Math.ceil(Math.log2(minimumBuckets))).fill(-1);
54
+ for (let index = 0; index < this.slots.length; index++) {
55
+ const slot = this.slots[index];
56
+ if (slot.high === undefined)
57
+ continue;
58
+ this.indexSlot(index);
59
+ }
60
+ }
61
+ bucket(high, low) {
62
+ const highWord = Number(high);
63
+ const lowWord = Number(low);
64
+ // Bucket selection may collide; the stored 128-bit identity is compared exactly.
65
+ const hash = Math.imul(highWord ^ Math.trunc(highWord / COMPLETION_HASH_WORD_SCALE), COMPLETION_HASH_MULTIPLIER) ^
66
+ lowWord ^
67
+ Math.trunc(lowWord / COMPLETION_HASH_WORD_SCALE);
68
+ return hash & (this.buckets.length - 1);
69
+ }
70
+ indexSlot(index) {
71
+ const slot = this.slots[index];
72
+ const bucket = this.bucket(slot.high, slot.low);
73
+ slot.hashNext = this.buckets[bucket];
74
+ this.buckets[bucket] = index;
75
+ }
76
+ findSlot(operationId) {
77
+ (0, operation_identity_1.validateOperationIdentity)(operationId);
78
+ for (let index = this.buckets[this.bucket(operationId.high, operationId.low)]; index !== -1; index = this.slots[index].hashNext) {
79
+ const slot = this.slots[index];
80
+ if (slot.high === operationId.high && slot.low === operationId.low)
81
+ return index;
82
+ }
83
+ return -1;
84
+ }
85
+ releaseSlot(index) {
86
+ const slot = this.slots[index];
87
+ if (slot.high !== undefined) {
88
+ const bucket = this.bucket(slot.high, slot.low);
89
+ let previous = -1;
90
+ let current = this.buckets[bucket];
91
+ while (current !== index) {
92
+ previous = current;
93
+ current = this.slots[current].hashNext;
94
+ }
95
+ if (previous === -1)
96
+ this.buckets[bucket] = slot.hashNext;
97
+ else
98
+ this.slots[previous].hashNext = slot.hashNext;
99
+ }
100
+ slot.signal?.removeEventListener('abort', slot.abort);
101
+ slot.high = undefined;
102
+ slot.low = undefined;
103
+ slot.hashNext = -1;
104
+ slot.signal = undefined;
105
+ slot.resolve = undefined;
106
+ slot.reject = undefined;
107
+ slot.next = this.free;
108
+ this.free = index;
109
+ this.activeCount--;
13
110
  }
14
111
  /**
15
112
  * Reserves the dispatcher slot before transport submission. The backend
@@ -24,39 +121,32 @@ class ZLinkMeshCompletionTable {
24
121
  return Promise.reject(signal.reason ?? new DOMException('The operation was aborted.', 'AbortError'));
25
122
  }
26
123
  return new Promise((resolve, reject) => {
27
- let key = Symbol();
28
- const abort = () => {
29
- this.pending.delete(key);
30
- reject(signal?.reason ?? new DOMException('The operation was aborted.', 'AbortError'));
31
- };
32
- if (signal?.aborted === true) {
33
- abort();
34
- return;
35
- }
36
- signal?.addEventListener('abort', abort, { once: true });
37
- const entry = {
38
- resolve,
39
- reject,
40
- removeAbort: signal === undefined ? undefined : () => signal.removeEventListener('abort', abort)
41
- };
42
- this.pending.set(key, entry);
124
+ if (this.free === -1)
125
+ this.prepareSlots();
126
+ const index = this.free;
127
+ const slot = this.slots[index];
128
+ this.free = slot.next;
129
+ const generation = ++slot.generation;
130
+ slot.resolve = resolve;
131
+ slot.reject = reject;
132
+ slot.signal = signal;
133
+ this.activeCount++;
43
134
  try {
135
+ signal?.addEventListener('abort', slot.abort, COMPLETION_ABORT_OPTIONS);
44
136
  const operationId = operation();
45
- // dispose/abort can consume the reserved slot during submission.
46
- if (!this.pending.delete(key))
137
+ // A reentrant abort may release and reuse this slot during submission.
138
+ if (slot.generation !== generation || slot.resolve !== resolve)
47
139
  return;
48
- key = (0, operation_identity_1.operationIdentityKey)(operationId);
49
- if (this.pending.has(key)) {
50
- throw new Error(`Mesh operation '${key}' is already pending.`);
140
+ if (this.findSlot(operationId) !== -1) {
141
+ throw new Error(`Mesh operation '${(0, operation_identity_1.operationIdentityKey)(operationId)}' is already pending.`);
51
142
  }
52
- this.pending.set(key, entry);
143
+ slot.high = operationId.high;
144
+ slot.low = operationId.low;
145
+ this.indexSlot(index);
53
146
  }
54
147
  catch (error) {
55
- // Remove only this submission's slot; a duplicate identity retains
56
- // the original waiter.
57
- if (this.pending.get(key) === entry)
58
- this.pending.delete(key);
59
- entry.removeAbort?.();
148
+ if (slot.generation === generation && slot.resolve === resolve)
149
+ this.releaseSlot(index);
60
150
  reject(error);
61
151
  }
62
152
  });
@@ -65,9 +155,8 @@ class ZLinkMeshCompletionTable {
65
155
  return this.disposed;
66
156
  }
67
157
  complete(record, materialize) {
68
- const key = (0, operation_identity_1.operationIdentityKey)(record.operationId);
69
- const pending = this.pending.get(key);
70
- if (pending === undefined) {
158
+ const index = this.findSlot(record.operationId);
159
+ if (index === -1) {
71
160
  this.onDiagnostic?.({
72
161
  kind: 'unknownOrLate',
73
162
  operationId: Object.freeze({ ...record.operationId }),
@@ -75,13 +164,15 @@ class ZLinkMeshCompletionTable {
75
164
  });
76
165
  return;
77
166
  }
78
- this.pending.delete(key);
79
- pending.removeAbort?.();
167
+ const slot = this.slots[index];
168
+ const resolve = slot.resolve;
169
+ const reject = slot.reject;
170
+ this.releaseSlot(index);
80
171
  try {
81
- pending.resolve(retainCompletion(materialize === undefined ? record : materialize()));
172
+ resolve(retainCompletion(materialize === undefined ? record : materialize()));
82
173
  }
83
174
  catch (error) {
84
- pending.reject(error);
175
+ reject(error);
85
176
  }
86
177
  }
87
178
  dispose(reason = new Error('Mesh completion table is disposed.')) {
@@ -89,34 +180,43 @@ class ZLinkMeshCompletionTable {
89
180
  return;
90
181
  }
91
182
  this.disposed = true;
92
- const pending = [...this.pending.values()];
93
- this.pending.clear();
94
- for (const entry of pending) {
95
- entry.removeAbort?.();
96
- }
97
- for (const entry of pending) {
98
- entry.reject(reason);
183
+ for (let index = 0; index < this.slots.length; index++) {
184
+ const reject = this.slots[index].reject;
185
+ if (reject === undefined)
186
+ continue;
187
+ this.releaseSlot(index);
188
+ reject(reason);
99
189
  }
100
190
  }
101
191
  get pendingCount() {
102
- return this.pending.size;
192
+ return this.activeCount;
103
193
  }
104
194
  }
105
195
  exports.ZLinkMeshCompletionTable = ZLinkMeshCompletionTable;
106
196
  function retainCompletion(record) {
197
+ const parts = retainCompletionParts(record.parts);
198
+ // The retention pass verifies every part is already a managed runtime message.
199
+ if (parts === record.parts)
200
+ return record;
107
201
  return {
108
202
  terminalResult: record.terminalResult,
109
203
  failureErrno: record.failureErrno,
110
204
  operationKind: record.operationKind,
111
205
  kindData: record.kindData,
112
- parts: record.parts.map(retainCompletionPart)
206
+ parts
113
207
  };
114
208
  }
115
- function retainCompletionPart(part) {
116
- // A runtime message already owns a managed Buffer and close() is a no-op.
117
- // Binding-native messages can expose native storage through data(), which
118
- // becomes invalid when their owner closes; materialize that one boundary copy.
119
- return part instanceof runtime_message_1.ZLinkBufferMessage ? part : runtime_message_1.ZLinkBufferMessage.fromOwned(Buffer.from(part.data()));
209
+ function retainCompletionParts(parts) {
210
+ // Reuse managed messages and wrap binding payloads in the runtime representation.
211
+ let retained;
212
+ for (let index = 0; index < parts.length; index++) {
213
+ const part = parts[index];
214
+ if (!(part instanceof runtime_message_1.ZLinkBufferMessage)) {
215
+ retained ??= parts.slice();
216
+ retained[index] = runtime_message_1.ZLinkBufferMessage.fromOwned(runtime_message_1.ZLinkBufferMessage.retainPayload(part));
217
+ }
218
+ }
219
+ return retained ?? parts;
120
220
  }
121
221
  function closeMeshCompletion(completion) {
122
222
  closeParts(completion.parts);
@@ -20,6 +20,7 @@ export interface ZLinkMeshDispatchFailureContext {
20
20
  export declare class ZLinkMeshDispatchPump {
21
21
  private readonly node;
22
22
  private readonly options;
23
+ private readonly dispatchOwnedRecord;
23
24
  private pendingDomains;
24
25
  private infrastructureScheduled;
25
26
  private disposed;
@@ -37,6 +38,8 @@ export declare class ZLinkMeshDispatchPump {
37
38
  private startApplicationWorker;
38
39
  private runApplicationWorker;
39
40
  private waitForApplicationReady;
41
+ private dispatchRecord;
42
+ private finishRecord;
40
43
  private reportDispatchError;
41
44
  /**
42
45
  * Infrastructure controls must not wait for an application permit. During
@@ -24,6 +24,7 @@ const detachedMeshDispatchScope = node_async_hooks_1.AsyncLocalStorage.snapshot(
24
24
  class ZLinkMeshDispatchPump {
25
25
  node;
26
26
  options;
27
+ dispatchOwnedRecord = this.dispatchRecord.bind(this);
27
28
  pendingDomains = service_runtime_contracts_1.ReadyDomain.None;
28
29
  infrastructureScheduled = false;
29
30
  disposed = false;
@@ -140,6 +141,31 @@ class ZLinkMeshDispatchPump {
140
141
  }
141
142
  return new Promise((resolve) => this.idleApplicationWorkers.add(resolve));
142
143
  }
144
+ dispatchRecord(owner, record) {
145
+ let result;
146
+ try {
147
+ result = this.options.dispatch(owner, record);
148
+ }
149
+ catch (error) {
150
+ this.reportDispatchError(error, meshDispatchFailureContext(record));
151
+ return;
152
+ }
153
+ return result === undefined
154
+ ? this.finishRecord(record)
155
+ : Promise.resolve(result).then(() => this.finishRecord(record), (error) => this.reportDispatchError(error, meshDispatchFailureContext(record)));
156
+ }
157
+ finishRecord(record) {
158
+ let result;
159
+ try {
160
+ result = record.onTerminalCompletion?.();
161
+ }
162
+ catch (error) {
163
+ this.reportDispatchError(error, meshDispatchFailureContext(record));
164
+ return;
165
+ }
166
+ if (result !== undefined)
167
+ return Promise.resolve(result).catch((error) => this.reportDispatchError(error, meshDispatchFailureContext(record)));
168
+ }
143
169
  reportDispatchError(error, context) {
144
170
  this.options.reportError?.(error, context);
145
171
  }
@@ -238,17 +264,10 @@ class ZLinkMeshDispatchPump {
238
264
  throw new Error('Pre-admitted raw ingress record lost its Application Job Queue permit.');
239
265
  }
240
266
  this.recordsSinceYield += 1;
241
- const dispatch = async () => {
242
- try {
243
- await this.options.dispatch(owner, record);
244
- await record.onTerminalCompletion?.();
245
- }
246
- catch (error) {
247
- this.reportDispatchError(error, meshDispatchFailureContext(record));
248
- }
249
- };
250
267
  if (permit === undefined) {
251
- await dispatch();
268
+ const dispatched = this.dispatchRecord(owner, record);
269
+ if (dispatched !== undefined)
270
+ await dispatched;
252
271
  }
253
272
  else {
254
273
  if (domain === service_runtime_contracts_1.ReadyDomain.Application &&
@@ -259,7 +278,9 @@ class ZLinkMeshDispatchPump {
259
278
  // owned by the receive attempt's finally block.
260
279
  if (permit === claimPermit)
261
280
  claimPermit = undefined;
262
- await (0, application_job_queue_scope_1.runWithApplicationJobPermit)(permit, dispatch);
281
+ const dispatched = (0, application_job_queue_scope_1.runWithApplicationJobPermit)(permit, this.dispatchOwnedRecord, owner, record);
282
+ if (dispatched !== undefined)
283
+ await dispatched;
263
284
  }
264
285
  }
265
286
  }
@@ -40,8 +40,8 @@ export declare function submitBindingReply(operation: ZLinkBindingReplyOperation
40
40
  export declare function submitBindingAsyncSend(operation: ZLinkBindingAsyncSendOperation, payload: unknown): Promise<void>;
41
41
  export declare function submitBindingSend(operation: ZLinkBindingAsyncSendOperation, payload: unknown): import('../raw-binding-port').ZLinkRawSendSubmission;
42
42
  export declare function submitBindingSyncSend(operation: ZLinkBindingAsyncSendOperation, payload: unknown): void;
43
- export declare function submitBindingRequest(operation: ZLinkBindingRequestOperation, payload: unknown, timeoutMs: number | undefined, recordReceived?: () => void): Promise<readonly unknown[]>;
44
- export declare function bindingRequestReply(submission: import('@zlink-systems/zlink').RequestSubmission, deadlineMs: number | undefined, recordReceived?: () => void): Promise<import('@zlink-systems/zlink').Message[]>;
43
+ export declare function submitBindingRequest(operation: ZLinkBindingRequestOperation, payload: unknown, timeoutMs: number | undefined, recordReceived?: () => void, onAdmitted?: () => void): Promise<readonly unknown[]>;
44
+ export declare function bindingRequestReply(submission: import('@zlink-systems/zlink').RequestSubmission, deadlineMs: number | undefined, recordReceived?: () => void, onAdmitted?: () => void): Promise<import('@zlink-systems/zlink').Message[]>;
45
45
  export declare function closeBindingReply(replies: readonly import('@zlink-systems/zlink').Message[]): void;
46
46
  /**
47
47
  * Closes a binding handle once. An already closed or terminated handle counts as
@@ -22,6 +22,7 @@ const submission_result_1 = require("../../messaging/submission-result");
22
22
  const node_backend_adapter_1 = require("../node-backend-adapter");
23
23
  const runtime_values_1 = require("../runtime-values");
24
24
  const nativeErrnoValues = node_os_1.constants.errno;
25
+ const completedSend = Promise.resolve();
25
26
  exports.zlink = (0, node_backend_adapter_1.loadBinding)();
26
27
  function isBindingNotFound(error) {
27
28
  return error instanceof exports.zlink.ConnectError && error.result === exports.zlink.ConnectResult.NotFound;
@@ -75,10 +76,14 @@ function submitBindingReply(operation, payload) {
75
76
  throw translateBindingResultError(error);
76
77
  }
77
78
  }
78
- async function submitBindingAsyncSend(operation, payload) {
79
- const submission = submitBindingSend(operation, payload);
80
- if (submission.result === runtime_values_1.SubmitResult.Backpressured)
81
- await submission.admitted;
79
+ function submitBindingAsyncSend(operation, payload) {
80
+ try {
81
+ const submission = submitBindingSend(operation, payload);
82
+ return submission.result === runtime_values_1.SubmitResult.Backpressured ? submission.admitted : completedSend;
83
+ }
84
+ catch (error) {
85
+ return Promise.reject(error);
86
+ }
82
87
  }
83
88
  function submitBindingSend(operation, payload) {
84
89
  let submission;
@@ -103,7 +108,8 @@ function submitBindingSend(operation, payload) {
103
108
  })
104
109
  };
105
110
  }
106
- return { result: runtime_values_1.SubmitResult.Ok, admitted: submission.admitted };
111
+ // Binding SendSubmission is the closed OK | BACKPRESSURED snapshot.
112
+ return submission;
107
113
  }
108
114
  function submitBindingSyncSend(operation, payload) {
109
115
  try {
@@ -120,7 +126,7 @@ function submitBindingSyncSend(operation, payload) {
120
126
  throw translateBindingResultError(error);
121
127
  }
122
128
  }
123
- async function submitBindingRequest(operation, payload, timeoutMs, recordReceived) {
129
+ async function submitBindingRequest(operation, payload, timeoutMs, recordReceived, onAdmitted) {
124
130
  const deadlineMs = timeoutMs === undefined ? undefined : performance.now() + timeoutMs;
125
131
  try {
126
132
  let current;
@@ -138,17 +144,17 @@ async function submitBindingRequest(operation, payload, timeoutMs, recordReceive
138
144
  if (timeoutMs !== undefined) {
139
145
  current = current.timeout(timeoutMs);
140
146
  }
141
- return await bindingRequestReply(current.submit(), deadlineMs, recordReceived);
147
+ return await bindingRequestReply(current.submit(), deadlineMs, recordReceived, onAdmitted);
142
148
  }
143
149
  catch (error) {
144
150
  throw translateBindingResultError(error);
145
151
  }
146
152
  }
147
- async function bindingRequestReply(submission, deadlineMs, recordReceived) {
153
+ async function bindingRequestReply(submission, deadlineMs, recordReceived, onAdmitted) {
148
154
  const reply = submission.reply;
149
155
  if (submission.result === runtime_values_1.SubmitResult.Backpressured) {
150
156
  try {
151
- const [, replies] = await (0, request_deadline_1.waitRequestReply)(Promise.all([submission.admitted, reply]), 'Request', deadlineMs);
157
+ const [, replies] = await (0, request_deadline_1.waitRequestReply)(Promise.all([submission.admitted.then(() => onAdmitted?.()), reply]), 'Request', deadlineMs);
152
158
  recordReceived?.();
153
159
  return replies;
154
160
  }
@@ -160,6 +166,7 @@ async function bindingRequestReply(submission, deadlineMs, recordReceived) {
160
166
  throw error;
161
167
  }
162
168
  }
169
+ onAdmitted?.();
163
170
  const replies = await reply;
164
171
  recordReceived?.();
165
172
  return replies;
@@ -7,7 +7,7 @@ export declare class ZLinkDealerChannelClientTransport implements ZLinkChannelCl
7
7
  private readonly publisher?;
8
8
  constructor(dealer: DealerSocket, publisher?: PubSocket | undefined);
9
9
  send(channelName: string, packetName: string | undefined, message: Message, metadata?: ReadonlyMap<string, string>): Promise<ZLinkSubmitResult>;
10
- request<TReply>(channelName: string, packetName: string | undefined, request: Message, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<TReply>;
10
+ request<TReply>(channelName: string, packetName: string | undefined, request: Message, timeoutMs: number | undefined, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>, onAdmitted?: () => void): Promise<TReply>;
11
11
  tryPublish(channelName: string, topic: string, packetName: string | undefined, event: Message, metadata?: ReadonlyMap<string, string>): ZLinkSubmitResult;
12
12
  publish(channelName: string, topic: string, packetName: string | undefined, event: Message, signal?: AbortSignal, metadata?: ReadonlyMap<string, string>): Promise<ZLinkSubmitResult>;
13
13
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZLinkDealerChannelClientTransport = void 0;
4
+ const node_backend_adapter_support_1 = require("./node-backend-adapter-support");
4
5
  const configuration_1 = require("../../configuration");
5
6
  const submission_result_1 = require("../../messaging/submission-result");
6
7
  const channel_envelope_1 = require("../../channels/channel-envelope");
@@ -22,12 +23,14 @@ class ZLinkDealerChannelClientTransport {
22
23
  await (0, flow_context_1.runWithOutboundFlow)(true, () => (0, channel_multipart_1.appendParts)(this.dealer.send(), (0, channel_envelope_1.encodeChannelEnvelopeParts)(3 /* ZLinkChannelMessageKind.Command */, channelName, packetName, message, undefined, undefined, undefined, undefined, true, metadata)).submit().admitted);
23
24
  return { status: submission_result_1.ZLinkSubmitStatus.Submitted };
24
25
  }
25
- async request(channelName, packetName, request, timeoutMs, signal, metadata = EMPTY_METADATA) {
26
+ async request(channelName, packetName, request, timeoutMs, signal, metadata = EMPTY_METADATA, onAdmitted) {
26
27
  (0, abort_1.throwIfAborted)(signal);
27
28
  const operation = (0, flow_context_1.runWithOutboundFlow)(true, () => (0, channel_multipart_1.appendParts)(this.dealer.request(), (0, channel_envelope_1.encodeChannelEnvelopeParts)(1 /* ZLinkChannelMessageKind.Request */, channelName, packetName, request, timeoutMs, undefined, undefined, undefined, true, metadata)));
28
29
  if (timeoutMs !== undefined)
29
30
  operation.timeout(timeoutMs);
30
- const reply = await (0, channel_multipart_1.submitRequestOperation)({ submit: () => operation.submit().reply }, 'channel request');
31
+ const reply = await (0, channel_multipart_1.submitRequestOperation)({
32
+ submit: () => (0, node_backend_adapter_support_1.bindingRequestReply)(operation.submit(), timeoutMs === undefined ? undefined : performance.now() + timeoutMs, undefined, onAdmitted)
33
+ }, 'channel request');
31
34
  try {
32
35
  return (0, channel_envelope_1.decodeChannelReply)(reply);
33
36
  }
@@ -5,6 +5,7 @@ const zlink_1 = require("@zlink-systems/zlink");
5
5
  const node_backend_adapter_support_1 = require("./node-backend-adapter-support");
6
6
  const node_socket_backend_adapter_1 = require("./node-socket-backend-adapter");
7
7
  const node_event_loop_poller_1 = require("./node-event-loop-poller");
8
+ const runtime_message_1 = require("../runtime-message");
8
9
  class ZLinkNodeRawBindingPort {
9
10
  sharedContext;
10
11
  routerReceiveTimeoutMs;
@@ -174,13 +175,39 @@ class NodeRawSocketPort {
174
175
  }
175
176
  class NodeRawRouterPort extends NodeRawSocketPort {
176
177
  nextIncomingRequestSequence = 1n;
178
+ routingIds = new Map();
179
+ nextRequestSequence = () => {
180
+ const current = this.nextIncomingRequestSequence;
181
+ this.nextIncomingRequestSequence =
182
+ current === BigInt(Number.MAX_SAFE_INTEGER) ? 1n : current + 1n;
183
+ return current;
184
+ };
185
+ replyParts = (targetRid, replyToken, parts) => {
186
+ appendReplyParts(this.socket.reply(this.preparedRoutingId(targetRid), replyToken), parts).submit();
187
+ };
188
+ preparedRoutingId(routingId) {
189
+ if (typeof routingId !== 'string')
190
+ return bindingRoutingId(routingId);
191
+ let prepared = this.routingIds.get(routingId);
192
+ if (prepared === undefined)
193
+ this.routingIds.set(routingId, (prepared = bindingRoutingId(routingId)));
194
+ return prepared;
195
+ }
196
+ close() {
197
+ try {
198
+ super.close();
199
+ }
200
+ finally {
201
+ this.routingIds.clear();
202
+ }
203
+ }
177
204
  setReceiveFlowState(state) {
178
205
  this.requireOpen();
179
206
  this.socket.setReceiveFlowState(state === 'paused' ? zlink_1.ReceiveFlowState.PAUSED : zlink_1.ReceiveFlowState.RUNNING);
180
207
  }
181
208
  disconnectRid(routingId) {
182
209
  this.requireOpen();
183
- this.socket.disconnectRid(bindingRoutingId(routingId));
210
+ this.socket.disconnectRid(this.preparedRoutingId(routingId));
184
211
  }
185
212
  constructor(socket, receiveTimeoutMs) {
186
213
  super(socket, true);
@@ -197,29 +224,29 @@ class NodeRawRouterPort extends NodeRawSocketPort {
197
224
  }
198
225
  setRoutingId(routingId) {
199
226
  this.requireOpen();
200
- this.socket.setRoutingId(bindingRoutingId(routingId));
227
+ this.socket.setRoutingId(this.preparedRoutingId(routingId));
201
228
  }
202
229
  connectToRoutingId(routingId, endpoint) {
203
230
  this.requireOpen();
204
- this.socket.options.setConnectRoutingId(bindingRoutingId(routingId));
231
+ this.socket.options.setConnectRoutingId(this.preparedRoutingId(routingId));
205
232
  this.connect(endpoint);
206
233
  }
207
234
  send(targetRid, parts) {
208
235
  this.requireOpen();
209
236
  requireParts(parts);
210
- return (0, node_backend_adapter_support_1.submitBindingAsyncSend)(this.socket.send(bindingRoutingId(targetRid)), parts);
237
+ return (0, node_backend_adapter_support_1.submitBindingAsyncSend)(this.socket.send(this.preparedRoutingId(targetRid)), parts);
211
238
  }
212
239
  submitSend(targetRid, parts) {
213
240
  this.requireOpen();
214
241
  requireParts(parts);
215
- return (0, node_backend_adapter_support_1.submitBindingSend)(this.socket.send(bindingRoutingId(targetRid)), parts);
242
+ return (0, node_backend_adapter_support_1.submitBindingSend)(this.socket.send(this.preparedRoutingId(targetRid)), parts);
216
243
  }
217
- async request(targetRid, parts, timeoutMs, recordReceived) {
244
+ async request(targetRid, parts, timeoutMs, recordReceived, onAdmitted) {
218
245
  this.requireOpen();
219
246
  const deadlineMs = performance.now() + timeoutMs;
220
247
  let submission;
221
248
  try {
222
- submission = appendRequestParts(this.socket.request(bindingRoutingId(targetRid)), parts)
249
+ submission = appendRequestParts(this.socket.request(this.preparedRoutingId(targetRid)), parts)
223
250
  .timeout(timeoutMs)
224
251
  .submit();
225
252
  }
@@ -227,8 +254,8 @@ class NodeRawRouterPort extends NodeRawSocketPort {
227
254
  throw (0, node_backend_adapter_support_1.translateBindingResultError)(error, 'submit');
228
255
  }
229
256
  try {
230
- const replies = await (0, node_backend_adapter_support_1.bindingRequestReply)(submission, deadlineMs, recordReceived);
231
- return copyAndClose(replies);
257
+ const replies = await (0, node_backend_adapter_support_1.bindingRequestReply)(submission, deadlineMs, recordReceived, onAdmitted);
258
+ return retainAndClose(replies);
232
259
  }
233
260
  catch (error) {
234
261
  throw (0, node_backend_adapter_support_1.translateBindingResultError)(error, 'completion');
@@ -243,14 +270,7 @@ class NodeRawRouterPort extends NodeRawSocketPort {
243
270
  }
244
271
  receive(dontWait = false) {
245
272
  this.requireOpen();
246
- return receiveRecord(this.socket, dontWait, () => {
247
- const current = this.nextIncomingRequestSequence;
248
- this.nextIncomingRequestSequence =
249
- current === BigInt(Number.MAX_SAFE_INTEGER) ? 1n : current + 1n;
250
- return current;
251
- }, (targetRid, replyToken, parts) => {
252
- appendReplyParts(this.socket.reply(bindingRoutingId(targetRid), replyToken), parts).submit();
253
- });
273
+ return receiveRecord(this.socket, dontWait, this.nextRequestSequence, this.replyParts);
254
274
  }
255
275
  }
256
276
  class NodeRawDealerPort extends NodeRawSocketPort {
@@ -266,7 +286,7 @@ class NodeRawDealerPort extends NodeRawSocketPort {
266
286
  requireParts(parts);
267
287
  return (0, node_backend_adapter_support_1.submitBindingAsyncSend)(this.socket.send(), parts);
268
288
  }
269
- async request(parts, timeoutMs) {
289
+ async request(parts, timeoutMs, onAdmitted) {
270
290
  this.requireOpen();
271
291
  const deadlineMs = performance.now() + timeoutMs;
272
292
  let submission;
@@ -277,8 +297,8 @@ class NodeRawDealerPort extends NodeRawSocketPort {
277
297
  throw (0, node_backend_adapter_support_1.translateBindingResultError)(error, 'submit');
278
298
  }
279
299
  try {
280
- const replies = await (0, node_backend_adapter_support_1.bindingRequestReply)(submission, deadlineMs);
281
- return copyAndClose(replies);
300
+ const replies = await (0, node_backend_adapter_support_1.bindingRequestReply)(submission, deadlineMs, undefined, onAdmitted);
301
+ return retainAndClose(replies);
282
302
  }
283
303
  catch (error) {
284
304
  throw (0, node_backend_adapter_support_1.translateBindingResultError)(error, 'completion');
@@ -390,9 +410,9 @@ function receiveRecord(socket, dontWait, nextRequestSequence, reply) {
390
410
  throw error;
391
411
  }
392
412
  }
393
- function copyAndClose(messages) {
413
+ function retainAndClose(messages) {
394
414
  try {
395
- return messages.map((message) => message.toBytes());
415
+ return messages.map((message) => runtime_message_1.ZLinkBufferMessage.retainPayload(message));
396
416
  }
397
417
  finally {
398
418
  for (const message of messages)