@zlink-systems/framework 0.30.0 → 0.30.1

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 (245) hide show
  1. package/LICENSE +150 -68
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
  4. package/dist/contracts/Channels/Calls.d.ts +2 -1
  5. package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
  6. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  7. package/dist/contracts/Handlers/Attributes.js +7 -11
  8. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  9. package/dist/contracts/Handlers/JsonContract.js +4 -153
  10. package/dist/contracts/Spots/Contracts.d.ts +2 -1
  11. package/dist/nest-integration.d.ts +1 -1
  12. package/dist/nest-integration.js +2 -1
  13. package/dist/runtime/actors/actor-client.d.ts +1 -1
  14. package/dist/runtime/actors/actor-client.js +14 -12
  15. package/dist/runtime/actors/actor-handoff.d.ts +1 -1
  16. package/dist/runtime/actors/actor-handoff.js +7 -4
  17. package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
  18. package/dist/runtime/actors/actor-local-native-join.js +9 -12
  19. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  20. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  21. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  22. package/dist/runtime/actors/index.d.ts +2 -1
  23. package/dist/runtime/actors/index.js +18 -6
  24. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  25. package/dist/runtime/admission.d.ts +1 -1
  26. package/dist/runtime/admission.js +15 -5
  27. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
  28. package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
  29. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +2 -1
  30. package/dist/runtime/application-jobs/application-job-queue-scope.js +37 -22
  31. package/dist/runtime/application-jobs/contracts.d.ts +10 -1
  32. package/dist/runtime/backend/contracts/index.d.ts +18 -9
  33. package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
  34. package/dist/runtime/backend/mesh-completion-table.js +149 -49
  35. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
  36. package/dist/runtime/backend/mesh-dispatch-pump.js +32 -11
  37. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
  38. package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
  39. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  40. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  41. package/dist/runtime/backend/node/node-raw-binding-port.js +42 -22
  42. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +13 -5
  43. package/dist/runtime/backend/node/node-raw-mesh-backend.js +69 -51
  44. package/dist/runtime/backend/node/node-socket-backend-adapter.js +6 -6
  45. package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
  46. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  47. package/dist/runtime/backend/runtime-message.js +5 -0
  48. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  49. package/dist/runtime/backend/runtime-values.js +2 -1
  50. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  51. package/dist/runtime/channels/channel-clients.js +58 -21
  52. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
  53. package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
  54. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  55. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  56. package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
  57. package/dist/runtime/channels/channel-dispatchers.js +27 -26
  58. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  59. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  60. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  61. package/dist/runtime/channels/channel-envelope.js +83 -8
  62. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  63. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  64. package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
  65. package/dist/runtime/channels/channel-runtime-manager.js +12 -12
  66. package/dist/runtime/channels/channel-transports.d.ts +18 -15
  67. package/dist/runtime/channels/channel-transports.js +48 -31
  68. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  69. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  70. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  71. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  72. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  73. package/dist/runtime/channels/source-spot-router.js +4 -4
  74. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  75. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  76. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  77. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  78. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  79. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  80. package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
  81. package/dist/runtime/execution/serial-execution-queue.js +1 -0
  82. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  83. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  84. package/dist/runtime/foundation/durable-service-request.js +98 -0
  85. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  86. package/dist/runtime/foundation/operation-identity.js +5 -1
  87. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +22 -5
  88. package/dist/runtime/foundation/raw-service-mesh-runtime.js +356 -232
  89. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
  90. package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
  91. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  92. package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
  93. package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
  94. package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -4
  95. package/dist/runtime/foundation/service-stateful-runtime.js +44 -103
  96. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +0 -5
  97. package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
  98. package/dist/runtime/foundation/service-topology-registry.js +61 -27
  99. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
  100. package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
  101. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  102. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  103. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  104. package/dist/runtime/host/application-job-queue.d.ts +19 -7
  105. package/dist/runtime/host/application-job-queue.js +150 -42
  106. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  107. package/dist/runtime/host/entry-actor-runtime.js +3 -0
  108. package/dist/runtime/host/index.d.ts +7 -1
  109. package/dist/runtime/host/index.js +142 -118
  110. package/dist/runtime/host/remote-bound-session-relay.js +2 -18
  111. package/dist/runtime/host/route-mesh-runtime.js +1 -1
  112. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  113. package/dist/runtime/host/service-relocation-control.js +10 -4
  114. package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
  115. package/dist/runtime/host/service-relocation-host-runtime.js +213 -241
  116. package/dist/runtime/host/spot-address-transport.js +3 -2
  117. package/dist/runtime/host/spot-runtime-options-factory.js +1 -0
  118. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  119. package/dist/runtime/locations/actor-location-claims.js +34 -19
  120. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  121. package/dist/runtime/locations/lifecycle.js +2 -5
  122. package/dist/runtime/locations/runtime.d.ts +1 -1
  123. package/dist/runtime/locations/runtime.js +24 -23
  124. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  125. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  126. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  127. package/dist/runtime/messaging/packet-name.js +8 -24
  128. package/dist/runtime/messaging/request-result.d.ts +2 -0
  129. package/dist/runtime/messaging/request-result.js +54 -0
  130. package/dist/runtime/messaging/submission-result.d.ts +1 -0
  131. package/dist/runtime/messaging/submission-result.js +5 -2
  132. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
  133. package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
  134. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
  135. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
  136. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
  137. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
  138. package/dist/runtime/spots/index.d.ts +3 -0
  139. package/dist/runtime/spots/index.js +9 -2
  140. package/dist/runtime/spots/spot-activation.d.ts +1 -0
  141. package/dist/runtime/spots/spot-activation.js +17 -8
  142. package/dist/runtime/spots/spot-entry-activation.js +6 -2
  143. package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
  144. package/dist/runtime/spots/spot-handler-registry.js +18 -8
  145. package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
  146. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  147. package/dist/runtime/spots/spot-outbound.js +24 -15
  148. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  149. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  150. package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -0
  151. package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
  152. package/dist/runtime/spots/spot-timer.js +1 -0
  153. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  154. package/dist/runtime/streams/stream-session-runtime.js +13 -27
  155. package/package.json +2 -2
  156. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  157. package/src/contracts/Channels/Calls.ts +2 -1
  158. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  159. package/src/contracts/Handlers/Attributes.ts +14 -21
  160. package/src/contracts/Handlers/JsonContract.ts +8 -216
  161. package/src/contracts/Spots/Contracts.ts +2 -1
  162. package/src/nest-integration.ts +1 -0
  163. package/src/runtime/actors/actor-client.ts +40 -16
  164. package/src/runtime/actors/actor-handoff.ts +9 -4
  165. package/src/runtime/actors/actor-join-relocation.ts +1 -0
  166. package/src/runtime/actors/actor-local-native-join.ts +17 -26
  167. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  168. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  169. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  170. package/src/runtime/actors/index.ts +19 -5
  171. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  172. package/src/runtime/admission.ts +18 -5
  173. package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
  174. package/src/runtime/application-jobs/application-job-queue-scope.ts +51 -22
  175. package/src/runtime/application-jobs/contracts.ts +14 -1
  176. package/src/runtime/backend/contracts/index.ts +53 -14
  177. package/src/runtime/backend/mesh-completion-table.ts +156 -57
  178. package/src/runtime/backend/mesh-dispatch-pump.ts +40 -10
  179. package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
  180. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  181. package/src/runtime/backend/node/node-raw-binding-port.ts +57 -30
  182. package/src/runtime/backend/node/node-raw-mesh-backend.ts +128 -65
  183. package/src/runtime/backend/node/node-socket-backend-adapter.ts +21 -6
  184. package/src/runtime/backend/raw-binding-port.ts +7 -2
  185. package/src/runtime/backend/runtime-message.ts +6 -0
  186. package/src/runtime/backend/runtime-values.ts +1 -0
  187. package/src/runtime/channels/channel-clients.ts +90 -41
  188. package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
  189. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  190. package/src/runtime/channels/channel-dispatchers.ts +29 -27
  191. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  192. package/src/runtime/channels/channel-envelope.ts +133 -8
  193. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  194. package/src/runtime/channels/channel-runtime-manager.ts +29 -12
  195. package/src/runtime/channels/channel-transports.ts +128 -60
  196. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  197. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  198. package/src/runtime/channels/source-spot-router.ts +8 -4
  199. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  200. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  201. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  202. package/src/runtime/execution/serial-execution-queue.ts +2 -0
  203. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  204. package/src/runtime/foundation/durable-service-request.ts +137 -0
  205. package/src/runtime/foundation/operation-identity.ts +5 -1
  206. package/src/runtime/foundation/raw-service-mesh-runtime.ts +484 -293
  207. package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
  208. package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
  209. package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
  210. package/src/runtime/foundation/service-stateful-runtime.ts +67 -125
  211. package/src/runtime/foundation/service-stateful-wire-codec.ts +0 -5
  212. package/src/runtime/foundation/service-topology-registry.ts +91 -36
  213. package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
  214. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  215. package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
  216. package/src/runtime/host/application-job-queue.ts +175 -41
  217. package/src/runtime/host/entry-actor-runtime.ts +4 -0
  218. package/src/runtime/host/index.ts +201 -156
  219. package/src/runtime/host/remote-bound-session-relay.ts +2 -23
  220. package/src/runtime/host/route-mesh-runtime.ts +1 -1
  221. package/src/runtime/host/service-relocation-control.ts +11 -5
  222. package/src/runtime/host/service-relocation-host-runtime.ts +315 -291
  223. package/src/runtime/host/spot-address-transport.ts +4 -2
  224. package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
  225. package/src/runtime/locations/actor-location-claims.ts +52 -30
  226. package/src/runtime/locations/lifecycle.ts +8 -26
  227. package/src/runtime/locations/runtime.ts +28 -24
  228. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  229. package/src/runtime/messaging/packet-name.ts +5 -25
  230. package/src/runtime/messaging/request-result.ts +58 -0
  231. package/src/runtime/messaging/submission-result.ts +5 -1
  232. package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
  233. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  234. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +43 -23
  235. package/src/runtime/spots/index.ts +14 -2
  236. package/src/runtime/spots/spot-activation.ts +28 -10
  237. package/src/runtime/spots/spot-entry-activation.ts +9 -2
  238. package/src/runtime/spots/spot-handler-registry.ts +41 -8
  239. package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
  240. package/src/runtime/spots/spot-outbound.ts +36 -16
  241. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  242. package/src/runtime/spots/spot-runtime-ports.ts +1 -0
  243. package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
  244. package/src/runtime/spots/spot-timer.ts +5 -1
  245. package/src/runtime/streams/stream-session-runtime.ts +12 -29
