@zlink-systems/framework 0.27.0 → 0.29.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 (191) 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 +2 -1
  5. package/dist/contracts/Configuration/Configs.d.ts +0 -1
  6. package/dist/contracts/Configuration/InternalDefaults.d.ts +3 -0
  7. package/dist/contracts/Configuration/InternalDefaults.js +4 -1
  8. package/dist/contracts/Configuration/RegistrationBuilders.js +9 -0
  9. package/dist/contracts/Configuration/RegistrationNormalizers.d.ts +1 -0
  10. package/dist/contracts/Configuration/RegistrationNormalizers.js +16 -0
  11. package/dist/contracts/Configuration/RegistrationTypes.d.ts +3 -5
  12. package/dist/contracts/Configuration/RegistrationValidators.js +0 -2
  13. package/dist/contracts/Spots/Contracts.d.ts +1 -1
  14. package/dist/contracts/Streams/BoundSessionContracts.d.ts +1 -1
  15. package/dist/contracts/Streams/IZLinkSession.d.ts +2 -3
  16. package/dist/contracts/Streams/IZLinkSessionActor.d.ts +2 -2
  17. package/dist/runtime/actors/actor-client.js +7 -10
  18. package/dist/runtime/actors/actor-mailbox.d.ts +2 -2
  19. package/dist/runtime/actors/actor-mailbox.js +2 -2
  20. package/dist/runtime/actors/actor-request-deadline.d.ts +1 -3
  21. package/dist/runtime/actors/actor-request-deadline.js +4 -29
  22. package/dist/runtime/actors/actor-routed-join-transport.d.ts +2 -3
  23. package/dist/runtime/backend/contracts/index.d.ts +1 -4
  24. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -0
  25. package/dist/runtime/backend/node/node-backend-adapter-support.js +35 -4
  26. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  27. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +1 -2
  28. package/dist/runtime/backend/node/node-raw-binding-port.js +10 -27
  29. package/dist/runtime/backend/node/node-raw-mesh-backend.js +1 -3
  30. package/dist/runtime/backend/node/node-socket-backend-adapter.js +1 -1
  31. package/dist/runtime/channels/channel-clients.js +8 -10
  32. package/dist/runtime/channels/channel-envelope.d.ts +1 -1
  33. package/dist/runtime/channels/channel-envelope.js +4 -10
  34. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  35. package/dist/runtime/channels/channel-outbound-operations.js +20 -36
  36. package/dist/runtime/channels/channel-runtime-manager.d.ts +4 -4
  37. package/dist/runtime/channels/channel-runtime-manager.js +8 -8
  38. package/dist/runtime/channels/channel-socket-options.js +0 -10
  39. package/dist/runtime/channels/channel-socket-registry.d.ts +1 -1
  40. package/dist/runtime/channels/channel-socket-registry.js +3 -14
  41. package/dist/runtime/channels/channel-transports.d.ts +10 -14
  42. package/dist/runtime/channels/channel-transports.js +11 -14
  43. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  44. package/dist/runtime/channels/local-spot-route-transport.js +1 -3
  45. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +1 -1
  46. package/dist/runtime/channels/router-socket-spot-route-transport.js +2 -2
  47. package/dist/runtime/channels/source-spot-router.d.ts +1 -1
  48. package/dist/runtime/channels/source-spot-router.js +2 -4
  49. package/dist/runtime/channels/spot-node-route-transport.d.ts +1 -1
  50. package/dist/runtime/channels/spot-node-route-transport.js +2 -3
  51. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +1 -1
  52. package/dist/runtime/channels/spot-route-bridge-transport.js +2 -2
  53. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +2 -4
  54. package/dist/runtime/channels/spot-route-dispatch-strategy.js +11 -12
  55. package/dist/runtime/execution/serial-execution-queue.d.ts +12 -3
  56. package/dist/runtime/execution/serial-execution-queue.js +116 -28
  57. package/dist/runtime/foundation/operation-registry.d.ts +3 -2
  58. package/dist/runtime/foundation/operation-registry.js +5 -1
  59. package/dist/runtime/foundation/raw-service-mesh-runtime.js +17 -11
  60. package/dist/runtime/foundation/service-authority-payload-codec.d.ts +0 -2
  61. package/dist/runtime/foundation/service-authority-payload-codec.js +0 -43
  62. package/dist/runtime/foundation/service-stateful-registry.d.ts +4 -3
  63. package/dist/runtime/foundation/service-stateful-registry.js +5 -2
  64. package/dist/runtime/foundation/service-stateful-runtime.d.ts +1 -8
  65. package/dist/runtime/foundation/service-stateful-runtime.js +78 -126
  66. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +0 -11
  67. package/dist/runtime/foundation/service-stateful-wire-codec.js +1 -23
  68. package/dist/runtime/foundation/service-topology-registry.d.ts +5 -0
  69. package/dist/runtime/foundation/service-topology-registry.js +16 -17
  70. package/dist/runtime/host/actor-packet-relay.d.ts +2 -2
  71. package/dist/runtime/host/actor-packet-relay.js +8 -10
  72. package/dist/runtime/host/index.js +1 -15
  73. package/dist/runtime/host/instance-activation-authority.d.ts +0 -1
  74. package/dist/runtime/host/instance-activation-authority.js +46 -97
  75. package/dist/runtime/host/remote-bound-session-relay.js +8 -8
  76. package/dist/runtime/host/spot-address-transport.d.ts +1 -9
  77. package/dist/runtime/host/spot-address-transport.js +47 -87
  78. package/dist/runtime/host/stateful-authority-route-runtime.d.ts +1 -0
  79. package/dist/runtime/host/stateful-authority-route-runtime.js +17 -9
  80. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  81. package/dist/runtime/locations/in-memory-authority-store.d.ts +2 -0
  82. package/dist/runtime/locations/in-memory-authority-store.js +22 -8
  83. package/dist/runtime/locations/in-memory-location-store.d.ts +1 -0
  84. package/dist/runtime/locations/in-memory-location-store.js +3 -0
  85. package/dist/runtime/locations/internal-store-contracts.d.ts +1 -1
  86. package/dist/runtime/locations/location-store-repository.d.ts +1 -0
  87. package/dist/runtime/locations/location-store-repository.js +98 -53
  88. package/dist/runtime/messaging/request-deadline.d.ts +3 -0
  89. package/dist/runtime/messaging/request-deadline.js +39 -0
  90. package/dist/runtime/messaging/submission-result.d.ts +2 -1
  91. package/dist/runtime/messaging/submission-result.js +11 -4
  92. package/dist/runtime/spots/spot-outbound.d.ts +3 -5
  93. package/dist/runtime/spots/spot-outbound.js +12 -15
  94. package/dist/runtime/spots/spot-serial-executor.js +4 -1
  95. package/dist/runtime/spots/spot-serial-turn-executor.d.ts +3 -0
  96. package/dist/runtime/spots/spot-serial-turn-executor.js +5 -0
  97. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -2
  98. package/dist/runtime/streams/bound-actor-relay-sender.js +14 -14
  99. package/dist/runtime/streams/bound-session-service.js +1 -1
  100. package/dist/runtime/streams/index.d.ts +2 -3
  101. package/dist/runtime/streams/index.js +6 -5
  102. package/dist/runtime/streams/managed-stream.d.ts +2 -2
  103. package/dist/runtime/streams/managed-stream.js +3 -5
  104. package/dist/runtime/streams/native-fallback-bound-session.js +13 -16
  105. package/dist/runtime/streams/protocol.js +0 -9
  106. package/dist/runtime/streams/session-calls.d.ts +5 -7
  107. package/dist/runtime/streams/session-calls.js +6 -23
  108. package/dist/runtime/streams/session-context.d.ts +4 -8
  109. package/dist/runtime/streams/session-context.js +3 -32
  110. package/dist/runtime/streams/session-serial-executor.d.ts +0 -1
  111. package/dist/runtime/streams/session-serial-executor.js +0 -3
  112. package/dist/runtime/streams/stream-message-utils.d.ts +0 -1
  113. package/dist/runtime/streams/stream-message-utils.js +0 -20
  114. package/dist/runtime/streams/stream-session-runtime.d.ts +6 -3
  115. package/dist/runtime/streams/stream-session-runtime.js +40 -85
  116. package/package.json +3 -3
  117. package/src/contracts/Actors/ZLinkActorClient.ts +1 -1
  118. package/src/contracts/Channels/Calls.ts +1 -1
  119. package/src/contracts/Configuration/Builders.ts +2 -1
  120. package/src/contracts/Configuration/Configs.ts +0 -1
  121. package/src/contracts/Configuration/InternalDefaults.ts +4 -0
  122. package/src/contracts/Configuration/RegistrationBuilders.ts +13 -3
  123. package/src/contracts/Configuration/RegistrationNormalizers.ts +25 -0
  124. package/src/contracts/Configuration/RegistrationTypes.ts +3 -5
  125. package/src/contracts/Configuration/RegistrationValidators.ts +0 -4
  126. package/src/contracts/Spots/Contracts.ts +1 -1
  127. package/src/contracts/Streams/BoundSessionContracts.ts +1 -1
  128. package/src/contracts/Streams/IZLinkSession.ts +2 -3
  129. package/src/contracts/Streams/IZLinkSessionActor.ts +2 -6
  130. package/src/runtime/actors/actor-client.ts +9 -15
  131. package/src/runtime/actors/actor-mailbox.ts +7 -2
  132. package/src/runtime/actors/actor-request-deadline.ts +4 -49
  133. package/src/runtime/actors/actor-routed-join-transport.ts +3 -5
  134. package/src/runtime/backend/contracts/index.ts +1 -8
  135. package/src/runtime/backend/node/node-backend-adapter-support.ts +45 -5
  136. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +0 -2
  137. package/src/runtime/backend/node/node-raw-binding-port.ts +15 -41
  138. package/src/runtime/backend/node/node-raw-mesh-backend.ts +1 -7
  139. package/src/runtime/backend/node/node-socket-backend-adapter.ts +1 -1
  140. package/src/runtime/channels/channel-clients.ts +9 -19
  141. package/src/runtime/channels/channel-envelope.ts +16 -28
  142. package/src/runtime/channels/channel-outbound-operations.ts +36 -38
  143. package/src/runtime/channels/channel-runtime-manager.ts +6 -28
  144. package/src/runtime/channels/channel-socket-options.ts +0 -13
  145. package/src/runtime/channels/channel-socket-registry.ts +3 -17
  146. package/src/runtime/channels/channel-transports.ts +7 -33
  147. package/src/runtime/channels/local-spot-route-transport.ts +1 -5
  148. package/src/runtime/channels/router-socket-spot-route-transport.ts +2 -6
  149. package/src/runtime/channels/source-spot-router.ts +2 -9
  150. package/src/runtime/channels/spot-node-route-transport.ts +2 -7
  151. package/src/runtime/channels/spot-route-bridge-transport.ts +5 -12
  152. package/src/runtime/channels/spot-route-dispatch-strategy.ts +11 -30
  153. package/src/runtime/execution/serial-execution-queue.ts +117 -29
  154. package/src/runtime/foundation/operation-registry.ts +16 -9
  155. package/src/runtime/foundation/raw-service-mesh-runtime.ts +17 -14
  156. package/src/runtime/foundation/service-authority-payload-codec.ts +0 -46
  157. package/src/runtime/foundation/service-stateful-registry.ts +10 -5
  158. package/src/runtime/foundation/service-stateful-runtime.ts +103 -181
  159. package/src/runtime/foundation/service-stateful-wire-codec.ts +0 -25
  160. package/src/runtime/foundation/service-topology-registry.ts +30 -20
  161. package/src/runtime/host/actor-packet-relay.ts +8 -15
  162. package/src/runtime/host/index.ts +2 -26
  163. package/src/runtime/host/instance-activation-authority.ts +58 -125
  164. package/src/runtime/host/remote-bound-session-relay.ts +8 -16
  165. package/src/runtime/host/spot-address-transport.ts +107 -166
  166. package/src/runtime/host/stateful-authority-route-runtime.ts +22 -9
  167. package/src/runtime/locations/domain-store-contract.ts +5 -0
  168. package/src/runtime/locations/in-memory-authority-store.ts +42 -8
  169. package/src/runtime/locations/in-memory-location-store.ts +8 -0
  170. package/src/runtime/locations/internal-store-contracts.ts +1 -0
  171. package/src/runtime/locations/location-store-repository.ts +130 -68
  172. package/src/runtime/messaging/request-deadline.ts +58 -0
  173. package/src/runtime/messaging/submission-result.ts +18 -4
  174. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
  175. package/src/runtime/spots/spot-outbound.ts +14 -24
  176. package/src/runtime/spots/spot-serial-executor.ts +4 -1
  177. package/src/runtime/spots/spot-serial-turn-executor.ts +10 -0
  178. package/src/runtime/streams/bound-actor-relay-sender.ts +12 -26
  179. package/src/runtime/streams/bound-session-service.ts +1 -1
  180. package/src/runtime/streams/index.ts +5 -5
  181. package/src/runtime/streams/managed-stream.ts +3 -13
  182. package/src/runtime/streams/native-fallback-bound-session.ts +13 -25
  183. package/src/runtime/streams/protocol.ts +0 -13
  184. package/src/runtime/streams/session-calls.ts +8 -34
  185. package/src/runtime/streams/session-context.ts +6 -47
  186. package/src/runtime/streams/session-serial-executor.ts +0 -8
  187. package/src/runtime/streams/stream-message-utils.ts +1 -27
  188. package/src/runtime/streams/stream-session-runtime.ts +54 -97
  189. package/dist/runtime/streams/session-requests.d.ts +0 -25
  190. package/dist/runtime/streams/session-requests.js +0 -101
  191. package/src/runtime/streams/session-requests.ts +0 -110
