@zlink-systems/framework 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Channels/IZLinkFanoutClient.d.ts +0 -6
  3. package/dist/contracts/RouteMesh/RuntimeTopology.d.ts +8 -0
  4. package/dist/internal.d.ts +1 -0
  5. package/dist/internal.js +1 -0
  6. package/dist/runtime/activation-admission.d.ts +29 -0
  7. package/dist/runtime/activation-admission.js +61 -0
  8. package/dist/runtime/actors/actor-context.js +6 -6
  9. package/dist/runtime/actors/actor-handoff.d.ts +9 -3
  10. package/dist/runtime/actors/actor-handoff.js +28 -17
  11. package/dist/runtime/actors/actor-local-native-join.js +2 -18
  12. package/dist/runtime/actors/actor-remote-joiner.d.ts +2 -2
  13. package/dist/runtime/actors/actor-remote-joiner.js +6 -8
  14. package/dist/runtime/actors/actor-runtime-contracts.d.ts +4 -2
  15. package/dist/runtime/actors/actor-source-transfer.d.ts +5 -5
  16. package/dist/runtime/actors/deferred-join-completion.d.ts +14 -0
  17. package/dist/runtime/actors/deferred-join-completion.js +20 -0
  18. package/dist/runtime/actors/index.d.ts +1 -1
  19. package/dist/runtime/actors/index.js +15 -5
  20. package/dist/runtime/admission.d.ts +5 -1
  21. package/dist/runtime/admission.js +4 -0
  22. package/dist/runtime/backend/contracts/index.d.ts +2 -10
  23. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -9
  24. package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +1 -2
  25. package/dist/runtime/backend/node/node-backend-adapter-factory.js +4 -18
  26. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +6 -3
  27. package/dist/runtime/backend/node/node-backend-adapter-support.js +12 -28
  28. package/dist/runtime/backend/node/node-event-loop-poller.d.ts +1 -1
  29. package/dist/runtime/backend/node/node-event-loop-poller.js +8 -2
  30. package/dist/runtime/backend/node/node-raw-binding-port.d.ts +1 -1
  31. package/dist/runtime/backend/node/node-raw-binding-port.js +11 -3
  32. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +12 -9
  33. package/dist/runtime/backend/node/node-raw-mesh-backend.js +61 -29
  34. package/dist/runtime/backend/node/node-socket-backend-adapter.js +1 -1
  35. package/dist/runtime/backend/raw-binding-port.d.ts +12 -0
  36. package/dist/runtime/channels/channel-clients.d.ts +0 -1
  37. package/dist/runtime/channels/channel-clients.js +0 -8
  38. package/dist/runtime/channels/channel-outbound-operations.js +2 -10
  39. package/dist/runtime/channels/channel-runtime-manager.d.ts +2 -5
  40. package/dist/runtime/channels/channel-runtime-manager.js +1 -12
  41. package/dist/runtime/channels/channel-socket-registry.d.ts +17 -4
  42. package/dist/runtime/channels/channel-socket-registry.js +49 -62
  43. package/dist/runtime/channels/channel-transports.d.ts +0 -3
  44. package/dist/runtime/channels/fanout-location-runtime.js +3 -9
  45. package/dist/runtime/execution/index.d.ts +18 -8
  46. package/dist/runtime/execution/index.js +55 -29
  47. package/dist/runtime/execution/serial-execution-queue.d.ts +5 -6
  48. package/dist/runtime/execution/serial-execution-queue.js +49 -15
  49. package/dist/runtime/foundation/listener-records.d.ts +11 -0
  50. package/dist/runtime/foundation/listener-records.js +20 -0
  51. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +10 -21
  52. package/dist/runtime/foundation/raw-service-mesh-runtime.js +66 -392
  53. package/dist/runtime/foundation/service-authority-payload-codec.d.ts +1 -0
  54. package/dist/runtime/foundation/service-authority-payload-codec.js +8 -0
  55. package/dist/runtime/foundation/service-maintenance-runtime.js +23 -2
  56. package/dist/runtime/foundation/service-relocation-coordinator.d.ts +9 -0
  57. package/dist/runtime/foundation/service-relocation-coordinator.js +14 -1
  58. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +8 -0
  59. package/dist/runtime/foundation/service-relocation-object-owner.js +16 -4
  60. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +6 -13
  61. package/dist/runtime/foundation/service-stateful-runtime.d.ts +10 -7
  62. package/dist/runtime/foundation/service-stateful-runtime.js +100 -60
  63. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +9 -4
  64. package/dist/runtime/foundation/service-stateful-wire-codec.js +153 -90
  65. package/dist/runtime/foundation/service-topology-registry.d.ts +1 -2
  66. package/dist/runtime/foundation/service-topology-registry.js +6 -30
  67. package/dist/runtime/host/actor-transfer-runtime.d.ts +17 -15
  68. package/dist/runtime/host/actor-transfer-runtime.js +73 -86
  69. package/dist/runtime/host/index.d.ts +6 -2
  70. package/dist/runtime/host/index.js +63 -37
  71. package/dist/runtime/host/remote-bound-session-relay.js +4 -3
  72. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -0
  73. package/dist/runtime/host/route-mesh-runtime.js +7 -5
  74. package/dist/runtime/host/service-relocation-host-runtime.d.ts +50 -8
  75. package/dist/runtime/host/service-relocation-host-runtime.js +343 -270
  76. package/dist/runtime/host/spot-runtime-options-factory.d.ts +7 -4
  77. package/dist/runtime/host/spot-runtime-options-factory.js +4 -8
  78. package/dist/runtime/host/stateful-authority-route-runtime.js +6 -2
  79. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +11 -3
  80. package/dist/runtime/host/user-spot-creation-coordinator.js +85 -87
  81. package/dist/runtime/locations/in-memory-provider-location-store.js +8 -6
  82. package/dist/runtime/locations/lifecycle.d.ts +1 -1
  83. package/dist/runtime/locations/lifecycle.js +2 -2
  84. package/dist/runtime/locations/resolvers.js +7 -2
  85. package/dist/runtime/locations/spot-location-claims.d.ts +2 -2
  86. package/dist/runtime/locations/spot-location-claims.js +3 -27
  87. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
  88. package/dist/runtime/protocol/service_wire_codec.generated.js +5 -1
  89. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +1 -0
  90. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +3 -2
  91. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +3 -3
  92. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +4 -4
  93. package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +3 -3
  94. package/dist/runtime/spots/index.d.ts +25 -19
  95. package/dist/runtime/spots/index.js +207 -205
  96. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  97. package/dist/runtime/spots/spot-activation-registry.js +34 -31
  98. package/dist/runtime/spots/spot-activation-state.d.ts +2 -11
  99. package/dist/runtime/spots/spot-activation-state.js +4 -17
  100. package/dist/runtime/spots/spot-activation.d.ts +8 -6
  101. package/dist/runtime/spots/spot-activation.js +54 -49
  102. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -1
  103. package/dist/runtime/spots/spot-actor-admission-coordinator.js +1 -1
  104. package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +2 -2
  105. package/dist/runtime/spots/spot-actor-join-dispatch.js +3 -5
  106. package/dist/runtime/spots/spot-actor-lifecycle-drain.js +2 -2
  107. package/dist/runtime/spots/spot-actor-membership.d.ts +4 -0
  108. package/dist/runtime/spots/spot-actor-membership.js +26 -12
  109. package/dist/runtime/spots/spot-entry-activation.d.ts +1 -2
  110. package/dist/runtime/spots/spot-entry-activation.js +0 -1
  111. package/dist/runtime/spots/spot-manager-public.js +1 -1
  112. package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +1 -1
  113. package/dist/runtime/spots/spot-native-actor-join-admission.js +2 -2
  114. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +5 -5
  115. package/dist/runtime/spots/spot-node-runtime-manager.js +7 -11
  116. package/dist/runtime/spots/spot-outbound.js +1 -29
  117. package/dist/runtime/spots/spot-routed-actor-admission.d.ts +1 -0
  118. package/dist/runtime/spots/spot-routed-actor-admission.js +10 -0
  119. package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +2 -6
  120. package/dist/runtime/spots/spot-routed-frame-dispatch.js +2 -70
  121. package/dist/runtime/spots/spot-runtime-ports.d.ts +3 -5
  122. package/dist/runtime/spots/spot-serial-executor.d.ts +5 -0
  123. package/dist/runtime/spots/spot-serial-executor.js +8 -1
  124. package/dist/runtime/spots/spot-serial-turn-executor.d.ts +3 -0
  125. package/dist/runtime/spots/spot-serial-turn-executor.js +8 -4
  126. package/dist/runtime/streams/actor-session-binding-registry.d.ts +13 -15
  127. package/dist/runtime/streams/actor-session-binding-registry.js +19 -171
  128. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +3 -4
  129. package/dist/runtime/streams/bound-session-service.js +1 -18
  130. package/dist/runtime/streams/index.d.ts +2 -0
  131. package/dist/runtime/streams/index.js +19 -19
  132. package/dist/runtime/streams/session-serial-executor.js +2 -2
  133. package/package.json +3 -3
  134. package/src/contracts/Channels/IZLinkFanoutClient.ts +0 -7
  135. package/src/contracts/RouteMesh/RuntimeTopology.ts +10 -0
  136. package/src/internal.ts +1 -0
  137. package/src/runtime/activation-admission.ts +78 -0
  138. package/src/runtime/actors/actor-context.ts +6 -6
  139. package/src/runtime/actors/actor-handoff.ts +31 -23
  140. package/src/runtime/actors/actor-local-native-join.ts +3 -42
  141. package/src/runtime/actors/actor-remote-joiner.ts +6 -25
  142. package/src/runtime/actors/actor-runtime-contracts.ts +4 -10
  143. package/src/runtime/actors/actor-source-transfer.ts +5 -18
  144. package/src/runtime/actors/deferred-join-completion.ts +40 -0
  145. package/src/runtime/actors/index.ts +22 -9
  146. package/src/runtime/admission.ts +5 -1
  147. package/src/runtime/backend/contracts/index.ts +2 -13
  148. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -10
  149. package/src/runtime/backend/node/node-backend-adapter-factory.ts +5 -25
  150. package/src/runtime/backend/node/node-backend-adapter-support.ts +9 -29
  151. package/src/runtime/backend/node/node-event-loop-poller.ts +14 -2
  152. package/src/runtime/backend/node/node-raw-binding-port.ts +17 -3
  153. package/src/runtime/backend/node/node-raw-mesh-backend.ts +65 -32
  154. package/src/runtime/backend/node/node-socket-backend-adapter.ts +2 -2
  155. package/src/runtime/backend/raw-binding-port.ts +13 -0
  156. package/src/runtime/channels/channel-clients.ts +0 -11
  157. package/src/runtime/channels/channel-outbound-operations.ts +3 -11
  158. package/src/runtime/channels/channel-runtime-manager.ts +4 -15
  159. package/src/runtime/channels/channel-socket-registry.ts +69 -71
  160. package/src/runtime/channels/channel-transports.ts +0 -3
  161. package/src/runtime/channels/fanout-location-runtime.ts +4 -16
  162. package/src/runtime/execution/index.ts +68 -30
  163. package/src/runtime/execution/serial-execution-queue.ts +52 -20
  164. package/src/runtime/foundation/listener-records.ts +21 -0
  165. package/src/runtime/foundation/raw-service-mesh-runtime.ts +66 -466
  166. package/src/runtime/foundation/service-authority-payload-codec.ts +10 -0
  167. package/src/runtime/foundation/service-maintenance-runtime.ts +30 -9
  168. package/src/runtime/foundation/service-relocation-coordinator.ts +13 -0
  169. package/src/runtime/foundation/service-relocation-object-owner.ts +18 -5
  170. package/src/runtime/foundation/service-session-binding-ingress-port.ts +6 -14
  171. package/src/runtime/foundation/service-stateful-runtime.ts +151 -89
  172. package/src/runtime/foundation/service-stateful-wire-codec.ts +203 -121
  173. package/src/runtime/foundation/service-topology-registry.ts +8 -48
  174. package/src/runtime/host/actor-transfer-runtime.ts +94 -166
  175. package/src/runtime/host/index.ts +119 -54
  176. package/src/runtime/host/remote-bound-session-relay.ts +4 -3
  177. package/src/runtime/host/route-mesh-runtime.ts +9 -5
  178. package/src/runtime/host/service-relocation-host-runtime.ts +495 -376
  179. package/src/runtime/host/spot-runtime-options-factory.ts +24 -13
  180. package/src/runtime/host/stateful-authority-route-runtime.ts +8 -4
  181. package/src/runtime/host/user-spot-creation-coordinator.ts +147 -142
  182. package/src/runtime/locations/in-memory-provider-location-store.ts +11 -7
  183. package/src/runtime/locations/lifecycle.ts +3 -2
  184. package/src/runtime/locations/resolvers.ts +19 -13
  185. package/src/runtime/locations/spot-location-claims.ts +5 -34
  186. package/src/runtime/protocol/service_wire_codec.generated.ts +9 -2
  187. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  188. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +6 -6
  189. package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +3 -3
  190. package/src/runtime/spots/index.ts +341 -295
  191. package/src/runtime/spots/spot-activation-registry.ts +41 -31
  192. package/src/runtime/spots/spot-activation-state.ts +4 -16
  193. package/src/runtime/spots/spot-activation.ts +102 -80
  194. package/src/runtime/spots/spot-actor-admission-coordinator.ts +2 -2
  195. package/src/runtime/spots/spot-actor-join-dispatch.ts +6 -7
  196. package/src/runtime/spots/spot-actor-lifecycle-drain.ts +20 -18
  197. package/src/runtime/spots/spot-actor-membership.ts +81 -17
  198. package/src/runtime/spots/spot-entry-activation.ts +0 -3
  199. package/src/runtime/spots/spot-manager-public.ts +8 -4
  200. package/src/runtime/spots/spot-native-actor-join-admission.ts +2 -2
  201. package/src/runtime/spots/spot-node-runtime-manager.ts +12 -18
  202. package/src/runtime/spots/spot-outbound.ts +4 -47
  203. package/src/runtime/spots/spot-routed-actor-admission.ts +20 -0
  204. package/src/runtime/spots/spot-routed-frame-dispatch.ts +6 -76
  205. package/src/runtime/spots/spot-runtime-ports.ts +6 -17
  206. package/src/runtime/spots/spot-serial-executor.ts +9 -1
  207. package/src/runtime/spots/spot-serial-turn-executor.ts +10 -4
  208. package/src/runtime/streams/actor-session-binding-registry.ts +20 -308
  209. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +2 -12
  210. package/src/runtime/streams/bound-session-service.ts +2 -36
  211. package/src/runtime/streams/index.ts +29 -27
  212. package/src/runtime/streams/session-serial-executor.ts +2 -2
  213. package/dist/runtime/actors/deferred-join-accepted-journal.d.ts +0 -47
  214. package/dist/runtime/actors/deferred-join-accepted-journal.js +0 -992
  215. package/src/runtime/actors/deferred-join-accepted-journal.ts +0 -1346
