@zlink-systems/framework 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Configuration/Builders.d.ts +1 -2
  3. package/dist/contracts/Configuration/Configs.d.ts +0 -5
  4. package/dist/contracts/Configuration/RegistrationBuilders.js +6 -4
  5. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -6
  6. package/dist/contracts/Configuration/RegistrationValidators.js +4 -4
  7. package/dist/contracts/Configuration/index.d.ts +1 -1
  8. package/dist/internal.d.ts +1 -0
  9. package/dist/internal.js +3 -1
  10. package/dist/runtime/actors/actor-handoff.d.ts +3 -2
  11. package/dist/runtime/actors/actor-handoff.js +9 -4
  12. package/dist/runtime/actors/actor-runtime-contracts.d.ts +1 -0
  13. package/dist/runtime/actors/index.d.ts +2 -0
  14. package/dist/runtime/actors/index.js +21 -6
  15. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +3 -1
  16. package/dist/runtime/application-jobs/application-ingress-record-owner.js +6 -1
  17. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +3 -1
  18. package/dist/runtime/application-jobs/application-job-queue-scope.js +5 -0
  19. package/dist/runtime/application-jobs/contracts.d.ts +5 -1
  20. package/dist/runtime/backend/contracts/index.d.ts +10 -19
  21. package/dist/runtime/backend/mesh-completion-table.d.ts +6 -4
  22. package/dist/runtime/backend/mesh-completion-table.js +28 -18
  23. package/dist/runtime/backend/mesh-dispatch-pump.js +21 -25
  24. package/dist/runtime/backend/node/node-backend-adapter-factory.js +6 -1
  25. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -3
  26. package/dist/runtime/backend/node/node-backend-adapter-support.js +24 -29
  27. package/dist/runtime/backend/node/node-mesh-backend-adapter.d.ts +1 -9
  28. package/dist/runtime/backend/node/node-mesh-backend-adapter.js +1 -1
  29. package/dist/runtime/backend/node/node-raw-binding-port.js +11 -6
  30. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +10 -12
  31. package/dist/runtime/backend/node/node-raw-mesh-backend.js +64 -98
  32. package/dist/runtime/backend/node/node-socket-backend-adapter.js +10 -5
  33. package/dist/runtime/backend/raw-binding-port.d.ts +9 -2
  34. package/dist/runtime/channels/channel-receive-loops.js +3 -3
  35. package/dist/runtime/channels/channel-runtime-lifecycle.js +2 -1
  36. package/dist/runtime/channels/channel-socket-registry.d.ts +10 -3
  37. package/dist/runtime/channels/channel-socket-registry.js +59 -82
  38. package/dist/runtime/diagnostics/message-flow.d.ts +1 -0
  39. package/dist/runtime/diagnostics/message-flow.js +3 -3
  40. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +15 -1
  41. package/dist/runtime/foundation/raw-service-mesh-runtime.js +193 -64
  42. package/dist/runtime/foundation/service-liveness-registry.d.ts +20 -8
  43. package/dist/runtime/foundation/service-liveness-registry.js +57 -44
  44. package/dist/runtime/foundation/service-mailbox.d.ts +3 -0
  45. package/dist/runtime/foundation/service-mailbox.js +2 -1
  46. package/dist/runtime/foundation/service-stateful-runtime.d.ts +7 -6
  47. package/dist/runtime/foundation/service-stateful-runtime.js +60 -41
  48. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +5 -2
  49. package/dist/runtime/foundation/service-stateful-wire-codec.js +43 -61
  50. package/dist/runtime/foundation/service-topology-registry.d.ts +5 -3
  51. package/dist/runtime/foundation/service-topology-registry.js +9 -4
  52. package/dist/runtime/handlers/handler-instance-scope.js +1 -1
  53. package/dist/runtime/host/actor-packet-relay.js +7 -7
  54. package/dist/runtime/host/actor-placement-coordinator.d.ts +2 -1
  55. package/dist/runtime/host/actor-placement-coordinator.js +2 -1
  56. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -1
  57. package/dist/runtime/host/actor-runtime-options-factory.js +2 -1
  58. package/dist/runtime/host/application-job-queue.d.ts +11 -4
  59. package/dist/runtime/host/application-job-queue.js +66 -10
  60. package/dist/runtime/host/entry-actor-runtime.js +1 -1
  61. package/dist/runtime/host/index.d.ts +1 -1
  62. package/dist/runtime/host/index.js +18 -13
  63. package/dist/runtime/host/instance-activation-authority.d.ts +2 -1
  64. package/dist/runtime/host/instance-activation-authority.js +89 -25
  65. package/dist/runtime/host/service-relocation-host-runtime.js +2 -2
  66. package/dist/runtime/host/spot-address-transport.d.ts +1 -0
  67. package/dist/runtime/host/spot-address-transport.js +25 -12
  68. package/dist/runtime/host/spot-runtime-options-factory.js +2 -2
  69. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +1 -0
  70. package/dist/runtime/host/user-spot-creation-coordinator.js +1 -0
  71. package/dist/runtime/locations/domain-store-contract.d.ts +3 -2
  72. package/dist/runtime/locations/in-memory-authority-store.d.ts +5 -2
  73. package/dist/runtime/locations/in-memory-authority-store.js +107 -14
  74. package/dist/runtime/locations/in-memory-location-store.d.ts +3 -3
  75. package/dist/runtime/locations/in-memory-location-store.js +31 -13
  76. package/dist/runtime/locations/internal-location-contracts.d.ts +8 -0
  77. package/dist/runtime/locations/location-store-repository.d.ts +4 -2
  78. package/dist/runtime/locations/location-store-repository.js +209 -33
  79. package/dist/runtime/locations/resolvers.d.ts +2 -1
  80. package/dist/runtime/locations/resolvers.js +10 -1
  81. package/dist/runtime/messaging/submission-result.d.ts +1 -1
  82. package/dist/runtime/messaging/submission-result.js +2 -2
  83. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +2 -0
  84. package/dist/runtime/spots/index.d.ts +4 -3
  85. package/dist/runtime/spots/index.js +14 -14
  86. package/dist/runtime/spots/spot-activation.d.ts +2 -1
  87. package/dist/runtime/spots/spot-activation.js +4 -4
  88. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +2 -1
  89. package/dist/runtime/spots/spot-actor-admission-coordinator.js +11 -10
  90. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +4 -1
  91. package/dist/runtime/spots/spot-actor-packet-dispatch.js +7 -5
  92. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  93. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -0
  94. package/dist/runtime/spots/spot-entry-activation.d.ts +1 -0
  95. package/dist/runtime/spots/spot-entry-activation.js +6 -1
  96. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +3 -1
  97. package/dist/runtime/spots/spot-node-runtime-manager.js +10 -11
  98. package/dist/runtime/spots/spot-routing-internal.d.ts +6 -0
  99. package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -1
  100. package/dist/runtime/spots/spot-serial-executor.d.ts +1 -0
  101. package/dist/runtime/spots/spot-serial-executor.js +10 -1
  102. package/dist/runtime/streams/stream-session-runtime.js +1 -1
  103. package/package.json +3 -3
  104. package/src/contracts/Configuration/Builders.ts +1 -2
  105. package/src/contracts/Configuration/Configs.ts +0 -6
  106. package/src/contracts/Configuration/RegistrationBuilders.ts +8 -12
  107. package/src/contracts/Configuration/RegistrationTypes.ts +1 -6
  108. package/src/contracts/Configuration/RegistrationValidators.ts +9 -10
  109. package/src/contracts/Configuration/index.ts +1 -6
  110. package/src/internal.ts +1 -0
  111. package/src/runtime/actors/actor-handoff.ts +13 -4
  112. package/src/runtime/actors/actor-runtime-contracts.ts +4 -0
  113. package/src/runtime/actors/index.ts +77 -42
  114. package/src/runtime/application-jobs/application-ingress-record-owner.ts +12 -2
  115. package/src/runtime/application-jobs/application-job-queue-scope.ts +6 -1
  116. package/src/runtime/application-jobs/contracts.ts +14 -1
  117. package/src/runtime/backend/contracts/index.ts +10 -18
  118. package/src/runtime/backend/mesh-completion-table.ts +36 -19
  119. package/src/runtime/backend/mesh-dispatch-pump.ts +19 -22
  120. package/src/runtime/backend/node/node-backend-adapter-factory.ts +12 -5
  121. package/src/runtime/backend/node/node-backend-adapter-support.ts +31 -29
  122. package/src/runtime/backend/node/node-mesh-backend-adapter.ts +3 -10
  123. package/src/runtime/backend/node/node-raw-binding-port.ts +19 -10
  124. package/src/runtime/backend/node/node-raw-mesh-backend.ts +81 -111
  125. package/src/runtime/backend/node/node-socket-backend-adapter.ts +12 -8
  126. package/src/runtime/backend/raw-binding-port.ts +12 -2
  127. package/src/runtime/channels/channel-receive-loops.ts +3 -3
  128. package/src/runtime/channels/channel-runtime-lifecycle.ts +7 -1
  129. package/src/runtime/channels/channel-socket-registry.ts +84 -130
  130. package/src/runtime/diagnostics/message-flow.ts +1 -1
  131. package/src/runtime/foundation/raw-service-mesh-runtime.ts +268 -70
  132. package/src/runtime/foundation/service-liveness-registry.ts +68 -59
  133. package/src/runtime/foundation/service-mailbox.ts +7 -1
  134. package/src/runtime/foundation/service-stateful-runtime.ts +109 -77
  135. package/src/runtime/foundation/service-stateful-wire-codec.ts +55 -79
  136. package/src/runtime/foundation/service-topology-registry.ts +13 -7
  137. package/src/runtime/handlers/handler-instance-scope.ts +2 -1
  138. package/src/runtime/host/actor-packet-relay.ts +7 -0
  139. package/src/runtime/host/actor-placement-coordinator.ts +8 -2
  140. package/src/runtime/host/actor-runtime-options-factory.ts +7 -0
  141. package/src/runtime/host/application-job-queue.ts +77 -10
  142. package/src/runtime/host/entry-actor-runtime.ts +1 -0
  143. package/src/runtime/host/index.ts +30 -7
  144. package/src/runtime/host/instance-activation-authority.ts +132 -27
  145. package/src/runtime/host/service-relocation-host-runtime.ts +2 -0
  146. package/src/runtime/host/spot-address-transport.ts +45 -22
  147. package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
  148. package/src/runtime/host/user-spot-creation-coordinator.ts +8 -0
  149. package/src/runtime/locations/domain-store-contract.ts +6 -2
  150. package/src/runtime/locations/in-memory-authority-store.ts +153 -12
  151. package/src/runtime/locations/in-memory-location-store.ts +39 -13
  152. package/src/runtime/locations/internal-location-contracts.ts +10 -0
  153. package/src/runtime/locations/location-store-repository.ts +295 -36
  154. package/src/runtime/locations/resolvers.ts +25 -2
  155. package/src/runtime/messaging/submission-result.ts +2 -2
  156. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +2 -0
  157. package/src/runtime/spots/index.ts +16 -0
  158. package/src/runtime/spots/spot-activation.ts +5 -0
  159. package/src/runtime/spots/spot-actor-admission-coordinator.ts +13 -0
  160. package/src/runtime/spots/spot-actor-packet-dispatch.ts +10 -0
  161. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  162. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +1 -0
  163. package/src/runtime/spots/spot-entry-activation.ts +7 -0
  164. package/src/runtime/spots/spot-node-runtime-manager.ts +14 -12
  165. package/src/runtime/spots/spot-routing-internal.ts +14 -0
  166. package/src/runtime/spots/spot-runtime-ports.ts +2 -0
  167. package/src/runtime/spots/spot-serial-executor.ts +10 -4
  168. package/src/runtime/streams/stream-session-runtime.ts +1 -1