@@ -25,6 +25,7 @@ export interface ZLinkDomainLocationStore {
25
25
  reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectReserveResult>;
26
26
  commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectCommitResult>;
27
27
  completeCreation(request: ZLinkObjectCreationCompleteRequest, signal?: AbortSignal): Promise<ZLinkObjectCreationCompleteResult>;
28
+ releaseEndedReservation?(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
28
29
  abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectAbortResult>;
29
30
  prepareAggregate(request: ZLinkAggregatePrepareRequest, signal?: AbortSignal): Promise<ZLinkAggregatePrepareResult>;
30
31
  commitAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateCommitResult>;
@@ -26,6 +26,8 @@ export declare class ZLinkInMemoryAuthorityStore {
26
26
  compareExchangeAuthority(key: ZLinkAuthorityKey, expectedStoreVersion: ZLinkAuthorityStoreVersion, mutation: ZLinkAuthorityMutation, signal?: AbortSignal): Promise<ZLinkAuthorityCompareExchangeResult>;
27
27
  listAuthorities(prefix: string, cursor: ZLinkAuthorityScanCursor | undefined, limit: number, signal?: AbortSignal): Promise<ZLinkAuthorityScanResult>;
28
28
  removeAllByOwner(owner: ZLinkLocationOwnerToken, signal?: AbortSignal): Promise<bigint>;
29
+ releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
30
+ private tryReleaseEndedReservation;
29
31
  reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal): Promise<ZLinkObjectReserveResult>;
30
32
  commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal): Promise<ZLinkObjectCommitResult>;
31
33
  completeCreation(request: ZLinkObjectCreationCompleteRequest, signal?: AbortSignal): Promise<ZLinkObjectCreationCompleteResult>;
@@ -171,6 +171,27 @@ class ZLinkInMemoryAuthorityStore {
171
171
  this.scanRevision++;
172
172
  return BigInt(removed);
173
173
  }
174
+ async releaseEndedReservation(key, expectedStoreVersion, signal) {
175
+ signal?.throwIfAborted();
176
+ return this.tryReleaseEndedReservation(key, expectedStoreVersion);
177
+ }
178
+ tryReleaseEndedReservation(key, expectedStoreVersion) {
179
+ const current = this.rows.get(key.value);
180
+ if (current === undefined ||
181
+ current.snapshot.storeVersion.value !== expectedStoreVersion ||
182
+ current.snapshot.allocation.state !== 'reserved' ||
183
+ current.creation === undefined ||
184
+ this.validation.isTargetLive(current.snapshot.allocation.descriptor, current.snapshot.allocation.descriptorLifecycleGeneration, {
185
+ ownerId: current.snapshot.ownerId,
186
+ leaseGeneration: current.snapshot.ownerLeaseGeneration
187
+ }))
188
+ return false;
189
+ this.adjustCapacity(this.pendingCapacity, current.snapshot.allocation, -1);
190
+ this.rows.delete(key.value);
191
+ this.creationTerminals.set(current.creation.reservationId, 'aborted');
192
+ this.scanRevision++;
193
+ return true;
194
+ }
174
195
  async reserve(request, signal) {
175
196
  signal?.throwIfAborted();
176
197
  validateReserve(request);
@@ -187,15 +208,8 @@ class ZLinkInMemoryAuthorityStore {
187
208
  if (current.snapshot.allocation.state === 'active') {
188
209
  return { kind: 'alreadyExists', current: this.snapshot(current.snapshot) };
189
210
  }
190
- // An unfinished creation whose owner lease ended is cancellable.
191
- // Reclaim it so the key does not stay blocked forever.
192
- if (this.isOwnerLive(current.snapshot) || current.creation === undefined) {
211
+ if (!this.tryReleaseEndedReservation((0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId), current.snapshot.storeVersion.value))
193
212
  return { kind: 'conflict', current: this.read(key) };
194
- }
195
- this.adjustCapacity(this.pendingCapacity, current.snapshot.allocation, -1);
196
- this.rows.delete(key);
197
- this.creationTerminals.set(current.creation.reservationId, 'aborted');
198
- this.scanRevision++;
199
213
  }
200
214
  const target = creationTarget(request);
201
215
  if (!this.validation.isTargetLive(target.descriptor, target.lifecycleGeneration, target.owner)) {
@@ -25,6 +25,7 @@ export declare class ZLinkInMemoryLocationStore implements ZLinkDomainLocationSt
25
25
  commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal): Promise<ZLinkObjectCommitResult>;
26
26
  completeCreation(request: ZLinkObjectCreationCompleteRequest, signal?: AbortSignal): Promise<ZLinkObjectCreationCompleteResult>;
27
27
  readCreationTerminal(operation: ZLinkCreationOperationIdentity, signal?: AbortSignal): Promise<ZLinkCreationTerminalReadResult>;
28
+ releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
28
29
  abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal): Promise<ZLinkObjectAbortResult>;
29
30
  prepareAggregate(request: ZLinkAggregatePrepareRequest, signal?: AbortSignal): Promise<ZLinkAggregatePrepareResult>;
30
31
  commitAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateCommitResult>;
@@ -86,6 +86,9 @@ class ZLinkInMemoryLocationStore {
86
86
  async readCreationTerminal(operation, signal) {
87
87
  return this.authority.readCreationTerminal(operation, signal);
88
88
  }
89
+ async releaseEndedReservation(key, expectedStoreVersion, signal) {
90
+ return this.authority.releaseEndedReservation(key, expectedStoreVersion, signal);
91
+ }
89
92
  async abort(request, signal) {
90
93
  return this.authority.abort(request, signal);
91
94
  }
@@ -1,7 +1,7 @@
1
1
  import type { ZLinkActorLocation, ZLinkActorLocationFilter, ZLinkActorLocationKey, ZLinkLocationOwnerToken, ZLinkLocationPage, ZLinkLocationWriteIntent, ZLinkLocationWriteResult, ZLinkLocationWriteStatus, ZLinkPageRequest, ZLinkPeerLocation, ZLinkPeerLocationFilter, ZLinkPeerLocationKey, ZLinkRouteLocation, ZLinkRouteLocationFilter, ZLinkRouteLocationKey, ZLinkSpotLocation, ZLinkSpotLocationFilter, ZLinkSpotLocationKey } from './internal-location-contracts';
2
2
  import type { ZLinkDomainLocationStore } from './domain-store-contract';
3
3
  export type ZLinkAuthorityStore = Pick<ZLinkDomainLocationStore, 'readAuthority' | 'compareExchangeAuthority' | 'listAuthorities'>;
4
- export type ZLinkObjectCreationStore = Pick<ZLinkDomainLocationStore, 'readCreationTerminal' | 'reserve' | 'commit' | 'completeCreation' | 'abort' | 'prepareAggregate' | 'commitAggregate' | 'abortAggregate'>;
4
+ export type ZLinkObjectCreationStore = Pick<ZLinkDomainLocationStore, 'readCreationTerminal' | 'reserve' | 'commit' | 'completeCreation' | 'abort' | 'releaseEndedReservation' | 'prepareAggregate' | 'commitAggregate' | 'abortAggregate'>;
5
5
  export type ZLinkOwnerLeaseStore = Pick<ZLinkDomainLocationStore, 'claimOwnerLease' | 'readOwnerLease' | 'renewOwnerLease' | 'releaseOwnerLease'>;
6
6
  export type ZLinkMeshNodeLocationStore = Pick<ZLinkDomainLocationStore, 'updateMeshNode' | 'removeMeshNode' | 'listMeshNodes'>;
7
7
  export type ZLinkClientServerLocationStore = Pick<ZLinkDomainLocationStore, 'updateClientServer' | 'removeClientServer' | 'listClientServers'>;
@@ -20,6 +20,7 @@ export declare class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationS
20
20
  commitAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateCommitResult>;
21
21
  private commitAggregateCore;
22
22
  abortAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateAbortResult>;
23
+ releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
23
24
  reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectReserveResult>;
24
25
  commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectCommitResult>;
25
26
  abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectAbortResult>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZLinkLocationStoreRepository = void 0;
4
+ const service_relocation_runtime_1 = require("../foundation/service-relocation-runtime");
4
5
  const stream_wire_1 = require("@zlink-systems/stream-wire");
5
6
  const node_crypto_1 = require("node:crypto");
6
7
  const Options_1 = require("../../contracts/Locations/Options");
@@ -46,7 +47,33 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
46
47
  constructor(provider, nowProvider = () => new Date()) {
47
48
  super(nowProvider);
48
49
  this.nowProvider = nowProvider;
49
- this.provider = provider;
50
+ // Classify only failures of the opaque SPI, before interpreting its records.
51
+ this.provider = {
52
+ async read(key, signal) {
53
+ try {
54
+ return await provider.read(key, signal);
55
+ }
56
+ catch (error) {
57
+ throw locationStoreProviderFailure(error, signal);
58
+ }
59
+ },
60
+ async write(request, signal) {
61
+ try {
62
+ return await provider.write(request, signal);
63
+ }
64
+ catch (error) {
65
+ throw locationStoreProviderFailure(error, signal);
66
+ }
67
+ },
68
+ async scan(request, signal) {
69
+ try {
70
+ return await provider.scan(request, signal);
71
+ }
72
+ catch (error) {
73
+ throw locationStoreProviderFailure(error, signal);
74
+ }
75
+ }
76
+ };
50
77
  this.aggregateInventory = new aggregate_inventory_store_1.ZLinkAggregateInventoryStore(this.provider);
51
78
  }
52
79
  async readAuthority(key, signal) {
@@ -787,6 +814,57 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
787
814
  return { kind: 'aborted' };
788
815
  }
789
816
  }
817
+ async releaseEndedReservation(key, expectedStoreVersion, signal) {
818
+ const rowKey = authorityKey(key.value);
819
+ const current = await this.provider.read(rowKey, signal);
820
+ if (current.kind === 'missing' || current.value.version.value !== expectedStoreVersion)
821
+ return false;
822
+ const record = decodeAuthorityRecord(current.value.bytes);
823
+ const snapshot = record.snapshot;
824
+ if (snapshot.allocation.state !== 'reserved' ||
825
+ snapshot.pendingCreation === undefined ||
826
+ record.aggregate !== undefined ||
827
+ hasRelocationAuthority(snapshot.payload))
828
+ return false;
829
+ const leaseKey = ownerKey(snapshot.ownerId);
830
+ const descriptorKey = meshKey(snapshot.allocation.descriptor.meshName, snapshot.allocation.descriptor.rid);
831
+ const capacityRowKey = capacityKey(snapshot.allocation.descriptor.meshName, String(snapshot.allocation.descriptor.rid));
832
+ const [lease, descriptor, capacity] = await Promise.all([
833
+ this.provider.read(leaseKey, signal),
834
+ this.provider.read(descriptorKey, signal),
835
+ this.provider.read(capacityRowKey, signal)
836
+ ]);
837
+ if (lease.kind === 'found' && lease.value.expiresAt === undefined)
838
+ throw new Error('Location Store owner lease record is invalid.');
839
+ if (sameLiveOwner(lease, snapshot) &&
840
+ descriptor.kind === 'found' &&
841
+ reviveMeshDescriptor(decodeCanonicalDescriptorRecord(descriptor.value.bytes).descriptor).lifecycleGeneration === snapshot.allocation.descriptorLifecycleGeneration)
842
+ return false;
843
+ const mutations = [
844
+ { kind: 'delete', key: rowKey }
845
+ ];
846
+ if (capacity.kind === 'found') {
847
+ const stored = decodeJson(capacity.value.bytes);
848
+ mutations.push({
849
+ kind: 'put',
850
+ key: capacityRowKey,
851
+ bytes: encodeJson({
852
+ active: stored.active,
853
+ pending: subtractCapacity(stored.pending, snapshot.allocation.capacity)
854
+ })
855
+ });
856
+ }
857
+ const result = await this.provider.write({
858
+ conditions: [
859
+ { kind: 'version', key: rowKey, expected: current.value.version },
860
+ conditionFor(leaseKey, lease),
861
+ conditionFor(descriptorKey, descriptor),
862
+ conditionFor(capacityRowKey, capacity)
863
+ ],
864
+ mutations
865
+ }, signal);
866
+ return result.kind === 'applied';
867
+ }
790
868
  async reserve(request, signal, deadlineUnixMs) {
791
869
  const encodedAuthorityKey = (0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId);
792
870
  const reservationId = (0, node_crypto_1.randomUUID)();
@@ -807,51 +885,8 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
807
885
  if (snapshot.allocation.state === 'active') {
808
886
  return { kind: 'alreadyExists', current: snapshot };
809
887
  }
810
- if (record.aggregate !== undefined ||
811
- isCanonicalAuthorityPayload(record.snapshot.payload)) {
812
- // A relocation record carries its own recovery protocol. Reserve
813
- // may reclaim only an unfinished plain creation.
888
+ if (!(await this.releaseEndedReservation(encodedAuthorityKey, current.value.version.value, signal)))
814
889
  return { kind: 'conflict', current: snapshot };
815
- }
816
- // The row is Reserved by another owner. An unfinished creation
817
- // whose owner lease ended is cancellable, so reclaim it and retry
818
- // instead of blocking the key forever.
819
- const staleOwnerKey = ownerKey(snapshot.ownerId);
820
- const staleCapacityKey = capacityKey(snapshot.allocation.descriptor.meshName, String(snapshot.allocation.descriptor.rid));
821
- const [staleOwnerRead, staleCapacityRead] = await Promise.all([
822
- this.provider.read(staleOwnerKey, signal),
823
- this.provider.read(staleCapacityKey, signal)
824
- ]);
825
- if (staleOwnerRead.kind === 'found' && staleOwnerRead.value.expiresAt === undefined) {
826
- // A lease is always written with a positive TTL, so a missing
827
- // expiry is a corrupt record. Reclaiming deletes authority state,
828
- // so refuse rather than read the absence as expiry.
829
- throw new Error('Location Store owner lease record is invalid.');
830
- }
831
- if (sameLiveOwner(staleOwnerRead, record.snapshot)) {
832
- return { kind: 'conflict', current: snapshot };
833
- }
834
- const staleCapacity = staleCapacityRead.kind === 'missing'
835
- ? emptyCapacityRecord()
836
- : decodeJson(staleCapacityRead.value.bytes);
837
- await this.provider.write({
838
- conditions: [
839
- { kind: 'version', key: rowKey, expected: current.value.version },
840
- versionCondition(staleOwnerKey, staleOwnerRead),
841
- conditionFor(staleCapacityKey, staleCapacityRead)
842
- ],
843
- mutations: [
844
- { kind: 'delete', key: rowKey },
845
- {
846
- kind: 'put',
847
- key: staleCapacityKey,
848
- bytes: encodeJson({
849
- active: staleCapacity.active,
850
- pending: subtractCapacity(staleCapacity.pending, record.snapshot.allocation.capacity)
851
- })
852
- }
853
- ]
854
- }, signal);
855
890
  continue;
856
891
  }
857
892
  const [descriptorRead, leaseRead] = await Promise.all([
@@ -859,7 +894,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
859
894
  this.provider.read(leaseKey, signal)
860
895
  ]);
861
896
  const descriptor = liveTargetDescriptor(descriptorRead, leaseRead, request.target);
862
- if (descriptor === undefined) {
897
+ if (descriptor === undefined || descriptor.state !== contracts_1.ZLinkFrameworkRuntimeState.Serving) {
863
898
  return { kind: 'conflict', current: { kind: 'missing', storeNow: current.storeNow } };
864
899
  }
865
900
  const [capacityRead, objectGenerationRead, authorityOwnerGenerationRead] = await Promise.all([
@@ -1042,9 +1077,11 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1042
1077
  !sameCreationTarget(record.snapshot, request.target)) {
1043
1078
  return { kind: 'stale' };
1044
1079
  }
1080
+ const descriptorKey = meshKey(request.target.meshName, request.target.nodeRid);
1045
1081
  const leaseKey = ownerKey(request.target.owner.ownerId);
1046
1082
  const capacityRowKey = capacityKey(request.target.meshName, String(request.target.nodeRid));
1047
- const [leaseRead, capacityRead] = await Promise.all([
1083
+ const [descriptorRead, leaseRead, capacityRead] = await Promise.all([
1084
+ this.provider.read(descriptorKey, signal),
1048
1085
  this.provider.read(leaseKey, signal),
1049
1086
  this.provider.read(capacityRowKey, signal)
1050
1087
  ]);
@@ -1054,7 +1091,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1054
1091
  // rather than read the absence as expiry.
1055
1092
  throw new Error('Location Store owner lease record is invalid.');
1056
1093
  }
1057
- if (!sameLiveOwner(leaseRead, record.snapshot))
1094
+ if (liveTargetDescriptor(descriptorRead, leaseRead, request.target) === undefined)
1058
1095
  return { kind: 'stale' };
1059
1096
  const capacity = capacityRead.kind === 'missing'
1060
1097
  ? emptyCapacityRecord()
@@ -1062,6 +1099,7 @@ class ZLinkLocationStoreRepository extends in_memory_location_store_1.ZLinkInMem
1062
1099
  const result = await this.provider.write({
1063
1100
  conditions: [
1064
1101
  { kind: 'version', key: rowKey, expected: current.value.version },
1102
+ versionCondition(descriptorKey, descriptorRead),
1065
1103
  leaseValueCondition(leaseKey, {
1066
1104
  ownerId: record.snapshot.ownerId,
1067
1105
  leaseGeneration: record.snapshot.ownerLeaseGeneration
@@ -2843,7 +2881,6 @@ function liveTargetDescriptor(descriptorRead, leaseRead, target) {
2843
2881
  descriptor.ownerId === target.owner.ownerId &&
2844
2882
  descriptor.leaseGeneration === target.owner.leaseGeneration &&
2845
2883
  descriptor.objectRole === contracts_1.ZLinkObjectRole.Server &&
2846
- descriptor.state === contracts_1.ZLinkFrameworkRuntimeState.Serving &&
2847
2884
  lease.ownerId === target.owner.ownerId &&
2848
2885
  BigInt(lease.leaseGeneration) === target.owner.leaseGeneration &&
2849
2886
  leaseRead.value.expiresAt !== undefined &&
@@ -2940,10 +2977,9 @@ function sameCreationTarget(snapshot, target) {
2940
2977
  snapshot.ownerId === target.owner.ownerId &&
2941
2978
  snapshot.ownerLeaseGeneration === target.owner.leaseGeneration);
2942
2979
  }
2943
- const CANONICAL_AUTHORITY_MAGIC = Buffer.from('ZLAU');
2944
- function isCanonicalAuthorityPayload(payload) {
2945
- return (payload.byteLength >= CANONICAL_AUTHORITY_MAGIC.byteLength &&
2946
- Buffer.from(payload.buffer, payload.byteOffset, CANONICAL_AUTHORITY_MAGIC.byteLength).equals(CANONICAL_AUTHORITY_MAGIC));
2980
+ const relocationAuthorityCodec = new service_relocation_runtime_1.ServiceRelocationAuthorityPayloadCodec();
2981
+ function hasRelocationAuthority(payload) {
2982
+ return relocationAuthorityCodec.read(payload) !== undefined;
2947
2983
  }
2948
2984
  function sameLiveOwner(lease, snapshot) {
2949
2985
  if (lease.kind === 'missing')
@@ -3237,3 +3273,12 @@ function throwIfOperationExpired(signal, deadlineUnixMs) {
3237
3273
  throw new DOMException('Operation deadline exceeded.', 'TimeoutError');
3238
3274
  }
3239
3275
  }
3276
+ // Store SPI §6: preserve caller failures and classify provider failures once.
3277
+ function locationStoreProviderFailure(error, signal) {
3278
+ if (error instanceof contracts_1.ZLinkFrameworkException ||
3279
+ error instanceof TypeError ||
3280
+ error instanceof RangeError ||
3281
+ signal?.aborted === true)
3282
+ return error;
3283
+ return new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.Unavailable, 'Location Store provider is unavailable.', error);
3284
+ }
@@ -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;
@@ -5,6 +5,7 @@ exports.submitToRequestResult = submitToRequestResult;
5
5
  exports.classifySubmitResult = classifySubmitResult;
6
6
  exports.requireOneWayCompletion = requireOneWayCompletion;
7
7
  exports.requirePublishCompletion = requirePublishCompletion;
8
+ exports.requireClassicFanoutCompletion = requireClassicFanoutCompletion;
8
9
  exports.throwAlreadySubmitted = throwAlreadySubmitted;
9
10
  const framework_errors_internal_1 = require("../framework-errors-internal");
10
11
  const contracts_1 = require("../../contracts");
@@ -18,7 +19,7 @@ var ZLinkSubmitStatus;
18
19
  ZLinkSubmitStatus["RouteNotConnected"] = "routeNotConnected";
19
20
  ZLinkSubmitStatus["Shutdown"] = "shutdown";
20
21
  })(ZLinkSubmitStatus || (exports.ZLinkSubmitStatus = ZLinkSubmitStatus = {}));
21
- /** Projects the Core submit result once; phase only determines capacity refusal meaning. */
22
+ /** Projects immediate refusal and pending admission failure from their Core phase. */
22
23
  function submitToRequestResult(result, phase) {
23
24
  switch (result) {
24
25
  case runtime_values_1.SubmitResult.Ok:
@@ -28,7 +29,7 @@ function submitToRequestResult(result, phase) {
28
29
  case runtime_values_1.SubmitResult.NotConnected:
29
30
  return runtime_values_1.RequestResult.NotConnected;
30
31
  case runtime_values_1.SubmitResult.NotFound:
31
- return runtime_values_1.RequestResult.NotFound;
32
+ return phase === 'submit' ? runtime_values_1.RequestResult.NotFound : runtime_values_1.RequestResult.NotConnected;
32
33
  case runtime_values_1.SubmitResult.NotAdmitted:
33
34
  return runtime_values_1.RequestResult.Rejected;
34
35
  case runtime_values_1.SubmitResult.InvalidHandle:
@@ -45,7 +46,7 @@ function submitToRequestResult(result, phase) {
45
46
  return runtime_values_1.RequestResult.InternalError;
46
47
  }
47
48
  }
48
- function classifySubmitResult(result, operation, phase = 'completion') {
49
+ function classifySubmitResult(result, operation, phase = 'submit') {
49
50
  const terminal = submitToRequestResult(result, phase);
50
51
  switch (terminal) {
51
52
  case runtime_values_1.RequestResult.Ok:
@@ -67,8 +68,9 @@ function requireOneWayCompletion(result, operation, notFoundKind = framework_err
67
68
  case ZLinkSubmitStatus.Submitted:
68
69
  return;
69
70
  case ZLinkSubmitStatus.TimedOut:
70
- case ZLinkSubmitStatus.Backpressured:
71
71
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.DeadlineExceeded, `${operation} did not obtain admission before its deadline.`, true);
72
+ case ZLinkSubmitStatus.Backpressured:
73
+ throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RouteNotConnected, `${operation} has no admission wait token.`, true);
72
74
  case ZLinkSubmitStatus.TargetNotFound:
73
75
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(notFoundKind, `${operation} target was not found.`);
74
76
  case ZLinkSubmitStatus.RouteNotConnected:
@@ -80,6 +82,11 @@ function requireOneWayCompletion(result, operation, notFoundKind = framework_err
80
82
  function requirePublishCompletion(result, operation) {
81
83
  requireOneWayCompletion(result, operation);
82
84
  }
85
+ function requireClassicFanoutCompletion(result, operation) {
86
+ requireOneWayCompletion(result.status === ZLinkSubmitStatus.Backpressured
87
+ ? { status: ZLinkSubmitStatus.TimedOut }
88
+ : result, operation);
89
+ }
83
90
  function throwAlreadySubmitted(operation) {
84
91
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.AlreadySubmitted, `${operation} has already been submitted.`);
85
92
  }
@@ -48,7 +48,7 @@ export interface ZLinkSpotAddressCallOptions {
48
48
  * activation. Public callers never handle an owner or generation fence.
49
49
  */
50
50
  export interface ZLinkSpotAddressTransport {
51
- sendToSpotAddress(spotId: RoutingId, message: unknown, options: ZLinkSpotAddressCallOptions): Promise<ZLinkSubmitResult>;
51
+ sendToSpotAddress(spotId: RoutingId, message: unknown, options: Omit<ZLinkSpotAddressCallOptions, 'timeoutMs' | 'signal'>): Promise<ZLinkSubmitResult>;
52
52
  requestToSpotAddress<TReply = unknown>(spotId: RoutingId, request: unknown, options: ZLinkSpotAddressCallOptions): Promise<TReply>;
53
53
  }
54
54
  export interface ZLinkSpotRoutedTransport {
@@ -60,13 +60,11 @@ export interface ZLinkSpotRoutedTransport {
60
60
  export interface ZLinkSpotRoutedSendOptions {
61
61
  readonly instanceSpot?: boolean;
62
62
  readonly packetName?: string;
63
- /** Internal end-to-end budget remaining for route admission. */
64
- readonly timeoutMs?: number;
65
- readonly signal?: AbortSignal;
66
63
  readonly metadata?: ReadonlyMap<string, string>;
67
64
  }
68
65
  export interface ZLinkSpotRoutedRequestOptions extends ZLinkSpotRoutedSendOptions {
69
66
  readonly timeoutMs?: number;
67
+ readonly signal?: AbortSignal;
70
68
  }
71
69
  export interface ZLinkSpotHandleCallOptions {
72
70
  readonly metadata?: ReadonlyMap<string, string>;
@@ -75,5 +73,5 @@ export interface ZLinkSpotHandleCallOptions {
75
73
  readonly spotRouterChannelIdForMesh?: (meshName: string) => string;
76
74
  readonly sourceSpot?: ZLinkBackendSpot;
77
75
  }
78
- export declare function sendToSpotHandle(transport: ZLinkSpotRoutedTransport, spot: SpotHandle, message: unknown, options?: ZLinkSpotHandleCallOptions): Promise<ZLinkSubmitResult>;
76
+ export declare function sendToSpotHandle(transport: ZLinkSpotRoutedTransport, spot: SpotHandle, message: unknown, options?: Omit<ZLinkSpotHandleCallOptions, 'timeoutMs' | 'signal'>): Promise<ZLinkSubmitResult>;
79
77
  export declare function requestToSpotHandle<TReply = unknown>(transport: ZLinkSpotRoutedTransport, spot: SpotHandle, request: unknown, options?: ZLinkSpotHandleCallOptions): Promise<TReply>;
@@ -103,10 +103,10 @@ function createAddressedSpotSendCall(serial, transport, spotId, message, sourceS
103
103
  options.initialMeshName = requireAddressValue(meshName, 'Mesh name', CoreTypes_1.ZLINK_MAX_MESH_NAME_BYTES);
104
104
  return this;
105
105
  },
106
- async submit(signal) {
106
+ async submit() {
107
107
  markSubmitted(options);
108
108
  const pending = startRequestOnSerial(serial, () => ({
109
- pending: transport.sendToSpotAddress(spotId, message, freezeAddressCallOptions(options, signal, sourceSpotProvider?.()))
109
+ pending: transport.sendToSpotAddress(spotId, message, freezeAddressCallOptions(options, sourceSpotProvider?.()))
110
110
  }));
111
111
  const result = await (serial.isCurrentTurn ? pending : (0, workers_1.deliverOnSerial)(serial, pending));
112
112
  (0, submission_result_1.requireOneWayCompletion)(result, 'Spot send', framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.SpotRouteNotFound);
@@ -119,7 +119,11 @@ function createAddressedSpotRequestCall(serial, transport, spotId, request, sour
119
119
  markSubmitted(options);
120
120
  rejectSameSpotAsyncRequest(serial, spotId, waitPolicy);
121
121
  return startRequestOnSerial(serial, () => ({
122
- pending: transport.requestToSpotAddress(spotId, request, freezeAddressCallOptions(options, signal, sourceSpotProvider?.()))
122
+ pending: transport.requestToSpotAddress(spotId, request, {
123
+ ...freezeAddressCallOptions(options, sourceSpotProvider?.()),
124
+ timeoutMs: options.timeoutMs,
125
+ signal
126
+ })
123
127
  }));
124
128
  };
125
129
  return {
@@ -200,14 +204,12 @@ function markSubmitted(options) {
200
204
  }
201
205
  options.submitted = true;
202
206
  }
203
- function freezeAddressCallOptions(options, signal, sourceSpot) {
207
+ function freezeAddressCallOptions(options, sourceSpot) {
204
208
  return {
205
209
  ...(options.metadataPresent ? { metadata: new Map(options.metadata) } : {}),
206
210
  instanceSpot: options.instanceSpot,
207
211
  instanceSpotType: options.instanceSpotType,
208
212
  initialMeshName: options.initialMeshName,
209
- timeoutMs: options.timeoutMs,
210
- signal,
211
213
  sourceSpot
212
214
  };
213
215
  }
@@ -227,8 +229,8 @@ function wrapSendCall(serial, inner) {
227
229
  inner.metadata(key);
228
230
  return this;
229
231
  },
230
- async submit(signal) {
231
- const result = await runInternalTransportStart(serial, () => inner.submit(signal));
232
+ async submit() {
233
+ const result = await runInternalTransportStart(serial, () => inner.submit());
232
234
  return result;
233
235
  }
234
236
  };
@@ -302,11 +304,10 @@ function wrapRoutedSpotSendCall(serial, transport, spot, message, spotRouterChan
302
304
  }
303
305
  return this;
304
306
  },
305
- async submit(signal) {
307
+ async submit() {
306
308
  const pending = startRequestOnSerial(serial, () => ({
307
309
  pending: sendToSpotHandle(transport, spot, message, {
308
310
  metadata,
309
- signal,
310
311
  spotRouterChannelIdForMesh,
311
312
  sourceSpot: sourceSpotProvider?.()
312
313
  })
@@ -376,19 +377,15 @@ async function sendToSpotHandle(transport, spot, message, options = {}) {
376
377
  if (options.sourceSpot !== undefined && transport.sendFromSpotToSpot !== undefined) {
377
378
  return transport.sendFromSpotToSpot(options.sourceSpot, target, message, {
378
379
  packetName,
379
- timeoutMs: options.timeoutMs,
380
- signal: options.signal,
381
380
  metadata: options.metadata
382
381
  });
383
382
  }
384
383
  return transport.sendToSpot(target, message, {
385
384
  packetName,
386
- timeoutMs: options.timeoutMs,
387
- signal: options.signal,
388
385
  metadata: options.metadata
389
386
  });
390
387
  };
391
- return sendResolved(await requireSpotRef(spot, options.signal));
388
+ return sendResolved(await requireSpotRef(spot));
392
389
  }
393
390
  async function requestToSpotHandle(transport, spot, request, options = {}) {
394
391
  const packetName = (0, packet_name_1.resolveFrameworkPacketName)(request, undefined, 'SPOT');
@@ -96,7 +96,10 @@ class ZLinkSpotSerialExecutor {
96
96
  this.throwIfClosing();
97
97
  let executor = this.actorExecutors.get(actorId);
98
98
  if (executor === undefined) {
99
- executor = new actors_1.ZLinkActorSerialExecutor(actorId, this.sourceSpotId, this.actorOptions);
99
+ executor =
100
+ this.executionMode === contracts_1.ZLinkUserSpotExecutionMode.SpotWide
101
+ ? this.spotSerial.createActorExecutor(actorId, this.sourceSpotId, this.actorOptions)
102
+ : new actors_1.ZLinkActorSerialExecutor(actorId, this.sourceSpotId, this.actorOptions);
100
103
  this.actorExecutors.set(actorId, executor);
101
104
  }
102
105
  return executor;
@@ -3,6 +3,7 @@ import type { SpotId } from '../../contracts';
3
3
  import type { ZLinkFrameworkException } from '../../contracts/Errors/ZLinkFrameworkException';
4
4
  import { type ZLinkSerialSchedulerOptions, type ZLinkSerialWorkOptions, type ZLinkSerialWorkRecord } from '../execution/serial-execution-queue';
5
5
  import type { ZLinkSerialLifecycleContext } from '../execution/serial-execution-queue';
6
+ import { ZLinkActorSerialExecutor } from '../actors/actor-mailbox';
6
7
  export type ZLinkSpotApplicationTurnContext = ZLinkExecutionBarrierClaim & {
7
8
  readonly replay?: (failure?: unknown) => Promise<unknown> | unknown;
8
9
  };
@@ -19,6 +20,8 @@ export declare class ZLinkSpotSerialTurnExecutor {
19
20
  activeTurnId: number;
20
21
  constructor(yieldAllowed?: boolean, sourceSpotId?: SpotId | undefined, schedulerOptions?: ZLinkSerialSchedulerOptions);
21
22
  get isExecuting(): boolean;
23
+ /** Creates a passive Actor mailbox consumed by this Spot's scheduler. */
24
+ createActorExecutor(actorId: string, sourceSpotId: unknown, options?: ZLinkSerialSchedulerOptions): ZLinkActorSerialExecutor;
22
25
  get isCurrentTurn(): boolean;
23
26
  get hasPendingWork(): boolean;
24
27
  get lastActivityAt(): number;
@@ -4,6 +4,7 @@ exports.ZLinkSpotSerialTurnExecutor = void 0;
4
4
  const execution_1 = require("../execution");
5
5
  const framework_errors_internal_1 = require("../framework-errors-internal");
6
6
  const serial_execution_queue_1 = require("../execution/serial-execution-queue");
7
+ const actor_mailbox_1 = require("../actors/actor-mailbox");
7
8
  const application_job_queue_scope_1 = require("../application-jobs/application-job-queue-scope");
8
9
  class ZLinkSpotSerialTurnExecutor {
9
10
  yieldAllowed;
@@ -24,6 +25,10 @@ class ZLinkSpotSerialTurnExecutor {
24
25
  get isExecuting() {
25
26
  return this.depth > 0;
26
27
  }
28
+ /** Creates a passive Actor mailbox consumed by this Spot's scheduler. */
29
+ createActorExecutor(actorId, sourceSpotId, options) {
30
+ return new actor_mailbox_1.ZLinkActorSerialExecutor(actorId, sourceSpotId, options, this.scheduler);
31
+ }
27
32
  get isCurrentTurn() {
28
33
  return this.depth > 0 && (0, execution_1.isCurrentZLinkSpotSerialTurn)(this);
29
34
  }
@@ -12,7 +12,7 @@ export interface ZLinkBoundActorRelaySenderOptions {
12
12
  readonly dispatchErrors?: ZLinkDispatchErrorReporter;
13
13
  readonly actorBindTimeoutMs?: number;
14
14
  readonly messageSerializers?: ReadonlyMap<string, ZLinkMessageSerializer>;
15
- readonly relay?: (actor: ZLinkSessionActor, header: ZLinkStreamFrameHeader, payload: Message, signal?: AbortSignal) => Promise<boolean>;
15
+ readonly relay?: (actor: ZLinkSessionActor, header: ZLinkStreamFrameHeader, payload: Message) => Promise<boolean>;
16
16
  readonly notifyDisconnected?: (actor: ZLinkSessionActor, signal?: AbortSignal) => Promise<void>;
17
17
  }
18
18
  export declare class ZLinkBoundActorRelaySender {
@@ -21,7 +21,7 @@ export declare class ZLinkBoundActorRelaySender {
21
21
  private readonly options;
22
22
  private readonly lifecycle;
23
23
  constructor(routes: ZLinkActorSessionBindingRegistry<DefaultZLinkSessionContext, DefaultZLinkSessionActor>, frameMessages: ZLinkStreamFrameMessageFactory, options?: ZLinkBoundActorRelaySenderOptions, lifecycle?: ZLinkActorSessionLifecycleCoordinator);
24
- relay(actor: DefaultZLinkSessionActor, payload: ZLinkMessage, signal?: AbortSignal, dispatchHeader?: ZLinkStreamFrameHeader): Promise<ZLinkSubmitResult>;
24
+ relay(actor: DefaultZLinkSessionActor, payload: ZLinkMessage, dispatchHeader?: ZLinkStreamFrameHeader): Promise<ZLinkSubmitResult>;
25
25
  private traceHeldDrop;
26
26
  private relayAcceptedFrame;
27
27
  private currentHeader;