@zlink-systems/framework 0.29.0 → 0.30.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 (168) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  3. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  4. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  5. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  6. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  7. package/dist/contracts/Configuration/index.d.ts +1 -1
  8. package/dist/internal.d.ts +1 -0
  9. package/dist/internal.js +3 -1
  10. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  11. package/dist/runtime/actors/actor-handoff.js +9 -4
  12. package/dist/runtime/actors/actor-runtime-contracts.d.ts +1 -0
  13. package/dist/runtime/actors/index.d.ts +2 -0
  14. package/dist/runtime/actors/index.js +21 -6
  15. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +3 -1
  16. package/dist/runtime/application-jobs/application-ingress-record-owner.js +6 -1
  17. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +3 -1
  18. package/dist/runtime/application-jobs/application-job-queue-scope.js +5 -0
  19. package/dist/runtime/application-jobs/contracts.d.ts +5 -1
  20. package/dist/runtime/backend/contracts/index.d.ts +10 -19
  21. package/dist/runtime/backend/mesh-completion-table.d.ts +6 -4
  22. package/dist/runtime/backend/mesh-completion-table.js +28 -18
  23. package/dist/runtime/backend/mesh-dispatch-pump.js +21 -25
  24. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  25. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  26. package/dist/runtime/backend/node/node-backend-adapter-support.js +24 -29
  27. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  28. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  29. package/dist/runtime/backend/node/node-raw-binding-port.js +11 -6
  30. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +10 -12
  31. package/dist/runtime/backend/node/node-raw-mesh-backend.js +64 -98
  32. package/dist/runtime/backend/node/node-socket-backend-adapter.js +10 -5
  33. package/dist/runtime/backend/raw-binding-port.d.ts +9 -2
  34. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  35. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  36. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  37. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  38. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  39. package/dist/runtime/diagnostics/message-flow.js +3 -3
  40. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +15 -1
  41. package/dist/runtime/foundation/raw-service-mesh-runtime.js +193 -64
  42. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  43. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  44. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  45. package/dist/runtime/foundation/service-mailbox.js +2 -1
  46. package/dist/runtime/foundation/service-stateful-runtime.d.ts +7 -6
  47. package/dist/runtime/foundation/service-stateful-runtime.js +60 -41
  48. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -2
  49. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  50. package/dist/runtime/foundation/service-topology-registry.d.ts +5 -3
  51. package/dist/runtime/foundation/service-topology-registry.js +9 -4
  52. package/dist/runtime/handlers/handler-instance-scope.js +1 -1
  53. package/dist/runtime/host/actor-packet-relay.js +7 -7
  54. package/dist/runtime/host/actor-placement-coordinator.d.ts +2 -1
  55. package/dist/runtime/host/actor-placement-coordinator.js +2 -1
  56. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -1
  57. package/dist/runtime/host/actor-runtime-options-factory.js +2 -1
  58. package/dist/runtime/host/application-job-queue.d.ts +11 -4
  59. package/dist/runtime/host/application-job-queue.js +66 -10
  60. package/dist/runtime/host/entry-actor-runtime.js +1 -1
  61. package/dist/runtime/host/index.d.ts +1 -1
  62. package/dist/runtime/host/index.js +18 -13
  63. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  64. package/dist/runtime/host/instance-activation-authority.js +89 -25
  65. package/dist/runtime/host/service-relocation-host-runtime.js +2 -2
  66. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  67. package/dist/runtime/host/spot-address-transport.js +25 -12
  68. package/dist/runtime/host/spot-runtime-options-factory.js +2 -2
  69. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  70. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  71. package/dist/runtime/locations/domain-store-contract.d.ts +3 -2
  72. package/dist/runtime/locations/in-memory-authority-store.d.ts +5 -2
  73. package/dist/runtime/locations/in-memory-authority-store.js +107 -14
  74. package/dist/runtime/locations/in-memory-location-store.d.ts +3 -3
  75. package/dist/runtime/locations/in-memory-location-store.js +31 -13
  76. package/dist/runtime/locations/internal-location-contracts.d.ts +8 -0
  77. package/dist/runtime/locations/location-store-repository.d.ts +4 -2
  78. package/dist/runtime/locations/location-store-repository.js +209 -33
  79. package/dist/runtime/locations/resolvers.d.ts +2 -1
  80. package/dist/runtime/locations/resolvers.js +10 -1
  81. package/dist/runtime/messaging/submission-result.d.ts +1 -1
  82. package/dist/runtime/messaging/submission-result.js +2 -2
  83. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +2 -0
  84. package/dist/runtime/spots/index.d.ts +4 -3
  85. package/dist/runtime/spots/index.js +14 -14
  86. package/dist/runtime/spots/spot-activation.d.ts +2 -1
  87. package/dist/runtime/spots/spot-activation.js +4 -4
  88. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  89. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  90. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  91. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  92. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  93. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  94. package/dist/runtime/spots/spot-entry-activation.d.ts +1 -0
  95. package/dist/runtime/spots/spot-entry-activation.js +6 -1
  96. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +3 -1
  97. package/dist/runtime/spots/spot-node-runtime-manager.js +10 -11
  98. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  99. package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -1
  100. package/dist/runtime/spots/spot-serial-executor.d.ts +1 -0
  101. package/dist/runtime/spots/spot-serial-executor.js +10 -1
  102. package/dist/runtime/streams/stream-session-runtime.js +1 -1
  103. package/package.json +3 -3
  104. package/src/contracts/Configuration/Builders.ts +1 -2
  105. package/src/contracts/Configuration/Configs.ts +0 -6
  106. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  107. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  108. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  109. package/src/contracts/Configuration/index.ts +1 -6
  110. package/src/internal.ts +1 -0
  111. package/src/runtime/actors/actor-handoff.ts +13 -4
  112. package/src/runtime/actors/actor-runtime-contracts.ts +4 -0
  113. package/src/runtime/actors/index.ts +77 -42
  114. package/src/runtime/application-jobs/application-ingress-record-owner.ts +12 -2
  115. package/src/runtime/application-jobs/application-job-queue-scope.ts +6 -1
  116. package/src/runtime/application-jobs/contracts.ts +14 -1
  117. package/src/runtime/backend/contracts/index.ts +10 -18
  118. package/src/runtime/backend/mesh-completion-table.ts +36 -19
  119. package/src/runtime/backend/mesh-dispatch-pump.ts +19 -22
  120. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  121. package/src/runtime/backend/node/node-backend-adapter-support.ts +31 -29
  122. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  123. package/src/runtime/backend/node/node-raw-binding-port.ts +19 -10
  124. package/src/runtime/backend/node/node-raw-mesh-backend.ts +81 -111
  125. package/src/runtime/backend/node/node-socket-backend-adapter.ts +12 -8
  126. package/src/runtime/backend/raw-binding-port.ts +12 -2
  127. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  128. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  129. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  130. package/src/runtime/diagnostics/message-flow.ts +1 -1
  131. package/src/runtime/foundation/raw-service-mesh-runtime.ts +268 -70
  132. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  133. package/src/runtime/foundation/service-mailbox.ts +7 -1
  134. package/src/runtime/foundation/service-stateful-runtime.ts +109 -77
  135. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -79
  136. package/src/runtime/foundation/service-topology-registry.ts +13 -7
  137. package/src/runtime/handlers/handler-instance-scope.ts +2 -1
  138. package/src/runtime/host/actor-packet-relay.ts +7 -0
  139. package/src/runtime/host/actor-placement-coordinator.ts +8 -2
  140. package/src/runtime/host/actor-runtime-options-factory.ts +7 -0
  141. package/src/runtime/host/application-job-queue.ts +77 -10
  142. package/src/runtime/host/entry-actor-runtime.ts +1 -0
  143. package/src/runtime/host/index.ts +30 -7
  144. package/src/runtime/host/instance-activation-authority.ts +132 -27
  145. package/src/runtime/host/service-relocation-host-runtime.ts +2 -0
  146. package/src/runtime/host/spot-address-transport.ts +45 -22
  147. package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
  148. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  149. package/src/runtime/locations/domain-store-contract.ts +6 -2
  150. package/src/runtime/locations/in-memory-authority-store.ts +153 -12
  151. package/src/runtime/locations/in-memory-location-store.ts +39 -13
  152. package/src/runtime/locations/internal-location-contracts.ts +10 -0
  153. package/src/runtime/locations/location-store-repository.ts +295 -36
  154. package/src/runtime/locations/resolvers.ts +25 -2
  155. package/src/runtime/messaging/submission-result.ts +2 -2
  156. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +2 -0
  157. package/src/runtime/spots/index.ts +16 -0
  158. package/src/runtime/spots/spot-activation.ts +5 -0
  159. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  160. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  161. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  162. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  163. package/src/runtime/spots/spot-entry-activation.ts +7 -0
  164. package/src/runtime/spots/spot-node-runtime-manager.ts +14 -12
  165. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  166. package/src/runtime/spots/spot-runtime-ports.ts +2 -0
  167. package/src/runtime/spots/spot-serial-executor.ts +10 -4
  168. package/src/runtime/streams/stream-session-runtime.ts +1 -1