@@ -144,7 +144,8 @@ class ZLinkHostSpotAddressTransport {
144
144
  instanceSpot: call.instanceSpot,
145
145
  timeoutMs: deadline.requireRemaining(),
146
146
  signal: deadline.signal,
147
- metadata: call.metadata
147
+ metadata: call.metadata,
148
+ onAdmitted: call.onAdmitted
148
149
  }), deadline.signal);
149
150
  this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.ReplyReceived, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Request, spotId, request, existing.routerChannelId, existing.stableType, existing.targetNodeRid);
150
151
  return reply;
@@ -173,7 +174,7 @@ class ZLinkHostSpotAddressTransport {
173
174
  const table = this.options.completions(selected.meshName);
174
175
  if (table === undefined)
175
176
  throw new Error(`MeshNode '${selected.meshName}' completion table is not started.`);
176
- const completionPromise = table.submit(() => selected.node.requestToMissingInstanceSpot(selected.target, encoded, deadlineUnixMs, call.sourceSpot === undefined ? undefined : String(call.sourceSpot.routingId), call.metadata), deadline.signal);
177
+ const completionPromise = table.submit(() => selected.node.requestToMissingInstanceSpot(selected.target, encoded, deadlineUnixMs, call.sourceSpot === undefined ? undefined : String(call.sourceSpot.routingId), call.metadata, call.onAdmitted), deadline.signal);
177
178
  this.traceInstanceAddress(ZLinkDispatchOptions_1.ZLinkRuntimeMessageFlowOutcome.Sent, ZLinkDispatchOptions_1.ZLinkDispatchMessageKind.Request, spotId, request, selected.meshName, selected.target.stableType, selected.target.targetNodeRid);
178
179
  const completion = await (0, abort_1.awaitWithAbort)(completionPromise, deadline.signal);
179
180
  try {
@@ -178,6 +178,7 @@ class ZLinkSpotRuntimeOptionsFactory {
178
178
  contracts_1.ZLinkSpotRelocationCoordinationMode.FrameworkManaged);
179
179
  },
180
180
  actorTransferRuntime,
181
+ releaseActorMembers: (meshName, spotId) => this.options.actorManager()?.releaseSpotActorMembers(meshName, spotId) ?? Promise.resolve(),
181
182
  boundSessionRuntime: this.options.boundSessionRelay.boundSessions,
182
183
  actorHandoffRuntime: this.options.actorHandoff,
183
184
  metrics: this.options.metrics,
@@ -1,6 +1,7 @@
1
1
  import type { ActorRef, RoutingId } from '../../contracts/Common';
2
2
  import { type ZLinkActorLocation } from './internal-location-contracts';
3
3
  import type { ZLinkActorLocationStore, ZLinkAuthorityStore } from './internal-store-contracts';
4
+ import { ZLinkSpotKind } from '../../contracts/Spots';
4
5
  import type { IZLinkLocationLifecycleRuntime, ZLinkOwnershipLostEvent } from './lifecycle-runtime';
5
6
  export declare enum ZLinkActorClaimStatus {
6
7
  Claimed = "claimed",
@@ -31,8 +32,7 @@ export declare class ZLinkActorLocationClaims {
31
32
  claim(actorType: string, actorId: string, nodeRid: RoutingId, deactivate?: () => Promise<void>): Promise<ZLinkActorClaimResult>;
32
33
  setRef(actorType: string, actorId: string, actorRef: ActorRef, ownerNodeGeneration: bigint): Promise<void>;
33
34
  takeoverJoinedSpot(actorType: string, actorId: string, actorRef: ActorRef, spotMeshName: string, spotId: RoutingId, spotGeneration: bigint, membershipEpoch: bigint, ownerNodeGeneration: bigint, deactivate?: () => Promise<void>): Promise<ZLinkActorClaimResult>;
34
- notifyJoinedSpot(actorType: string, actorId: string, _spotMeshName: string, spotId: RoutingId, spotGeneration: bigint, membershipEpoch: bigint, ownerNodeGeneration: bigint): Promise<void>;
35
- notifyLeftSpot(actorType: string, actorId: string, entrySpotId: RoutingId, entrySpotGeneration: bigint, membershipEpoch: bigint, ownerNodeGeneration: bigint): Promise<void>;
35
+ commitMembership(actorType: string, actorRef: ActorRef, authorityOwnerGeneration: bigint, spotId: RoutingId, spotGeneration: bigint, spotKind: ZLinkSpotKind.Entry | ZLinkSpotKind.User, ownerNodeGeneration: bigint): Promise<void>;
36
36
  release(_actorType: string, actorId: string, actorRef?: ActorRef): Promise<void>;
37
37
  owns(_actorType: string, actorId: string): boolean;
38
38
  snapshot(actorId: string): ZLinkActorLocation | undefined;
@@ -6,6 +6,7 @@ const Spots_1 = require("../../contracts/Spots");
6
6
  const key_codec_1 = require("./key-codec");
7
7
  const authority_key_codec_1 = require("./authority-key-codec");
8
8
  const routing_id_1 = require("../routing-id");
9
+ const actor_authority_publication_1 = require("../actors/actor-authority-publication");
9
10
  var ZLinkActorClaimStatus;
10
11
  (function (ZLinkActorClaimStatus) {
11
12
  ZLinkActorClaimStatus["Claimed"] = "claimed";
@@ -149,25 +150,39 @@ class ZLinkActorLocationClaims {
149
150
  });
150
151
  return { status: ZLinkActorClaimStatus.Claimed, claimed, generation: result.generation };
151
152
  }
152
- async notifyJoinedSpot(actorType, actorId, _spotMeshName, spotId, spotGeneration, membershipEpoch, ownerNodeGeneration) {
153
- await this.renew(actorType, actorId, (row) => ({
154
- ...row,
155
- spotKind: Spots_1.ZLinkSpotKind.User,
156
- spotId,
157
- spotGeneration,
158
- membershipEpoch,
159
- ownerNodeGeneration
160
- }));
161
- }
162
- async notifyLeftSpot(actorType, actorId, entrySpotId, entrySpotGeneration, membershipEpoch, ownerNodeGeneration) {
163
- await this.renew(actorType, actorId, (row) => ({
164
- ...row,
165
- spotKind: Spots_1.ZLinkSpotKind.Entry,
166
- spotId: entrySpotId,
167
- spotGeneration: entrySpotGeneration,
168
- membershipEpoch,
169
- ownerNodeGeneration
170
- }));
153
+ async commitMembership(actorType, actorRef, authorityOwnerGeneration, spotId, spotGeneration, spotKind, ownerNodeGeneration) {
154
+ const actorId = actorRef.actorId;
155
+ const store = this.authorityStore;
156
+ const owner = this.runtime.currentOwnerToken;
157
+ if (store === undefined || owner === undefined) {
158
+ throw new Error('Actor membership commit requires Location Store authority and owner.');
159
+ }
160
+ const key = (0, authority_key_codec_1.encodeAuthorityKey)('actor', actorId);
161
+ const current = await store.readAuthority(key);
162
+ if (!matchesActorAuthority(current, actorRef, owner) ||
163
+ current.allocation.stableType !== actorType ||
164
+ current.authorityOwnerGeneration !== authorityOwnerGeneration ||
165
+ current.allocation.descriptorLifecycleGeneration !== ownerNodeGeneration) {
166
+ throw new Error(`Actor '${actorId}' membership authority fence does not match.`);
167
+ }
168
+ const identity = (0, actor_authority_publication_1.decodeActorAuthorityIdentity)(current.payload, current.objectGeneration);
169
+ if (identity === undefined ||
170
+ identity.actorType !== actorType ||
171
+ identity.ownerNodeGeneration !== ownerNodeGeneration ||
172
+ identity.owner.ownerId !== owner.ownerId ||
173
+ identity.owner.leaseGeneration !== owner.leaseGeneration ||
174
+ !(0, routing_id_1.routingIdsEqual)(identity.actor.nodeRid, actorRef.nodeRid) ||
175
+ identity.meshName !== actorRef.meshName) {
176
+ throw new Error(`Actor '${actorId}' membership authority identity does not match.`);
177
+ }
178
+ const result = await store.compareExchangeAuthority(key, current.storeVersion, {
179
+ kind: 'put',
180
+ generationTransition: 'preserve',
181
+ payload: (0, actor_authority_publication_1.rewriteActorAuthorityRoute)(current.payload, actorRef, String(spotId), spotGeneration, spotKind)
182
+ });
183
+ if (result.kind !== 'stored') {
184
+ throw new Error(`Actor '${actorId}' membership commit was rejected with status ${result.kind}.`);
185
+ }
171
186
  }
172
187
  async release(_actorType, actorId, actorRef) {
173
188
  const key = { meshName: this.entryMeshName, actorId };
@@ -19,8 +19,7 @@ export declare class ZLinkLocationLifecycle {
19
19
  claimActor(actorType: string, actorId: string, nodeRid: RoutingId, deactivate?: () => Promise<void>): Promise<ZLinkActorClaimResult>;
20
20
  setActorRef(actorType: string, actorId: string, actorRef: ActorRef, ownerNodeGeneration?: bigint): Promise<void>;
21
21
  takeoverActorJoinedSpot(actorType: string, actorId: string, actorRef: ActorRef, spotMeshName: string, spotId: RoutingId, spotGeneration: bigint, membershipEpoch: bigint, ownerNodeGeneration: bigint, deactivate?: () => Promise<void>): Promise<ZLinkActorClaimResult>;
22
- notifyActorJoinedSpot(actorType: string, actorId: string, spotMeshName: string, spotId: RoutingId, spotGeneration: bigint, membershipEpoch: bigint, ownerNodeGeneration: bigint): Promise<void>;
23
- notifyActorLeftSpot(actorType: string, actorId: string, entrySpotId: RoutingId, entrySpotGeneration: bigint, membershipEpoch: bigint, ownerNodeGeneration: bigint): Promise<void>;
22
+ commitActorMembership(actorType: string, actorRef: ActorRef, authorityOwnerGeneration: bigint, spotId: RoutingId, spotGeneration: bigint, spotKind: ZLinkSpotKind.Entry | ZLinkSpotKind.User, ownerNodeGeneration: bigint): Promise<void>;
24
23
  releaseActor(actorType: string, actorId: string, actorRef?: ActorRef): Promise<void>;
25
24
  ownsActor(actorType: string, actorId: string): boolean;
26
25
  actorLocationSnapshot(actorId: string): ZLinkActorLocation | undefined;
@@ -34,11 +34,8 @@ class ZLinkLocationLifecycle {
34
34
  async takeoverActorJoinedSpot(actorType, actorId, actorRef, spotMeshName, spotId, spotGeneration, membershipEpoch, ownerNodeGeneration, deactivate) {
35
35
  return await this.actorClaims.takeoverJoinedSpot(actorType, actorId, actorRef, spotMeshName, spotId, spotGeneration, membershipEpoch, ownerNodeGeneration, deactivate);
36
36
  }
37
- async notifyActorJoinedSpot(actorType, actorId, spotMeshName, spotId, spotGeneration, membershipEpoch, ownerNodeGeneration) {
38
- await this.actorClaims.notifyJoinedSpot(actorType, actorId, spotMeshName, spotId, spotGeneration, membershipEpoch, ownerNodeGeneration);
39
- }
40
- async notifyActorLeftSpot(actorType, actorId, entrySpotId, entrySpotGeneration, membershipEpoch, ownerNodeGeneration) {
41
- await this.actorClaims.notifyLeftSpot(actorType, actorId, entrySpotId, entrySpotGeneration, membershipEpoch, ownerNodeGeneration);
37
+ async commitActorMembership(actorType, actorRef, authorityOwnerGeneration, spotId, spotGeneration, spotKind, ownerNodeGeneration) {
38
+ await this.actorClaims.commitMembership(actorType, actorRef, authorityOwnerGeneration, spotId, spotGeneration, spotKind, ownerNodeGeneration);
42
39
  }
43
40
  async releaseActor(actorType, actorId, actorRef) {
44
41
  await this.actorClaims.release(actorType, actorId, actorRef);
@@ -83,7 +83,7 @@ export declare class ZLinkLocationRuntime implements ZLinkLocationRuntimeQuery {
83
83
  private readonly meshNames;
84
84
  private readonly leaseScopes;
85
85
  private readonly rewriteAuthorityPayloadForOwner?;
86
- private nextLeaseRenewAtMs?;
86
+ private leaseOperationStartedAtMs;
87
87
  private ownerToken?;
88
88
  private lastOwnerToken?;
89
89
  private ownerLeaseDeadlineMs?;
@@ -52,7 +52,7 @@ class ZLinkLocationRuntime {
52
52
  meshNames;
53
53
  leaseScopes;
54
54
  rewriteAuthorityPayloadForOwner;
55
- nextLeaseRenewAtMs;
55
+ leaseOperationStartedAtMs = 0;
56
56
  ownerToken;
57
57
  lastOwnerToken;
58
58
  ownerLeaseDeadlineMs;
@@ -191,12 +191,7 @@ class ZLinkLocationRuntime {
191
191
  const claim = this.renewOwnerLeaseOnce(signal, shutdownSignal);
192
192
  this.heartbeatRenewal = claim;
193
193
  try {
194
- const claimed = await claim;
195
- if (claimed) {
196
- this.scheduleHeartbeat();
197
- return;
198
- }
199
- this.nextLeaseRenewAtMs = this.monotonicNowMs() + this.options.ownerLeaseRenewIntervalMs;
194
+ await claim;
200
195
  this.scheduleHeartbeat();
201
196
  }
202
197
  catch (error) {
@@ -211,7 +206,7 @@ class ZLinkLocationRuntime {
211
206
  this.clearTimer(this.heartbeatTimer);
212
207
  this.heartbeatTimer = undefined;
213
208
  }
214
- this.nextLeaseRenewAtMs = undefined;
209
+ this.leaseOperationStartedAtMs = 0;
215
210
  this.ownerLeaseDeadlineMs = undefined;
216
211
  await this.cleanupOwner(signal);
217
212
  }
@@ -263,6 +258,7 @@ class ZLinkLocationRuntime {
263
258
  const wasOwnerLeaseUsable = this.ownerLeaseUsable;
264
259
  try {
265
260
  const renewStartedAtMs = this.monotonicNowMs();
261
+ this.leaseOperationStartedAtMs = renewStartedAtMs;
266
262
  const result = await withTimeout((renewSignal) => this.stores.ownerLeaseStore.renewOwnerLease(this.ownerToken, this.options.ownerLeaseTtlMs, renewSignal), this.options.ownerLeaseRenewTimeoutMs, signal);
267
263
  const renewCompletedAtMs = this.monotonicNowMs();
268
264
  if (result.kind !== 'renewed') {
@@ -303,10 +299,11 @@ class ZLinkLocationRuntime {
303
299
  }
304
300
  async claimFreshOwnerLease(signal, shutdownSignal) {
305
301
  const claimStartedAtMs = this.monotonicNowMs();
306
- const timeoutDeadline = performance.now() + this.options.ownerLeaseRenewTimeoutMs;
302
+ this.leaseOperationStartedAtMs = claimStartedAtMs;
303
+ const timeoutStartedAtMs = performance.now();
307
304
  let claim;
308
305
  try {
309
- claim = await this.claimOwnerLeaseWithConfirmation(timeoutDeadline, signal, shutdownSignal);
306
+ claim = await this.claimOwnerLeaseWithConfirmation(timeoutStartedAtMs, signal, shutdownSignal);
310
307
  }
311
308
  catch (error) {
312
309
  if (signal?.aborted === true)
@@ -334,7 +331,6 @@ class ZLinkLocationRuntime {
334
331
  this.ownerLeaseRenewedAt = claim.storeNow;
335
332
  this.setOwnerLeaseDeadline(claimStartedAtMs, claimCompletedAtMs, claim.leaseExpiresAt, claim.storeNow);
336
333
  this.lastError = undefined;
337
- this.nextLeaseRenewAtMs = this.monotonicNowMs() + this.options.ownerLeaseRenewIntervalMs;
338
334
  for (const handler of this.ownerLeaseRenewedHandlers) {
339
335
  handler({
340
336
  kind: 'renewed',
@@ -351,12 +347,12 @@ class ZLinkLocationRuntime {
351
347
  return false;
352
348
  }
353
349
  }
354
- async claimOwnerLeaseWithConfirmation(timeoutDeadline, signal, shutdownSignal) {
350
+ async claimOwnerLeaseWithConfirmation(timeoutStartedAtMs, signal, shutdownSignal) {
355
351
  signal?.throwIfAborted();
356
352
  let claim;
357
353
  let request;
358
354
  try {
359
- claim = await withTimeout((claimSignal) => (request = this.stores.ownerLeaseStore.claimOwnerLease(this.ownerId, this.options.ownerLeaseTtlMs, claimSignal)), remainingTimeoutMs(timeoutDeadline), signal);
355
+ claim = await withTimeout((claimSignal) => (request = this.stores.ownerLeaseStore.claimOwnerLease(this.ownerId, this.options.ownerLeaseTtlMs, claimSignal)), remainingTimeoutMs(timeoutStartedAtMs, this.options.ownerLeaseRenewTimeoutMs), signal);
360
356
  }
361
357
  catch (error) {
362
358
  if (error instanceof OwnerLeaseRenewTimeoutError)
@@ -364,7 +360,9 @@ class ZLinkLocationRuntime {
364
360
  if (signal?.aborted === true && request !== undefined) {
365
361
  const cleanupSignal = shutdownSignal?.();
366
362
  try {
367
- await withTimeout(() => request, cleanupSignal === undefined ? remainingTimeoutMs(timeoutDeadline) : undefined, cleanupSignal);
363
+ await withTimeout(() => request, cleanupSignal === undefined
364
+ ? remainingTimeoutMs(timeoutStartedAtMs, this.options.ownerLeaseRenewTimeoutMs)
365
+ : undefined, cleanupSignal);
368
366
  }
369
367
  catch (completionError) {
370
368
  if (cleanupSignal?.aborted === true ||
@@ -376,7 +374,7 @@ class ZLinkLocationRuntime {
376
374
  }
377
375
  }
378
376
  }
379
- const confirmed = await this.confirmOwnerLease(error, timeoutDeadline, signal, shutdownSignal);
377
+ const confirmed = await this.confirmOwnerLease(error, timeoutStartedAtMs, signal, shutdownSignal);
380
378
  if (confirmed !== undefined)
381
379
  return confirmed;
382
380
  throw error;
@@ -384,12 +382,14 @@ class ZLinkLocationRuntime {
384
382
  if (claim.kind !== 'conflict')
385
383
  return claim;
386
384
  const conflict = new ZLinkOwnerLeaseClaimError(claim.kind);
387
- return ((await this.confirmOwnerLease(conflict, timeoutDeadline, signal, shutdownSignal)) ?? claim);
385
+ return ((await this.confirmOwnerLease(conflict, timeoutStartedAtMs, signal, shutdownSignal)) ?? claim);
388
386
  }
389
- async confirmOwnerLease(originalError, timeoutDeadline, signal, shutdownSignal) {
387
+ async confirmOwnerLease(originalError, timeoutStartedAtMs, signal, shutdownSignal) {
390
388
  const cancelled = signal?.aborted === true;
391
389
  const cleanupSignal = cancelled ? shutdownSignal?.() : undefined;
392
- const confirmationTimeoutMs = cleanupSignal === undefined ? remainingTimeoutMs(timeoutDeadline) : undefined;
390
+ const confirmationTimeoutMs = cleanupSignal === undefined
391
+ ? remainingTimeoutMs(timeoutStartedAtMs, this.options.ownerLeaseRenewTimeoutMs)
392
+ : undefined;
393
393
  if (confirmationTimeoutMs !== undefined && confirmationTimeoutMs <= 0)
394
394
  throw originalError;
395
395
  let confirmed;
@@ -407,7 +407,9 @@ class ZLinkLocationRuntime {
407
407
  }
408
408
  if (signal?.aborted === true) {
409
409
  try {
410
- await withTimeout((releaseSignal) => this.stores.ownerLeaseStore.releaseOwnerLease(confirmed.token, releaseSignal), cleanupSignal === undefined ? remainingTimeoutMs(timeoutDeadline) : undefined, cleanupSignal);
410
+ await withTimeout((releaseSignal) => this.stores.ownerLeaseStore.releaseOwnerLease(confirmed.token, releaseSignal), cleanupSignal === undefined
411
+ ? remainingTimeoutMs(timeoutStartedAtMs, this.options.ownerLeaseRenewTimeoutMs)
412
+ : undefined, cleanupSignal);
411
413
  }
412
414
  catch (releaseError) {
413
415
  this.recordFailure(errorMessage(releaseError), 'owner_lease_release');
@@ -778,7 +780,7 @@ class ZLinkLocationRuntime {
778
780
  if (!this.started) {
779
781
  return;
780
782
  }
781
- const scheduledAt = this.nextLeaseRenewAtMs ?? this.monotonicNowMs() + this.options.ownerLeaseRenewIntervalMs;
783
+ const scheduledAt = this.leaseOperationStartedAtMs + this.options.ownerLeaseRenewIntervalMs;
782
784
  const delayMs = Math.max(0, scheduledAt - this.monotonicNowMs());
783
785
  this.heartbeatTimer = this.setTimer(() => {
784
786
  this.heartbeatTimer = undefined;
@@ -786,7 +788,6 @@ class ZLinkLocationRuntime {
786
788
  for (const scope of this.leaseScopes) {
787
789
  this.metrics?.recordOwnerLeaseRenewLateness(lateness, scope.kind, scope.name);
788
790
  }
789
- this.nextLeaseRenewAtMs = this.monotonicNowMs() + this.options.ownerLeaseRenewIntervalMs;
790
791
  if (this.ownerLeaseDeadlineMs !== undefined &&
791
792
  this.monotonicNowMs() >= this.ownerLeaseDeadlineMs) {
792
793
  this.ownerLeaseHealthy = false;
@@ -908,8 +909,8 @@ class OwnerLeaseRenewTimeoutError extends Error {
908
909
  this.name = 'OwnerLeaseRenewTimeoutError';
909
910
  }
910
911
  }
911
- function remainingTimeoutMs(timeoutDeadline) {
912
- return Math.max(0, timeoutDeadline - performance.now());
912
+ function remainingTimeoutMs(timeoutStartedAtMs, timeoutMs) {
913
+ return Math.max(0, timeoutMs - (performance.now() - timeoutStartedAtMs));
913
914
  }
914
915
  function errorMessage(error) {
915
916
  return error instanceof Error ? error.message : String(error);
@@ -1,7 +1,5 @@
1
- import type { ZLinkJsonSchema } from '../../contracts/Handlers/JsonContract';
1
+ import * as profile from '@zlink-systems/stream-wire/internal/json';
2
2
  export declare const FRAMEWORK_JSON_V1_PROFILE = "framework-json-v1";
3
- export interface FrameworkJsonParseOptions {
4
- readonly rejectPropertyName?: (name: string) => boolean;
5
- }
6
- export declare function stringifyFrameworkJsonV1(value: unknown, schema?: ZLinkJsonSchema): string;
7
- export declare function parseFrameworkJsonV1(text: string, options?: FrameworkJsonParseOptions, schema?: ZLinkJsonSchema): unknown;
3
+ export declare const stringifyFrameworkJsonV1: typeof profile.stringifyFrameworkJsonV1;
4
+ export declare const parseFrameworkJsonV1: typeof profile.parseFrameworkJsonV1;
5
+ export type { FrameworkJsonParseOptions } from '@zlink-systems/stream-wire/internal/json';
@@ -1,296 +1,40 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FRAMEWORK_JSON_V1_PROFILE = void 0;
4
- exports.stringifyFrameworkJsonV1 = stringifyFrameworkJsonV1;
5
- exports.parseFrameworkJsonV1 = parseFrameworkJsonV1;
6
- exports.FRAMEWORK_JSON_V1_PROFILE = 'framework-json-v1';
7
- const SIGNED_64_MIN = -(1n << 63n);
8
- const UNSIGNED_64_MAX = (1n << 64n) - 1n;
9
- function stringifyFrameworkJsonV1(value, schema) {
10
- if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
11
- throw new TypeError('framework-json-v1 payload is not a JSON value.');
12
- }
13
- const encoded = JSON.stringify(value, frameworkJsonV1Replacer);
14
- if (schema !== undefined) {
15
- validateFrameworkJsonV1Value(JSON.parse(encoded), schema, '$', false);
16
- }
17
- return encoded;
18
- }
19
- // Module-level so JSON.stringify does not allocate a fresh closure per
20
- // encoded message. On the root call `this` is the {'': value} wrapper, so
21
- // this[key] resolves the raw (pre-toJSON) source for every key including ''.
22
- function frameworkJsonV1Replacer(key, item) {
23
- const source = this[key];
24
- if (typeof source === 'number' && !Number.isFinite(source)) {
25
- throw new TypeError('framework-json-v1 only accepts finite JSON numbers.');
26
- }
27
- if (typeof source === 'bigint') {
28
- if (source < SIGNED_64_MIN || source > UNSIGNED_64_MAX) {
29
- throw new RangeError('framework-json-v1 64-bit integer is outside the supported range.');
30
- }
31
- return source.toString(10);
32
- }
33
- if (source instanceof Uint8Array) {
34
- return Buffer.from(source.buffer, source.byteOffset, source.byteLength).toString('base64');
35
- }
36
- if (source instanceof Date) {
37
- throw new TypeError('framework-json-v1 does not implicitly encode Date values.');
38
- }
39
- if (typeof source === 'object' &&
40
- source !== null &&
41
- typeof source.toJSON === 'function') {
42
- throw new TypeError('framework-json-v1 does not implicitly invoke custom toJSON methods.');
43
- }
44
- return item;
45
- }
46
- function parseFrameworkJsonV1(text, options = {}, schema) {
47
- if (text.charCodeAt(0) === 0xfeff) {
48
- throw new SyntaxError('framework-json-v1 does not allow a UTF-8 BOM.');
49
- }
50
- new JsonPropertyScanner(text, options).scan();
51
- const parsed = JSON.parse(text);
52
- return schema === undefined ? parsed : validateFrameworkJsonV1Value(parsed, schema, '$', true);
53
- }
54
- // Sticky pattern shared across scans; matching happens synchronously so the
55
- // mutable lastIndex never crosses calls.
56
- const NUMBER_TOKEN_PATTERN = /-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?/uy;
57
- const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u;
58
- const INT32_MIN = -2_147_483_648;
59
- const INT32_MAX = 2_147_483_647;
60
- const UINT32_MAX = 4_294_967_295;
61
- function validateFrameworkJsonV1Value(value, schema, path, decode) {
62
- switch (schema.type) {
63
- case 'boolean':
64
- if (typeof value !== 'boolean')
65
- schemaFailure(path, 'a boolean');
66
- return value;
67
- case 'string':
68
- if (typeof value !== 'string')
69
- schemaFailure(path, 'a string');
70
- return value;
71
- case 'number':
72
- if (typeof value !== 'number' || !Number.isFinite(value))
73
- schemaFailure(path, 'a finite number');
74
- return value;
75
- case 'int32':
76
- if (!Number.isInteger(value) ||
77
- value < INT32_MIN ||
78
- value > INT32_MAX) {
79
- schemaFailure(path, 'an int32 JSON number');
80
- }
81
- return value;
82
- case 'uint32':
83
- if (!Number.isInteger(value) || value < 0 || value > UINT32_MAX) {
84
- schemaFailure(path, 'a uint32 JSON number');
85
- }
86
- return value;
87
- case 'int64':
88
- return validateDecimalInteger(value, path, true, decode);
89
- case 'uint64':
90
- return validateDecimalInteger(value, path, false, decode);
91
- case 'bytes': {
92
- if (typeof value !== 'string' || !BASE64_PATTERN.test(value)) {
93
- schemaFailure(path, 'padded RFC 4648 base64');
94
- }
95
- const bytes = Buffer.from(value, 'base64');
96
- if (bytes.toString('base64') !== value)
97
- schemaFailure(path, 'canonical padded RFC 4648 base64');
98
- return decode ? Uint8Array.from(bytes) : value;
99
- }
100
- case 'enum':
101
- if (typeof value !== 'string' || !schema.names.includes(value)) {
102
- schemaFailure(path, `one of ${schema.names.join(', ')}`);
103
- }
104
- return value;
105
- case 'nullable':
106
- return value === null
107
- ? null
108
- : validateFrameworkJsonV1Value(value, schema.value, path, decode);
109
- case 'array':
110
- if (!Array.isArray(value))
111
- schemaFailure(path, 'an array');
112
- return value.map((item, index) => validateFrameworkJsonV1Value(item, schema.items, `${path}[${index}]`, decode));
113
- case 'record': {
114
- if (!isJsonObject(value))
115
- schemaFailure(path, 'an object');
116
- const result = {};
117
- for (const [name, item] of Object.entries(value)) {
118
- result[name] = validateFrameworkJsonV1Value(item, schema.values, `${path}.${name}`, decode);
119
- }
120
- return decode ? result : value;
121
- }
122
- case 'object': {
123
- if (!isJsonObject(value))
124
- schemaFailure(path, 'an object');
125
- const input = value;
126
- for (const name of schema.required) {
127
- if (!Object.prototype.hasOwnProperty.call(input, name)) {
128
- throw new TypeError(`framework-json-v1 required property '${path}.${name}' is missing.`);
129
- }
130
- }
131
- const result = {};
132
- for (const [name, item] of Object.entries(input)) {
133
- const propertySchema = schema.properties[name];
134
- if (propertySchema === undefined) {
135
- if (schema.additionalProperties === false) {
136
- throw new TypeError(`framework-json-v1 property '${path}.${name}' is not allowed.`);
137
- }
138
- continue;
139
- }
140
- result[name] = validateFrameworkJsonV1Value(item, propertySchema, `${path}.${name}`, decode);
141
- }
142
- return decode ? result : value;
143
- }
144
- }
145
- }
146
- function validateDecimalInteger(value, path, signed, decode) {
147
- if (typeof value !== 'string' || !/^(?:0|[1-9][0-9]*|-[1-9][0-9]*)$/u.test(value)) {
148
- schemaFailure(path, signed ? 'a canonical int64 decimal string' : 'a canonical uint64 decimal string');
149
- }
150
- const parsed = BigInt(value);
151
- const minimum = signed ? SIGNED_64_MIN : 0n;
152
- const maximum = signed ? (1n << 63n) - 1n : UNSIGNED_64_MAX;
153
- if (parsed < minimum || parsed > maximum)
154
- schemaFailure(path, signed ? 'an int64 value' : 'a uint64 value');
155
- return decode ? parsed : value;
156
- }
157
- function isJsonObject(value) {
158
- return typeof value === 'object' && value !== null && !Array.isArray(value);
159
- }
160
- function schemaFailure(path, expected) {
161
- throw new TypeError(`framework-json-v1 value '${path}' must be ${expected}.`);
162
- }
163
- class JsonPropertyScanner {
164
- text;
165
- options;
166
- index = 0;
167
- constructor(text, options) {
168
- this.text = text;
169
- this.options = options;
170
- }
171
- scan() {
172
- this.skipWhitespace();
173
- this.scanValue();
174
- this.skipWhitespace();
175
- if (this.index !== this.text.length)
176
- this.fail('trailing data');
177
- }
178
- scanValue() {
179
- this.skipWhitespace();
180
- const token = this.text[this.index];
181
- if (token === '{')
182
- return this.scanObject();
183
- if (token === '[')
184
- return this.scanArray();
185
- if (token === '"') {
186
- this.scanString();
187
- return;
188
- }
189
- if (token === 't')
190
- return this.scanLiteral('true');
191
- if (token === 'f')
192
- return this.scanLiteral('false');
193
- if (token === 'n')
194
- return this.scanLiteral('null');
195
- this.scanNumber();
196
- }
197
- scanObject() {
198
- this.index++;
199
- this.skipWhitespace();
200
- if (this.text[this.index] === '}') {
201
- this.index++;
202
- return;
203
- }
204
- const properties = new Set();
205
- for (;;) {
206
- this.skipWhitespace();
207
- if (this.text[this.index] !== '"')
208
- this.fail('object property name');
209
- const property = this.scanString();
210
- if (properties.has(property)) {
211
- throw new SyntaxError(`framework-json-v1 duplicate property '${property}'.`);
212
- }
213
- properties.add(property);
214
- if (this.options.rejectPropertyName?.(property) === true) {
215
- throw new SyntaxError(`framework-json-v1 property '${property}' is not allowed.`);
216
- }
217
- this.skipWhitespace();
218
- if (this.text[this.index] !== ':')
219
- this.fail("':' after object property");
220
- this.index++;
221
- this.scanValue();
222
- this.skipWhitespace();
223
- const delimiter = this.text[this.index++];
224
- if (delimiter === '}')
225
- return;
226
- if (delimiter !== ',')
227
- this.fail("',' or '}' after object property");
228
- }
229
- }
230
- scanArray() {
231
- this.index++;
232
- this.skipWhitespace();
233
- if (this.text[this.index] === ']') {
234
- this.index++;
235
- return;
236
- }
237
- for (;;) {
238
- this.scanValue();
239
- this.skipWhitespace();
240
- const delimiter = this.text[this.index++];
241
- if (delimiter === ']')
242
- return;
243
- if (delimiter !== ',')
244
- this.fail("',' or ']' after array item");
245
- }
246
- }
247
- scanString() {
248
- const start = this.index++;
249
- let sawEscape = false;
250
- for (;;) {
251
- if (this.index >= this.text.length)
252
- this.fail('unterminated string');
253
- const character = this.text[this.index++];
254
- if (character === '"') {
255
- // Without escapes the token content is verbatim; the outer
256
- // JSON.parse pass still rejects any raw control characters.
257
- return sawEscape
258
- ? JSON.parse(this.text.slice(start, this.index))
259
- : this.text.slice(start + 1, this.index - 1);
260
- }
261
- if (character === '\\') {
262
- sawEscape = true;
263
- if (this.index >= this.text.length)
264
- this.fail('unterminated escape');
265
- const escaped = this.text[this.index++];
266
- if (escaped === 'u')
267
- this.index += 4;
268
- }
269
- }
270
- }
271
- scanLiteral(value) {
272
- if (!this.text.startsWith(value, this.index))
273
- this.fail(value);
274
- this.index += value.length;
275
- }
276
- scanNumber() {
277
- NUMBER_TOKEN_PATTERN.lastIndex = this.index;
278
- const match = NUMBER_TOKEN_PATTERN.exec(this.text);
279
- if (match === null)
280
- this.fail('JSON value');
281
- this.index += match[0].length;
282
- }
283
- skipWhitespace() {
284
- for (;;) {
285
- const code = this.text.charCodeAt(this.index);
286
- if (code === 0x20 || code === 0x09 || code === 0x0a || code === 0x0d) {
287
- this.index += 1;
288
- continue;
289
- }
290
- return;
291
- }
292
- }
293
- fail(expected) {
294
- throw new SyntaxError(`framework-json-v1 expected ${expected} at offset ${this.index}.`);
295
- }
296
- }
36
+ exports.parseFrameworkJsonV1 = exports.stringifyFrameworkJsonV1 = exports.FRAMEWORK_JSON_V1_PROFILE = void 0;
37
+ const profile = __importStar(require("@zlink-systems/stream-wire/internal/json"));
38
+ exports.FRAMEWORK_JSON_V1_PROFILE = profile.FRAMEWORK_JSON_V1_PROFILE;
39
+ exports.stringifyFrameworkJsonV1 = profile.stringifyFrameworkJsonV1;
40
+ exports.parseFrameworkJsonV1 = profile.parseFrameworkJsonV1;
@@ -1,4 +1,4 @@
1
1
  import type { ZLinkPacketJsonContract } from '../../contracts/Handlers/JsonContract';
2
2
  export declare function resolveFrameworkPacketName(payload: unknown, explicitPacketName: string | undefined, surface: string): string;
3
3
  export declare function resolveFrameworkPacketJsonContract(payload: unknown, explicitPacketName?: string): ZLinkPacketJsonContract | undefined;
4
- export declare function readFrameworkPacketJsonContract(type: object, explicitPacketName?: string): ZLinkPacketJsonContract | undefined;
4
+ export { readFrameworkPacketJsonContract } from '@zlink-systems/stream-wire/internal/json';