@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
@@ -54,8 +54,7 @@ function encodeNodeSendHeader() {
54
54
  function encodeNodeRequestHeader(correlation) {
55
55
  return withU64(prefix(exports.M6aServiceWireCommand.nodeRequest), correlation, 'correlation');
56
56
  }
57
- function decodeNodeRequestHeader(frame) {
58
- const header = decodeHeader(frame);
57
+ function decodeNodeRequestHeader(frame, header = decodeHeader(frame)) {
59
58
  if (header.command !== exports.M6aServiceWireCommand.nodeRequest ||
60
59
  header.flags !== 0 ||
61
60
  frame.byteLength !== 13) {
@@ -66,8 +65,7 @@ function decodeNodeRequestHeader(frame) {
66
65
  function encodeChannelSendHeader(channelName) {
67
66
  return concat(prefix(exports.M6aServiceWireCommand.channelSend), encodeText8(channelName, 'channelName'));
68
67
  }
69
- function decodeChannelSendHeader(frame) {
70
- const header = decodeHeader(frame);
68
+ function decodeChannelSendHeader(frame, header = decodeHeader(frame)) {
71
69
  if (header.command !== exports.M6aServiceWireCommand.channelSend || header.flags !== 0) {
72
70
  fail('Invalid channelSend header.');
73
71
  }
@@ -79,8 +77,7 @@ function decodeChannelSendHeader(frame) {
79
77
  function encodeChannelRequestHeader(correlation, channelName) {
80
78
  return concat(withU64(prefix(exports.M6aServiceWireCommand.channelRequest), correlation, 'correlation'), encodeText8(channelName, 'channelName'));
81
79
  }
82
- function decodeChannelRequestHeader(frame) {
83
- const header = decodeHeader(frame);
80
+ function decodeChannelRequestHeader(frame, header = decodeHeader(frame)) {
84
81
  if (header.command !== exports.M6aServiceWireCommand.channelRequest || header.flags !== 0) {
85
82
  fail('Invalid channelRequest header.');
86
83
  }
@@ -127,22 +124,8 @@ function decodeReplyHeader(frame) {
127
124
  return result;
128
125
  }
129
126
  function encodeApplicationPayload(payload) {
130
- const packetName = encodeText8(payload.packetName, 'packetName');
131
- const contentType = encodeText8(payload.contentType, 'contentType');
132
- if (payload.payload.byteLength > MAX_U32)
133
- fail('Application payload exceeds u32.');
134
- const bodyLength = packetName.byteLength + contentType.byteLength + 4 + payload.payload.byteLength;
135
- if (bodyLength > MAX_U32)
136
- fail('Application payload body exceeds u32.');
137
- const result = Buffer.alloc(5 + bodyLength);
138
- result[0] = exports.APPLICATION_PAYLOAD_VERSION;
139
- result.writeUInt32BE(bodyLength, 1);
140
- let offset = 5;
141
- offset += packetName.copy(result, offset);
142
- offset += contentType.copy(result, offset);
143
- result.writeUInt32BE(payload.payload.byteLength, offset);
144
- offset += 4;
145
- Buffer.from(payload.payload.buffer, payload.payload.byteOffset, payload.payload.byteLength).copy(result, offset);
127
+ const result = allocateApplicationPayload(payload.packetName, payload.contentType, payload.payload.byteLength);
128
+ result.set(payload.payload, result.byteLength - payload.payload.byteLength);
146
129
  return result;
147
130
  }
148
131
  /**
@@ -155,8 +138,6 @@ function encodeMultipartApplicationPayload(parts, packetName, contentType) {
155
138
  fail('Multipart payload must contain at least one part.');
156
139
  if (parts.length > MAX_U32)
157
140
  fail('Multipart part count exceeds u32.');
158
- const packetNameBytes = encodeText8(packetName, 'packetName');
159
- const contentTypeBytes = encodeText8(contentType, 'contentType');
160
141
  let multipartLength = 4;
161
142
  for (const part of parts) {
162
143
  if (part.byteLength > MAX_U32)
@@ -165,27 +146,44 @@ function encodeMultipartApplicationPayload(parts, packetName, contentType) {
165
146
  if (multipartLength > MAX_U32)
166
147
  fail('Multipart payload exceeds u32.');
167
148
  }
168
- const bodyLength = packetNameBytes.byteLength + contentTypeBytes.byteLength + 4 + multipartLength;
169
- if (bodyLength > MAX_U32)
170
- fail('Application payload body exceeds u32.');
171
- const result = Buffer.alloc(5 + bodyLength);
172
- result[0] = exports.APPLICATION_PAYLOAD_VERSION;
173
- result.writeUInt32BE(bodyLength, 1);
174
- let offset = 5;
175
- offset += packetNameBytes.copy(result, offset);
176
- offset += contentTypeBytes.copy(result, offset);
177
- result.writeUInt32BE(multipartLength, offset);
178
- offset += 4;
149
+ const result = allocateApplicationPayload(packetName, contentType, multipartLength);
150
+ let offset = result.byteLength - multipartLength;
179
151
  result.writeUInt32BE(parts.length, offset);
180
152
  offset += 4;
181
153
  for (const part of parts) {
182
154
  result.writeUInt32BE(part.byteLength, offset);
183
155
  offset += 4;
184
- Buffer.from(part.buffer, part.byteOffset, part.byteLength).copy(result, offset);
156
+ result.set(part, offset);
185
157
  offset += part.byteLength;
186
158
  }
187
159
  return result;
188
160
  }
161
+ function allocateApplicationPayload(packetName, contentType, payloadLength) {
162
+ const packetNameBytes = (0, service_wire_binary_primitives_1.encodeCanonicalServiceWireText)(packetName, 'packetName', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
163
+ const contentTypeBytes = (0, service_wire_binary_primitives_1.encodeCanonicalServiceWireText)(contentType, 'contentType', service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
164
+ if (payloadLength > MAX_U32)
165
+ fail('Application payload exceeds u32.');
166
+ const frameLength = exports.APPLICATION_PAYLOAD_MINIMUM_FIELD_BYTES +
167
+ packetNameBytes.byteLength +
168
+ contentTypeBytes.byteLength +
169
+ payloadLength;
170
+ const prefixLength = 1 + APPLICATION_PAYLOAD_LENGTH_FIELD_BYTES;
171
+ const bodyLength = frameLength - prefixLength;
172
+ if (bodyLength > MAX_U32)
173
+ fail('Application payload body exceeds u32.');
174
+ const result = Buffer.alloc(frameLength);
175
+ result[0] = exports.APPLICATION_PAYLOAD_VERSION;
176
+ result.writeUInt32BE(bodyLength, 1);
177
+ let offset = prefixLength;
178
+ result[offset++] = packetNameBytes.byteLength;
179
+ result.set(packetNameBytes, offset);
180
+ offset += packetNameBytes.byteLength;
181
+ result[offset++] = contentTypeBytes.byteLength;
182
+ result.set(contentTypeBytes, offset);
183
+ offset += contentTypeBytes.byteLength;
184
+ result.writeUInt32BE(payloadLength, offset);
185
+ return result;
186
+ }
189
187
  function decodeApplicationPayload(frame) {
190
188
  const decoded = decodeApplicationPayloadView(frame);
191
189
  return {
@@ -419,7 +417,7 @@ function encodeU64(value) {
419
417
  return result;
420
418
  }
421
419
  function encodeText8(value, field) {
422
- const bytes = (0, service_wire_binary_primitives_1.encodeCanonicalServiceWireText)(value, field, 0xff, fail);
420
+ const bytes = (0, service_wire_binary_primitives_1.encodeCanonicalServiceWireText)(value, field, service_wire_binary_primitives_1.SERVICE_WIRE_TEXT8_MAX_BYTES, fail);
423
421
  return concat(Buffer.of(bytes.byteLength), bytes);
424
422
  }
425
423
  function encodeText16(value, field) {
@@ -430,7 +428,7 @@ function tlv(id, value) {
430
428
  return concat(Buffer.of(id), encodeU32(value.byteLength), value);
431
429
  }
432
430
  function concat(...parts) {
433
- return Buffer.concat(parts.map((part) => Buffer.from(part)));
431
+ return Buffer.concat(parts);
434
432
  }
435
433
  function readNonZeroU64(bytes, offset, field) {
436
434
  const result = bytes.readBigUInt64BE(offset);
@@ -5,9 +5,17 @@ export interface ZLinkHandlerInstanceScope {
5
5
  resolve<T>(type: Type<T>): Promise<T>;
6
6
  dispose(): Promise<void>;
7
7
  }
8
+ interface ZLinkHandlerInstanceScopeFactory {
9
+ prepare?(type: Type): void | (() => unknown);
10
+ create(context?: ZLinkMessageContext): ZLinkHandlerInstanceScope;
11
+ }
12
+ export declare function registerHandlerInstanceScopeFactory(providerResolver: ZLinkProviderResolver, factory: ZLinkHandlerInstanceScopeFactory): void;
13
+ export declare function prepareHandlerInstance<T>(providerResolver: ZLinkProviderResolver | undefined, type: Type<T>): (() => T) | undefined;
8
14
  export declare function runInHandlerInstanceScope<T>(providerResolver: ZLinkProviderResolver | undefined, context: ZLinkMessageContext | undefined, callback: (scope: ZLinkHandlerInstanceScope) => Promise<T>): Promise<T>;
9
15
  export declare function resolveLifecycleHandler<T>(owner: object, type: Type<T>, providerResolver?: ZLinkProviderResolver): Promise<T>;
10
16
  export declare function runWithLifecycleHandler<THandler, TResult>(owner: object, type: Type<THandler>, providerResolver: ZLinkProviderResolver | undefined, callback: (handler: THandler) => Promise<TResult>): Promise<TResult>;
11
17
  export declare function disposeLifecycleHandlers(owner: object, detachedTaskRunner: ZLinkDetachedTaskRunner): Promise<void>;
12
18
  export declare function disposeOwnedInstance(instance: unknown): Promise<void>;
19
+ export declare function handlerInstanceCleanup(instance: unknown): (() => unknown) | undefined;
13
20
  export declare function disposeOwnedInstances(instances: readonly unknown[]): Promise<void>;
21
+ export {};
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerHandlerInstanceScopeFactory = registerHandlerInstanceScopeFactory;
4
+ exports.prepareHandlerInstance = prepareHandlerInstance;
3
5
  exports.runInHandlerInstanceScope = runInHandlerInstanceScope;
4
6
  exports.resolveLifecycleHandler = resolveLifecycleHandler;
5
7
  exports.runWithLifecycleHandler = runWithLifecycleHandler;
6
8
  exports.disposeLifecycleHandlers = disposeLifecycleHandlers;
7
9
  exports.disposeOwnedInstance = disposeOwnedInstance;
10
+ exports.handlerInstanceCleanup = handlerInstanceCleanup;
8
11
  exports.disposeOwnedInstances = disposeOwnedInstances;
9
12
  const node_async_hooks_1 = require("node:async_hooks");
10
13
  const HANDLER_SCOPE_FACTORY = Symbol.for('@zlink-systems/framework.handler-instance-scope-factory');
@@ -13,10 +16,27 @@ const activeLifecycleScope = new node_async_hooks_1.AsyncLocalStorage();
13
16
  const detachedLifecycleResource = new node_async_hooks_1.AsyncResource('zlink:handler-instance-scope');
14
17
  const dispatchScopes = new WeakMap();
15
18
  const lifecycleScopes = new WeakMap();
19
+ function registerHandlerInstanceScopeFactory(providerResolver, factory) {
20
+ Object.defineProperty(providerResolver, HANDLER_SCOPE_FACTORY, {
21
+ value: factory,
22
+ enumerable: false
23
+ });
24
+ }
25
+ function prepareHandlerInstance(providerResolver, type) {
26
+ if (providerResolver === undefined)
27
+ return () => new type();
28
+ const factory = providerResolver[HANDLER_SCOPE_FACTORY];
29
+ if (isHandlerInstanceScopeFactory(factory)) {
30
+ const activate = factory.prepare?.(type);
31
+ if (activate !== undefined)
32
+ return activate;
33
+ }
34
+ return undefined;
35
+ }
16
36
  async function runInHandlerInstanceScope(providerResolver, context, callback) {
17
37
  const active = activeHandlerScope.getStore();
18
38
  if (active !== undefined) {
19
- return callback(active.scope);
39
+ return callback(active);
20
40
  }
21
41
  if (context !== undefined) {
22
42
  const existing = dispatchScopes.get(context);
@@ -29,7 +49,7 @@ async function runInHandlerInstanceScope(providerResolver, context, callback) {
29
49
  dispatchScopes.set(context, scope);
30
50
  }
31
51
  try {
32
- return await activeHandlerScope.run({ scope }, () => callback(scope));
52
+ return await activeHandlerScope.run(scope, () => callback(scope));
33
53
  }
34
54
  finally {
35
55
  if (context !== undefined && dispatchScopes.get(context) === scope) {
@@ -94,14 +114,15 @@ class DefaultHandlerInstanceScope {
94
114
  return existing;
95
115
  const activation = createDeferred();
96
116
  this.instances.set(type, activation.promise);
97
- void this.activate(type, activation);
117
+ this.activate(type, activation);
98
118
  return activation.promise;
99
119
  }
100
120
  async dispose() {
101
121
  if (this.disposed)
102
122
  return;
103
123
  this.disposed = true;
104
- await Promise.allSettled(this.instances.values());
124
+ if (this.owned.length !== this.instances.size)
125
+ await Promise.allSettled(this.instances.values());
105
126
  try {
106
127
  await disposeOwnedInstances(this.owned);
107
128
  }
@@ -110,21 +131,37 @@ class DefaultHandlerInstanceScope {
110
131
  this.instances.clear();
111
132
  }
112
133
  }
113
- async activate(type, activation) {
114
- let instance;
134
+ activate(type, activation) {
115
135
  try {
116
136
  const created = this.providerResolver?.create?.(type);
117
- instance = created === undefined ? new type() : await created;
137
+ if (created === undefined) {
138
+ this.completeActivation(new type(), activation);
139
+ }
140
+ else {
141
+ void this.activatePending(created, activation);
142
+ }
118
143
  }
119
144
  catch (error) {
120
145
  activation.reject(error);
121
- return;
122
146
  }
147
+ }
148
+ async activatePending(created, activation) {
149
+ try {
150
+ this.completeActivation(await created, activation);
151
+ }
152
+ catch (error) {
153
+ activation.reject(error);
154
+ }
155
+ }
156
+ completeActivation(instance, activation) {
123
157
  if (!this.disposed) {
124
158
  this.owned.push(instance);
125
159
  activation.resolve(instance);
126
160
  return;
127
161
  }
162
+ void this.disposeLateActivation(instance, activation);
163
+ }
164
+ async disposeLateActivation(instance, activation) {
128
165
  try {
129
166
  await disposeOwnedInstance(instance);
130
167
  activation.reject(new Error('Handler instance scope was disposed during activation.'));
@@ -240,18 +277,24 @@ function startOutsideLifecycleInvocation(work) {
240
277
  return detachedLifecycleResource.runInAsyncScope(work);
241
278
  }
242
279
  async function disposeOwnedInstance(instance) {
280
+ const cleanup = handlerInstanceCleanup(instance);
281
+ if (cleanup !== undefined)
282
+ await cleanup.call(instance);
283
+ }
284
+ function handlerInstanceCleanup(instance) {
243
285
  if (instance === null || instance === undefined)
244
286
  return;
245
287
  const value = instance;
246
288
  if (typeof value.dispose === 'function') {
247
- await value.dispose();
289
+ return value.dispose;
248
290
  }
249
291
  else if (typeof value.close === 'function') {
250
- await value.close();
292
+ return value.close;
251
293
  }
252
294
  else if (typeof value.onModuleDestroy === 'function') {
253
- await value.onModuleDestroy();
295
+ return value.onModuleDestroy;
254
296
  }
297
+ return undefined;
255
298
  }
256
299
  async function disposeOwnedInstances(instances) {
257
300
  const failures = [];
@@ -149,9 +149,9 @@ class ZLinkActorRuntimeOptionsFactory {
149
149
  staleActorRefReporter: (_meshName, actorId) => this.options.actorHandoff.recordStaleFailure(actorId),
150
150
  staleActorRefPredicate: (meshName, actor) => this.actorBelongsToMesh(meshName, actor.actorId) &&
151
151
  this.options.actorHandoff.isKnownStale(actor),
152
- handoffCapture: (meshName, actorId, parts, returnResponse, actor, deadlineUnixMs) => this.actorBelongsToMesh(meshName, actorId) &&
152
+ handoffCapture: (meshName, actorId, parts, returnResponse, actor, deadlineUnixMs, onAdmitted) => this.actorBelongsToMesh(meshName, actorId) &&
153
153
  !this.options.actorHandoff.isProvisional(actorId)
154
- ? this.options.actorHandoff.capture('local', actorId, parts, returnResponse, undefined, actor, deadlineUnixMs)
154
+ ? this.options.actorHandoff.capture('local', actorId, parts, returnResponse, undefined, actor, deadlineUnixMs, undefined, undefined, onAdmitted)
155
155
  : undefined,
156
156
  sendErrorReporter: this.options.reportPostCommitError
157
157
  };
@@ -1,4 +1,4 @@
1
- import type { ApplicationJobOrigin, ApplicationJobPermitPort, ApplicationJobQueuePort } from '../application-jobs/contracts';
1
+ import type { ApplicationJobOrigin, ApplicationJobPermitPort, ApplicationJobReceiveRotationPort, ApplicationJobQueuePort } from '../application-jobs/contracts';
2
2
  export type ApplicationJobQueueProfileValue = 'compact' | 'low_latency' | 'balanced' | 'throughput';
3
3
  export interface ApplicationJobQueueOptions {
4
4
  readonly profile?: ApplicationJobQueueProfileValue;
@@ -40,12 +40,17 @@ export declare function resolveApplicationJobQueueConfiguration(options?: Applic
40
40
  export declare class ApplicationJobQueuePermit implements ApplicationJobPermitPort {
41
41
  private readonly owner;
42
42
  readonly origin: ApplicationJobOrigin;
43
+ private readonly reusable;
44
+ detachedForHandlerTurn: boolean;
43
45
  private state;
44
- constructor(owner: ApplicationJobQueue, origin: ApplicationJobOrigin);
46
+ constructor(owner: ApplicationJobQueue, origin: ApplicationJobOrigin, reusable?: boolean);
47
+ reserveStorage(): boolean;
48
+ releaseStorage(): void;
49
+ detachForHandlerTurn(): void;
45
50
  markApplicationQueued(): void;
46
51
  releaseBeforeHandler(): void;
47
52
  releaseAfterInternalProcessing(): void;
48
- private release;
53
+ takeReleaseState(): 'reserved' | 'queued' | undefined;
49
54
  }
50
55
  /**
51
56
  * Host-instance owner of the ordinary-ingress queue permit lifecycle.
@@ -59,9 +64,10 @@ export declare class ApplicationJobQueue implements ApplicationJobQueuePort {
59
64
  private readonly loggerFailureReporter?;
60
65
  private localWaiters;
61
66
  private localBacklogLogged;
62
- private reservedSupplyPermits;
63
- private queuedApplicationJobs;
64
- private peakPermitsInUse;
67
+ private readonly permitCounts;
68
+ private readonly limitCount;
69
+ private readonly pauseCount;
70
+ private readonly resumeCount;
65
71
  private capacityWaitCount;
66
72
  private capacityWaitDurationSeconds;
67
73
  private metricsEpoch;
@@ -79,6 +85,9 @@ export declare class ApplicationJobQueue implements ApplicationJobQueuePort {
79
85
  private readonly receiveFlowController;
80
86
  constructor(configuration: ApplicationJobQueueConfiguration, nowMs?: () => number, handlerStartGate?: (() => boolean) | undefined, loggerFailureReporter?: ((error: unknown) => void) | undefined);
81
87
  shouldHoldPermitBeforeHandler(): boolean;
88
+ createReceiveRotation(capacity: number, origin: ApplicationJobOrigin): ApplicationJobReceiveRotationPort;
89
+ receiveRotationCapacity(capacity: number): number;
90
+ reserveReceiveRotation(count: number): void;
82
91
  registerReceiveFlowTarget(identity: object, applyState: (state: ApplicationJobQueuePressureState) => void, failureSink?: (error: unknown) => void): boolean;
83
92
  unregisterReceiveFlowTarget(identity: object): void;
84
93
  acquire(signal: AbortSignal | undefined, origin: ApplicationJobOrigin): Promise<ApplicationJobQueuePermit>;
@@ -90,9 +99,12 @@ export declare class ApplicationJobQueue implements ApplicationJobQueuePort {
90
99
  onPressureStateChange(listener: (state: ApplicationJobQueuePressureState, sequence: bigint) => void): () => void;
91
100
  recordFlowStateConfigFailure(): void;
92
101
  markQueued(): void;
93
- release(state: 'reserved' | 'queued'): void;
102
+ releasePermit(permit: ApplicationJobQueuePermit): void;
103
+ releaseUnusedReceiveRotation(grants: readonly (ApplicationJobQueuePermit | undefined)[], consumed: number, granted: number): void;
104
+ release(state: 'reserved' | 'queued', count?: number): void;
94
105
  private limit;
95
106
  private permitsInUse;
107
+ private reserveSupply;
96
108
  private reserve;
97
109
  private drainWaiters;
98
110
  private cancel;
@@ -53,10 +53,31 @@ function resolveApplicationJobQueueConfiguration(options = {}, effectiveProcesso
53
53
  class ApplicationJobQueuePermit {
54
54
  owner;
55
55
  origin;
56
- state = 'reserved';
57
- constructor(owner, origin) {
56
+ reusable;
57
+ detachedForHandlerTurn = false;
58
+ state;
59
+ constructor(owner, origin, reusable = false) {
58
60
  this.owner = owner;
59
61
  this.origin = origin;
62
+ this.reusable = reusable;
63
+ this.state = reusable ? 'idle' : 'reserved';
64
+ }
65
+ reserveStorage() {
66
+ if (this.state !== 'idle')
67
+ return false;
68
+ this.state = 'reserved';
69
+ this.detachedForHandlerTurn = false;
70
+ return true;
71
+ }
72
+ releaseStorage() {
73
+ if (!this.reusable || this.state === 'idle')
74
+ return;
75
+ if (this.state !== 'released')
76
+ throw new Error('Reservation storage still owns queue capacity.');
77
+ this.state = 'idle';
78
+ }
79
+ detachForHandlerTurn() {
80
+ this.detachedForHandlerTurn = true;
60
81
  }
61
82
  markApplicationQueued() {
62
83
  if (this.state !== 'reserved') {
@@ -68,19 +89,75 @@ class ApplicationJobQueuePermit {
68
89
  releaseBeforeHandler() {
69
90
  if (this.owner.shouldHoldPermitBeforeHandler())
70
91
  return;
71
- this.release();
92
+ this.owner.releasePermit(this);
72
93
  }
73
94
  releaseAfterInternalProcessing() {
74
- this.release();
95
+ this.owner.releasePermit(this);
75
96
  }
76
- release() {
77
- if (this.state === 'released')
78
- return;
79
- this.owner.release(this.state);
97
+ takeReleaseState() {
98
+ if (this.state === 'released' || this.state === 'idle')
99
+ return undefined;
100
+ const state = this.state;
80
101
  this.state = 'released';
102
+ return state;
81
103
  }
82
104
  }
83
105
  exports.ApplicationJobQueuePermit = ApplicationJobQueuePermit;
106
+ /** Connection-owned storage; queue accounting remains with the host queue. */
107
+ class ApplicationJobReceiveRotation {
108
+ owner;
109
+ capacity;
110
+ origin;
111
+ storage = [];
112
+ grants;
113
+ granted = 0;
114
+ consumed = 0;
115
+ constructor(owner, capacity, origin) {
116
+ this.owner = owner;
117
+ this.capacity = capacity;
118
+ this.origin = origin;
119
+ this.grants = new Array(capacity);
120
+ this.prepareStorage();
121
+ }
122
+ prepareStorage() {
123
+ for (let index = 0; index < this.capacity; index++)
124
+ this.storage.push(new ApplicationJobQueuePermit(this.owner, this.origin, true));
125
+ }
126
+ reserve() {
127
+ this.releaseUnused();
128
+ const count = this.owner.receiveRotationCapacity(this.capacity);
129
+ if (count === 0)
130
+ return;
131
+ for (let index = 0; index < this.storage.length; index++) {
132
+ const permit = this.storage[index];
133
+ if (permit.reserveStorage())
134
+ this.grants[this.granted++] = permit;
135
+ if (this.granted === count)
136
+ break;
137
+ }
138
+ if (this.granted < count) {
139
+ const start = this.storage.length;
140
+ this.prepareStorage();
141
+ for (let index = start; this.granted < count; index++) {
142
+ const permit = this.storage[index];
143
+ permit.reserveStorage();
144
+ this.grants[this.granted++] = permit;
145
+ }
146
+ }
147
+ this.owner.reserveReceiveRotation(count);
148
+ }
149
+ take() {
150
+ if (this.consumed === this.granted)
151
+ return undefined;
152
+ return this.grants[this.consumed++];
153
+ }
154
+ releaseUnused() {
155
+ this.owner.releaseUnusedReceiveRotation(this.grants, this.consumed, this.granted);
156
+ // Keep the prepared grant slots and reset only the logical count.
157
+ this.granted = 0;
158
+ this.consumed = 0;
159
+ }
160
+ }
84
161
  /**
85
162
  * Host-instance owner of the ordinary-ingress queue permit lifecycle.
86
163
  * It reserves capacity before receive/claim and transfers released capacity
@@ -93,9 +170,11 @@ class ApplicationJobQueue {
93
170
  loggerFailureReporter;
94
171
  localWaiters = 0;
95
172
  localBacklogLogged = false;
96
- reservedSupplyPermits = 0n;
97
- queuedApplicationJobs = 0n;
98
- peakPermitsInUse = 0n;
173
+ // The contract bounds capacity by INT32_MAX; public snapshots remain bigint.
174
+ permitCounts = new Uint32Array(3 /* QueuePermitCount.Size */);
175
+ limitCount;
176
+ pauseCount;
177
+ resumeCount;
99
178
  capacityWaitCount = 0n;
100
179
  capacityWaitDurationSeconds = 0;
101
180
  metricsEpoch = 0n;
@@ -116,11 +195,27 @@ class ApplicationJobQueue {
116
195
  this.nowMs = nowMs;
117
196
  this.handlerStartGate = handlerStartGate;
118
197
  this.loggerFailureReporter = loggerFailureReporter;
198
+ this.limitCount = Number(configuration.effectiveMaxQueuedApplicationJobs);
199
+ this.pauseCount = Number(configuration.pausePermitCount);
200
+ this.resumeCount = Number(configuration.resumePermitCount);
119
201
  this.receiveFlowController = new receive_flow_controller_1.ApplicationJobReceiveFlowController(this, (state) => state);
120
202
  }
121
203
  shouldHoldPermitBeforeHandler() {
122
204
  return this.handlerStartGate?.() === true;
123
205
  }
206
+ createReceiveRotation(capacity, origin) {
207
+ if (!Number.isSafeInteger(capacity) || capacity < 1)
208
+ throw new RangeError('Receive capacity must be positive.');
209
+ return new ApplicationJobReceiveRotation(this, capacity, origin);
210
+ }
211
+ receiveRotationCapacity(capacity) {
212
+ if (this.waiters.length !== 0)
213
+ return 0;
214
+ return Math.min(capacity, this.limitCount - this.permitsInUse());
215
+ }
216
+ reserveReceiveRotation(count) {
217
+ this.reserveSupply(count);
218
+ }
124
219
  registerReceiveFlowTarget(identity, applyState, failureSink) {
125
220
  this.unregisterReceiveFlowTarget(identity);
126
221
  const target = {
@@ -173,7 +268,7 @@ class ApplicationJobQueue {
173
268
  reject(abortReason(signal));
174
269
  return undefined;
175
270
  }
176
- if (this.waiters.length === 0 && this.permitsInUse() < this.limit()) {
271
+ if (this.waiters.length === 0 && this.permitsInUse() < this.limitCount) {
177
272
  return this.reserve(origin);
178
273
  }
179
274
  new Promise((resolve, reject) => {
@@ -204,10 +299,10 @@ class ApplicationJobQueue {
204
299
  const now = this.nowMs();
205
300
  return Object.freeze({
206
301
  ...this.configuration,
207
- reservedSupplyPermits: this.reservedSupplyPermits,
208
- queuedApplicationJobs: this.queuedApplicationJobs,
209
- permitsInUse,
210
- peakPermitsInUse: this.peakPermitsInUse,
302
+ reservedSupplyPermits: BigInt(this.permitCounts[0 /* QueuePermitCount.Reserved */]),
303
+ queuedApplicationJobs: BigInt(this.permitCounts[1 /* QueuePermitCount.Queued */]),
304
+ permitsInUse: BigInt(permitsInUse),
305
+ peakPermitsInUse: BigInt(this.permitCounts[2 /* QueuePermitCount.Peak */]),
211
306
  capacityWaiters: BigInt(this.waiters.length),
212
307
  capacityWaitCount: this.capacityWaitCount,
213
308
  capacityWaitDurationSeconds: this.capacityWaitDurationSeconds,
@@ -221,7 +316,7 @@ class ApplicationJobQueue {
221
316
  }
222
317
  resetMetrics() {
223
318
  this.metricsEpoch += 1n;
224
- this.peakPermitsInUse = this.permitsInUse();
319
+ this.permitCounts[2 /* QueuePermitCount.Peak */] = this.permitsInUse();
225
320
  this.capacityWaitCount = 0n;
226
321
  this.capacityWaitDurationSeconds = 0;
227
322
  this.runningTransitionCount = 0n;
@@ -248,25 +343,37 @@ class ApplicationJobQueue {
248
343
  this.flowStateConfigFailureCount += 1n;
249
344
  }
250
345
  markQueued() {
251
- if (this.reservedSupplyPermits === 0n) {
346
+ if (this.permitCounts[0 /* QueuePermitCount.Reserved */] === 0) {
252
347
  throw new Error('Application job queue has no reserved supply permit.');
253
348
  }
254
- this.reservedSupplyPermits -= 1n;
255
- this.queuedApplicationJobs += 1n;
256
- }
257
- release(state) {
258
- if (state === 'reserved') {
259
- if (this.reservedSupplyPermits === 0n) {
260
- throw new Error('Application job queue reserved permit accounting underflow.');
261
- }
262
- this.reservedSupplyPermits -= 1n;
349
+ this.permitCounts[0 /* QueuePermitCount.Reserved */] =
350
+ this.permitCounts[0 /* QueuePermitCount.Reserved */] - 1;
351
+ this.permitCounts[1 /* QueuePermitCount.Queued */] = this.permitCounts[1 /* QueuePermitCount.Queued */] + 1;
352
+ }
353
+ releasePermit(permit) {
354
+ const state = permit.takeReleaseState();
355
+ if (state !== undefined)
356
+ this.release(state);
357
+ }
358
+ releaseUnusedReceiveRotation(grants, consumed, granted) {
359
+ const count = granted - consumed;
360
+ if (count === 0)
361
+ return;
362
+ // Unconsumed grants still belong to this receive round; no record has acquired them.
363
+ for (let index = consumed; index < granted; index++) {
364
+ const permit = grants[index];
365
+ permit.takeReleaseState();
366
+ permit.releaseStorage();
263
367
  }
264
- else {
265
- if (this.queuedApplicationJobs === 0n) {
266
- throw new Error('Application job queue queued permit accounting underflow.');
267
- }
268
- this.queuedApplicationJobs -= 1n;
368
+ this.release('reserved', count);
369
+ }
370
+ release(state, count = 1) {
371
+ const index = state === 'reserved' ? 0 /* QueuePermitCount.Reserved */ : 1 /* QueuePermitCount.Queued */;
372
+ const available = this.permitCounts[index];
373
+ if (available < count) {
374
+ throw new Error(`Application job queue ${state} permit accounting underflow.`);
269
375
  }
376
+ this.permitCounts[index] = available - count;
270
377
  this.drainWaiters();
271
378
  this.evaluatePressure();
272
379
  }
@@ -274,19 +381,21 @@ class ApplicationJobQueue {
274
381
  return this.configuration.effectiveMaxQueuedApplicationJobs;
275
382
  }
276
383
  permitsInUse() {
277
- return this.reservedSupplyPermits + this.queuedApplicationJobs;
384
+ return (this.permitCounts[0 /* QueuePermitCount.Reserved */] + this.permitCounts[1 /* QueuePermitCount.Queued */]);
278
385
  }
279
- reserve(origin, evaluatePressure = true) {
280
- this.reservedSupplyPermits += 1n;
281
- const current = this.permitsInUse();
282
- if (current > this.peakPermitsInUse)
283
- this.peakPermitsInUse = current;
386
+ reserveSupply(count, evaluatePressure = true) {
387
+ this.permitCounts[0 /* QueuePermitCount.Reserved */] =
388
+ this.permitCounts[0 /* QueuePermitCount.Reserved */] + count;
389
+ this.permitCounts[2 /* QueuePermitCount.Peak */] = Math.max(this.permitCounts[2 /* QueuePermitCount.Peak */], this.permitsInUse());
284
390
  if (evaluatePressure)
285
391
  this.evaluatePressure();
392
+ }
393
+ reserve(origin, evaluatePressure = true) {
394
+ this.reserveSupply(1, evaluatePressure);
286
395
  return new ApplicationJobQueuePermit(this, origin);
287
396
  }
288
397
  drainWaiters() {
289
- while (this.waiters.length > 0 && this.permitsInUse() < this.limit()) {
398
+ while (this.waiters.length > 0 && this.permitsInUse() < this.limitCount) {
290
399
  const waiter = this.waiters.shift();
291
400
  if (!waiter.active)
292
401
  continue;
@@ -348,12 +457,11 @@ class ApplicationJobQueue {
348
457
  }
349
458
  }
350
459
  evaluatePressure() {
351
- const permitsInUse = this.permitsInUse();
352
460
  const next = this.pressureStateValue === 'running'
353
- ? permitsInUse >= this.configuration.pausePermitCount
461
+ ? this.permitsInUse() >= this.pauseCount
354
462
  ? 'paused'
355
463
  : 'running'
356
- : permitsInUse <= this.configuration.resumePermitCount
464
+ : this.permitsInUse() <= this.resumeCount
357
465
  ? 'running'
358
466
  : 'paused';
359
467
  if (next === this.pressureStateValue)
@@ -20,6 +20,7 @@ export declare class ZLinkEntryActorRuntimeService implements ZLinkEntryActorRun
20
20
  private readonly binder;
21
21
  constructor(options: ZLinkEntryActorRuntimeOptions);
22
22
  resolveActor(actorId: string): ZLinkActor | undefined;
23
+ releaseMembers(meshName: string): Promise<void>;
23
24
  commitActorTransaction(actor: ZLinkActor, onJoined: () => Promise<void>): Promise<void>;
24
25
  destroyActor(node: ZLinkBackendSpotNode, entryNodeRid: ActorRef['nodeRid'], actor: ZLinkActor, signal?: AbortSignal): Promise<void>;
25
26
  routePacket(actorId: string, parts: readonly Message[], returnResponse?: boolean, remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget, fallbackActorRef?: ActorRef): Promise<{