@@ -210,7 +210,7 @@ export interface ZLinkBackendMeshNode {
210
210
  timeoutMs?: number;
211
211
  applicationMetadata?: Buffer;
212
212
  }): MeshOperationId;
213
- sendActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, parts: MessageLike | readonly MessageLike[], flags?: number, actorFence?: ZLinkBackendActorSessionSendFence): Promise<SubmitResult>;
213
+ sendActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, parts: MessageLike | readonly MessageLike[], flags?: number): Promise<SubmitResult>;
214
214
  closeActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, timeoutMs?: number): MeshOperationId;
215
215
  leaveActor(actor: ZLinkBackendActorRef, expectedMembershipEpoch: bigint, timeoutMs?: number): MeshOperationId;
216
216
  setReadyHandler(handler: (readyDomains: number) => number): void;
@@ -237,14 +237,8 @@ export interface ZLinkBackendActorRef {
237
237
  readonly actorId: string;
238
238
  readonly generation: bigint;
239
239
  }
240
- export interface ZLinkBackendActorSessionSendFence {
241
- readonly targetNodeGeneration: bigint;
242
- readonly authorityOwnerGeneration: bigint;
243
- readonly ownerLeaseGeneration: bigint;
244
- }
245
240
  export interface ZLinkBackendActorSessionNode {
246
- actorNodeGeneration?(actor: ZLinkBackendActorRef): bigint | undefined;
247
- sendActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, parts: readonly Message[], flags: number, actorFence?: ZLinkBackendActorSessionSendFence): Promise<ZLinkSubmitResult>;
241
+ sendActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, parts: readonly Message[], flags: number): Promise<ZLinkSubmitResult>;
248
242
  closeActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, timeoutMs: number, signal?: AbortSignal): Promise<void>;
