@zlink-systems/framework 0.27.0 → 0.28.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 (121) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Actors/ZLinkActorClient.d.ts +1 -1
  3. package/dist/contracts/Channels/Calls.d.ts +1 -1
  4. package/dist/contracts/Configuration/Builders.d.ts +0 -1
  5. package/dist/contracts/Configuration/Configs.d.ts +0 -1
  6. package/dist/contracts/Configuration/RegistrationTypes.d.ts +0 -5
  7. package/dist/contracts/Configuration/RegistrationValidators.js +0 -2
  8. package/dist/contracts/Spots/Contracts.d.ts +1 -1
  9. package/dist/contracts/Streams/BoundSessionContracts.d.ts +1 -1
  10. package/dist/contracts/Streams/IZLinkSession.d.ts +2 -3
  11. package/dist/contracts/Streams/IZLinkSessionActor.d.ts +2 -2
  12. package/dist/runtime/actors/actor-client.js +7 -10
  13. package/dist/runtime/actors/actor-request-deadline.d.ts +1 -3
  14. package/dist/runtime/actors/actor-request-deadline.js +4 -29
  15. package/dist/runtime/actors/actor-routed-join-transport.d.ts +2 -3
  16. package/dist/runtime/backend/contracts/index.d.ts +1 -4
  17. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -0
  18. package/dist/runtime/backend/node/node-backend-adapter-support.js +35 -4
  19. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  20. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +1 -2
  21. package/dist/runtime/backend/node/node-raw-binding-port.js +10 -27
  22. package/dist/runtime/backend/node/node-socket-backend-adapter.js +1 -1
  23. package/dist/runtime/channels/channel-clients.js +8 -10
  24. package/dist/runtime/channels/channel-envelope.d.ts +1 -1
  25. package/dist/runtime/channels/channel-envelope.js +4 -10
  26. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  27. package/dist/runtime/channels/channel-outbound-operations.js +20 -36
  28. package/dist/runtime/channels/channel-runtime-manager.d.ts +4 -4
  29. package/dist/runtime/channels/channel-runtime-manager.js +8 -8
  30. package/dist/runtime/channels/channel-socket-options.js +0 -10
  31. package/dist/runtime/channels/channel-socket-registry.d.ts +1 -1
  32. package/dist/runtime/channels/channel-socket-registry.js +3 -14
  33. package/dist/runtime/channels/channel-transports.d.ts +10 -14
  34. package/dist/runtime/channels/channel-transports.js +11 -14
  35. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  36. package/dist/runtime/channels/local-spot-route-transport.js +1 -3
  37. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +1 -1
  38. package/dist/runtime/channels/router-socket-spot-route-transport.js +2 -2
  39. package/dist/runtime/channels/source-spot-router.d.ts +1 -1
  40. package/dist/runtime/channels/source-spot-router.js +2 -4
  41. package/dist/runtime/channels/spot-node-route-transport.d.ts +1 -1
  42. package/dist/runtime/channels/spot-node-route-transport.js +2 -3
  43. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +1 -1
  44. package/dist/runtime/channels/spot-route-bridge-transport.js +2 -2
  45. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +2 -4
  46. package/dist/runtime/channels/spot-route-dispatch-strategy.js +11 -12
  47. package/dist/runtime/foundation/raw-service-mesh-runtime.js +17 -11
  48. package/dist/runtime/host/actor-packet-relay.d.ts +2 -2
  49. package/dist/runtime/host/actor-packet-relay.js +8 -10
  50. package/dist/runtime/host/index.js +1 -15
  51. package/dist/runtime/host/remote-bound-session-relay.js +8 -8
  52. package/dist/runtime/host/spot-address-transport.d.ts +1 -9
  53. package/dist/runtime/host/spot-address-transport.js +46 -86
  54. package/dist/runtime/locations/location-store-repository.js +6 -4
  55. package/dist/runtime/messaging/request-deadline.d.ts +3 -0
  56. package/dist/runtime/messaging/request-deadline.js +39 -0
  57. package/dist/runtime/messaging/submission-result.d.ts +2 -1
  58. package/dist/runtime/messaging/submission-result.js +11 -4
  59. package/dist/runtime/spots/spot-outbound.d.ts +3 -5
  60. package/dist/runtime/spots/spot-outbound.js +12 -15
  61. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -2
  62. package/dist/runtime/streams/bound-actor-relay-sender.js +14 -14
  63. package/dist/runtime/streams/bound-session-service.js +1 -1
  64. package/dist/runtime/streams/index.d.ts +2 -2
  65. package/dist/runtime/streams/index.js +2 -2
  66. package/dist/runtime/streams/managed-stream.d.ts +2 -2
  67. package/dist/runtime/streams/managed-stream.js +3 -5
  68. package/dist/runtime/streams/native-fallback-bound-session.js +13 -16
  69. package/dist/runtime/streams/session-calls.d.ts +5 -7
  70. package/dist/runtime/streams/session-calls.js +6 -23
  71. package/dist/runtime/streams/session-context.d.ts +4 -4
  72. package/dist/runtime/streams/session-context.js +3 -6
  73. package/package.json +3 -3
  74. package/src/contracts/Actors/ZLinkActorClient.ts +1 -1
  75. package/src/contracts/Channels/Calls.ts +1 -1
  76. package/src/contracts/Configuration/Builders.ts +0 -1
  77. package/src/contracts/Configuration/Configs.ts +0 -1
  78. package/src/contracts/Configuration/RegistrationBuilders.ts +0 -3
  79. package/src/contracts/Configuration/RegistrationTypes.ts +0 -5
  80. package/src/contracts/Configuration/RegistrationValidators.ts +0 -4
  81. package/src/contracts/Spots/Contracts.ts +1 -1
  82. package/src/contracts/Streams/BoundSessionContracts.ts +1 -1
  83. package/src/contracts/Streams/IZLinkSession.ts +2 -3
  84. package/src/contracts/Streams/IZLinkSessionActor.ts +2 -6
  85. package/src/runtime/actors/actor-client.ts +9 -15
  86. package/src/runtime/actors/actor-request-deadline.ts +4 -49
  87. package/src/runtime/actors/actor-routed-join-transport.ts +3 -5
  88. package/src/runtime/backend/contracts/index.ts +1 -8
  89. package/src/runtime/backend/node/node-backend-adapter-support.ts +45 -5
  90. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +0 -2
  91. package/src/runtime/backend/node/node-raw-binding-port.ts +15 -41
  92. package/src/runtime/backend/node/node-socket-backend-adapter.ts +1 -1
  93. package/src/runtime/channels/channel-clients.ts +9 -19
  94. package/src/runtime/channels/channel-envelope.ts +16 -28
  95. package/src/runtime/channels/channel-outbound-operations.ts +36 -38
  96. package/src/runtime/channels/channel-runtime-manager.ts +6 -28
  97. package/src/runtime/channels/channel-socket-options.ts +0 -13
  98. package/src/runtime/channels/channel-socket-registry.ts +3 -17
  99. package/src/runtime/channels/channel-transports.ts +7 -33
  100. package/src/runtime/channels/local-spot-route-transport.ts +1 -5
  101. package/src/runtime/channels/router-socket-spot-route-transport.ts +2 -6
  102. package/src/runtime/channels/source-spot-router.ts +2 -9
  103. package/src/runtime/channels/spot-node-route-transport.ts +2 -7
  104. package/src/runtime/channels/spot-route-bridge-transport.ts +5 -12
  105. package/src/runtime/channels/spot-route-dispatch-strategy.ts +11 -30
  106. package/src/runtime/foundation/raw-service-mesh-runtime.ts +17 -14
  107. package/src/runtime/host/actor-packet-relay.ts +8 -15
  108. package/src/runtime/host/index.ts +2 -26
  109. package/src/runtime/host/remote-bound-session-relay.ts +8 -16
  110. package/src/runtime/host/spot-address-transport.ts +106 -165
  111. package/src/runtime/locations/location-store-repository.ts +7 -4
  112. package/src/runtime/messaging/request-deadline.ts +58 -0
  113. package/src/runtime/messaging/submission-result.ts +18 -4
  114. package/src/runtime/spots/spot-outbound.ts +14 -24
  115. package/src/runtime/streams/bound-actor-relay-sender.ts +12 -26
  116. package/src/runtime/streams/bound-session-service.ts +1 -1
  117. package/src/runtime/streams/index.ts +2 -4
  118. package/src/runtime/streams/managed-stream.ts +3 -13
  119. package/src/runtime/streams/native-fallback-bound-session.ts +13 -25
  120. package/src/runtime/streams/session-calls.ts +8 -34
  121. package/src/runtime/streams/session-context.ts +6 -15