@@ -7,7 +7,6 @@ import type { ZLinkDispatchOptionsBuilder, ZLinkInboundDispatchOptions } from '.
7
7
  import type { ZLinkLocationOptions, ZLinkLocationStore, ZLinkRelocationStore } from '../Locations';
8
8
  import type { RoutingId, Type } from '../Common';
9
9
  import type { ZLinkWorkerOptions } from './RegistrationTypes';
10
- import type { ZLinkSpotPublisherConfig } from './Configs';
11
10
  import type { ZLinkActorFactoryBuilder, ZLinkInstanceSpotFactoryBuilder, ZLinkUserSpotFactoryBuilder } from './ObjectRoles';
12
11
  import type { ZLinkRequestHandler, ZLinkRouteRequestHandler, ZLinkRouteSendHandler, ZLinkSendHandler } from '../Handlers';
13
12
  export interface ZLinkFrameworkOptions {
@@ -96,7 +95,6 @@ export interface ZLinkMeshNodeBuilder {
96
95
  setActivationConcurrency(limit: number): this;
97
96
  setInstanceSpotIdleTimeout(timeoutMs: number): this;
98
97
  configureRouterSocket(): ZLinkMeshNodeSocketConfig;
99
- configureSpotPublisher(): ZLinkSpotPublisherConfig;
100
98
  peerConnections(): ZLinkMeshPeerConnections;
101
99
  setDefaultRequestTimeout(timeoutMs: number): this;
102
100
  objects(): ZLinkMeshObjectRoleBuilder;
@@ -136,6 +134,7 @@ export interface ZLinkFanoutChannelBuilder {
136
134
  routingId(routingId: string): this;
137
135
  setRoutingIdPrefix(prefix: string): this;
138
136
  setNoDrop(noDrop?: boolean): this;
137
+ setSendTimeout(timeoutMs: number): this;
139
138
  enableSubscriber(): this;
140
139
  subscribe(topic: string): this;
141
140
  connect(endpoint: string): this;
@@ -16,8 +16,3 @@ export interface ZLinkOutboundRouteConfig {
16
16
  targetNodeRid: RoutingId;
17
17
  endpoint: string;
18
18
  }
19
- export interface ZLinkSpotPublisherConfig {
20
- sendHighWaterMark: number;
21
- sendTimeoutMs?: number;
22
- lingerMs?: number;
23
- }
@@ -10,6 +10,7 @@ const ConfigurationException_1 = require("./ConfigurationException");
10
10
  const DiagnosticsValidation_1 = require("./DiagnosticsValidation");
11
11
  const EndpointNotation_1 = require("./EndpointNotation");
12
12
  const FanoutTopic_1 = require("./FanoutTopic");
13
+ const SendTimeoutValidation_1 = require("./SendTimeoutValidation");
13
14
  const InternalDefaults_1 = require("./InternalDefaults");
14
15
  const ObjectRoles_1 = require("./ObjectRoles");
15
16
  const RegistrationBuilderPolicy_1 = require("./RegistrationBuilderPolicy");
@@ -374,6 +375,11 @@ class DefaultFanoutChannelBuilder {
374
375
  this.channel.noDrop = noDrop;
375
376
  return this;
376
377
  }
378
+ setSendTimeout(timeoutMs) {
379
+ (0, SendTimeoutValidation_1.requireValidSendTimeoutMs)(`Fanout channel '${this.name}' send timeout`, timeoutMs);
380
+ this.channel.sendTimeoutMs = timeoutMs;
381
+ return this;
382
+ }
377
383
  enableSubscriber(endpoint) {
378
384
  this.selectSubscriberMode(endpoint === undefined ? 'automatic' : 'manual');
379
385
  this.channel.subscriber ??= { manualConnections: [] };
@@ -758,10 +764,6 @@ class DefaultMeshNodeBuilder {
758
764
  this.node.router ??= {};
759
765
  return this.node.router;
760
766
  }
761
- configureSpotPublisher() {
762
- this.node.publisherConfig ??= {};
763
- return this.node.publisherConfig;
764
- }
765
767
  peerConnections() {
766
768
  this.node.router ??= {};
767
769
  return new DefaultMeshPeerConnections(this.node.router);
@@ -139,6 +139,7 @@ export interface ZLinkChannelOptions {
139
139
  readonly routingId?: string;
140
140
  readonly routingIdPrefix?: string;
141
141
  readonly noDrop?: boolean;
142
+ readonly sendTimeoutMs?: number;
142
143
  readonly requestTimeoutMs?: number;
143
144
  readonly client?: ZLinkClientCapabilityOptions;
144
145
  readonly publisher?: ZLinkPublisherCapabilityOptions;
@@ -167,7 +168,6 @@ export interface ZLinkClientCapabilityOptions {
167
168
  readonly maxMessageSize?: number;
168
169
  }
169
170
  export interface ZLinkPublisherCapabilityOptions {
170
- readonly sendTimeoutMs?: number;
171
171
  readonly bind?: string;
172
172
  readonly bindHost?: string;
173
173
  readonly advertiseHost?: string;
@@ -243,11 +243,6 @@ export interface ZLinkSpotNodeOptions {
243
243
  readonly routeSendHandlers?: readonly ZLinkRouteMeshSendHandlerRegistration[];
244
244
  readonly routeRequestHandlers?: readonly ZLinkRouteMeshRequestHandlerRegistration[];
245
245
  readonly requestTimeoutMs?: number;
246
- readonly publisherConfig?: {
247
- readonly sendHighWaterMark?: number;
248
- readonly sendTimeoutMs?: number;
249
- readonly lingerMs?: number;
250
- };
251
246
  readonly entrySpotTimerHandlers?: readonly ZLinkEntrySpotTimerHandlerRegistration[];
252
247
  readonly entrySpotPacketHandlers?: readonly ZLinkEntrySpotPacketHandlerRegistration[];
253
248
  readonly entrySpotSubscriptionHandlers?: readonly ZLinkEntrySpotSubscriptionHandlerRegistration[];
@@ -155,8 +155,9 @@ function validateChannelCapabilities(channels, peerLocationConfigured) {
155
155
  if (channel.noDrop !== undefined && typeof channel.noDrop !== 'boolean') {
156
156
  throw new ConfigurationException_1.ZLinkConfigurationException(`Channel '${channelName}' NoDrop must be a boolean.`);
157
157
  }
158
- if (channel.noDrop !== undefined && channel.publisher === undefined) {
159
- throw new ConfigurationException_1.ZLinkConfigurationException(`Channel '${channelName}' NoDrop requires a publisher role.`);
158
+ if ((channel.noDrop !== undefined || channel.sendTimeoutMs !== undefined) &&
159
+ channel.publisher === undefined) {
160
+ throw new ConfigurationException_1.ZLinkConfigurationException(`Channel '${channelName}': NoDrop and send timeout require the publisher role.`);
160
161
  }
161
162
  if (channel.server !== undefined) {
162
163
  requireEndpoint(`channel '${channelName}' server`, channel.server.bind);
@@ -167,8 +168,8 @@ function validateChannelCapabilities(channels, peerLocationConfigured) {
167
168
  requirePeerWeight(`channel '${channelName}' server weight`, channel.server.weight);
168
169
  requireSocketOptions(`channel '${channelName}' server`, channel.server);
169
170
  }
171
+ (0, SendTimeoutValidation_1.requireValidSendTimeoutMs)(`channel '${channelName}' publisher sendTimeoutMs`, channel.sendTimeoutMs);
170
172
  if (channel.publisher !== undefined) {
171
- (0, SendTimeoutValidation_1.requireValidSendTimeoutMs)(`channel '${channelName}' publisher sendTimeoutMs`, channel.publisher.sendTimeoutMs);
172
173
  requireEndpoint(`channel '${channelName}' publisher`, channel.publisher.bind);
173
174
  validateListenerNetworkIdentity(`channel '${channelName}' publisher`, channel.publisher.bindHost, channel.publisher.advertiseHost);
174
175
  validateFanoutPublisherIdentity(channelName, channel.routingId, channel.routingIdPrefix, peerLocationConfigured);
@@ -220,7 +221,6 @@ function validateSpotNodes(registration) {
220
221
  }
221
222
  validateSpotNodeCapability(`SpotNode '${spotNodeName}' pubSub`, spotNode.pubSub);
222
223
  requireNonNegativeSafeInteger(`SpotNode '${spotNodeName}' instanceSpotIdleTimeoutMs`, spotNode.instanceSpotIdleTimeoutMs);
223
- (0, SendTimeoutValidation_1.requireValidSendTimeoutMs)(`SpotNode '${spotNodeName}' publisher sendTimeoutMs`, spotNode.publisherConfig?.sendTimeoutMs);
224
224
  validateSpotNodeFactories(spotNodeName, spotNode);
225
225
  validateSpotNodeTimers(spotNode);
226
226
  if (spotNode.objectRole === 'client' &&
@@ -1,5 +1,5 @@
1
1
  export type { ZLinkClientServerChannelClientBuilder, ZLinkClientServerChannelRoleBuilder, ZLinkClientServerChannelServerBuilder, ZLinkFanoutChannelBuilder, ZLinkFrameworkOptions, ZLinkMeshChannelBuilder, ZLinkMeshChannelClientBuilder, ZLinkMeshChannelServerBuilder, ZLinkMeshObjectClientBuilder, ZLinkMeshObjectRoleBuilder, ZLinkMeshObjectServerBuilder, ZLinkMeshNodeBuilder, ZLinkMeshNodeSocketConfig, ZLinkMeshPeerConnection, ZLinkMeshPeerConnections, ZLinkNetworkOptions, ZLinkMetadataPolicyBuilder, ZLinkStreamCompressionBuilder, ZLinkStreamSocketConfig, ZLinkStreamNodeBuilder } from './Builders';
2
- export type { ZLinkOutboundRouteConfig, ZLinkRouteConfig, ZLinkSocketConfig, ZLinkSpotPublisherConfig } from './Configs';
2
+ export type { ZLinkOutboundRouteConfig, ZLinkRouteConfig, ZLinkSocketConfig } from './Configs';
3
3
  export * from './Connections';
4
4
  export * from './ObjectRoles';
5
5
  export type { ZLinkApplicationJobQueueOptions, ZLinkCoreHwmOptions, ZLinkWorkerOptions } from './RegistrationTypes';
@@ -1,5 +1,6 @@
1
1
  /** Test and companion-package integration surface. It is not exported by package.json. */
2
2
  export * from './index';
3
+ export { requireValidSendTimeoutMs } from './contracts/Configuration/SendTimeoutValidation';
3
4
  export * from './runtime/diagnostics';
4
5
  export * from './runtime/host';
5
6
  export * from './runtime/admission';
package/dist/internal.js CHANGED
@@ -14,9 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.requirePublicWeight = exports.isValidCapacity = exports.isValidListenerPort = exports.isValidPositiveCapacity = exports.isValidPublicWeight = exports.ZLINK_MAX_CAPACITY = exports.ZLINK_MAX_PUBLIC_WEIGHT = exports.MAX_LISTENER_PORT = exports.ZLINK_MAX_STABLE_TYPE_BYTES = exports.ZLINK_RELOCATION_MAX_BLOB_REFERENCE_BYTES = exports.ZLinkLocationWriteStatus = exports.ZLinkLocationWriteIntent = exports.ZLinkRouteKind = exports.ZLinkLocationKind = exports.ZLinkLocationAutoConnectType = void 0;
17
+ exports.requirePublicWeight = exports.isValidCapacity = exports.isValidListenerPort = exports.isValidPositiveCapacity = exports.isValidPublicWeight = exports.ZLINK_MAX_CAPACITY = exports.ZLINK_MAX_PUBLIC_WEIGHT = exports.MAX_LISTENER_PORT = exports.ZLINK_MAX_STABLE_TYPE_BYTES = exports.ZLINK_RELOCATION_MAX_BLOB_REFERENCE_BYTES = exports.ZLinkLocationWriteStatus = exports.ZLinkLocationWriteIntent = exports.ZLinkRouteKind = exports.ZLinkLocationKind = exports.ZLinkLocationAutoConnectType = exports.requireValidSendTimeoutMs = void 0;
18
18
  /** Test and companion-package integration surface. It is not exported by package.json. */
19
19
  __exportStar(require("./index"), exports);
20
+ var SendTimeoutValidation_1 = require("./contracts/Configuration/SendTimeoutValidation");
21
+ Object.defineProperty(exports, "requireValidSendTimeoutMs", { enumerable: true, get: function () { return SendTimeoutValidation_1.requireValidSendTimeoutMs; } });
20
22
  __exportStar(require("./runtime/diagnostics"), exports);
21
23
  __exportStar(require("./runtime/host"), exports);
22
24
  __exportStar(require("./runtime/admission"), exports);
@@ -1,5 +1,6 @@
1
1
  import { type ActorRef, type RoutingId } from '../../contracts';
2
2
  import type { Message } from '../../contracts/Common/Message';
3
+ import type { ApplicationJobOrigin } from '../application-jobs/contracts';
3
4
  import type { ZLinkMessageFollowOrigin } from '../foundation/service-runtime-contracts';
4
5
  import { ZLinkFrameworkInternalErrorKind } from '../framework-errors-internal';
5
6
  import type { ZLinkSpotRouteTarget } from '../spots/spot-routing-internal';
@@ -56,7 +57,7 @@ export interface ZLinkActorHandoffPreparedReplayAdmission {
56
57
  run<T>(operation: () => Promise<T>): Promise<T>;
57
58
  cancel(): void;
58
59
  }
59
- export type ZLinkActorHandoffReplayPreparation = (signal: AbortSignal) => Promise<ZLinkActorHandoffPreparedReplayAdmission>;
60
+ export type ZLinkActorHandoffReplayPreparation = (signal: AbortSignal, origin: ApplicationJobOrigin) => Promise<ZLinkActorHandoffPreparedReplayAdmission>;
60
61
  export interface ZLinkActorHandoffPrefixAdmission {
61
62
  /** Completes after every child callback reaches its real terminal. */
62
63
  readonly terminal: Promise<void>;
@@ -141,7 +142,7 @@ export declare class ZLinkActorHandoffCoordinator {
141
142
  */
142
143
  failPending(actorId: string, reason: unknown): void;
143
144
  cancel(actorId: string): void;
144
- capture(actorId: string, parts: readonly Message[], returnResponse?: boolean, remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget, fallbackActorRef?: ActorRef, deadlineUnixMs?: number, messageFollowOrigin?: ZLinkMessageFollowOrigin, provisionalReplay?: ZLinkActorHandoffDispatch): Promise<unknown> | undefined;
145
+ capture(origin: ApplicationJobOrigin, actorId: string, parts: readonly Message[], returnResponse?: boolean, remoteBoundSessionTarget?: ZLinkRemoteBoundSessionTarget, fallbackActorRef?: ActorRef, deadlineUnixMs?: number, messageFollowOrigin?: ZLinkMessageFollowOrigin, provisionalReplay?: ZLinkActorHandoffDispatch): Promise<unknown> | undefined;
145
146
  snapshot(actorId: string): readonly ZLinkActorHandoffPacket[];
146
147
  snapshotCoreBacklog(actorId: string): readonly ZLinkActorHandoffPacket[];
147
148
  /**
@@ -247,7 +247,7 @@ class ZLinkActorHandoffCoordinator {
247
247
  try {
248
248
  await waitForHandoffReplayStart(release.start, signal);
249
249
  if (release.preparation !== undefined) {
250
- const next = await release.preparation(signal);
250
+ const next = await release.preparation(signal, pending.origin);
251
251
  if (signal.aborted) {
252
252
  next.cancel();
253
253
  throw signal.reason;
@@ -422,7 +422,7 @@ class ZLinkActorHandoffCoordinator {
422
422
  pending.reject?.(error);
423
423
  }
424
424
  }
425
- capture(actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef, deadlineUnixMs, messageFollowOrigin, provisionalReplay) {
425
+ capture(origin, actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef, deadlineUnixMs, messageFollowOrigin, provisionalReplay) {
426
426
  const incomingContext = (0, actor_message_follow_context_1.actorMessageFollowContext)(fallbackActorRef);
427
427
  const originalDeadlineUnixMs = deadlineUnixMs ?? incomingContext?.deadlineUnixMs ?? packetDeadlineUnixMs(parts);
428
428
  const handoff = this.active.get(actorId);
@@ -456,7 +456,7 @@ class ZLinkActorHandoffCoordinator {
456
456
  this.reportRequestFrame(actorId, packet);
457
457
  }
458
458
  if (!returnResponse) {
459
- handoff.pending.push({ packet });
459
+ handoff.pending.push({ packet, origin });
460
460
  // The durable handoff now owns this record. Return the ingress permit
461
461
  // before waiting for a later replay, which must acquire its own fresh
462
462
  // application-job permit.
@@ -494,7 +494,12 @@ class ZLinkActorHandoffCoordinator {
494
494
  }, RELOCATION_REPLY_RETENTION_MS);
495
495
  route.deadline.unref();
496
496
  this.replyRoutes.set(source.replyRouteId, route);
497
- handoff.pending.push({ packet: requestPacket, resolve, reject });
497
+ handoff.pending.push({
498
+ packet: requestPacket,
499
+ origin,
500
+ resolve,
501
+ reject
502
+ });
498
503
  });
499
504
  (0, application_job_queue_scope_1.releaseApplicationJobPermitForDurableHandoff)();
500
505
  if (handoff.prefixRelease !== undefined) {
@@ -27,6 +27,7 @@ export interface ZLinkActorManagerOptions {
27
27
  readonly actorRefResolver?: ZLinkActorRuntimeLocationLookup;
28
28
  readonly actorCreatedNotifier?: (nodeRid: RoutingId, actor: ZLinkActor, createRequest: ZLinkMessage, signal?: AbortSignal) => Promise<ZLinkActorCreateResponse | undefined>;
29
29
  readonly actorDestroyedCleanup?: (actorId: string) => void;
30
+ readonly terminateActorActivation?: (actor: ZLinkActor, terminal: () => Promise<void>) => Promise<void>;
30
31
  readonly publishActorAuthority?: (actorType: string, actorRef: ActorRef, ownerNodeGeneration: bigint, signal?: AbortSignal) => Promise<void>;
31
32
  readonly locationLifecycle?: ZLinkLocationLifecycle;
32
33
  readonly boundSessionFactory?: ZLinkActorBoundSessionFactory;
@@ -55,6 +55,8 @@ export declare class DefaultZLinkActorManager implements ZLinkActorManager {
55
55
  completeCoreRelocationSource(actorId: string): Promise<void>;
56
56
  private finalizeActorState;
57
57
  private finalizeDestroyedActor;
58
+ private terminateActor;
59
+ private awaitActorDestroy;
58
60
  getOrCreateActor(actorId: string, actorType: string, signal?: AbortSignal): Promise<ZLinkActor>;
59
61
  getOrCreateWithNativeRef(actorId: string, actorType: string, actorRef: ZLinkBackendActorRef, createRequest?: unknown, signal?: AbortSignal): Promise<ZLinkActor>;
60
62
  getOrCreateActorResult(actorId: string, actorType: string, createRequest?: unknown, signal?: AbortSignal): Promise<ZLinkActorLocalCreateResult>;
@@ -11,6 +11,7 @@ const runtime_metrics_1 = require("../diagnostics/runtime-metrics");
11
11
  const execution_1 = require("../execution");
12
12
  const framework_errors_internal_1 = require("../framework-errors-internal");
13
13
  const handler_instance_scope_1 = require("../handlers/handler-instance-scope");
14
+ const actor_execution_context_1 = require("./actor-execution-context");
14
15
  const payload_codec_1 = require("../messaging/payload-codec");
15
16
  const actor_creation_1 = require("./actor-creation");
16
17
  const actor_runtime_state_1 = require("./actor-runtime-state");
@@ -139,7 +140,7 @@ class DefaultZLinkActorManager {
139
140
  const entryNodeRid = state.entryNodeRid ?? current.nodeRid;
140
141
  if (node === undefined || completions === undefined)
141
142
  return false;
142
- const destroyTask = state.getOrStartDestroy(entryNodeRid, async (nativeRef) => {
143
+ const destroyTask = state.getOrStartDestroy(entryNodeRid, (nativeRef) => this.terminateActor(state, async () => {
143
144
  if (nativeRef !== undefined) {
144
145
  const completion = await completions.submit(() => node.destroyActor(nativeRef, 0), signal);
145
146
  try {
@@ -161,9 +162,9 @@ class DefaultZLinkActorManager {
161
162
  await this.options.locationLifecycle?.releaseActor(state.actorType, actor.actorId, current);
162
163
  }
163
164
  await this.finalizeDestroyedActor(actor.actorId, state);
164
- });
165
+ }));
165
166
  try {
166
- await destroyTask;
167
+ await this.awaitActorDestroy(state, destroyTask);
167
168
  }
168
169
  catch (error) {
169
170
  state.clearFailedDestroy(destroyTask);
@@ -381,6 +382,20 @@ class DefaultZLinkActorManager {
381
382
  this.options.metrics?.change(runtime_metrics_1.METRIC_NAMES.ActorCount, -1);
382
383
  }
383
384
  }
385
+ terminateActor(state, terminal) {
386
+ const actor = state.actor;
387
+ const completion = actor === undefined || this.options.terminateActorActivation === undefined
388
+ ? terminal()
389
+ : this.options.terminateActorActivation(actor, terminal);
390
+ return completion;
391
+ }
392
+ awaitActorDestroy(state, completion) {
393
+ if ((0, actor_execution_context_1.currentZLinkActorExecution)()?.actorId === state.actorId) {
394
+ this.detachedTaskRunner.runDetached('Actor terminal cleanup', () => completion);
395
+ return Promise.resolve();
396
+ }
397
+ return completion;
398
+ }
384
399
  async getOrCreateActor(actorId, actorType, signal) {
385
400
  this.rememberActorMeshFromType(actorId, actorType);
386
401
  const result = await this.createOrGet(actorId, actorType, false, undefined, signal);
@@ -429,7 +444,7 @@ class DefaultZLinkActorManager {
429
444
  if (state.isJoined) {
430
445
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.ActorRouteNotFound, `Actor '${actor.context.actorId}' must leave its current SPOT before destroy.`);
431
446
  }
432
- const destroyTask = state.getOrStartDestroy(entryNodeRid, async (actorRef) => {
447
+ const destroyTask = state.getOrStartDestroy(entryNodeRid, (actorRef) => this.terminateActor(state, async () => {
433
448
  const destroyedActorRef = actorRef === undefined ? undefined : (0, actor_runtime_state_1.toFrameworkActorRef)(actorRef, state.meshName ?? '');
434
449
  if (actorRef !== undefined) {
435
450
  await node.destroyActor(actorRef, 0, destroySignal);
@@ -439,9 +454,9 @@ class DefaultZLinkActorManager {
439
454
  await this.options.locationLifecycle?.releaseActor(state.actorType, actor.context.actorId, destroyedActorRef);
440
455
  }
441
456
  await this.finalizeDestroyedActor(actor.context.actorId, state);
442
- });
457
+ }));
443
458
  try {
444
- await destroyTask;
459
+ await this.awaitActorDestroy(state, destroyTask);
445
460
  }
446
461
  catch (error) {
447
462
  state.clearFailedDestroy(destroyTask);
@@ -1,4 +1,4 @@
1
- import type { ApplicationJobPermitPort, ApplicationJobQueuePort } from './contracts';
1
+ import type { ApplicationJobOrigin, ApplicationJobPermitPort, ApplicationJobQueuePort } from './contracts';
2
2
  export type ApplicationJobRecordDomain = 'application' | 'infrastructure';
3
3
  export interface IngressRecordPort {
4
4
  close(): void;
@@ -30,6 +30,7 @@ export declare class ApplicationJobRecordLease implements ApplicationJobPermitPo
30
30
  private detachedForHandlerTurn;
31
31
  private jobReleased;
32
32
  constructor(shared: SharedIngressRecordState, permit: ApplicationJobPermitPort);
33
+ get origin(): ApplicationJobOrigin;
33
34
  markApplicationQueued(): void;
34
35
  detachForHandlerTurn(): void;
35
36
  releaseBeforeHandler(): void;
@@ -45,6 +46,7 @@ declare class SharedIngressRecordState {
45
46
  private jobCount;
46
47
  private initialPermit?;
47
48
  private recordClosed;
49
+ readonly origin: ApplicationJobOrigin;
48
50
  constructor(queue: ApplicationJobQueuePort, initialPermit: ApplicationJobPermitPort, record: IngressRecordPort);
49
51
  retainOwner(): void;
50
52
  releaseOwner(): void;
@@ -68,6 +68,9 @@ class ApplicationJobRecordLease {
68
68
  this.shared = shared;
69
69
  this.permit = permit;
70
70
  }
71
+ get origin() {
72
+ return this.shared.origin;
73
+ }
71
74
  markApplicationQueued() {
72
75
  // The owner classifies and marks the child atomically when it is created;
73
76
  // downstream dispatch must not mutate queue accounting a second time.
@@ -114,9 +117,11 @@ class SharedIngressRecordState {
114
117
  jobCount = 0;
115
118
  initialPermit;
116
119
  recordClosed = false;
120
+ origin;
117
121
  constructor(queue, initialPermit, record) {
118
122
  this.queue = queue;
119
123
  this.record = record;
124
+ this.origin = initialPermit.origin;
120
125
  this.initialPermit = initialPermit;
121
126
  }
122
127
  retainOwner() {
@@ -138,7 +143,7 @@ class SharedIngressRecordState {
138
143
  return this.createJob(permit, domain);
139
144
  }
140
145
  acquirePermit(signal) {
141
- return this.queue.acquire(signal);
146
+ return this.queue.acquire(signal, this.origin);
142
147
  }
143
148
  createJob(permit, domain) {
144
149
  this.jobCount += 1;
@@ -1,4 +1,4 @@
1
- import type { ApplicationJobPermitPort } from './contracts';
1
+ import type { ApplicationJobOrigin, ApplicationJobPermitPort } from './contracts';
2
2
  /**
3
3
  * Carries the host-owned queue permit through internal async dispatch without
4
4
  * leaking capacity ownership into public handler contracts.
@@ -8,6 +8,8 @@ export declare function runWithApplicationJobPermit<TResult>(permit: Application
8
8
  export declare function releaseApplicationJobPermitBeforeHandler(): void;
9
9
  /** True while dispatch already owns the host-wide application job permit. */
10
10
  export declare function hasApplicationJobPermit(): boolean;
11
+ /** Keeps the ingress origin when a durable record later reacquires its permit. */
12
+ export declare function currentApplicationJobOrigin(): ApplicationJobOrigin;
11
13
  /** Re-enters the captured permit scope when a serial executor runs later. */
12
14
  export declare function bindApplicationJobPermit<TResult, TArgument>(callback: (argument?: TArgument) => Promise<TResult> | TResult): (argument?: TArgument) => Promise<TResult> | TResult;
13
15
  /**
@@ -4,6 +4,7 @@ exports.runWithApplicationJobPermit = runWithApplicationJobPermit;
4
4
  exports.releaseApplicationJobPermitBeforeHandler = releaseApplicationJobPermitBeforeHandler;
5
5
  exports.releaseApplicationJobPermitForDurableHandoff = releaseApplicationJobPermitForDurableHandoff;
6
6
  exports.hasApplicationJobPermit = hasApplicationJobPermit;
7
+ exports.currentApplicationJobOrigin = currentApplicationJobOrigin;
7
8
  exports.bindApplicationJobPermit = bindApplicationJobPermit;
8
9
  exports.detachApplicationJobPermit = detachApplicationJobPermit;
9
10
  const node_async_hooks_1 = require("node:async_hooks");
@@ -36,6 +37,10 @@ function releaseApplicationJobPermitForDurableHandoff() {
36
37
  function hasApplicationJobPermit() {
37
38
  return applicationJobPermitScope.getStore() !== undefined;
38
39
  }
40
+ /** Keeps the ingress origin when a durable record later reacquires its permit. */
41
+ function currentApplicationJobOrigin() {
42
+ return applicationJobPermitScope.getStore().permit.origin;
43
+ }
39
44
  /** Re-enters the captured permit scope when a serial executor runs later. */
40
45
  function bindApplicationJobPermit(callback) {
41
46
  const scope = applicationJobPermitScope.getStore();
@@ -1,4 +1,6 @@
1
+ export type ApplicationJobOrigin = 'local' | 'remote';
1
2
  export interface ApplicationJobPermitPort {
3
+ readonly origin: ApplicationJobOrigin;
2
4
  markApplicationQueued(): void;
3
5
  /** Transfers ingress-record cleanup to a detached exact-target handler turn. */
4
6
  detachForHandlerTurn?(): void;
@@ -6,7 +8,9 @@ export interface ApplicationJobPermitPort {
6
8
  releaseAfterInternalProcessing(): void;
7
9
  }
8
10
  export interface ApplicationJobQueuePort {
9
- acquire(signal?: AbortSignal): Promise<ApplicationJobPermitPort>;
11
+ acquire(signal: AbortSignal | undefined, origin: ApplicationJobOrigin): Promise<ApplicationJobPermitPort>;
12
+ /** Returns a grant now, or registers one FIFO waiter that later calls resume. */
13
+ acquireOrResume(resume: (permit: ApplicationJobPermitPort) => void, reject: (reason: unknown) => void, signal: AbortSignal | undefined, origin: ApplicationJobOrigin): ApplicationJobPermitPort | undefined;
10
14
  registerReceiveFlowTarget?(identity: object, applyState: (state: 'running' | 'paused') => void, failureSink?: (error: unknown) => void): boolean;
11
15
  unregisterReceiveFlowTarget?(identity: object): void;
12
16
  pressureState?(): 'running' | 'paused';
@@ -1,5 +1,5 @@
1
1
  import type { RequestResult, SubmitResult, ZLinkBackendMessageLike, ZLinkBackendMonitorEventType, ZLinkBackendReceived, ZLinkBackendTopicMessage } from '../runtime-values';
2
- import type { CoreHwmBudgetSnapshot } from '@zlink-systems/zlink';
2
+ import type { CoreHwmBudgetSnapshot, ReceiveFlowState } from '@zlink-systems/zlink';
3
3
  import { type ZLinkBackendRecvFlags, type ZLinkBackendSendFlags } from '../runtime-values';
4
4
  export * from '../runtime-values';
5
5
  type MessageLike = ZLinkBackendMessageLike;
@@ -10,10 +10,11 @@ import type { MeshNodeStatus, MeshOperationId, MeshPeerEntry, MeshPublisher, Rea
10
10
  import type { RoutingId } from '../../../contracts';
11
11
  import type { ZLinkCoreHwmOptions } from '../../../contracts/Configuration';
12
12
  import type { ZLinkSubmitResult } from '../../messaging/submission-result';
13
+ import type { ZLinkMeshCompletionHandler } from '../mesh-completion-table';
13
14
  import type { Message } from '../../../contracts/Common/Message';
14
15
  import type { ServiceSpotMessageFollowSeal, ServiceUserSpotOperationHandler, ServiceUserSpotOperationResult } from '../../foundation/service-stateful-runtime';
15
16
  import type { ServiceApplicationPayload } from '../../foundation/service-wire-m6a-codec';
16
- import type { ServiceActorCreateRecord, ServiceDirectSpotRouteFence, ServiceInstanceRouteFence, ServiceUserSpotCloseRecord, ServiceUserSpotCreateRecord } from '../../foundation/service-stateful-wire-codec';
17
+ import type { ServiceActorCreateRecord, ServiceDirectSpotRouteFence, ServiceInstanceRouteFence, ServiceInstanceColdActivationTarget, ServiceUserSpotCloseRecord, ServiceUserSpotCreateRecord } from '../../foundation/service-stateful-wire-codec';
17
18
  export declare const ZLINK_BACKEND_SPOT_ROUTE_BRIDGE_ROUTE_WITH_CHANNEL_INBOUND = 3;
18
19
  export type ZLinkBackendMeshNodeStatus = MeshNodeStatus;
19
20
  export type ZLinkBackendMeshPeerEntry = MeshPeerEntry;
@@ -66,20 +67,8 @@ export interface ZLinkBackendMeshNode {
66
67
  }): void;
67
68
  selectObjectPlacement(stableType: string): ZLinkBackendObjectPlacement;
68
69
  instanceSpotPlacementTypes?(): readonly string[];
69
- sendToMissingInstanceSpot(target: {
70
- readonly targetNodeRid: string;
71
- readonly targetNodeGeneration: bigint;
72
- readonly targetSpotId: string;
73
- readonly stableType: string;
74
- readonly descriptorVersion: string;
75
- }, parts: ZLinkBackendMessageLike | readonly ZLinkBackendMessageLike[], deadlineUnixMs: bigint, sourceSpotId?: string, metadata?: ReadonlyMap<string, string>): Promise<SubmitResult>;
76
- requestToMissingInstanceSpot(target: {
77
- readonly targetNodeRid: string;
78
- readonly targetNodeGeneration: bigint;
79
- readonly targetSpotId: string;
80
- readonly stableType: string;
81
- readonly descriptorVersion: string;
82
- }, parts: ZLinkBackendMessageLike | readonly ZLinkBackendMessageLike[], deadlineUnixMs: bigint, sourceSpotId?: string, metadata?: ReadonlyMap<string, string>): MeshOperationId;
70
+ sendToMissingInstanceSpot(target: ServiceInstanceColdActivationTarget, parts: ZLinkBackendMessageLike | readonly ZLinkBackendMessageLike[], deadlineUnixMs: bigint, sourceSpotId?: string, metadata?: ReadonlyMap<string, string>): Promise<SubmitResult>;
71
+ requestToMissingInstanceSpot(target: ServiceInstanceColdActivationTarget, parts: ZLinkBackendMessageLike | readonly ZLinkBackendMessageLike[], deadlineUnixMs: bigint, sourceSpotId?: string, metadata?: ReadonlyMap<string, string>): MeshOperationId;
83
72
  sendToInstanceSpot(route: ServiceInstanceRouteFence, parts: MessageLike | readonly MessageLike[], sourceSpotId?: string, metadata?: ReadonlyMap<string, string>, instanceIntent?: boolean): Promise<SubmitResult>;
84
73
  requestInstanceSpot(route: ServiceInstanceRouteFence, parts: MessageLike | readonly MessageLike[], timeoutMs?: number, sourceSpotId?: string, metadata?: ReadonlyMap<string, string>, instanceIntent?: boolean): MeshOperationId;
85
74
  registerUserSpotOperationHandler(handler: ServiceUserSpotOperationHandler): void;
@@ -215,6 +204,7 @@ export interface ZLinkBackendMeshNode {
215
204
  closeActorBoundSession(actor: ZLinkBackendActorRef, expectedBindingGeneration: bigint, timeoutMs?: number): MeshOperationId;
216
205
  leaveActor(actor: ZLinkBackendActorRef, expectedMembershipEpoch: bigint, timeoutMs?: number): MeshOperationId;
217
206
  setReadyHandler(handler: (readyDomains: number) => number): void;
207
+ setCompletionHandler(handler: ZLinkMeshCompletionHandler): void;
218
208
  createReadyBatch(capacity: number): ReadyBatch;
219
209
  createReceiveBatch(messageCapacity: number, partCapacity: number): ReceiveBatch;
220
210
  drainReady(domains: number, batch: ReadyBatch, flags?: number): {
@@ -278,7 +268,6 @@ export interface ZLinkBackendSocket extends ZLinkBackendObject {
278
268
  readonly lastEndpoint?: string;
279
269
  bind(endpoint: string): void;
280
270
  setChannelName(channelName: string): void;
281
- setReceiveFlowState?(state: 0 | 1): void;
282
271
  dispose(): Promise<void>;
283
272
  }
284
273
  export interface ZLinkBackendConnectableSocket extends ZLinkBackendSocket {
@@ -286,7 +275,7 @@ export interface ZLinkBackendConnectableSocket extends ZLinkBackendSocket {
286
275
  disconnect(endpoint: string): void;
287
276
  }
288
277
  export interface ZLinkBackendDealerSocket extends ZLinkBackendConnectableSocket {
289
- setReceiveFlowState(state: 0 | 1): void;
278
+ receiveAdmission?: import('../../foundation/service-liveness-registry').ServiceLivenessConnection;
290
279
  setRoutingId(routingId: RoutingId): void;
291
280
  peerWeight: number;
292
281
  sendHighWaterMark: number;
@@ -311,7 +300,7 @@ export interface ZLinkBackendRequestOperation {
311
300
  submit(): Promise<readonly Message[]>;
312
301
  }
313
302
  export interface ZLinkBackendRouterSocket extends ZLinkBackendConnectableSocket {
314
- setReceiveFlowState(state: 0 | 1): void;
303
+ setReceiveFlowState(state: ReceiveFlowState): void;
315
304
  /** Enables the native probe handshake for manually configured routes. */
316
305
  setProbe(enabled: boolean): void;
317
306
  peerWeight: number;
@@ -330,6 +319,7 @@ export interface ZLinkBackendRouterSocket extends ZLinkBackendConnectableSocket
330
319
  reply(routingId: RoutingId, replyToken: unknown, message: Message | readonly Message[]): void;
331
320
  }
332
321
  export interface ZLinkBackendPublisherSocket extends ZLinkBackendSocket {
322
+ lingerMs: number;
333
323
  sendTimeoutMs: number;
334
324
  sendHighWaterMark: number;
335
325
  noDrop: boolean;
@@ -447,6 +437,7 @@ export interface ZLinkMeshBackendAdapter {
447
437
  readonly trustProfile?: string;
448
438
  readonly applicationJobQueue: import('../../application-jobs/contracts').ApplicationJobQueuePort;
449
439
  readonly applicationJobReceiveFlowFailureSink?: (error: unknown) => void;
440
+ readonly infrastructureTaskRunner?: import('../../spots/spot-actor-join-dispatch').ZLinkDetachedTaskRunner;
450
441
  readonly peerAdmissionSealed?: () => boolean;
451
442
  }): ZLinkBackendMeshNode;
452
443
  }
@@ -12,20 +12,22 @@ export interface ZLinkMeshCompletion {
12
12
  readonly kindData: ReceiveKindData | null;
13
13
  readonly parts: Message[];
14
14
  }
15
+ export type ZLinkMeshCompletionTerminal = Pick<ReceiveRecord, 'operationId' | 'terminalResult'>;
16
+ export type ZLinkMeshCompletionHandler = (terminal: ZLinkMeshCompletionTerminal, materialize: () => ReceiveRecord) => void;
15
17
  export declare class ZLinkMeshCompletionTable {
16
18
  private readonly onDiagnostic?;
17
19
  private readonly pending;
18
20
  private disposed;
19
21
  constructor(onDiagnostic?: ((diagnostic: ZLinkMeshCompletionDiagnostic) => void) | undefined);
20
22
  /**
21
- * Submits and registers without yielding control to the event loop. Mesh
22
- * completion dispatch is asynchronous, so a completion cannot overtake the
23
- * registration. The table therefore does not need to retain responses that
24
- * arrived before their waiter.
23
+ * Reserves the dispatcher slot before transport submission. The backend
24
+ * observes native terminals through Promises, so identity binding finishes
25
+ * before the terminal callback can run, without an infrastructure pump.
25
26
  */
26
27
  submit(operation: () => MeshOperationId, signal?: AbortSignal): Promise<ZLinkMeshCompletion>;
27
28
  private isDisposed;
28
29
  complete(record: ReceiveRecord): void;
30
+ complete(record: ZLinkMeshCompletionTerminal, materialize: () => ReceiveRecord): void;
29
31
  dispose(reason?: unknown): void;
30
32
  get pendingCount(): number;
31
33
  }
@@ -12,10 +12,9 @@ class ZLinkMeshCompletionTable {
12
12
  this.onDiagnostic = onDiagnostic;
13
13
  }
14
14
  /**
15
- * Submits and registers without yielding control to the event loop. Mesh
16
- * completion dispatch is asynchronous, so a completion cannot overtake the
17
- * registration. The table therefore does not need to retain responses that
18
- * arrived before their waiter.
15
+ * Reserves the dispatcher slot before transport submission. The backend
16
+ * observes native terminals through Promises, so identity binding finishes
17
+ * before the terminal callback can run, without an infrastructure pump.
19
18
  */
20
19
  submit(operation, signal) {
21
20
  if (this.isDisposed()) {
@@ -24,17 +23,8 @@ class ZLinkMeshCompletionTable {
24
23
  if (signal?.aborted === true) {
25
24
  return Promise.reject(signal.reason ?? new DOMException('The operation was aborted.', 'AbortError'));
26
25
  }
27
- const operationId = operation();
28
- // The backend submission callback can synchronously re-enter `dispose()`.
29
- // TypeScript's control-flow analysis cannot observe mutation through it.
30
- if (this.disposed) {
31
- return Promise.reject(new Error('Mesh completion table is disposed.'));
32
- }
33
- const key = (0, operation_identity_1.operationIdentityKey)(operationId);
34
- if (this.pending.has(key)) {
35
- return Promise.reject(new Error(`Mesh operation '${key}' is already pending.`));
36
- }
37
26
  return new Promise((resolve, reject) => {
27
+ let key = Symbol();
38
28
  const abort = () => {
39
29
  this.pending.delete(key);
40
30
  reject(signal?.reason ?? new DOMException('The operation was aborted.', 'AbortError'));
@@ -44,17 +34,37 @@ class ZLinkMeshCompletionTable {
44
34
  return;
45
35
  }
46
36
  signal?.addEventListener('abort', abort, { once: true });
47
- this.pending.set(key, {
37
+ const entry = {
48
38
  resolve,
49
39
  reject,
50
40
  removeAbort: signal === undefined ? undefined : () => signal.removeEventListener('abort', abort)
51
- });
41
+ };
42
+ this.pending.set(key, entry);
43
+ try {
44
+ const operationId = operation();
45
+ // dispose/abort can consume the reserved slot during submission.
46
+ if (!this.pending.delete(key))
47
+ return;
48
+ key = (0, operation_identity_1.operationIdentityKey)(operationId);
49
+ if (this.pending.has(key)) {
50
+ throw new Error(`Mesh operation '${key}' is already pending.`);
51
+ }
52
+ this.pending.set(key, entry);
53
+ }
54
+ catch (error) {
55
+ // Remove only this submission's slot; a duplicate identity retains
56
+ // the original waiter.
57
+ if (this.pending.get(key) === entry)
58
+ this.pending.delete(key);
59
+ entry.removeAbort?.();
60
+ reject(error);
61
+ }
52
62
  });
53
63
  }
54
64
  isDisposed() {
55
65
  return this.disposed;
56
66
  }
57
- complete(record) {
67
+ complete(record, materialize) {
58
68
  const key = (0, operation_identity_1.operationIdentityKey)(record.operationId);
59
69
  const pending = this.pending.get(key);
60
70
  if (pending === undefined) {
@@ -68,7 +78,7 @@ class ZLinkMeshCompletionTable {
68
78
  this.pending.delete(key);
69
79
  pending.removeAbort?.();
70
80
  try {
71
- pending.resolve(retainCompletion(record));
81
+ pending.resolve(retainCompletion(materialize === undefined ? record : materialize()));
72
82
  }
73
83
  catch (error) {
74
84
  pending.reject(error);