249
243
  }
250
244
  export interface ZLinkBackendActorRecvInfo {
@@ -446,7 +440,6 @@ export interface ZLinkBackendSpot extends ZLinkBackendObject {
446
440
  recvActorLifecycle(flags: ZLinkBackendRecvFlags): unknown | null;
447
441
  drainReply(): number;
448
442
  drainChannelReply(subjectHandle: bigint): number;
449
- recvRoute(result: Received, flags: ZLinkBackendRecvFlags): boolean;
450
443
  setDispatchHandler(handler: (info: ZLinkBackendSpotDispatchInfo) => void): void;
451
444
  requestToChannel(channelName: string, payload: Message | readonly Message[], timeoutMs?: number): Promise<readonly Message[]>;
452
445
  sendToChannel(channelName: string, payload: Message | readonly Message[]): Promise<void>;
@@ -486,7 +479,6 @@ export interface ZLinkMonitoringBackendAdapter {
486
479
  openSocketMonitor(socket: ZLinkBackendSocket): ZLinkBackendSocketMonitor;
487
480
  }
488
481
  export interface ZLinkBackendAdapterFactory {
489
- createReceived(): Received;
490
482
  createTopicMessage(): TopicMessage;
491
483
  createChannelAdapter(): ZLinkChannelBackendAdapter;
492
484
  createMeshAdapter(): ZLinkMeshBackendAdapter;
@@ -4,17 +4,10 @@ exports.meshActorSessionNodeAdapter = meshActorSessionNodeAdapter;
4
4
  const runtime_values_1 = require("./runtime-values");
5
5
  const submission_result_1 = require("../messaging/submission-result");
6
6
  const mesh_completion_table_1 = require("./mesh-completion-table");
7
- const routing_id_1 = require("../routing-id");
8
7
  function meshActorSessionNodeAdapter(node, completions) {
9
8
  return {
10
- actorNodeGeneration(actor) {
11
- const status = node.status();
12
- return (0, routing_id_1.routingIdsEqual)(status.routingId, actor.nodeRid)
13
- ? status.lifecycleGeneration
14
- : undefined;
15
- },
16
- async sendActorBoundSession(actor, expectedBindingGeneration, parts, flags, actorFence) {
17
- const result = await node.sendActorBoundSession(actor, expectedBindingGeneration, parts, flags, actorFence);
9
+ async sendActorBoundSession(actor, expectedBindingGeneration, parts, flags) {
10
+ const result = await node.sendActorBoundSession(actor, expectedBindingGeneration, parts, flags);
18
11
  switch (result) {
19
12
  case runtime_values_1.SubmitResult.Ok:
20
13
  return { status: submission_result_1.ZLinkSubmitStatus.Submitted };
@@ -1,8 +1,7 @@
1
1
  import type { TopicMessage } from '@zlink-systems/zlink';
2
- import type { ZLinkBackendAdapterFactory, ZLinkBackendReceived, ZLinkChannelBackendAdapter, ZLinkMonitoringBackendAdapter, ZLinkStreamBackendAdapter } from '../contracts';
2
+ import type { ZLinkBackendAdapterFactory, ZLinkChannelBackendAdapter, ZLinkMonitoringBackendAdapter, ZLinkStreamBackendAdapter } from '../contracts';
3
3
  import { ZLinkNodeMeshBackendAdapter } from './node-mesh-backend-adapter';
4
4
  export declare class ZLinkNodeBackendAdapterFactory implements ZLinkBackendAdapterFactory {
5
- createReceived(): ZLinkBackendReceived;
6
5
  createTopicMessage(): TopicMessage;
7
6
  createChannelAdapter(): ZLinkChannelBackendAdapter;
8
7
  createMeshAdapter(): ZLinkNodeMeshBackendAdapter;
@@ -6,9 +6,6 @@ const node_monitor_backend_adapter_1 = require("./node-monitor-backend-adapter")
6
6
  const node_socket_backend_adapter_1 = require("./node-socket-backend-adapter");
7
7
  const node_mesh_backend_adapter_1 = require("./node-mesh-backend-adapter");
8
8
  class ZLinkNodeBackendAdapterFactory {
9
- createReceived() {
10
- return new node_backend_adapter_support_1.zlink.Received();
11
- }
12
9
  createTopicMessage() {
13
10
  return new node_backend_adapter_support_1.zlink.TopicMessage();
14
11
  }
@@ -51,7 +48,8 @@ class ZLinkNodeChannelBackendAdapter {
51
48
  }
52
49
  class ZLinkNodeStreamBackendAdapter {
53
50
  createStreamSocket(context) {
54
- const socket = node_backend_adapter_support_1.zlink.createStreamSocket(asNodeContext(context));
51
+ const nodeContext = asNodeContext(context);
52
+ const socket = node_backend_adapter_support_1.zlink.createStreamSocket(nodeContext);
55
53
  socket.options.recvMode = node_backend_adapter_support_1.zlink.StreamRecvMode.Packet;
56
54
  return (0, node_socket_backend_adapter_1.wrapSocket)(socket, true);
57
55
  }
@@ -93,20 +91,8 @@ class ZLinkNodeBackendContext {
93
91
  this.nativeInstance.resetCoreHwmBudgetMetrics();
94
92
  }
95
93
  async dispose() {
96
- // Terminal cleanup shuts the context down before terminating it, the same
97
- // sequence the .NET reference binding runs inside `Context.Dispose()`
98
- // (`zlink_ctx_shutdown` then `zlink_ctx_term`). Without the shutdown signal
99
- // termination can block forever waiting on the reaper even after every
100
- // socket this runtime owns has been closed.
101
- try {
102
- this.nativeInstance.shutdown();
103
- }
104
- catch (error) {
105
- if (!(0, node_backend_adapter_support_1.isContextTerminatedError)(error)) {
106
- throw error;
107
- }
108
- }
109
- await (0, node_backend_adapter_support_1.closeWithBusyRetry)(this.nativeInstance);
94
+ // Binding Context.close() shuts down and then terminates the native context.
95
+ (0, node_backend_adapter_support_1.closeBindingHandle)(this.nativeInstance);
110
96
  }
111
97
  close() {
112
98
  this.nativeInstance.close();
@@ -35,15 +35,18 @@ interface ZLinkBindingRequestSubmitOperation {
35
35
  }
36
36
  export declare function isBindingNotFound(error: unknown): boolean;
37
37
  export declare function isRouteRecvRetryable(error: unknown): boolean;
38
- export declare function isPollerInterruptedError(error: unknown): boolean;
39
38
  export declare function submitBindingPublish(operation: ZLinkBindingPublishOperation, payload: unknown): void;
40
39
  export declare function submitBindingReply(operation: ZLinkBindingReplyOperation, payload: unknown): void;
41
40
  export declare function submitBindingAsyncSend(operation: ZLinkBindingAsyncSendOperation, payload: unknown): Promise<void>;
42
41
  export declare function submitBindingSyncSend(operation: ZLinkBindingAsyncSendOperation, payload: unknown): void;
43
42
  export declare function submitBindingRequest(operation: ZLinkBindingRequestOperation, payload: unknown, timeoutMs: number | undefined): Promise<readonly unknown[]>;
44
- export declare function closeWithBusyRetry(target: {
43
+ /**
44
+ * Closes a binding handle once. An already closed or terminated handle counts as
45
+ * closed. A busy close propagates to the caller.
46
+ */
47
+ export declare function closeBindingHandle(target: {
45
48
  close(): void;
46
- }): Promise<void>;
49
+ }): void;
47
50
  export declare function isContextTerminatedError(error: unknown): boolean;
48
51
  export declare function disableSocketLinger(target: unknown): void;
49
52
  export declare function toNativeRoutingId(routingId: unknown): unknown;
@@ -3,13 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.zlink = void 0;
4
4
  exports.isBindingNotFound = isBindingNotFound;
5
5
  exports.isRouteRecvRetryable = isRouteRecvRetryable;
6
- exports.isPollerInterruptedError = isPollerInterruptedError;
7
6
  exports.submitBindingPublish = submitBindingPublish;
8
7
  exports.submitBindingReply = submitBindingReply;
9
8
  exports.submitBindingAsyncSend = submitBindingAsyncSend;
10
9
  exports.submitBindingSyncSend = submitBindingSyncSend;
11
10
  exports.submitBindingRequest = submitBindingRequest;
12
- exports.closeWithBusyRetry = closeWithBusyRetry;
11
+ exports.closeBindingHandle = closeBindingHandle;
13
12
  exports.isContextTerminatedError = isContextTerminatedError;
14
13
  exports.disableSocketLinger = disableSocketLinger;
15
14
  exports.toNativeRoutingId = toNativeRoutingId;
@@ -32,9 +31,6 @@ function isRouteRecvRetryable(error) {
32
31
  error.result === exports.zlink.RecvResult.InvalidHandle) &&
33
32
  isNativeBadAddress(error)));
34
33
  }
35
- function isPollerInterruptedError(error) {
36
- return error instanceof exports.zlink.RecvError && error.nativeErrno === 4;
37
- }
38
34
  function isNativeBadAddress(error) {
39
35
  return error.nativeErrno === 14 || /Bad address/i.test(String(error.message ?? ''));
40
36
  }
@@ -126,30 +122,18 @@ async function submitBindingRequest(operation, payload, timeoutMs) {
126
122
  throw translateBindingResultError(error);
127
123
  }
128
124
  }
129
- async function closeWithBusyRetry(target) {
130
- let lastError;
131
- for (let attempt = 0; attempt < 8; attempt++) {
132
- try {
133
- target.close();
134
- return;
135
- }
136
- catch (error) {
137
- if (isSuccessfulOrAlreadyShutdownCloseError(error)) {
138
- return;
139
- }
140
- if (!isBusyCloseError(error)) {
141
- throw error;
142
- }
143
- lastError = error;
144
- await new Promise((resolve) => setImmediate(resolve));
145
- }
125
+ /**
126
+ * Closes a binding handle once. An already closed or terminated handle counts as
127
+ * closed. A busy close propagates to the caller.
128
+ */
129
+ function closeBindingHandle(target) {
130
+ try {
131
+ target.close();
132
+ }
133
+ catch (error) {
134
+ if (!isSuccessfulOrAlreadyShutdownCloseError(error))
135
+ throw error;
146
136
  }
147
- throw lastError;
148
- }
149
- function isBusyCloseError(error) {
150
- return (error instanceof Error &&
151
- 'code' in error &&
152
- [401, 404].includes(error.code));
153
137
  }
154
138
  function isSuccessfulOrAlreadyShutdownCloseError(error) {
155
139
  return (isContextTerminatedError(error) ||
@@ -9,7 +9,7 @@ export declare class ZLinkNodeEventLoopPoller {
9
9
  private readonly events;
10
10
  private readableHandler;
11
11
  private disposed;
12
- constructor(socket: Socket, pollCompletion: boolean, readableHandler: () => void);
12
+ constructor(socket: Socket, pollCompletion: boolean, readableHandler: () => void, pollRoute?: boolean);
13
13
  setReadableHandler(handler: () => void): void;
14
14
  dispose(): void;
15
15
  private readonly onReady;
@@ -12,12 +12,16 @@ class ZLinkNodeEventLoopPoller {
12
12
  events = node_backend_adapter_support_1.zlink.createPollEvents(1);
13
13
  readableHandler;
14
14
  disposed = false;
15
- constructor(socket, pollCompletion, readableHandler) {
15
+ constructor(socket, pollCompletion, readableHandler, pollRoute = false) {
16
16
  this.readableHandler = readableHandler;
17
17
  try {
18
18
  const pollEvents = [node_backend_adapter_support_1.zlink.PollEventFlag.PollIn];
19
19
  if (pollCompletion)
20
20
  pollEvents.push(node_backend_adapter_support_1.zlink.PollEventFlag.PollCompletion);
21
+ // A ROUTER selected-route change (Core ROUTER §10.1) wakes the same
22
+ // handler, whose owner is the socket's one route observer.
23
+ if (pollRoute)
24
+ pollEvents.push(node_backend_adapter_support_1.zlink.PollEventFlag.PollRoute);
21
25
  this.poller.add(socket, pollEvents, 0);
22
26
  socket.setReadableHandler(this.onReady);
23
27
  }
@@ -41,7 +45,9 @@ class ZLinkNodeEventLoopPoller {
41
45
  if (this.disposed)
42
46
  return;
43
47
  const ready = this.poller.wait(this.events, 0);
44
- if (ready === 0 || this.events.hasEvent(0, node_backend_adapter_support_1.zlink.PollEventFlag.PollIn)) {
48
+ if (ready === 0 ||
49
+ this.events.hasEvent(0, node_backend_adapter_support_1.zlink.PollEventFlag.PollIn) ||
50
+ this.events.hasEvent(0, node_backend_adapter_support_1.zlink.PollEventFlag.PollRoute)) {
45
51
  this.readableHandler();
46
52
  }
47
53
  };
@@ -1,6 +1,6 @@
1
1
  import { type Context } from '@zlink-systems/zlink';
2
2
  import type { ZLinkRawBindingPort, ZLinkRawHostPort } from '../raw-binding-port';
3
- export type { ZLinkRawBindingPort, ZLinkRawDealerPort, ZLinkRawHostPort, ZLinkRawMonitorPort, ZLinkRawMonitorRecord, ZLinkRawReceivedRecord, ZLinkRawRouterPort, ZLinkRawSocketPort } from '../raw-binding-port';
3
+ export type { ZLinkRawBindingPort, ZLinkRawDealerPort, ZLinkRawHostPort, ZLinkRawMonitorPort, ZLinkRawMonitorRecord, ZLinkRawReceivedRecord, ZLinkRawRouterPort, ZLinkRawRouterRoute, ZLinkRawSocketPort } from '../raw-binding-port';
4
4
  export declare class ZLinkNodeRawBindingPort implements ZLinkRawBindingPort {
5
5
  private readonly sharedContext?;
6
6
  private readonly routerReceiveTimeoutMs?;
@@ -85,9 +85,9 @@ class NodeRawSocketPort {
85
85
  monitors = new Set();
86
86
  eventLoopPoller;
87
87
  closed = false;
88
- constructor(socket) {
88
+ constructor(socket, pollRoute = false) {
89
89
  this.socket = socket;
90
- this.eventLoopPoller = new node_event_loop_poller_1.ZLinkNodeEventLoopPoller(socket, true, () => { });
90
+ this.eventLoopPoller = new node_event_loop_poller_1.ZLinkNodeEventLoopPoller(socket, true, () => { }, pollRoute);
91
91
  }
92
92
  setReadableHandler(handler) {
93
93
  this.requireOpen();
@@ -183,7 +183,7 @@ class NodeRawRouterPort extends NodeRawSocketPort {
183
183
  this.socket.disconnectRid(bindingRoutingId(routingId));
184
184
  }
185
185
  constructor(socket, receiveTimeoutMs) {
186
- super(socket);
186
+ super(socket, true);
187
187
  socket.options.handover = true;
188
188
  socket.options.mandatory = true;
189
189
  socket.options.probe = true;
@@ -223,6 +223,13 @@ class NodeRawRouterPort extends NodeRawSocketPort {
223
223
  throw (0, node_backend_adapter_support_1.translateBindingResultError)(error);
224
224
  }
225
225
  }
226
+ routesSnapshot() {
227
+ this.requireOpen();
228
+ return this.socket.routesSnapshot().map((route) => ({
229
+ routingId: route.routingId.toString(),
230
+ routeGeneration: route.routeGeneration
231
+ }));
232
+ }
226
233
  receive(dontWait = false) {
227
234
  this.requireOpen();
228
235
  return receiveRecord(this.socket, dontWait, () => {
@@ -344,6 +351,7 @@ function receiveRecord(socket, dontWait, nextRequestSequence, reply) {
344
351
  return {
345
352
  sourceRid,
346
353
  sourceRoute,
354
+ routeGeneration: received.routeGeneration,
347
355
  ...(requestSeq === undefined ? {} : { requestSeq }),
348
356
  ...(receivedReply === undefined
349
357
  ? {}
@@ -4,13 +4,13 @@ import type { ZLinkDispatchErrorReporter } from '../../channels/dispatch-error-r
4
4
  import type { MeshOperationId, MeshPeerEntry, MeshPublisher, ReadyBatch, ReadyRecord, ReceiveBatch, ServiceSpot, StreamSessionService } from '../../foundation/service-runtime-contracts';
5
5
  import { type RawServiceRequestResult } from '../../foundation/raw-service-mesh-runtime';
6
6
  import { type ServiceApplicationPayload } from '../../foundation/service-wire-m6a-codec';
7
- import { type ServiceAsyncInstanceActivationAuthority, type ServiceInstanceApplicationLifecycle, type ServicePendingInstanceActivation, type ServiceSpotMessageFollowSeal, type ServiceUserSpotOperationHandler, type ServiceUserSpotOperationResult } from '../../foundation/service-stateful-runtime';
7
+ import { ServiceStatefulRuntime, type ServiceAsyncInstanceActivationAuthority, type ServiceInstanceApplicationLifecycle, type ServicePendingInstanceActivation, type ServiceSpotMessageFollowSeal, type ServiceUserSpotOperationHandler, type ServiceUserSpotOperationResult } from '../../foundation/service-stateful-runtime';
8
8
  import type { ServiceActorRef, ServiceSpotState } from '../../foundation/service-stateful-registry';
9
9
  import type { ServiceActorCreateRecord, ServiceDirectSpotRouteFence, ServiceInstanceActivationTarget, ServiceInstanceRouteFence, ServiceSpotRouteFence, ServiceUserSpotCloseRecord, ServiceUserSpotCreateRecord } from '../../foundation/service-stateful-wire-codec';
10
10
  import type { ServiceInstanceActivationRecoveryEnvelope } from '../../foundation/service-instance-activation-recovery-codec';
11
11
  import type { ServiceNodeDescriptor } from '../../foundation/service-topology-registry';
12
12
  import type { RoutingId } from '../../../contracts';
13
- import type { ZLinkBackendActorRef, ZLinkBackendActorSessionSendFence, ZLinkBackendObjectPlacement, ZLinkBackendMeshNode } from '../contracts';
13
+ import type { ZLinkBackendActorRef, ZLinkBackendObjectPlacement, ZLinkBackendMeshNode } from '../contracts';
14
14
  import type { ZLinkRawBindingPort } from '../raw-binding-port';
15
15
  import type { ApplicationJobQueuePort } from '../../application-jobs/contracts';
16
16
  /**
@@ -54,6 +54,7 @@ export declare class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
54
54
  private protocolError?;
55
55
  private messageFollowHandler?;
56
56
  private dispatchErrors?;
57
+ private spotAdmissionProvider?;
57
58
  private readonly peerDisconnectedHandlers;
58
59
  constructor(meshName: string, routingId: string | undefined, bindingPort: ZLinkRawBindingPort, applicationJobQueue?: ApplicationJobQueuePort | undefined, applicationJobReceiveFlowFailureSink?: ((error: unknown) => void) | undefined, peerAdmissionSealed?: (() => boolean) | undefined);
59
60
  configureObjectPlacement(options: {
@@ -69,6 +70,7 @@ export declare class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
69
70
  readonly owner: string;
70
71
  }) => void): void;
71
72
  setDispatchErrorReporter(reporter: ZLinkDispatchErrorReporter): void;
73
+ setSpotAdmissionProvider(provider: Parameters<ServiceStatefulRuntime['setSpotAdmissionProvider']>[0]): void;
72
74
  setProtocolErrorHandler(handler: (record: {
73
75
  readonly sourceNodeRid: string;
74
76
  readonly request: boolean;
@@ -229,7 +231,7 @@ export declare class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
229
231
  actorRequestToActor(source: ZLinkBackendActorRef, target: ZLinkBackendActorRef, parts: MessageLike | readonly MessageLike[], options?: {
230
232
  readonly timeoutMs?: number;
231
233
  }): MeshOperationId;
232
- sendActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, parts: MessageLike | readonly MessageLike[], _flags?: number, actorFence?: ZLinkBackendActorSessionSendFence): Promise<SubmitResultValue>;
234
+ sendActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, parts: MessageLike | readonly MessageLike[], _flags?: number): Promise<SubmitResultValue>;
233
235
  closeActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, timeoutMs?: number): MeshOperationId;
234
236
  leaveActor(actor: ZLinkBackendActorRef, expectedMembershipEpoch: bigint, timeoutMs?: number): MeshOperationId;
235
237
  createStreamSessionService(stream: unknown): StreamSessionService;
@@ -261,10 +263,11 @@ export declare class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
261
263
  private requireNotStarted;
262
264
  }
263
265
  /**
264
- * Classifies a generic node/channel request rejection into a completion
265
- * terminal. Spec 32-framework-error-model:91-92 — a reply that could not be
266
- * decoded (ServiceWireProtocolError from the reply parser) is a protocol
267
- * failure, not connection loss; only genuine transport rejections collapse to
268
- * NotConnected.
266
+ * The one classification of a failed node/channel/stateful request into its
267
+ * completion terminal. A binding REQUEST result is Core's decision and is kept
268
+ * as is; a submit failure retains its Core meaning at the request boundary.
269
+ * A reply that could not be decoded is a protocol
270
+ * failure (spec 32-framework-error-model:91-92). The failure code is a wire
271
+ * code, so a Core result carries 0.
269
272
  */
270
- export declare function genericOperationFailure(error: unknown): RawServiceRequestResult;
273
+ export declare function requestFailureResult(error: unknown): RawServiceRequestResult;
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZLinkNodeRawMeshBackend = void 0;
4
- exports.genericOperationFailure = genericOperationFailure;
4
+ exports.requestFailureResult = requestFailureResult;
5
5
  const node_crypto_1 = require("node:crypto");
6
6
  const promises_1 = require("node:timers/promises");
7
7
  const stream_wire_1 = require("@zlink-systems/stream-wire");
8
8
  const node_socket_backend_adapter_1 = require("./node-socket-backend-adapter");
9
+ const node_backend_adapter_support_1 = require("./node-backend-adapter-support");
9
10
  const contracts_1 = require("../../../contracts");
10
11
  const framework_errors_internal_1 = require("../../framework-errors-internal");
11
12
  const zlink_1 = require("@zlink-systems/zlink");
@@ -25,7 +26,7 @@ const MULTIPART_PACKET_NAME = service_wire_constants_generated_1.SERVICE_FRAMEWO
25
26
  const MULTIPART_CONTENT_TYPE = service_wire_constants_generated_1.SERVICE_FRAMEWORK_MULTIPART_CONTENT_TYPE;
26
27
  const FATAL_UTF8 = new TextDecoder('utf-8', { fatal: true });
27
28
  const MAX_DRAIN_RECORDS = 64;
28
- // Preserve the existing monitor/admission/liveness cadence. Only the binding
29
+ // Preserve the existing route observation/admission/liveness cadence. Only the binding
29
30
  // readable handler admits receive work; this timer never probes the socket.
30
31
  const MESH_BACKEND_MAINTENANCE_INTERVAL_MS = 1;
31
32
  /**
@@ -82,6 +83,7 @@ class ZLinkNodeRawMeshBackend {
82
83
  protocolError;
83
84
  messageFollowHandler;
84
85
  dispatchErrors;
86
+ spotAdmissionProvider;
85
87
  peerDisconnectedHandlers = new Set();
86
88
  constructor(meshName, routingId, bindingPort, applicationJobQueue, applicationJobReceiveFlowFailureSink, peerAdmissionSealed) {
87
89
  this.meshName = meshName;
@@ -114,6 +116,10 @@ class ZLinkNodeRawMeshBackend {
114
116
  this.dispatchErrors = reporter;
115
117
  this.stateful?.setDispatchErrorReporter(reporter, this.meshName);
116
118
  }
119
+ setSpotAdmissionProvider(provider) {
120
+ this.spotAdmissionProvider = provider;
121
+ this.stateful?.setSpotAdmissionProvider(provider);
122
+ }
117
123
  setProtocolErrorHandler(handler) {
118
124
  this.protocolError = handler;
119
125
  }
@@ -210,6 +216,9 @@ class ZLinkNodeRawMeshBackend {
210
216
  });
211
217
  runtime.start();
212
218
  this.stateful = new service_stateful_runtime_1.ServiceStatefulRuntime(runtime, descriptor.nodeRoutingId, descriptor.lifecycleGeneration);
219
+ if (this.spotAdmissionProvider !== undefined) {
220
+ this.stateful.setSpotAdmissionProvider(this.spotAdmissionProvider);
221
+ }
213
222
  if (this.dispatchErrors !== undefined) {
214
223
  this.stateful.setDispatchErrorReporter(this.dispatchErrors, this.meshName);
215
224
  }
@@ -688,8 +697,8 @@ class ZLinkNodeRawMeshBackend {
688
697
  actorRequestToActor(source, target, parts, options) {
689
698
  return this.observeStateful(service_runtime_contracts_1.OperationKind.ActorRequest, this.requireStateful().requestToActor(target, this.peerGeneration(String(target.nodeRid)), target.generation, encodeMultipart(parts), options?.timeoutMs ?? 30_000, source));
690
699
  }
691
- async sendActorBoundSession(actor, expectedBindingGeneration, parts, _flags, actorFence) {
692
- return (await this.requireStateful().sendBoundSession(actor, expectedBindingGeneration, encodeMultipart(parts), actorFence));
700
+ async sendActorBoundSession(actor, expectedBindingGeneration, parts, _flags) {
701
+ return (await this.requireStateful().sendBoundSession(actor, expectedBindingGeneration, encodeMultipart(parts)));
693
702
  }
694
703
  closeActorBoundSession(actor, expectedBindingGeneration, timeoutMs = 30_000) {
695
704
  const binding = this.requireStateful().registry.binding(actor);
@@ -804,12 +813,12 @@ class ZLinkNodeRawMeshBackend {
804
813
  }
805
814
  observeCompletion(low, operationKind, promise) {
806
815
  const id = { high: 1n, low };
807
- void promise.then((result) => this.enqueueCompletion(id, operationKind, result), (error) => this.enqueueCompletion(id, operationKind, genericOperationFailure(error)));
816
+ void promise.then((result) => this.enqueueCompletion(id, operationKind, result), (error) => this.enqueueCompletion(id, operationKind, requestFailureResult(error)));
808
817
  return id;
809
818
  }
810
819
  observeStateful(operationKind, pending) {
811
820
  const id = { high: 2n, low: pending.id };
812
- void pending.promise.then((result) => this.enqueueCompletion(id, operationKind, result), (error) => this.enqueueCompletion(id, operationKind, statefulOperationFailure(error)));
821
+ void pending.promise.then((result) => this.enqueueCompletion(id, operationKind, result), (error) => this.enqueueCompletion(id, operationKind, requestFailureResult(error)));
813
822
  return id;
814
823
  }
815
824
  enqueueImmediateFailure(operationKind, terminalResult) {
@@ -1519,38 +1528,61 @@ function readyDomain(domain) {
1519
1528
  return domain === 'infrastructure' ? service_runtime_contracts_1.ReadyDomain.Infrastructure : service_runtime_contracts_1.ReadyDomain.Application;
1520
1529
  }
1521
1530
  /**
1522
- * Classifies a generic node/channel request rejection into a completion
1523
- * terminal. Spec 32-framework-error-model:91-92 — a reply that could not be
1524
- * decoded (ServiceWireProtocolError from the reply parser) is a protocol
1525
- * failure, not connection loss; only genuine transport rejections collapse to
1526
- * NotConnected.
1531
+ * The one classification of a failed node/channel/stateful request into its
1532
+ * completion terminal. A binding REQUEST result is Core's decision and is kept
1533
+ * as is; a submit failure retains its Core meaning at the request boundary.
1534
+ * A reply that could not be decoded is a protocol
1535
+ * failure (spec 32-framework-error-model:91-92). The failure code is a wire
1536
+ * code, so a Core result carries 0.
1527
1537
  */
1528
- function genericOperationFailure(error) {
1538
+ function requestFailureResult(error) {
1539
+ const failure = (0, node_backend_adapter_support_1.translateBindingResultError)(error);
1540
+ if ((0, runtime_values_1.isZLinkBackendResultError)(failure)) {
1541
+ return {
1542
+ terminalResult: failure.operation === 'request' ? failure.result : submitFailureTerminal(failure.result),
1543
+ failureCode: 0
1544
+ };
1545
+ }
1529
1546
  // requestProtocolError(16): the schema terminal-failure-integrity rule
1530
- // forbids a typed terminal (104) with failure none, so the synthesized
1531
- // decode-failure pair is 104+16; genuine transport loss stays 109+0.
1532
- return error instanceof service_wire_m6a_codec_1.ServiceWireProtocolError
1533
- ? { terminalResult: zlink_1.RequestResult.ProtocolError, failureCode: 16 }
1534
- : { terminalResult: zlink_1.RequestResult.NotConnected, failureCode: 0 };
1535
- }
1536
- function statefulOperationFailure(error) {
1537
- if (error instanceof contracts_1.ZLinkFrameworkException) {
1538
- return (0, framework_errors_internal_1.internalFrameworkWireReply)(error);
1547
+ // forbids a typed terminal (104) with failure none.
1548
+ if (failure instanceof service_wire_m6a_codec_1.ServiceWireProtocolError) {
1549
+ return { terminalResult: zlink_1.RequestResult.ProtocolError, failureCode: 16 };
1539
1550
  }
1540
- if (error instanceof operation_registry_1.OperationTimeoutError) {
1541
- return { terminalResult: zlink_1.RequestResult.TimedOut, failureCode: 0 };
1551
+ if (failure instanceof contracts_1.ZLinkFrameworkException) {
1552
+ return (0, framework_errors_internal_1.internalFrameworkWireReply)(failure);
1542
1553
  }
1543
- if ((0, runtime_values_1.isZLinkBackendResultError)(error)) {
1544
- return {
1545
- terminalResult: error.result,
1546
- failureCode: error.nativeErrno ?? 0
1547
- };
1554
+ if (failure instanceof operation_registry_1.OperationTimeoutError) {
1555
+ return { terminalResult: zlink_1.RequestResult.TimedOut, failureCode: 0 };
1548
1556
  }
1549
- if (error instanceof operation_registry_1.OperationCancelledError) {
1557
+ if (failure instanceof operation_registry_1.OperationCancelledError) {
1550
1558
  return { terminalResult: zlink_1.RequestResult.NotConnected, failureCode: 0 };
1551
1559
  }
1552
1560
  return { terminalResult: zlink_1.RequestResult.InternalError, failureCode: 17 };
1553
1561
  }
1562
+ function submitFailureTerminal(result) {
1563
+ switch (result) {
1564
+ case zlink_1.SubmitResult.Backpressured:
1565
+ return zlink_1.RequestResult.Backpressured;
1566
+ case zlink_1.SubmitResult.NotConnected:
1567
+ return zlink_1.RequestResult.NotConnected;
1568
+ case zlink_1.SubmitResult.NotFound:
1569
+ return zlink_1.RequestResult.NotFound;
1570
+ case zlink_1.SubmitResult.NotAdmitted:
1571
+ return zlink_1.RequestResult.Rejected;
1572
+ case zlink_1.SubmitResult.InvalidHandle:
1573
+ case zlink_1.SubmitResult.InvalidArgument:
1574
+ case zlink_1.SubmitResult.ThreadViolation:
1575
+ return zlink_1.RequestResult.InvalidArgument;
1576
+ case zlink_1.SubmitResult.InvalidState:
1577
+ return zlink_1.RequestResult.InvalidState;
1578
+ case zlink_1.SubmitResult.NotSupported:
1579
+ return zlink_1.RequestResult.NotSupported;
1580
+ case zlink_1.SubmitResult.Terminated:
1581
+ return zlink_1.RequestResult.Terminated;
1582
+ default:
1583
+ return zlink_1.RequestResult.InternalError;
1584
+ }
1585
+ }
1554
1586
  function encodeMultipart(parts) {
1555
1587
  const values = Array.isArray(parts) ? parts : [parts];
1556
1588
  if (values.length === 0)
@@ -20,7 +20,7 @@ function wrapSocket(nativeInstance, pollCompletion) {
20
20
  async dispose() {
21
21
  eventLoopPoller?.dispose();
22
22
  (0, node_backend_adapter_support_1.disableSocketLinger)(nativeInstance);
23
- await (0, node_backend_adapter_support_1.closeWithBusyRetry)(nativeInstance);
23
+ (0, node_backend_adapter_support_1.closeBindingHandle)(nativeInstance);
24
24
  },
25
25
  close() {
26
26
  eventLoopPoller?.dispose();
@@ -2,6 +2,11 @@ export interface ZLinkRawReceivedRecord {
2
2
  readonly sourceRid: string;
3
3
  readonly sourceRoute: Uint8Array;
4
4
  readonly requestSeq?: bigint;
5
+ /**
6
+ * Core selected-route generation of the ROUTER route that delivered this
7
+ * record (Core ROUTER §10.1); 0n for a non-ROUTER receive. Equality only.
8
+ */
9
+ readonly routeGeneration: bigint;
5
10
  readonly reply?: (parts: readonly Uint8Array[]) => void;
6
11
  readonly parts: readonly Buffer[];
7
12
  /** Releases the ordinary Framework-owned receive record exactly once. */
@@ -33,6 +38,11 @@ export interface ZLinkRawMonitorPort {
33
38
  statusReady(): boolean;
34
39
  close(): void;
35
40
  }
41
+ /** One row of the ROUTER selected-route snapshot (Core ROUTER §10.1). */
42
+ export interface ZLinkRawRouterRoute {
43
+ readonly routingId: string;
44
+ readonly routeGeneration: bigint;
45
+ }
36
46
  export interface ZLinkRawRouterPort extends ZLinkRawSocketPort {
37
47
  disconnectRid?(routingId: string): void;
38
48
  localEndpoint(): string;
@@ -41,6 +51,8 @@ export interface ZLinkRawRouterPort extends ZLinkRawSocketPort {
41
51
  send(targetRid: string, parts: readonly Uint8Array[]): Promise<void>;
42
52
  request(targetRid: string, parts: readonly Uint8Array[], timeoutMs: number): Promise<readonly Buffer[]>;
43
53
  receive(dontWait?: boolean): ZLinkRawReceivedRecord | undefined;
54
+ /** The selected route of every RID. The socket's one route observer calls it. */
55
+ routesSnapshot(): readonly ZLinkRawRouterRoute[];
44
56
  }
45
57
  export interface ZLinkRawDealerPort extends ZLinkRawSocketPort {
46
58
  setRoutingId(routingId: string): void;
@@ -18,7 +18,6 @@ export declare class DefaultZLinkFanoutClient implements ZLinkFanoutClient {
18
18
  constructor(registration: ZLinkFrameworkRegistration, transport?: ZLinkChannelClientTransportSource | undefined);
19
19
  publish(channelName: string, event: unknown): ZLinkFanoutPublishCall;
20
20
  publish(channelName: string, topic: string, event: unknown): ZLinkFanoutPublishCall;
21
- getListenerStatus(channelName: string): import('../../contracts').ZLinkFanoutListenerStatus;
22
21
  private requirePublisherChannel;
23
22
  private requireTransport;
24
23
  }
@@ -64,14 +64,6 @@ class DefaultZLinkFanoutClient {
64
64
  status: (await this.requireTransport().publish(channelName, topic, packetName, event, signal)).status
65
65
  }));
66
66
  }
67
- getListenerStatus(channelName) {
68
- this.requirePublisherChannel(channelName);
69
- const status = this.requireTransport().getFanoutListenerStatus?.(channelName);
70
- if (status === undefined) {
71
- throw new configuration_1.ZLinkConfigurationException(`Fanout publisher '${channelName}' has not reported a bound listener.`);
72
- }
73
- return status;
74
- }
75
67
  requirePublisherChannel(channelName) {
76
68
  if (!this.registration.fanoutPublishers.has(channelName)) {
77
69
  throw new configuration_1.ZLinkConfigurationException(`Channel '${channelName}' does not have a publisher capability.`);
@@ -39,11 +39,7 @@ class ZLinkChannelOutboundOperations {
39
39
  (0, abort_1.throwIfAborted)(signal);
40
40
  const dealer = await this.sockets.awaitClientDealerForOutbound(channelName, signal);
41
41
  if (dealer === undefined) {
42
- return {
43
- status: this.sockets.hasKnownClientServerTargets(channelName)
44
- ? submission_result_1.ZLinkSubmitStatus.RouteNotConnected
45
- : submission_result_1.ZLinkSubmitStatus.TargetNotFound
46
- };
42
+ return { status: submission_result_1.ZLinkSubmitStatus.RouteNotConnected };
47
43
  }
48
44
  const parts = (0, channel_envelope_1.encodeChannelEnvelopeParts)(3 /* ZLinkChannelMessageKind.Command */, channelName, packetName, message, undefined, undefined, this.codecs, undefined, this.dispatchServices.flowCreationEnabled(), metadata);
49
45
  try {
@@ -108,11 +104,7 @@ class ZLinkChannelOutboundOperations {
108
104
  // Binding timeouts are whole milliseconds; rounding down keeps the call's deadline.
109
105
  const remainingMs = deadlineAtMs === undefined ? undefined : Math.floor(deadlineAtMs - performance.now());
110
106
  if (dealer === undefined || (remainingMs !== undefined && remainingMs <= 0)) {
111
- throw (0, framework_errors_internal_1.createInternalFrameworkException)(this.sockets.hasKnownClientServerTargets(channelName)
112
- ? framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RouteNotConnected
113
- : framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestTargetNotFound, this.sockets.hasKnownClientServerTargets(channelName)
114
- ? `Channel '${channelName}' has known ClientServer targets but no ready server.`
115
- : `Channel '${channelName}' has no ready ClientServer server.`);
107
+ throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RouteNotConnected, `Channel '${channelName}' has no ready ClientServer server.`);
116
108
  }
117
109
  const serverRid = this.sockets.selectedClientServerRid(channelName, dealer);
118
110
  selectedServerRid = serverRid;