@@ -30,7 +30,10 @@ class ZLinkHostSpotAddressTransport {
30
30
  }
31
31
  async sendToSpotAddressScoped(spotId, message, call) {
32
32
  const activationDeadlineUnixMs = BigInt(Math.round(Date.now() + this.options.defaultRequestTimeoutMs));
33
- const existing = await this.resolveExisting(spotId);
33
+ const resolution = await this.resolveExisting(spotId, undefined, call);
34
+ const existing = resolution !== undefined && !('kind' in resolution) ? resolution : undefined;
35
+ if (resolution !== undefined && 'kind' in resolution)
36
+ call = this.reactivationCall(resolution, call);
34
37
  if (existing !== undefined) {
35
38
  this.validateExisting(existing, call);
36
39
  try {
@@ -64,7 +67,7 @@ class ZLinkHostSpotAddressTransport {
64
67
  if (!call.instanceSpot) {
65
68
  return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
66
69
  }
67
- const selected = this.selectMissingTarget(spotId, call);
70
+ const selected = this.selectMissingTarget(spotId, call, resolution);
68
71
  if (selected.kind === 'unsupported') {
69
72
  this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Dropped, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Send, spotId, message, call.initialMeshName, call.instanceSpotType, undefined, ZLinkDispatchOptions_1.ZLinkRuntimeDispatchErrorReason.StaleTarget);
70
73
  return { status: submission_result_1.ZLinkSubmitStatus.TargetNotFound };
@@ -91,10 +94,13 @@ class ZLinkHostSpotAddressTransport {
91
94
  const timeoutMs = call.timeoutMs ?? this.options.defaultRequestTimeoutMs;
92
95
  const deadline = createSpotAddressDeadline(timeoutMs, call.signal);
93
96
  try {
94
- const existing = await this.resolveExisting(spotId, deadline.signal);
97
+ const resolution = await this.resolveExisting(spotId, deadline.signal, call);
98
+ const existing = resolution !== undefined && !('kind' in resolution) ? resolution : undefined;
99
+ if (resolution !== undefined && 'kind' in resolution)
100
+ call = this.reactivationCall(resolution, call);
95
101
  deadline.requireRemaining();
96
102
  if (existing === undefined) {
97
- return await this.requestToMissingInstance(spotId, request, call, deadline);
103
+ return await this.requestToMissingInstance(spotId, request, call, deadline, resolution);
98
104
  }
99
105
  this.validateExisting(existing, call);
100
106
  try {
@@ -143,11 +149,11 @@ class ZLinkHostSpotAddressTransport {
143
149
  this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.ReplyReceived, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Request, spotId, request, existing.routerChannelId, existing.stableType, existing.targetNodeRid);
144
150
  return reply;
145
151
  }
146
- async requestToMissingInstance(spotId, request, call, deadline) {
152
+ async requestToMissingInstance(spotId, request, call, deadline, current) {
147
153
  if (!call.instanceSpot) {
148
154
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RequestTargetNotFound, `Spot '${String(spotId)}' has no Ready authority.`);
149
155
  }
150
- const selected = this.selectMissingTarget(spotId, call);
156
+ const selected = this.selectMissingTarget(spotId, call, current);
151
157
  if (selected.kind === 'capacity') {
152
158
  throw missingInstancePlacementCapacity(spotId, call.instanceSpotType);
153
159
  }
@@ -214,13 +220,15 @@ class ZLinkHostSpotAddressTransport {
214
220
  errorReason
215
221
  });
216
222
  }
217
- async resolveExisting(spotId, signal) {
223
+ async resolveExisting(spotId, signal, call) {
218
224
  const resolver = this.options.resolver();
219
225
  if (resolver === undefined) {
220
226
  throw new Error('Global Spot address resolution requires a Location Store.');
221
227
  }
222
228
  try {
223
- return await (0, abort_1.awaitWithAbort)(resolver.resolve(spotId, signal), signal);
229
+ return await (0, abort_1.awaitWithAbort)(call?.instanceSpot === true
230
+ ? resolver.resolve(spotId, signal, true)
231
+ : resolver.resolve(spotId, signal), signal);
224
232
  }
225
233
  catch (error) {
226
234
  if (error instanceof contracts_1.ZLinkFrameworkException &&
@@ -230,7 +238,11 @@ class ZLinkHostSpotAddressTransport {
230
238
  throw error;
231
239
  }
232
240
  }
233
- selectMissingTarget(spotId, call) {
241
+ reactivationCall(route, call) {
242
+ this.validateExisting(route, call);
243
+ return { ...call, initialMeshName: route.meshName, instanceSpotType: route.stableType };
244
+ }
245
+ selectMissingTarget(spotId, call, current) {
234
246
  const configuredMeshes = this.options.meshNames();
235
247
  if (call.initialMeshName !== undefined &&
236
248
  this.options.isMeshConfigured?.(call.initialMeshName) === false) {
@@ -253,11 +265,11 @@ class ZLinkHostSpotAddressTransport {
253
265
  const stableType = call.instanceSpotType ?? (distinctTypes.length === 1 ? distinctTypes[0] : undefined);
254
266
  if (stableType === undefined) {
255
267
  if (distinctTypes.length === 0)
256
- return { kind: 'unsupported' };
268
+ return { kind: current === undefined ? 'unsupported' : 'unavailable' };
257
269
  throw (0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.InvalidOperation, 'Instance Spot type is required when multiple types are registered.');
258
270
  }
259
271
  if (canInspectPlacementTypes && !distinctTypes.includes(stableType)) {
260
- return { kind: 'unsupported' };
272
+ return { kind: current === undefined ? 'unsupported' : 'unavailable' };
261
273
  }
262
274
  let unavailable = false;
263
275
  let capacity = false;
@@ -276,6 +288,7 @@ class ZLinkHostSpotAddressTransport {
276
288
  node,
277
289
  target: {
278
290
  ...placement.target,
291
+ targetMeshName: meshName,
279
292
  targetSpotId: String(spotId),
280
293
  stableType
281
294
  }
@@ -293,7 +306,7 @@ class ZLinkHostSpotAddressTransport {
293
306
  if (capacity)
294
307
  return { kind: 'capacity' };
295
308
  if (unsupported)
296
- return { kind: 'unsupported' };
309
+ return { kind: current === undefined ? 'unsupported' : 'unavailable' };
297
310
  return { kind: 'unavailable' };
298
311
  }
299
312
  validateExisting(target, call) {
@@ -25,12 +25,12 @@ class ZLinkSpotRuntimeOptionsFactory {
25
25
  ?.notifyPrimaryEntrySpotActorLeft(actor, signal, actorRef, membershipEpoch) ??
26
26
  Promise.resolve()
27
27
  },
28
- dispatchEntryActorPacket: (actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin) => {
28
+ dispatchEntryActorPacket: (origin, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin) => {
29
29
  const runtime = this.options.spotNodeRuntime();
30
30
  if (runtime === undefined) {
31
31
  throw new configuration_1.ZLinkConfigurationException('Entry Spot actor packet dispatch requires the MeshNode runtime.');
32
32
  }
33
- return runtime.dispatchEntryActorPacket(actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin);
33
+ return runtime.dispatchEntryActorPacket(origin, actorId, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef, requestTerminal, messageFollowOrigin);
34
34
  },
35
35
  dispatchEntryActorJoin: async (meshName, actor, handoffBacklog) => {
36
36
  const runtime = this.options.spotNodeRuntime();
@@ -5,6 +5,7 @@ import type { ZLinkAuthoritySnapshot, ZLinkLocationOwnerToken } from '../locatio
5
5
  import type { ZLinkAuthorityStore, ZLinkObjectCreationStore } from '../locations/internal-store-contracts';
6
6
  import type { ZLinkLocalSpotCreateResult } from '../spots/spot-manager-internal-contracts';
7
7
  export interface ZLinkUserSpotCreationCoordinatorOptions {
8
+ readonly relocationPolicy?: (meshName: string, stableType: string) => import('../locations/internal-location-contracts').ZLinkObjectReserveRequest['actorRelocationPolicy'];
8
9
  readonly store: ZLinkObjectCreationStore & ZLinkAuthorityStore;
9
10
  readonly target: (request: Pick<ZLinkUserSpotCreationRequest, 'meshName' | 'stableType'>, signal?: AbortSignal, excludedNodeRids?: ReadonlySet<string>) => Promise<{
10
11
  readonly meshName: string;
@@ -62,6 +62,7 @@ class ZLinkUserSpotCreationCoordinator {
62
62
  try {
63
63
  reserved = await this.options.store.reserve({
64
64
  key: { kind: 'user_spot', globalId: String(request.spotId) },
65
+ actorRelocationPolicy: this.options.relocationPolicy?.(target.meshName, request.stableType),
65
66
  intent: {
66
67
  stableType: request.stableType,
67
68
  requestContentReference: contentReference,
@@ -1,5 +1,6 @@
1
1
  import type { ZLinkLocationOwnerToken, ZLinkLocationPage, ZLinkLocationWriteIntent, ZLinkLocationWriteResult, ZLinkLocationWriteStatus, ZLinkMeshNodeDescriptor, ZLinkMeshNodeDescriptorKey, ZLinkClientServerServerDescriptor, ZLinkClientServerServerDescriptorKey, ZLinkFanoutPublisherDescriptor, ZLinkFanoutPublisherDescriptorKey, ZLinkOwnerLeaseClaimResult, ZLinkOwnerLeaseReadResult, ZLinkOwnerLeaseReleaseResult, ZLinkOwnerLeaseRenewResult, ZLinkPageRequest } from '../../contracts/Locations/Models';
2
- import type { ZLinkAggregateAbortResult, ZLinkAggregateCommitResult, ZLinkAggregateFence, ZLinkAggregatePrepareRequest, ZLinkAggregatePrepareResult, ZLinkAuthorityCompareExchangeResult, ZLinkAuthorityKey, ZLinkAuthorityMutation, ZLinkAuthorityReadResult, ZLinkAuthorityScanCursor, ZLinkAuthorityScanResult, ZLinkAuthorityStoreVersion, ZLinkCreationOperationIdentity, ZLinkCreationTerminalReadResult, ZLinkObjectAbortRequest, ZLinkObjectAbortResult, ZLinkObjectCommitRequest, ZLinkObjectCommitResult, ZLinkObjectCreationCompleteRequest, ZLinkObjectCreationCompleteResult, ZLinkObjectReserveRequest, ZLinkObjectReserveResult } from '../../contracts/Locations/Authority';
2
+ import type { ZLinkAggregateAbortResult, ZLinkAggregateCommitResult, ZLinkAggregateFence, ZLinkAggregatePrepareRequest, ZLinkAggregatePrepareResult, ZLinkAuthorityCompareExchangeResult, ZLinkAuthorityKey, ZLinkAuthorityMutation, ZLinkAuthorityReadResult, ZLinkAuthorityScanCursor, ZLinkAuthorityScanResult, ZLinkAuthorityStoreVersion, ZLinkCreationOperationIdentity, ZLinkCreationTerminalReadResult, ZLinkObjectAbortRequest, ZLinkObjectAbortResult, ZLinkObjectCommitRequest, ZLinkObjectCommitResult, ZLinkObjectCreationCompleteRequest, ZLinkObjectCreationCompleteResult, ZLinkObjectReserveResult } from '../../contracts/Locations/Authority';
3
+ import type { ZLinkObjectReserveRequest, ZLinkEndedOwnerReleaseIntent } from './internal-location-contracts';
3
4
  /**
4
5
  * Framework-private domain repository. Provider implementations never
5
6
  * implement this interface; the framework maps it to the opaque Store SPI.
@@ -25,7 +26,7 @@ export interface ZLinkDomainLocationStore {
25
26
  reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectReserveResult>;
26
27
  commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectCommitResult>;
27
28
  completeCreation(request: ZLinkObjectCreationCompleteRequest, signal?: AbortSignal): Promise<ZLinkObjectCreationCompleteResult>;
28
- releaseEndedReservation?(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
29
+ releaseEndedReservation?(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal, request?: ZLinkEndedOwnerReleaseIntent): Promise<boolean>;
29
30
  abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectAbortResult>;
30
31
  prepareAggregate(request: ZLinkAggregatePrepareRequest, signal?: AbortSignal): Promise<ZLinkAggregatePrepareResult>;
31
32
  commitAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateCommitResult>;
@@ -1,8 +1,10 @@
1
- import type { ZLinkAggregateAbortResult, ZLinkAggregateCommitResult, ZLinkAggregateFence, ZLinkAggregatePrepareRequest, ZLinkAggregatePrepareResult, ZLinkAuthorityCompareExchangeResult, ZLinkAuthorityKey, ZLinkAuthorityMutation, ZLinkAuthorityReadResult, ZLinkAuthorityScanCursor, ZLinkAuthorityScanResult, ZLinkAuthorityStoreVersion, ZLinkCapacityVector, ZLinkLocationOwnerToken, ZLinkMeshNodeDescriptorKey, ZLinkObjectAbortRequest, ZLinkObjectAbortResult, ZLinkObjectCommitRequest, ZLinkObjectCommitResult, ZLinkObjectCreationCompleteRequest, ZLinkObjectCreationCompleteResult, ZLinkObjectReserveRequest, ZLinkObjectReserveResult, ZLinkCreationOperationIdentity, ZLinkCreationTerminalReadResult } from './internal-location-contracts';
1
+ import type { ZLinkAggregateAbortResult, ZLinkAggregateCommitResult, ZLinkAggregateFence, ZLinkAggregatePrepareRequest, ZLinkAggregatePrepareResult, ZLinkAuthorityCompareExchangeResult, ZLinkAuthorityKey, ZLinkAuthorityMutation, ZLinkAuthorityReadResult, ZLinkAuthorityScanCursor, ZLinkAuthorityScanResult, ZLinkAuthorityStoreVersion, ZLinkCapacityVector, ZLinkLocationOwnerToken, ZLinkMeshNodeDescriptorKey, ZLinkObjectAbortRequest, ZLinkObjectAbortResult, ZLinkObjectCommitRequest, ZLinkObjectCommitResult, ZLinkObjectCreationCompleteRequest, ZLinkObjectCreationCompleteResult, ZLinkEndedOwnerReleaseIntent, ZLinkObjectReserveRequest, ZLinkObjectReserveResult, ZLinkCreationOperationIdentity, ZLinkCreationTerminalReadResult } from './internal-location-contracts';
2
2
  export interface ZLinkInMemoryAuthorityValidation {
3
+ isOwnerLive(owner: ZLinkLocationOwnerToken): boolean;
3
4
  isTargetLive(descriptor: ZLinkMeshNodeDescriptorKey, lifecycleGeneration: bigint, owner: ZLinkLocationOwnerToken): boolean;
4
5
  placementCapacityAvailable?(descriptor: ZLinkMeshNodeDescriptorKey, requested: ZLinkCapacityVector, currentReserved: ZLinkCapacityVector, currentActive: ZLinkCapacityVector): boolean;
5
6
  identityClaimed?(authorityKey: string): boolean;
7
+ hasSpotMembers?(spotId: string, objectGeneration: bigint): boolean;
6
8
  }
7
9
  /**
8
10
  * In-memory reference provider for the provider-owned authority state machine.
@@ -26,7 +28,8 @@ export declare class ZLinkInMemoryAuthorityStore {
26
28
  compareExchangeAuthority(key: ZLinkAuthorityKey, expectedStoreVersion: ZLinkAuthorityStoreVersion, mutation: ZLinkAuthorityMutation, signal?: AbortSignal): Promise<ZLinkAuthorityCompareExchangeResult>;
27
29
  listAuthorities(prefix: string, cursor: ZLinkAuthorityScanCursor | undefined, limit: number, signal?: AbortSignal): Promise<ZLinkAuthorityScanResult>;
28
30
  removeAllByOwner(owner: ZLinkLocationOwnerToken, signal?: AbortSignal): Promise<bigint>;
29
- releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal): Promise<boolean>;
31
+ releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal, request?: ZLinkEndedOwnerReleaseIntent): Promise<boolean>;
32
+ acceptsUserSpotMembership(spotId: string, objectGeneration: bigint): boolean;
30
33
  private tryReleaseEndedReservation;
31
34
  reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal): Promise<ZLinkObjectReserveResult>;
32
35
  commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal): Promise<ZLinkObjectCommitResult>;
@@ -6,12 +6,18 @@ const stream_wire_1 = require("@zlink-systems/stream-wire");
6
6
  const CoreTypes_1 = require("../../contracts/Common/CoreTypes");
7
7
  const Stores_1 = require("../../contracts/Locations/Stores");
8
8
  const node_crypto_1 = require("node:crypto");
9
+ const contracts_1 = require("../../contracts");
9
10
  const actor_join_recovery_codec_1 = require("../foundation/actor-join-recovery-codec");
10
11
  const authority_key_codec_1 = require("./authority-key-codec");
11
12
  const opaque_record_key_1 = require("./opaque-record-key");
13
+ const service_relocation_runtime_1 = require("../foundation/service-relocation-runtime");
14
+ const service_authority_payload_codec_1 = require("../foundation/service-authority-payload-codec");
15
+ const actor_authority_payload_codec_1 = require("../actors/actor-authority-payload-codec");
16
+ const contracts_2 = require("../../contracts");
12
17
  const MAX_GENERATION = 0x7fffffffffffffffn;
13
18
  const CREATION_TERMINAL_RETENTION_MS = 5 * 60 * 1000;
14
19
  const MAX_U64 = stream_wire_1.UINT64_MAX;
20
+ const relocationAuthorityCodec = new service_relocation_runtime_1.ServiceRelocationAuthorityPayloadCodec();
15
21
  /**
16
22
  * In-memory reference provider for the provider-owned authority state machine.
17
23
  * Opaque payload bytes are copied but never parsed.
@@ -105,6 +111,18 @@ class ZLinkInMemoryAuthorityStore {
105
111
  if (!this.isOwnerLive(row.snapshot)) {
106
112
  return { kind: 'conflict', current: this.read(keyValue) };
107
113
  }
114
+ const actor = row.snapshot.allocation.objectKind === 'actor'
115
+ ? (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(mutation.payload))
116
+ : undefined;
117
+ const previousActor = actor === undefined
118
+ ? undefined
119
+ : (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(row.snapshot.payload));
120
+ if (actor?.currentSpotKind === contracts_2.ZLinkSpotKind.User &&
121
+ (previousActor?.currentSpotKind !== contracts_2.ZLinkSpotKind.User ||
122
+ previousActor.currentSpotId !== actor.currentSpotId ||
123
+ previousActor.currentSpotGeneration !== actor.currentSpotGeneration) &&
124
+ !this.acceptsUserSpotMembership(actor.currentSpotId, actor.currentSpotGeneration))
125
+ return { kind: 'conflict', current: this.read(keyValue) };
108
126
  if (mutation.generationTransition === 'reincarnate' &&
109
127
  (this.objectGeneration >= MAX_GENERATION || this.ownerGeneration >= MAX_GENERATION)) {
110
128
  return { kind: 'generationExhausted' };
@@ -171,24 +189,77 @@ class ZLinkInMemoryAuthorityStore {
171
189
  this.scanRevision++;
172
190
  return BigInt(removed);
173
191
  }
174
- async releaseEndedReservation(key, expectedStoreVersion, signal) {
192
+ async releaseEndedReservation(key, expectedStoreVersion, signal, request) {
175
193
  signal?.throwIfAborted();
176
- return this.tryReleaseEndedReservation(key, expectedStoreVersion);
177
- }
178
- tryReleaseEndedReservation(key, expectedStoreVersion) {
194
+ return this.tryReleaseEndedReservation(key, expectedStoreVersion, request);
195
+ }
196
+ acceptsUserSpotMembership(spotId, objectGeneration) {
197
+ const row = this.rows.get((0, authority_key_codec_1.encodeAuthorityKey)('user_spot', spotId).value);
198
+ return (row !== undefined &&
199
+ row.snapshot.allocation.objectKind === 'user_spot' &&
200
+ row.snapshot.allocation.state === 'active' &&
201
+ row.snapshot.objectGeneration === objectGeneration &&
202
+ (0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(row.snapshot.payload)?.kind === 'user_spot' &&
203
+ this.isOwnerLive(row.snapshot));
204
+ }
205
+ tryReleaseEndedReservation(key, expectedStoreVersion, request) {
179
206
  const current = this.rows.get(key.value);
180
207
  if (current === undefined ||
181
208
  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, {
209
+ (current.snapshot.allocation.state === 'active'
210
+ ? request === undefined
211
+ : current.creation === undefined))
212
+ return false;
213
+ if (current.snapshot.allocation.state === 'active') {
214
+ let unavailable = false;
215
+ for (const aggregate of this.aggregates.values()) {
216
+ if (aggregate.state === 'prepared' &&
217
+ aggregate.request.participants.some((participant) => participant.authorityKey.value === key.value))
218
+ unavailable = true;
219
+ }
220
+ unavailable ||= relocationAuthorityCodec.read(current.snapshot.payload) !== undefined;
221
+ if (this.validation.isOwnerLive({
185
222
  ownerId: current.snapshot.ownerId,
186
223
  leaseGeneration: current.snapshot.ownerLeaseGeneration
187
224
  }))
225
+ return false;
226
+ const spot = current.snapshot.allocation.objectKind === 'actor'
227
+ ? undefined
228
+ : (0, service_authority_payload_codec_1.decodeServiceReadySpotAuthority)(current.snapshot.payload);
229
+ if (current.snapshot.allocation.objectKind !== 'actor') {
230
+ unavailable ||=
231
+ spot === undefined ||
232
+ spot.kind !== request?.key.kind ||
233
+ spot.stableType !== request.intent.stableType ||
234
+ spot.spotId !== request.key.globalId ||
235
+ spot.activationRecovery !== undefined;
236
+ if (spot?.kind === 'user_spot') {
237
+ unavailable ||=
238
+ this.validation.hasSpotMembers?.(spot.spotId, current.snapshot.objectGeneration) ===
239
+ true;
240
+ for (const row of this.rows.values()) {
241
+ if (row.snapshot.allocation.objectKind !== 'actor')
242
+ continue;
243
+ const actor = (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(row.snapshot.payload));
244
+ unavailable ||=
245
+ actor?.currentSpotKind === contracts_2.ZLinkSpotKind.User &&
246
+ actor.currentSpotId === spot.spotId &&
247
+ actor.currentSpotGeneration === current.snapshot.objectGeneration;
248
+ }
249
+ }
250
+ }
251
+ if (unavailable || request?.actorRelocationPolicy !== 'disabled')
252
+ throw new contracts_1.ZLinkFrameworkException(contracts_1.ZLinkFrameworkErrorKind.Unavailable, 'Object owner lease is unavailable.');
253
+ }
254
+ else if (this.validation.isTargetLive(current.snapshot.allocation.descriptor, current.snapshot.allocation.descriptorLifecycleGeneration, {
255
+ ownerId: current.snapshot.ownerId,
256
+ leaseGeneration: current.snapshot.ownerLeaseGeneration
257
+ }))
188
258
  return false;
189
- this.adjustCapacity(this.pendingCapacity, current.snapshot.allocation, -1);
259
+ this.adjustCapacity(current.snapshot.allocation.state === 'active' ? this.activeCapacity : this.pendingCapacity, current.snapshot.allocation, -1);
190
260
  this.rows.delete(key.value);
191
- this.creationTerminals.set(current.creation.reservationId, 'aborted');
261
+ if (current.snapshot.allocation.state === 'reserved' && current.creation !== undefined)
262
+ this.creationTerminals.set(current.creation.reservationId, 'aborted');
192
263
  this.scanRevision++;
193
264
  return true;
194
265
  }
@@ -205,11 +276,10 @@ class ZLinkInMemoryAuthorityStore {
205
276
  current.snapshot.allocation.stableType !== request.intent.stableType) {
206
277
  return { kind: 'typeMismatch', current: this.snapshot(current.snapshot) };
207
278
  }
208
- if (current.snapshot.allocation.state === 'active') {
209
- return { kind: 'alreadyExists', current: this.snapshot(current.snapshot) };
210
- }
211
- if (!this.tryReleaseEndedReservation((0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId), current.snapshot.storeVersion.value))
212
- return { kind: 'conflict', current: this.read(key) };
279
+ if (!this.tryReleaseEndedReservation((0, authority_key_codec_1.encodeAuthorityKey)(request.key.kind, request.key.globalId), current.snapshot.storeVersion.value, request))
280
+ return current.snapshot.allocation.state === 'active'
281
+ ? { kind: 'alreadyExists', current: this.snapshot(current.snapshot) }
282
+ : { kind: 'conflict', current: this.read(key) };
213
283
  }
214
284
  const target = creationTarget(request);
215
285
  if (!this.validation.isTargetLive(target.descriptor, target.lifecycleGeneration, target.owner)) {
@@ -336,6 +406,12 @@ class ZLinkInMemoryAuthorityStore {
336
406
  if (!this.creationTerminalAvailable(terminalRecord)) {
337
407
  return { kind: 'stale' };
338
408
  }
409
+ const actor = request.completion.kind === 'created'
410
+ ? (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(request.completion.readyPayload))
411
+ : undefined;
412
+ if (actor?.currentSpotKind === contracts_2.ZLinkSpotKind.User &&
413
+ !this.acceptsUserSpotMembership(actor.currentSpotId, actor.currentSpotGeneration))
414
+ return { kind: 'stale' };
339
415
  const nextVersion = this.tryNextStoreVersion();
340
416
  if (nextVersion === undefined)
341
417
  return { kind: 'generationExhausted' };
@@ -479,6 +555,23 @@ class ZLinkInMemoryAuthorityStore {
479
555
  row.snapshot.storeVersion.value !== participant.expectedStoreVersion.value) {
480
556
  return { kind: 'stale' };
481
557
  }
558
+ const actor = row.snapshot.allocation.objectKind === 'actor'
559
+ ? (0, actor_authority_payload_codec_1.decodeActorAuthorityPayload)((0, service_relocation_runtime_1.serviceRelocationAuthorityApplicationPayload)(participant.authorityPayload))
560
+ : undefined;
561
+ if (actor?.currentSpotKind === contracts_2.ZLinkSpotKind.User) {
562
+ const participantSpot = aggregate.request.participants.find((candidate) => candidate.authorityKey.value ===
563
+ (0, authority_key_codec_1.encodeAuthorityKey)('user_spot', actor.currentSpotId).value);
564
+ if (participantSpot === undefined) {
565
+ if (!this.acceptsUserSpotMembership(actor.currentSpotId, actor.currentSpotGeneration))
566
+ return { kind: 'stale' };
567
+ }
568
+ else {
569
+ const spot = this.rows.get(participantSpot.authorityKey.value);
570
+ if (spot?.snapshot.allocation.objectKind !== 'user_spot' ||
571
+ spot.snapshot.objectGeneration !== actor.currentSpotGeneration)
572
+ return { kind: 'stale' };
573
+ }
574
+ }
482
575
  if (participant.ownerTransition === 'newOwner') {
483
576
  if (!this.validation.isTargetLive(aggregate.request.targetDescriptor, aggregate.request.targetDescriptorLifecycleGeneration, aggregate.request.targetOwner)) {
484
577
  return { kind: 'stale' };
@@ -1,6 +1,6 @@
1
1
  import type { ZLinkActorTransferPrepareRequest, ZLinkActorTransferRecord, ZLinkActorTransferWriteResult } from '../../contracts/Locations/ActorTransfer';
2
2
  import type { ZLinkDomainLocationStore } from './domain-store-contract';
3
- import { ZLinkLocationWriteIntent, ZLinkLocationWriteStatus, type ZLinkActorLocation, type ZLinkActorLocationFilter, type ZLinkActorLocationKey, type ZLinkAggregateAbortResult, type ZLinkAggregateCommitResult, type ZLinkAggregateFence, type ZLinkAggregatePrepareRequest, type ZLinkAggregatePrepareResult, type ZLinkAuthorityCompareExchangeResult, type ZLinkAuthorityKey, type ZLinkAuthorityMutation, type ZLinkAuthorityReadResult, type ZLinkAuthorityScanCursor, type ZLinkAuthorityScanResult, type ZLinkAuthorityStoreVersion, type ZLinkClientServerServerDescriptor, type ZLinkClientServerServerDescriptorKey, type ZLinkCreationOperationIdentity, type ZLinkCreationTerminalReadResult, type ZLinkFanoutPublisherDescriptor, type ZLinkFanoutPublisherDescriptorKey, type ZLinkLocationChangeStampScope, type ZLinkLocationOwnerToken, type ZLinkLocationPage, type ZLinkLocationWriteResult, type ZLinkMeshNodeDescriptor, type ZLinkMeshNodeDescriptorKey, type ZLinkObjectAbortRequest, type ZLinkObjectAbortResult, type ZLinkObjectCommitRequest, type ZLinkObjectCommitResult, type ZLinkObjectCreationCompleteRequest, type ZLinkObjectCreationCompleteResult, type ZLinkObjectReserveRequest, type ZLinkObjectReserveResult, type ZLinkOwnerLeaseClaimResult, type ZLinkOwnerLeaseReadResult, type ZLinkOwnerLeaseReleaseResult, type ZLinkOwnerLeaseRenewResult, type ZLinkPageRequest, type ZLinkPeerLocation, type ZLinkPeerLocationFilter, type ZLinkPeerLocationKey, type ZLinkRouteLocation, type ZLinkRouteLocationFilter, type ZLinkRouteLocationKey, type ZLinkSpotLocation, type ZLinkSpotLocationFilter, type ZLinkSpotLocationKey } from './internal-location-contracts';
3
+ import { ZLinkLocationWriteIntent, ZLinkLocationWriteStatus, type ZLinkActorLocation, type ZLinkActorLocationFilter, type ZLinkActorLocationKey, type ZLinkAggregateAbortResult, type ZLinkAggregateCommitResult, type ZLinkAggregateFence, type ZLinkAggregatePrepareRequest, type ZLinkAggregatePrepareResult, type ZLinkAuthorityCompareExchangeResult, type ZLinkAuthorityKey, type ZLinkAuthorityMutation, type ZLinkAuthorityReadResult, type ZLinkAuthorityScanCursor, type ZLinkAuthorityScanResult, type ZLinkAuthorityStoreVersion, type ZLinkClientServerServerDescriptor, type ZLinkClientServerServerDescriptorKey, type ZLinkCreationOperationIdentity, type ZLinkCreationTerminalReadResult, type ZLinkFanoutPublisherDescriptor, type ZLinkFanoutPublisherDescriptorKey, type ZLinkLocationChangeStampScope, type ZLinkLocationOwnerToken, type ZLinkLocationPage, type ZLinkLocationWriteResult, type ZLinkMeshNodeDescriptor, type ZLinkMeshNodeDescriptorKey, type ZLinkObjectAbortRequest, type ZLinkObjectAbortResult, type ZLinkObjectCommitRequest, type ZLinkObjectCommitResult, type ZLinkObjectCreationCompleteRequest, type ZLinkObjectCreationCompleteResult, type ZLinkEndedOwnerReleaseIntent, type ZLinkObjectReserveRequest, type ZLinkObjectReserveResult, type ZLinkOwnerLeaseClaimResult, type ZLinkOwnerLeaseReadResult, type ZLinkOwnerLeaseReleaseResult, type ZLinkOwnerLeaseRenewResult, type ZLinkPageRequest, type ZLinkPeerLocation, type ZLinkPeerLocationFilter, type ZLinkPeerLocationKey, type ZLinkRouteLocation, type ZLinkRouteLocationFilter, type ZLinkRouteLocationKey, type ZLinkSpotLocation, type ZLinkSpotLocationFilter, type ZLinkSpotLocationKey } from './internal-location-contracts';
4
4
  import type { ZLinkFanoutLocationStore } from './internal-store-contracts';
5
5
  export declare class ZLinkInMemoryLocationStore implements ZLinkDomainLocationStore, ZLinkFanoutLocationStore {
6
6
  private readonly now;
@@ -25,7 +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
+ releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal, request?: ZLinkEndedOwnerReleaseIntent): Promise<boolean>;
29
29
  abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal): Promise<ZLinkObjectAbortResult>;
30
30
  prepareAggregate(request: ZLinkAggregatePrepareRequest, signal?: AbortSignal): Promise<ZLinkAggregatePrepareResult>;
31
31
  commitAggregate(fence: ZLinkAggregateFence, signal?: AbortSignal): Promise<ZLinkAggregateCommitResult>;
@@ -72,7 +72,7 @@ export declare class ZLinkInMemoryLocationStore implements ZLinkDomainLocationSt
72
72
  private transitionActorTransfer;
73
73
  private remove;
74
74
  private removeByOwner;
75
- private isOwnerLive;
75
+ private liveOwnerLease;
76
76
  private bump;
77
77
  private removeFanoutByOwner;
78
78
  private bumpScope;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZLinkInMemoryLocationStore = void 0;
4
+ const contracts_1 = require("../../contracts");
4
5
  const CoreTypes_1 = require("../../contracts/Common/CoreTypes");
5
6
  const RegistrationBuilderPolicy_1 = require("../../contracts/Configuration/RegistrationBuilderPolicy");
6
7
  const location_store_integration_1 = require("../../location-store-integration");
@@ -27,19 +28,19 @@ class ZLinkInMemoryLocationStore {
27
28
  authority;
28
29
  constructor(now = () => new Date()) {
29
30
  this.now = now;
31
+ const isOwnerLive = (owner) => this.liveOwnerLease(owner.ownerId, this.now())?.token.leaseGeneration ===
32
+ owner.leaseGeneration;
30
33
  this.authority = new in_memory_authority_store_1.ZLinkInMemoryAuthorityStore({
34
+ isOwnerLive,
31
35
  isTargetLive: (key, lifecycleGeneration, owner) => {
32
36
  const descriptor = this.meshNodes.rows.get(meshNodeKey(key.meshName, key.rid));
33
- const lease = this.leases.get(owner.ownerId);
34
37
  return (descriptor !== undefined &&
35
38
  descriptor.lifecycleGeneration === lifecycleGeneration &&
36
39
  descriptor.ownerId === owner.ownerId &&
37
40
  descriptor.leaseGeneration === owner.leaseGeneration &&
38
41
  descriptor.objectRole === internal_location_contracts_1.ZLinkObjectRole.Server &&
39
42
  descriptor.state === internal_location_contracts_1.ZLinkFrameworkRuntimeState.Serving &&
40
- lease !== undefined &&
41
- lease.token.leaseGeneration === owner.leaseGeneration &&
42
- lease.leaseExpiresAt.getTime() > this.now().getTime());
43
+ isOwnerLive(owner));
43
44
  },
44
45
  placementCapacityAvailable: (key, requested, reserved, active) => {
45
46
  const descriptor = this.meshNodes.rows.get(meshNodeKey(key.meshName, key.rid));
@@ -62,7 +63,16 @@ class ZLinkInMemoryLocationStore {
62
63
  spotType.count <=
63
64
  typeCapacity.limit))));
64
65
  },
65
- identityClaimed: (authorityKey) => this.entrySpotClaims.has(authorityKey)
66
+ identityClaimed: (authorityKey) => this.entrySpotClaims.has(authorityKey),
67
+ hasSpotMembers: (spotId, objectGeneration) => {
68
+ for (const actor of this.actors.rows.values()) {
69
+ if (actor.spotKind === contracts_1.ZLinkSpotKind.User &&
70
+ String(actor.spotId) === spotId &&
71
+ actor.spotGeneration === objectGeneration)
72
+ return true;
73
+ }
74
+ return false;
75
+ }
66
76
  }, now);
67
77
  }
68
78
  async readAuthority(key, signal) {
@@ -86,8 +96,8 @@ class ZLinkInMemoryLocationStore {
86
96
  async readCreationTerminal(operation, signal) {
87
97
  return this.authority.readCreationTerminal(operation, signal);
88
98
  }
89
- async releaseEndedReservation(key, expectedStoreVersion, signal) {
90
- return this.authority.releaseEndedReservation(key, expectedStoreVersion, signal);
99
+ async releaseEndedReservation(key, expectedStoreVersion, signal, request) {
100
+ return this.authority.releaseEndedReservation(key, expectedStoreVersion, signal, request);
91
101
  }
92
102
  async abort(request, signal) {
93
103
  return this.authority.abort(request, signal);
@@ -316,7 +326,7 @@ class ZLinkInMemoryLocationStore {
316
326
  async listFanoutPublishers(channelName, page = {}, signal) {
317
327
  signal?.throwIfAborted();
318
328
  const storeNow = this.now();
319
- return pageRows(this.fanoutPublishers, (row) => row.channelName === channelName && this.isOwnerLive(row.ownerId, storeNow), page);
329
+ return pageRows(this.fanoutPublishers, (row) => row.channelName === channelName && this.liveOwnerLease(row.ownerId, storeNow) !== undefined, page);
320
330
  }
321
331
  async updatePeer(peer, intent) {
322
332
  return this.write(this.peers, key_codec_1.ZLinkLocationKeyCodec.encodePeerKey({
@@ -342,7 +352,7 @@ class ZLinkInMemoryLocationStore {
342
352
  const current = this.spots.rows.get(key);
343
353
  if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim &&
344
354
  current !== undefined &&
345
- this.isOwnerLive(current.ownerId, updatedAt)) {
355
+ this.liveOwnerLease(current.ownerId, updatedAt) !== undefined) {
346
356
  return rejectedConflict();
347
357
  }
348
358
  if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.Renew) {
@@ -389,9 +399,15 @@ class ZLinkInMemoryLocationStore {
389
399
  });
390
400
  const updatedAt = this.now();
391
401
  const current = this.actors.rows.get(key);
402
+ if (actor.spotKind === contracts_1.ZLinkSpotKind.User &&
403
+ (current?.spotKind !== contracts_1.ZLinkSpotKind.User ||
404
+ String(current.spotId) !== String(actor.spotId) ||
405
+ current.spotGeneration !== actor.spotGeneration) &&
406
+ !this.authority.acceptsUserSpotMembership(String(actor.spotId), actor.spotGeneration))
407
+ return rejectedConflict();
392
408
  if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim &&
393
409
  current !== undefined &&
394
- this.isOwnerLive(current.ownerId, updatedAt)) {
410
+ this.liveOwnerLease(current.ownerId, updatedAt) !== undefined) {
395
411
  return rejectedConflict();
396
412
  }
397
413
  if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.Renew) {
@@ -651,7 +667,7 @@ class ZLinkInMemoryLocationStore {
651
667
  const current = table.rows.get(key);
652
668
  if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim &&
653
669
  current !== undefined &&
654
- this.isOwnerLive(ownerOf(current), updatedAt)) {
670
+ this.liveOwnerLease(ownerOf(current), updatedAt) !== undefined) {
655
671
  return rejectedConflict();
656
672
  }
657
673
  if (intent === internal_location_contracts_1.ZLinkLocationWriteIntent.NewClaim ||
@@ -714,9 +730,11 @@ class ZLinkInMemoryLocationStore {
714
730
  }
715
731
  return removed;
716
732
  }
717
- isOwnerLive(ownerId, now) {
733
+ liveOwnerLease(ownerId, now) {
718
734
  const lease = this.leases.get(ownerId);
719
- return lease !== undefined && lease.leaseExpiresAt.getTime() > now.getTime();
735
+ return lease !== undefined && lease.leaseExpiresAt.getTime() > now.getTime()
736
+ ? lease
737
+ : undefined;
720
738
  }
721
739
  bump(kind, meshName) {
722
740
  this.bumpScope({ kind, meshName });
@@ -1,4 +1,12 @@
1
1
  export * from '../../contracts/Locations';
2
+ import type { ZLinkObjectReserveRequest as ReserveRequest } from '../../contracts/Locations/Authority';
3
+ import type { ZLinkRelocationConfiguration } from '../../contracts/Configuration/RegistrationTypes';
4
+ export interface ZLinkObjectReserveRequest extends ReserveRequest {
5
+ readonly actorRelocationPolicy?: ZLinkRelocationConfiguration<unknown>['kind'];
6
+ }
7
+ export type ZLinkEndedOwnerReleaseIntent = Pick<ZLinkObjectReserveRequest, 'key' | 'actorRelocationPolicy'> & {
8
+ readonly intent: Pick<ZLinkObjectReserveRequest['intent'], 'stableType'>;
9
+ };
2
10
  export type * from '../../contracts/Locations/Authority';
3
11
  export type { ZLinkActorLocation, ZLinkPeerLocation, ZLinkRouteLocation, ZLinkSpotLocation } from '../../contracts/Locations/Rows';
4
12
  export type { ZLinkActorLocationFilter, ZLinkActorLocationKey, ZLinkLocationKey, ZLinkPeerLocationFilter, ZLinkPeerLocationKey, ZLinkRouteLocationFilter, ZLinkRouteLocationKey, ZLinkSpotLocationFilter, ZLinkSpotLocationKey } from '../../contracts/Locations/Keys';
@@ -1,6 +1,6 @@
1
1
  import { type ZLinkClientServerServerDescriptor, type ZLinkClientServerServerDescriptorKey, type ZLinkFanoutPublisherDescriptor, type ZLinkFanoutPublisherDescriptorKey, type ZLinkLocationPage, type ZLinkLocationStore, type ZLinkMeshNodeDescriptor, type ZLinkMeshNodeDescriptorKey, type ZLinkPageRequest } from '../../contracts';
2
2
  import { ZLinkInMemoryLocationStore } from './in-memory-location-store';
3
- import { type ZLinkActorLocation, type ZLinkActorLocationFilter, type ZLinkActorLocationKey, type ZLinkAggregateAbortResult, type ZLinkAggregateCommitResult, type ZLinkAggregateFence, type ZLinkAggregatePrepareRequest, type ZLinkAggregatePrepareResult, type ZLinkAuthorityCompareExchangeResult, type ZLinkAuthorityKey, type ZLinkAuthorityMutation, type ZLinkAuthorityReadResult, type ZLinkAuthorityScanCursor, type ZLinkAuthorityScanResult, type ZLinkAuthorityStoreVersion, type ZLinkCreationOperationIdentity, type ZLinkCreationTerminalReadResult, type ZLinkLocationOwnerToken, type ZLinkLocationWriteResult, type ZLinkLocationWriteStatus, type ZLinkObjectAbortRequest, type ZLinkObjectAbortResult, type ZLinkObjectCommitRequest, type ZLinkObjectCommitResult, type ZLinkObjectCreationCompleteRequest, type ZLinkObjectCreationCompleteResult, type ZLinkObjectReserveRequest, type ZLinkObjectReserveResult, type ZLinkOwnerLeaseClaimResult, type ZLinkOwnerLeaseReadResult, type ZLinkOwnerLeaseReleaseResult, type ZLinkOwnerLeaseRenewResult, type ZLinkRouteLocation, type ZLinkRouteLocationFilter, type ZLinkRouteLocationKey, type ZLinkSpotLocation, type ZLinkSpotLocationFilter, type ZLinkSpotLocationKey, ZLinkLocationWriteIntent } from './internal-location-contracts';
3
+ import { type ZLinkActorLocation, type ZLinkActorLocationFilter, type ZLinkActorLocationKey, type ZLinkAggregateAbortResult, type ZLinkAggregateCommitResult, type ZLinkAggregateFence, type ZLinkAggregatePrepareRequest, type ZLinkAggregatePrepareResult, type ZLinkAuthorityCompareExchangeResult, type ZLinkAuthorityKey, type ZLinkAuthorityMutation, type ZLinkAuthorityReadResult, type ZLinkAuthorityScanCursor, type ZLinkAuthorityScanResult, type ZLinkAuthorityStoreVersion, type ZLinkCreationOperationIdentity, type ZLinkCreationTerminalReadResult, type ZLinkLocationOwnerToken, type ZLinkLocationWriteResult, type ZLinkLocationWriteStatus, type ZLinkObjectAbortRequest, type ZLinkObjectAbortResult, type ZLinkObjectCommitRequest, type ZLinkObjectCommitResult, type ZLinkObjectCreationCompleteRequest, type ZLinkObjectCreationCompleteResult, type ZLinkEndedOwnerReleaseIntent, type ZLinkObjectReserveRequest, type ZLinkObjectReserveResult, type ZLinkOwnerLeaseClaimResult, type ZLinkOwnerLeaseReadResult, type ZLinkOwnerLeaseReleaseResult, type ZLinkOwnerLeaseRenewResult, type ZLinkRouteLocation, type ZLinkRouteLocationFilter, type ZLinkRouteLocationKey, type ZLinkSpotLocation, type ZLinkSpotLocationFilter, type ZLinkSpotLocationKey, ZLinkLocationWriteIntent } from './internal-location-contracts';
4
4
  /**
5
5
  * Maps framework domain records to the minimal provider SPI.
6
6
  *
@@ -20,7 +20,8 @@ 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
+ releaseEndedReservation(key: ZLinkAuthorityKey, expectedStoreVersion: string, signal?: AbortSignal, request?: ZLinkEndedOwnerReleaseIntent): Promise<boolean>;
24
+ private tryReleaseEndedReservation;
24
25
  reserve(request: ZLinkObjectReserveRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectReserveResult>;
25
26
  commit(request: ZLinkObjectCommitRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectCommitResult>;
26
27
  abort(request: ZLinkObjectAbortRequest, signal?: AbortSignal, deadlineUnixMs?: bigint): Promise<ZLinkObjectAbortResult>;
@@ -58,6 +59,7 @@ export declare class ZLinkLocationStoreRepository extends ZLinkInMemoryLocationS
58
59
  private writeDescriptorWithReconciliation;
59
60
  private removeDescriptor;
60
61
  private listDescriptors;
62
+ private userSpotMembershipConditions;
61
63
  private updateOwnedLocation;
62
64
  private removeOwnedLocation;
63
65
  private readOwnedLocation;