@@ -41,35 +41,34 @@ class ZLinkSpotRouteDispatchStrategy {
41
41
  canRoutePacketChannel(routerChannelId) {
42
42
  return this.targets.canRoutePacketChannel(routerChannelId);
43
43
  }
44
- routeSendToSpot(spotRouteTarget, packetName, message, signal, metadata, timeoutMs) {
44
+ routeSendToSpot(spotRouteTarget, packetName, message, metadata) {
45
45
  // Call-scoped flow (spec 27 §4): the envelope flow pair lives only for
46
46
  // the duration of this outbound call, never in the caller's context.
47
- return (0, flow_context_1.runWithOutboundFlow)(this.options.flowCreationEnabled?.() ?? true, () => this.routeSendToSpotScoped(spotRouteTarget, packetName, message, signal, metadata, timeoutMs));
47
+ return (0, flow_context_1.runWithOutboundFlow)(this.options.flowCreationEnabled?.() ?? true, () => this.routeSendToSpotScoped(spotRouteTarget, packetName, message, metadata));
48
48
  }
49
- async routeSendToSpotScoped(spotRouteTarget, packetName, message, signal, metadata, timeoutMs) {
50
- (0, abort_1.throwIfAborted)(signal);
49
+ async routeSendToSpotScoped(spotRouteTarget, packetName, message, metadata) {
51
50
  const localSpotRouteNode = this.targets.localRouteNode(spotRouteTarget);
52
51
  if (localSpotRouteNode !== undefined) {
53
- await this.localTransport.send(spotRouteTarget.routerChannelId, spotRouteTarget.spotId, packetName, message, signal, metadata, timeoutMs);
52
+ await this.localTransport.send(spotRouteTarget.routerChannelId, spotRouteTarget.spotId, packetName, message, metadata);
54
53
  return;
55
54
  }
56
55
  const parts = (0, channel_envelope_1.encodeChannelEnvelopeParts)(3 /* ZLinkChannelMessageKind.Command */, spotRouteTarget.routerChannelId, packetName, message, undefined, undefined, (0, channel_framework_packets_1.codecsForFrameworkPacket)(packetName, this.options.codecs), undefined, this.options.flowCreationEnabled?.() ?? true, metadata);
57
56
  if (this.targets.hasNamedSpotNode(spotRouteTarget.routerChannelId) &&
58
- (await this.spotNodeTransport.send(spotRouteTarget, parts, signal))) {
57
+ (await this.spotNodeTransport.send(spotRouteTarget, parts))) {
59
58
  return;
60
59
  }
61
60
  if (this.bridgeTransport.has(spotRouteTarget.routerChannelId)) {
62
- await this.bridgeTransport.send(spotRouteTarget, parts, signal);
61
+ await this.bridgeTransport.send(spotRouteTarget, parts);
63
62
  return;
64
63
  }
65
64
  if (this.targets.hasBoundRouteRouter(spotRouteTarget.routerChannelId)) {
66
- await this.routerSocketTransport.send(spotRouteTarget, parts, ZLINK_SEND_DONT_WAIT, signal);
65
+ await this.routerSocketTransport.send(spotRouteTarget, parts, ZLINK_SEND_DONT_WAIT);
67
66
  return;
68
67
  }
69
- if (await this.spotNodeTransport.send(spotRouteTarget, parts, signal)) {
68
+ if (await this.spotNodeTransport.send(spotRouteTarget, parts)) {
70
69
  return;
71
70
  }
72
- await this.routerSocketTransport.send(spotRouteTarget, parts, ZLINK_SEND_DONT_WAIT, signal);
71
+ await this.routerSocketTransport.send(spotRouteTarget, parts, ZLINK_SEND_DONT_WAIT);
73
72
  }
74
73
  routeRequestToSpot(spotRouteTarget, packetName, request, timeoutMs, signal, metadata) {
75
74
  return (0, flow_context_1.runWithOutboundFlow)(this.options.flowCreationEnabled?.() ?? true, () => this.routeRequestToSpotScoped(spotRouteTarget, packetName, request, timeoutMs, signal, metadata));
@@ -102,8 +101,8 @@ class ZLinkSpotRouteDispatchStrategy {
102
101
  routeRequestFromSpotToSpot(sourceSpot, spotRouteTarget, packetName, request, timeoutMs, signal) {
103
102
  return this.sourceSpotRouter.request(sourceSpot, spotRouteTarget, packetName, request, timeoutMs, signal);
104
103
  }
105
- async routeSendFromSpotToSpot(sourceSpot, spotRouteTarget, packetName, message, signal, metadata, timeoutMs) {
106
- await this.sourceSpotRouter.send(sourceSpot, spotRouteTarget, packetName, message, signal, metadata, timeoutMs);
104
+ async routeSendFromSpotToSpot(sourceSpot, spotRouteTarget, packetName, message, metadata) {
105
+ await this.sourceSpotRouter.send(sourceSpot, spotRouteTarget, packetName, message, metadata);
107
106
  }
108
107
  routeRequestRawFromSpotToSpot(sourceSpot, spotRouteTarget, request, timeoutMs, signal) {
109
108
  return this.sourceSpotRouter.requestRaw(sourceSpot, spotRouteTarget, request, timeoutMs, signal);
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RawServiceMeshRuntime = exports.RAW_MESH_RECEIVE_TIME_BUDGET_MS = void 0;
4
4
  const node_os_1 = require("node:os");
5
5
  const application_ingress_record_owner_1 = require("../application-jobs/application-ingress-record-owner");
6
+ const submission_result_1 = require("../messaging/submission-result");
6
7
  const runtime_values_1 = require("../backend/runtime-values");
7
8
  const service_wire_codec_generated_1 = require("../protocol/service_wire_codec.generated");
8
9
  const operation_registry_1 = require("./operation-registry");
@@ -564,16 +565,16 @@ class RawServiceMeshRuntime {
564
565
  const record = livenessCodec.decodeLivenessRecord(received.parts[0]);
565
566
  if (record.command === service_wire_m6a_codec_1.M6aServiceWireCommand.livenessProbe) {
566
567
  const ack = this.liveness.acknowledgeProbe(received.sourceRid, peer.connectionId, record.probeId);
567
- const sent = ack !== undefined &&
568
- (await this.send(received.sourceRid, [
569
- livenessCodec.encodeLivenessRecord({
570
- command: service_wire_m6a_codec_1.M6aServiceWireCommand.livenessAck,
571
- probeId: record.probeId
572
- })
573
- ]));
574
- if (!sent) {
568
+ if (ack === undefined)
575
569
  return 'protocolError';
576
- }
570
+ const sent = await this.send(received.sourceRid, [
571
+ livenessCodec.encodeLivenessRecord({
572
+ command: service_wire_m6a_codec_1.M6aServiceWireCommand.livenessAck,
573
+ probeId: record.probeId
574
+ })
575
+ ]);
576
+ if (!sent)
577
+ return 'dropped';
577
578
  }
578
579
  else {
579
580
  this.liveness.acknowledge(received.sourceRid, peer.connectionId, record.probeId, nowMs);
@@ -962,8 +963,13 @@ class RawServiceMeshRuntime {
962
963
  await this.requireStarted().send(targetNodeRoutingId, parts);
963
964
  return true;
964
965
  }
965
- catch {
966
- return false;
966
+ catch (error) {
967
+ if ((0, runtime_values_1.isZLinkBackendResultError)(error) && error.operation === 'submit') {
968
+ const terminal = (0, submission_result_1.submitToRequestResult)(error.result, error.phase);
969
+ if (terminal === runtime_values_1.RequestResult.NotConnected || terminal === runtime_values_1.RequestResult.NotFound)
970
+ return false;
971
+ }
972
+ throw error;
967
973
  }
968
974
  }
969
975
  }
@@ -43,7 +43,7 @@ export declare class ZLinkActorPacketRelay {
43
43
  readonly deferredResponse?: boolean;
44
44
  readonly actorPacketTarget?: unknown;
45
45
  }>;
46
- relayActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message, signal?: AbortSignal): Promise<boolean>;
46
+ relayActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message): Promise<boolean>;
47
47
  confirmRemoteSessionBinding(actor: ActorRef, sessionNodeRid: RoutingId, sessionRid: RoutingId, signal?: AbortSignal, options?: ZLinkSessionBindingConfirmationOptions): Promise<void>;
48
48
  /**
49
49
  * Session–Actor binding §5·§6 (.NET ZLinkSessionActorCoordinator rule): a
@@ -51,7 +51,7 @@ export declare class ZLinkActorPacketRelay {
51
51
  * same install a remote command 38 uses, so relocation seals and carries it.
52
52
  */
53
53
  private installSameNodeSessionBinding;
54
- relayRemoteActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message, signal?: AbortSignal): Promise<boolean>;
54
+ relayRemoteActorPacket(actor: ZLinkSessionActor, frameHeader: ZLinkStreamFrameHeader, payload: Message): Promise<boolean>;
55
55
  notifyRemoteActorDisconnected(actorId: string, remoteTarget: ZLinkRemoteBoundSessionTarget | ZLinkRemoteActorPacketTarget, signal?: AbortSignal, bindingActorRef?: ActorRef): Promise<void>;
56
56
  private requireCurrentRemoteBinding;
57
57
  private requestRemoteTarget;
@@ -273,11 +273,11 @@ class ZLinkActorPacketRelay {
273
273
  }
274
274
  }
275
275
  }
276
- async relayActorPacket(actor, frameHeader, payload, signal) {
277
- if (await this.relayRemoteActorPacket(actor, frameHeader, payload, signal)) {
276
+ async relayActorPacket(actor, frameHeader, payload) {
277
+ if (await this.relayRemoteActorPacket(actor, frameHeader, payload)) {
278
278
  return true;
279
279
  }
280
- return this.relayLocalActorPacket(actor, frameHeader, payload, signal);
280
+ return this.relayLocalActorPacket(actor, frameHeader, payload);
281
281
  }
282
282
  async confirmRemoteSessionBinding(actor, sessionNodeRid, sessionRid, signal, options) {
283
283
  const target = this.targets.targetForActorRef(actor);
@@ -349,7 +349,7 @@ class ZLinkActorPacketRelay {
349
349
  bindingGeneration: binding.bindingGeneration
350
350
  });
351
351
  }
352
- async relayRemoteActorPacket(actor, frameHeader, payload, signal) {
352
+ async relayRemoteActorPacket(actor, frameHeader, payload) {
353
353
  const streamRuntime = this.options.streamBindingRuntime();
354
354
  const responseTarget = await streamRuntime.captureBoundSessionResponseTarget(actor);
355
355
  const localNode = this.options.spotNodeRuntime()?.primaryMeshNode;
@@ -419,7 +419,7 @@ class ZLinkActorPacketRelay {
419
419
  if ((frameHeader.kind === protocol_1.ZLinkStreamMessageKind.Send || frameHeader.requestSeq === undefined) &&
420
420
  remoteAddress.spotKind === contracts_1.ZLinkSpotKind.Entry &&
421
421
  this.options.routeTransport.submit !== undefined) {
422
- const result = await this.options.routeTransport.submit(remoteAddress.routerChannelId, String(remoteAddress.targetNodeRid), actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET, request, signal);
422
+ const result = await this.options.routeTransport.submit(remoteAddress.routerChannelId, String(remoteAddress.targetNodeRid), actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET, request);
423
423
  if (result.status !== submission_result_1.ZLinkSubmitStatus.Submitted) {
424
424
  throw new Error(`Actor '${actor.actorId}' remote node relay was not admitted.`);
425
425
  }
@@ -427,8 +427,7 @@ class ZLinkActorPacketRelay {
427
427
  }
428
428
  if (frameHeader.kind === protocol_1.ZLinkStreamMessageKind.Send || frameHeader.requestSeq === undefined) {
429
429
  await this.options.routeTransport.sendToSpot(remoteAddress, request, {
430
- packetName: actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET,
431
- signal
430
+ packetName: actors_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET
432
431
  });
433
432
  return true;
434
433
  }
@@ -438,7 +437,7 @@ class ZLinkActorPacketRelay {
438
437
  throw new Error(`Remote actor packet relay reply was empty for '${actor.actorId}'.`);
439
438
  }
440
439
  return JSON.parse(parts[0].getString('utf8'));
441
- }, signal);
440
+ });
442
441
  const actorPacketTarget = this.targets.decodeFromWire(reply.actorPacketTarget);
443
442
  const currentStoredRoute = await streamRuntime.sessionRouteFence(actor.actorId);
444
443
  const currentAggregateRoute = aggregateOwner === undefined ? undefined : await aggregateOwner.committedRoute(actor.actorId);
@@ -526,8 +525,7 @@ class ZLinkActorPacketRelay {
526
525
  }
527
526
  return (0, actor_routed_json_request_1.requestRoutedJsonReply)(this.options.routeTransport, withDefaultSpotKind(target), request, { timeoutMs: this.options.requestTimeoutMs, signal }, unavailableMessage, decodeReply);
528
527
  }
529
- async relayLocalActorPacket(actor, frameHeader, payload, signal) {
530
- void signal;
528
+ async relayLocalActorPacket(actor, frameHeader, payload) {
531
529
  const state = this.options.actorManager()?.getState(actor.actorId);
532
530
  const spotId = state?.spotId;
533
531
  const hasActiveSpot = spotId !== undefined && this.options.spotManager()?.hasActiveSpot(spotId) === true;
@@ -70,7 +70,6 @@ const user_spot_creation_coordinator_1 = require("./user-spot-creation-coordinat
70
70
  const HOST_SHUTDOWN_POLL_INTERVAL_MS = 100;
71
71
  const HANDOFF_ACCEPTANCE_POLL_INTERVAL_MS = 10;
72
72
  const DEFAULT_HOST_CONTROL_TIMEOUT_MS = 30_000;
73
- const LEGACY_MESH_SEND_TIMEOUT_MS = 1000;
74
73
  class ZLinkFrameworkRuntimeHost {
75
74
  options;
76
75
  backendAdapterFactory;
@@ -168,16 +167,6 @@ class ZLinkFrameworkRuntimeHost {
168
167
  this.fanoutRuntime = new topology_runtime_projections_1.ZLinkFanoutRuntimeProjection(() => this.channelRuntime, () => this.runtimeState);
169
168
  this.meshRouters = new mesh_router_resolver_1.MeshRouterResolver(options.registration);
170
169
  this.spotRouterChannelIdForMesh = this.meshRouters.spotRouterChannelIdByMesh();
171
- const sendTimeoutMsForSpotMesh = (meshName) => options.registration.spotNodes.get(meshName)?.router?.sendTimeoutMs ??
172
- LEGACY_MESH_SEND_TIMEOUT_MS;
173
- const sendTimeoutMsForSpotRouteChannel = (routeChannelId) => {
174
- const routeChannel = options.registration.routeChannelOptions.get(routeChannelId);
175
- if (routeChannel !== undefined) {
176
- return routeChannel.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS;
177
- }
178
- return sendTimeoutMsForSpotMesh(routeChannelId);
179
- };
180
- const defaultSpotSendTimeoutMs = Math.max(LEGACY_MESH_SEND_TIMEOUT_MS, ...[...options.registration.spotNodes.values()].map((node) => node.router?.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS), ...[...options.registration.routeChannelOptions.values()].map((route) => route.sendTimeoutMs ?? LEGACY_MESH_SEND_TIMEOUT_MS));
181
170
  this.routeTransport = new channels_1.ZLinkRuntimeRouteTransport(() => this.channelRuntime, (routerChannelId) => this.meshRouters.canUseRouterChannel(routerChannelId), () => this.spotNodeRuntime, { serializers: options.registration.messageSerializers }, (meshName, targetNodeRid) => this.meshRouters.classifyManualNodeTarget(meshName, targetNodeRid), (meshName, sourceNodeRid, parts) => this.submitLocalMeshRoute(meshName, sourceNodeRid, parts), this.metrics, () => this.flowCreationEnabled(), () => this.createDispatchErrorReporter(this.runtimeOrPreStartErrorSink).flow);
182
171
  this.spotAddressTransport = new spot_address_transport_1.ZLinkHostSpotAddressTransport({
183
172
  resolver: () => this.createLocationSpotRouteResolver(),
@@ -190,9 +179,6 @@ class ZLinkFrameworkRuntimeHost {
190
179
  completions: (meshName) => this.spotNodeRuntime?.meshCompletionTable(meshName),
191
180
  codecs: { serializers: options.registration.messageSerializers },
192
181
  defaultRequestTimeoutMs: options.registration.requestTimeoutMs ?? Registration_1.DEFAULT_REQUEST_TIMEOUT_MS,
193
- defaultSendTimeoutMs: defaultSpotSendTimeoutMs,
194
- sendTimeoutMsForMesh: sendTimeoutMsForSpotMesh,
195
- sendTimeoutMsForRouteChannel: sendTimeoutMsForSpotRouteChannel,
196
182
  dispatchErrors: this.createDispatchErrorReporter(this.runtimeOrPreStartErrorSink)
197
183
  });
198
184
  this.locationOwner = new location_runtime_owner_1.ZLinkLocationRuntimeOwner({
@@ -233,7 +219,7 @@ class ZLinkFrameworkRuntimeHost {
233
219
  ? Promise.resolve()
234
220
  : this.boundSessionRelay.actorPackets.confirmRemoteSessionBinding(actor, sessionNode.status().routingId, sessionRid, signal, options);
235
221
  },
236
- relay: (actor, header, payload, signal) => this.boundSessionRelay.actorPackets.relayActorPacket(actor, header, payload, signal),
222
+ relay: (actor, header, payload) => this.boundSessionRelay.actorPackets.relayActorPacket(actor, header, payload),
237
223
  notifyDisconnected: (actor, signal) => this.boundSessionRelay.actorPackets.notifyBoundActorDisconnected(actor, signal)
238
224
  });
239
225
  this.actorHandoff = new actors_1.ZLinkActorHandoffCoordinator({
@@ -420,7 +420,7 @@ class ZLinkRemoteBoundSessionRelay {
420
420
  const actorRef = currentActorRef(state, fallbackActorRef);
421
421
  const remoteTarget = fallbackBoundSessionTarget ?? state?.remoteBoundSessionTarget;
422
422
  if (remoteTarget !== undefined) {
423
- await this.sendRemoteBoundSessionResponse(remoteTarget, actor.context.actorId, packetName, requestSeq, response, replyOptions, signal);
423
+ await this.sendRemoteBoundSessionResponse(remoteTarget, actor.context.actorId, packetName, requestSeq, response, replyOptions);
424
424
  return;
425
425
  }
426
426
  if (actorRef === undefined) {
@@ -444,7 +444,7 @@ class ZLinkRemoteBoundSessionRelay {
444
444
  const actorRef = currentActorRef(state, fallbackActorRef) ?? this.options.destroyedActorRefs.get(actorId);
445
445
  const remoteTarget = fallbackBoundSessionTarget ?? state?.remoteBoundSessionTarget;
446
446
  if (remoteTarget !== undefined) {
447
- await this.sendRemoteBoundSessionError(remoteTarget, actorId, packetName, requestSeq, error, metadata, signal);
447
+ await this.sendRemoteBoundSessionError(remoteTarget, actorId, packetName, requestSeq, error, metadata);
448
448
  return;
449
449
  }
450
450
  if (actorRef === undefined) {
@@ -458,7 +458,7 @@ class ZLinkRemoteBoundSessionRelay {
458
458
  .streamBindingRuntime()
459
459
  .sendNativeBoundSessionError(actorSessionNode, actorRef, packetName, requestSeq, error, metadata, signal);
460
460
  }
461
- async sendRemoteBoundSessionResponse(target, actorId, packetName, requestSeq, message, replyOptions, signal) {
461
+ async sendRemoteBoundSessionResponse(target, actorId, packetName, requestSeq, message, replyOptions) {
462
462
  const actorPacketTarget = (0, actor_packet_relay_wire_1.encodeRemoteActorPacketTarget)(this.options.actorPacketTargetForState(actorId));
463
463
  await this.sendRemoteBoundSessionControl(target, (0, bound_session_wire_1.encodeRemoteBoundSessionResponsePayload)({
464
464
  actorId,
@@ -468,9 +468,9 @@ class ZLinkRemoteBoundSessionRelay {
468
468
  metadata: replyOptions.metadata,
469
469
  compressPayload: replyOptions.compressPayload,
470
470
  actorPacketTarget
471
- }), signal);
471
+ }));
472
472
  }
473
- async sendRemoteBoundSessionError(target, actorId, packetName, requestSeq, error, metadata, signal) {
473
+ async sendRemoteBoundSessionError(target, actorId, packetName, requestSeq, error, metadata) {
474
474
  await this.sendRemoteBoundSessionControl(target, (0, bound_session_wire_1.encodeRemoteBoundSessionErrorPayload)({
475
475
  actorId,
476
476
  boundPacketName: packetName,
@@ -478,9 +478,9 @@ class ZLinkRemoteBoundSessionRelay {
478
478
  error,
479
479
  metadata,
480
480
  actorPacketTarget: (0, actor_packet_relay_wire_1.encodeRemoteActorPacketTarget)(this.options.actorPacketTargetForState(actorId))
481
- }), signal);
481
+ }));
482
482
  }
483
- async sendRemoteBoundSessionControl(target, payload, signal) {
483
+ async sendRemoteBoundSessionControl(target, payload) {
484
484
  const packetName = payload.packetName;
485
485
  if (typeof packetName !== 'string') {
486
486
  throw new Error('Remote bound session control payload does not declare a packet name.');
@@ -489,7 +489,7 @@ class ZLinkRemoteBoundSessionRelay {
489
489
  if (submit === undefined) {
490
490
  throw new Error('Remote bound session node-direct transport is not available.');
491
491
  }
492
- const result = await submit.call(this.options.routeTransport, target.routerChannelId, String(target.targetNodeRid), packetName, payload, signal);
492
+ const result = await submit.call(this.options.routeTransport, target.routerChannelId, String(target.targetNodeRid), packetName, payload);
493
493
  if (result.status !== submission_result_1.ZLinkSubmitStatus.Submitted) {
494
494
  throw new Error(`Remote bound session control '${packetName}' was not admitted` +
495
495
  ` on '${target.routerChannelId}' for '${String(target.targetNodeRid)}'` +
@@ -15,12 +15,6 @@ export interface ZLinkHostSpotAddressTransportOptions {
15
15
  readonly completions: (meshName: string) => ZLinkMeshCompletionTable | undefined;
16
16
  readonly codecs?: ZLinkChannelEnvelopeCodecRegistry;
17
17
  readonly defaultRequestTimeoutMs: number;
18
- /** Internal one-way deadline policy; public calls do not expose this option. */
19
- readonly defaultSendTimeoutMs?: number;
20
- /** Resolves the send timeout for a configured Spot Mesh. */
21
- readonly sendTimeoutMsForMesh?: (meshName: string) => number;
22
- /** Resolves the send timeout for a resolved Spot route channel. */
23
- readonly sendTimeoutMsForRouteChannel?: (routeChannelId: string) => number;
24
18
  readonly dispatchErrors?: ZLinkDispatchErrorReporter;
25
19
  }
26
20
  export declare function hasObjectClientCapability(role: 'none' | 'client' | 'server' | undefined): boolean;
@@ -28,7 +22,7 @@ export declare function hasObjectClientCapability(role: 'none' | 'client' | 'ser
28
22
  export declare class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTransport {
29
23
  private readonly options;
30
24
  constructor(options: ZLinkHostSpotAddressTransportOptions);
31
- sendToSpotAddress(spotId: RoutingId, message: unknown, call: ZLinkSpotAddressCallOptions): Promise<ZLinkSubmitResult>;
25
+ sendToSpotAddress(spotId: RoutingId, message: unknown, call: Omit<ZLinkSpotAddressCallOptions, 'timeoutMs' | 'signal'>): Promise<ZLinkSubmitResult>;
32
26
  private sendToSpotAddressScoped;
33
27
  requestToSpotAddress<TReply = unknown>(spotId: RoutingId, request: unknown, call: ZLinkSpotAddressCallOptions): Promise<TReply>;
34
28
  private requestToSpotAddressScoped;
@@ -38,8 +32,6 @@ export declare class ZLinkHostSpotAddressTransport implements ZLinkSpotAddressTr
38
32
  private traceInstanceAddress;
39
33
  private resolveExisting;
40
34
  private selectMissingTarget;
41
- private sendTimeoutMsForMesh;
42
- private sendTimeoutMsForRouteChannel;
43
35
  private validateExisting;
44
36
  private encode;
45
37
  private encodeAtDeadline;
@@ -29,79 +29,60 @@ class ZLinkHostSpotAddressTransport {
29
29
  return (0, flow_context_1.runWithOutboundFlow)(this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true, () => this.sendToSpotAddressScoped(spotId, message, call));
30
30
  }
31
31
  async sendToSpotAddressScoped(spotId, message, call) {
32
- const timeoutMs = initialSendTimeoutMs(this.options, call);
33
- const deadline = createSpotAddressDeadline(timeoutMs, call.signal);
34
- try {
35
- const existing = await this.resolveExisting(spotId, deadline.signal);
36
- deadline.requireRemaining();
37
- if (existing !== undefined) {
38
- this.validateExisting(existing, call);
39
- deadline.setOwnerTimeout(this.sendTimeoutMsForRouteChannel(existing.routerChannelId));
40
- try {
41
- const result = await (0, abort_1.awaitWithAbort)(this.options.routed.sendToSpot(existing, message, {
42
- instanceSpot: call.instanceSpot,
43
- timeoutMs: deadline.requireRemaining(),
44
- signal: deadline.signal,
45
- metadata: call.metadata
46
- }), deadline.signal);
47
- if (result.status === submission_result_1.ZLinkSubmitStatus.Submitted) {
48
- this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Sent, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid);
49
- }
50
- else {
51
- this.traceInstanceAddress(submitResultFlowOutcome(result.status), ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid, submitResultReason(result.status));
52
- }
53
- if (result.status === submission_result_1.ZLinkSubmitStatus.TargetNotFound ||
54
- result.status === submission_result_1.ZLinkSubmitStatus.RouteNotConnected) {
55
- this.options.resolver()?.invalidate?.(spotId);
56
- }
57
- return result;
32
+ const activationDeadlineUnixMs = BigInt(Math.round(Date.now() + this.options.defaultRequestTimeoutMs));
33
+ const existing = await this.resolveExisting(spotId);
34
+ if (existing !== undefined) {
35
+ this.validateExisting(existing, call);
36
+ try {
37
+ const result = await this.options.routed.sendToSpot(existing, message, {
38
+ instanceSpot: call.instanceSpot,
39
+ metadata: call.metadata
40
+ });
41
+ if (result.status === submission_result_1.ZLinkSubmitStatus.Submitted) {
42
+ this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Sent, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid);
58
43
  }
59
- catch (error) {
60
- if (isSpotRouteRefreshError(error)) {
61
- this.options.resolver()?.invalidate?.(spotId);
62
- }
63
- const reason = addressedInstanceErrorReason(error);
64
- this.traceInstanceAddress(reason === ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.Backpressure
65
- ? ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Backpressured
66
- : ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid, reason);
67
- throw error;
44
+ else {
45
+ this.traceInstanceAddress(submitResultFlowOutcome(result.status), ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid, submitResultReason(result.status));
68
46
  }
47
+ if (result.status === submission_result_1.ZLinkSubmitStatus.TargetNotFound ||
48
+ result.status === submission_result_1.ZLinkSubmitStatus.RouteNotConnected) {
49
+ this.options.resolver()?.invalidate?.(spotId);
50
+ }
51
+ return result;
69
52
  }
70
- if (!call.instanceSpot) {
71
- return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
72
- }
73
- const selected = this.selectMissingTarget(spotId, call);
74
- if (selected.kind === 'unsupported') {
75
- this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.StaleTarget);
76
- return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
77
- }
78
- if (selected.kind === 'capacity') {
79
- const error = missingInstancePlacementCapacity(spotId, call.instanceSpotType);
80
- this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Backpressured, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.Backpressure);
53
+ catch (error) {
54
+ if (isSpotRouteRefreshError(error)) {
55
+ this.options.resolver()?.invalidate?.(spotId);
56
+ }
57
+ const reason = addressedInstanceErrorReason(error);
58
+ this.traceInstanceAddress(reason === ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.Backpressure
59
+ ? ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Backpressured
60
+ : ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, existing.routerChannelId, existing.stableType, existing.targetNodeRid, reason);
81
61
  throw error;
82
62
  }
83
- if (selected.kind === 'unavailable') {
84
- this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.StaleTarget);
85
- return { status: submission_result_1.ZLinkSubmitStatus.RouteNotConnected };
86
- }
87
- deadline.setOwnerTimeout(this.sendTimeoutMsForMesh(selected.meshName));
88
- const encoded = this.encode(3 /* ZLinkChannelMessageKind.Command */, selected.meshName, message);
89
- const sourceSpotId = call.sourceSpot === undefined ? undefined : String(call.sourceSpot.routingId);
90
- const mapped = (0, submission_result_1.classifySubmitResult)(await (0, abort_1.awaitWithAbort)(selected.node.sendToMissingInstanceSpot(selected.target, encoded, BigInt(deadline.deadlineUnixMs), sourceSpotId, call.metadata), deadline.signal), 'Instance Spot submission');
91
- this.traceInstanceAddress(submitResultFlowOutcome(mapped.status), ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, selected.meshName, selected.target.stableType, selected.target.targetNodeRid, mapped.status === submission_result_1.ZLinkSubmitStatus.Submitted
92
- ? undefined
93
- : submitResultReason(mapped.status));
94
- return mapped;
95
63
  }
96
- catch (error) {
97
- if (deadline.expired()) {
98
- return { status: submission_result_1.ZLinkSubmitStatus.TimedOut };
99
- }
64
+ if (!call.instanceSpot) {
65
+ return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
66
+ }
67
+ const selected = this.selectMissingTarget(spotId, call);
68
+ if (selected.kind === 'unsupported') {
69
+ this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.StaleTarget);
70
+ return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
71
+ }
72
+ if (selected.kind === 'capacity') {
73
+ const error = missingInstancePlacementCapacity(spotId, call.instanceSpotType);
74
+ this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Backpressured, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.Backpressure);
100
75
  throw error;
101
76
  }
102
- finally {
103
- deadline.close();
77
+ if (selected.kind === 'unavailable') {
78
+ this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.StaleTarget);
79
+ return { status: submission_result_1.ZLinkSubmitStatus.RouteNotConnected };
104
80
  }
81
+ const encoded = this.encode(3 /* ZLinkChannelMessageKind.Command */, selected.meshName, message);
82
+ const sourceSpotId = call.sourceSpot === undefined ? undefined : String(call.sourceSpot.routingId);
83
+ const mapped = (0, submission_result_1.classifySubmitResult)(await selected.node.sendToMissingInstanceSpot(selected.target, encoded, activationDeadlineUnixMs, sourceSpotId, call.metadata), 'Instance Spot submission');
84
+ this.traceInstanceAddress(submitResultFlowOutcome(mapped.status), ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, selected.meshName, selected.target.stableType, selected.target.targetNodeRid, mapped.status === submission_result_1.ZLinkSubmitStatus.Submitted ? undefined : submitResultReason(mapped.status));
85
+ return mapped;
105
86
  }
106
87
  requestToSpotAddress(spotId, request, call) {
107
88
  return (0, flow_context_1.runWithOutboundFlow)(this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true, () => this.requestToSpotAddressScoped(spotId, request, call));
@@ -315,16 +296,6 @@ class ZLinkHostSpotAddressTransport {
315
296
  return { kind: 'unsupported' };
316
297
  return { kind: 'unavailable' };
317
298
  }
318
- sendTimeoutMsForMesh(meshName) {
319
- return (this.options.sendTimeoutMsForMesh?.(meshName) ??
320
- this.options.defaultSendTimeoutMs ??
321
- this.options.defaultRequestTimeoutMs);
322
- }
323
- sendTimeoutMsForRouteChannel(routeChannelId) {
324
- return (this.options.sendTimeoutMsForRouteChannel?.(routeChannelId) ??
325
- this.options.defaultSendTimeoutMs ??
326
- this.options.defaultRequestTimeoutMs);
327
- }
328
299
  validateExisting(target, call) {
329
300
  if (!call.instanceSpot)
330
301
  return;
@@ -436,17 +407,10 @@ function addressedInstanceErrorReason(error) {
436
407
  }
437
408
  return ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.HandlerException;
438
409
  }
439
- function initialSendTimeoutMs(options, call) {
440
- return call.initialMeshName === undefined
441
- ? (options.defaultSendTimeoutMs ?? options.defaultRequestTimeoutMs)
442
- : (options.sendTimeoutMsForMesh?.(call.initialMeshName) ??
443
- options.defaultSendTimeoutMs ??
444
- options.defaultRequestTimeoutMs);
445
- }
446
410
  function createSpotAddressDeadline(timeoutMs, parent) {
447
411
  const startedAtMs = performance.now();
448
412
  const startedAtUnixMs = Date.now();
449
- let deadlineMs = startedAtMs + Math.max(0, timeoutMs);
413
+ const deadlineMs = startedAtMs + Math.max(0, timeoutMs);
450
414
  const controller = new AbortController();
451
415
  let expired = false;
452
416
  let timeout;
@@ -475,10 +439,6 @@ function createSpotAddressDeadline(timeoutMs, parent) {
475
439
  return Math.round(startedAtUnixMs + (deadlineMs - startedAtMs));
476
440
  },
477
441
  signal: controller.signal,
478
- setOwnerTimeout(ownerTimeoutMs) {
479
- deadlineMs = startedAtMs + Math.max(0, ownerTimeoutMs);
480
- arm();
481
- },
482
442
  requireRemaining() {
483
443
  const remainingMs = deadlineMs - performance.now();
484
444
  if (remainingMs <= 0) {
@@ -859,7 +859,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
859
859
  this.provider.read(leaseKey, signal)
860
860
  ]);
861
861
  const descriptor = liveTargetDescriptor(descriptorRead, leaseRead, request.target);
862
- if (descriptor === undefined) {
862
+ if (descriptor === undefined || descriptor.state !== contracts_1.ZLinkFrameworkRuntimeState.Serving) {
863
863
  return { kind: 'conflict', current: { kind: 'missing', storeNow: current.storeNow } };
864
864
  }
865
865
  const [capacityRead, objectGenerationRead, authorityOwnerGenerationRead] = await Promise.all([
@@ -1042,9 +1042,11 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1042
1042
  !sameCreationTarget(record.snapshot, request.target)) {
1043
1043
  return { kind: 'stale' };
1044
1044
  }
1045
+ const descriptorKey = meshKey(request.target.meshName, request.target.nodeRid);
1045
1046
  const leaseKey = ownerKey(request.target.owner.ownerId);
1046
1047
  const capacityRowKey = capacityKey(request.target.meshName, String(request.target.nodeRid));
1047
- const [leaseRead, capacityRead] = await Promise.all([
1048
+ const [descriptorRead, leaseRead, capacityRead] = await Promise.all([
1049
+ this.provider.read(descriptorKey, signal),
1048
1050
  this.provider.read(leaseKey, signal),
1049
1051
  this.provider.read(capacityRowKey, signal)
1050
1052
  ]);
@@ -1054,7 +1056,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1054
1056
  // rather than read the absence as expiry.
1055
1057
  throw new Error('Location Store owner lease record is invalid.');
1056
1058
  }
1057
- if (!sameLiveOwner(leaseRead, record.snapshot))
1059
+ if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined)
1058
1060
  return { kind: 'stale' };
1059
1061
  const capacity = capacityRead.kind === 'missing'
1060
1062
  ? emptyCapacityRecord()
@@ -1062,6 +1064,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1062
1064
  const result = await this.provider.write({
1063
1065
  conditions: [
1064
1066
  { kind: 'version', key: rowKey, expected: current.value.version },
1067
+ versionCondition(descriptorKey, descriptorRead),
1065
1068
  leaseValueCondition(leaseKey, {
1066
1069
  ownerId: record.snapshot.ownerId,
1067
1070
  leaseGeneration: record.snapshot.ownerLeaseGeneration
@@ -2843,7 +2846,6 @@ function liveTargetDescriptor(descriptorRead, leaseRead, target) {
2843
2846
  descriptor.ownerId === target.owner.ownerId &&
2844
2847
  descriptor.leaseGeneration === target.owner.leaseGeneration &&
2845
2848
  descriptor.objectRole === contracts_1.ZLinkObjectRole.Server &&
2846
- descriptor.state === contracts_1.ZLinkFrameworkRuntimeState.Serving &&
2847
2849
  lease.ownerId === target.owner.ownerId &&
2848
2850
  BigInt(lease.leaseGeneration) === target.owner.leaseGeneration &&
2849
2851
  leaseRead.value.expiresAt !== undefined &&
@@ -0,0 +1,3 @@
1
+ export declare function remainingRequestTimeout(operation: string, deadlineMs: number | undefined): number | undefined;
2
+ /** Bounds caller waiting across outbound admission and reply; late completions stay observed. */
3
+ export declare function waitRequestReply<T>(reply: Promise<T>, operation: string, deadlineMs: number | undefined, signal?: AbortSignal, endWait?: () => void, discardLateReply?: (reply: T) => void): Promise<T>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.remainingRequestTimeout = remainingRequestTimeout;
4
+ exports.waitRequestReply = waitRequestReply;
5
+ const abort_1 = require("../abort");
6
+ const framework_errors_internal_1 = require("../framework-errors-internal");
7
+ function remainingRequestTimeout(operation, deadlineMs) {
8
+ if (deadlineMs === undefined)
9
+ return undefined;
10
+ const remaining = deadlineMs - performance.now();
11
+ if (remaining <= 0) {
12
+ throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.DeadlineExceeded, `${operation} exceeded its deadline.`);
13
+ }
14
+ return Math.max(1, Math.ceil(remaining));
15
+ }
16
+ /** Bounds caller waiting across outbound admission and reply; late completions stay observed. */
17
+ async function waitRequestReply(reply, operation, deadlineMs, signal, endWait, discardLateReply) {
18
+ let timer;
19
+ let waiting = reply;
20
+ if (deadlineMs !== undefined) {
21
+ const timeout = new Promise((_resolve, reject) => {
22
+ const remaining = remainingRequestTimeout(operation, deadlineMs);
23
+ timer = setTimeout(() => reject((0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.DeadlineExceeded, `${operation} exceeded its deadline.`)), remaining);
24
+ });
25
+ waiting = Promise.race([reply, timeout]);
26
+ }
27
+ try {
28
+ return await (0, abort_1.awaitWithAbort)(waiting, signal);
29
+ }
30
+ catch (error) {
31
+ endWait?.();
32
+ if (discardLateReply !== undefined)
33
+ void reply.then(discardLateReply, () => undefined);
34
+ throw error;
35
+ }
36
+ finally {
37
+ clearTimeout(timer);
38
+ }
39
+ }
@@ -10,9 +10,10 @@ export declare enum ZLinkSubmitStatus {
10
10
  export interface ZLinkSubmitResult {
11
11
  readonly status: ZLinkSubmitStatus;
12
12
  }
13
- /** Projects the Core submit result once; phase only determines capacity refusal meaning. */
13
+ /** Projects immediate refusal and pending admission failure from their Core phase. */
14
14
  export declare function submitToRequestResult(result: number, phase: 'submit' | 'completion'): number;
15
15
  export declare function classifySubmitResult(result: number, operation: string, phase?: 'submit' | 'completion'): ZLinkSubmitResult;
16
16
  export declare function requireOneWayCompletion(result: ZLinkSubmitResult, operation: string, notFoundKind?: ZLinkFrameworkInternalErrorKind): void;
17
17
  export declare function requirePublishCompletion(result: ZLinkSubmitResult, operation: string): void;
18
+ export declare function requireClassicFanoutCompletion(result: ZLinkSubmitResult, operation: string): void;
18
19
  export declare function throwAlreadySubmitted(operation: string): never;