@uns-kit/core 3.0.36 → 3.0.38

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 (57) hide show
  1. package/MIGRATIONS.md +76 -0
  2. package/README.md +11 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +2 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/runtime/application-handover-state.d.ts +13 -0
  8. package/dist/runtime/application-handover-state.d.ts.map +1 -0
  9. package/dist/runtime/application-handover-state.js +43 -0
  10. package/dist/runtime/application-handover-state.js.map +1 -0
  11. package/dist/runtime/input-queue-boundary.d.ts +15 -0
  12. package/dist/runtime/input-queue-boundary.d.ts.map +1 -0
  13. package/dist/runtime/input-queue-boundary.js +33 -0
  14. package/dist/runtime/input-queue-boundary.js.map +1 -0
  15. package/dist/runtime/mqtt-handover-state.d.ts +8 -1
  16. package/dist/runtime/mqtt-handover-state.d.ts.map +1 -1
  17. package/dist/runtime/mqtt-handover-state.js +11 -4
  18. package/dist/runtime/mqtt-handover-state.js.map +1 -1
  19. package/dist/runtime/process-work.d.ts +16 -0
  20. package/dist/runtime/process-work.d.ts.map +1 -0
  21. package/dist/runtime/process-work.js +34 -0
  22. package/dist/runtime/process-work.js.map +1 -0
  23. package/dist/uns/handover-manager.d.ts +8 -1
  24. package/dist/uns/handover-manager.d.ts.map +1 -1
  25. package/dist/uns/handover-manager.js +128 -24
  26. package/dist/uns/handover-manager.js.map +1 -1
  27. package/dist/uns/handover-shutdown.d.ts +2 -0
  28. package/dist/uns/handover-shutdown.d.ts.map +1 -1
  29. package/dist/uns/handover-shutdown.js +1 -1
  30. package/dist/uns/handover-shutdown.js.map +1 -1
  31. package/dist/uns/uns-interfaces.d.ts +6 -0
  32. package/dist/uns/uns-interfaces.d.ts.map +1 -1
  33. package/dist/uns/uns-interfaces.js.map +1 -1
  34. package/dist/uns/uns-proxy-process.d.ts +14 -0
  35. package/dist/uns/uns-proxy-process.d.ts.map +1 -1
  36. package/dist/uns/uns-proxy-process.js +94 -7
  37. package/dist/uns/uns-proxy-process.js.map +1 -1
  38. package/dist/uns-mqtt/mqtt-proxy.d.ts +1 -0
  39. package/dist/uns-mqtt/mqtt-proxy.d.ts.map +1 -1
  40. package/dist/uns-mqtt/mqtt-proxy.js +1 -0
  41. package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
  42. package/dist/uns-mqtt/mqtt-worker.d.ts.map +1 -1
  43. package/dist/uns-mqtt/mqtt-worker.js +11 -0
  44. package/dist/uns-mqtt/mqtt-worker.js.map +1 -1
  45. package/dist/uns-mqtt/subscription-readiness.d.ts +2 -0
  46. package/dist/uns-mqtt/subscription-readiness.d.ts.map +1 -1
  47. package/dist/uns-mqtt/subscription-readiness.js +5 -1
  48. package/dist/uns-mqtt/subscription-readiness.js.map +1 -1
  49. package/dist/uns-mqtt/throttled-queue.d.ts +5 -8
  50. package/dist/uns-mqtt/throttled-queue.d.ts.map +1 -1
  51. package/dist/uns-mqtt/throttled-queue.js +25 -1
  52. package/dist/uns-mqtt/throttled-queue.js.map +1 -1
  53. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts +10 -8
  54. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts.map +1 -1
  55. package/dist/uns-mqtt/uns-mqtt-proxy.js +43 -3
  56. package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
  57. package/package.json +1 -1
package/MIGRATIONS.md CHANGED
@@ -9,6 +9,82 @@ Agents must inspect the application's existing ownership and shutdown flow
9
9
  before editing it. The examples below describe the intended behavior, not a
10
10
  mechanical search-and-replace operation.
11
11
 
12
+ ## 3.0.38 - Bounded late-subscriber input boundary (format3)
13
+
14
+ When crossing `<3.0.38` to `>=3.0.38`, non-opt-in applications keep their existing
15
+ protocol. For opt-in correlated-v2 MQTT handover, both peers must use the new
16
+ format3 implementation. Format is bound
17
+ into the compatibility digest: a mixed old/new pair refuses while the source
18
+ remains active. Review an initial stop-before-start upgrade, then use matching
19
+ peers for live moves. Never relabel a business contract to bypass this check.
20
+
21
+ No application-specific migration hooks are introduced. Keep existing
22
+ `deferHandoverUntilReady`, semantic contracts and accepted-work/drain ownership.
23
+ The SDK checks fresh broker subscription acknowledgements and uniquely shared
24
+ ordered input before release, including sparse sources whose target missed old
25
+ packets. Without proof the source stays active and the target remains passive.
26
+ Only read-only preparation can repeat after delayed input; unknown import or
27
+ activation effects remain blocked. Equal values are not deduplicated.
28
+
29
+ This does not move persistent queues or guarantee replay of broker losses.
30
+ Use a reviewed reverse hot move for return ownership and retain existing fences.
31
+ See [protocol, example and limits](https://github.com/uns-openhub/uns-kit/blob/master/docs/mqtt-stateful-handover.md#sparse-input-and-late-subscribers-3038).
32
+
33
+ ## 3.0.37 - Application lifecycle, HTTP ownership and bounded RAM state
34
+
35
+ When crossing `<3.0.37` to `>=3.0.37`, existing non-opt-in consumers retain their
36
+ protocol. The API plugin now closes its HTTP server on shutdown and the cron
37
+ plugin stops owned schedules. Review existing signal handlers so one owner calls
38
+ `drainForMigration()` and reports an unsuccessful drain honestly.
39
+
40
+ For stateful live migration, pass `uns.handoverProtocol` to `UnsProxyProcess`,
41
+ set `deferHandoverUntilReady: true`, install every handler and participant, then
42
+ call `enableMigrationDrain()`. API-only applications call
43
+ `await runtime.prepareHandover(config.uns.instanceMode, config.uns.handover)`
44
+ before that readiness declaration. Use `installSignalHandlers()` only when the
45
+ application has no signal owner already. Declare `unsDatahub.mqttDrain` protocol1
46
+ and `unsDatahub.mqttHandover` protocol2 only after this actual wiring is verified.
47
+
48
+ Use the shared `ProcessWork` to track accepted asynchronous work. Stop timer and
49
+ poller admission in `handoverShutdown.onRelease`; await `accepted.drain()` in
50
+ `handoverShutdown.drain`. `handoverShutdown.onActivate` prepares application
51
+ owners before successor input resumes. Do not discard already admitted input by
52
+ checking `isActive()` in its callback. Do gate new background work. A failed or
53
+ uncertain output stays latched and blocks a successful receipt.
54
+
55
+ Applications with RAM state additionally supply `handoverState: { contract,
56
+ exportState, validateState, importState }`. Use a stable semantic contract, check
57
+ all fields before mutating anything, and include unfinished windows, active
58
+ session IDs, original timestamps, conditions and counters. The shared transport
59
+ bounds plain JSON to 768 KiB, depth32/50,000 nodes within its 1 MiB envelope.
60
+ It refuses oversized state without truncation. Keep credentials and executable
61
+ objects out of snapshots. Matching unchanged MQTT-only consumers retain format2;
62
+ applications opting into new state require matching contracts on both peers.
63
+ Do not bypass a refused comparison with a relabelled contract.
64
+
65
+ Example:
66
+
67
+ ```ts
68
+ const accepted = new ProcessWork();
69
+ const runtime = new UnsProxyProcess(host, {
70
+ processName, handoverProtocol: config.uns.handoverProtocol,
71
+ deferHandoverUntilReady: true,
72
+ handoverShutdown: { onRelease: stopTimers, drain: () => accepted.drain() },
73
+ handoverState: {
74
+ contract: 'accumulator-v1', exportState: () => accumulator,
75
+ validateState: value => accumulatorSchema.parse(value),
76
+ importState: value => { accumulator = accumulatorSchema.parse(value); },
77
+ },
78
+ });
79
+ ```
80
+
81
+ The API plugin keeps passive routes unpublished, rejects passive requests with a
82
+ retryable 503 and drains accepted requests. Cron work is gated by ownership.
83
+ These mechanisms do not move disk queues or eliminate every routing gap. An
84
+ unknown external effect remains uncertain; reconcile the original operation and
85
+ use a reviewed reverse handover for return ownership. Ordinary SDK version
86
+ alignment alone does not enable a live migration.
87
+
12
88
  ## 3.0.36 - Unitless state and passive background publishers
13
89
 
14
90
  When crossing `<3.0.36` to `>=3.0.36`, MQTT handover preserves absent units
package/README.md CHANGED
@@ -273,6 +273,17 @@ and apply only the migrations whose version boundaries are crossed. The
273
273
  `3.0.0` migration documents the MQTT table-column object contract, while the
274
274
  `2.0.71` migration documents MQTT publish and shutdown ownership changes.
275
275
 
276
+ ## State-preserving MQTT handover
277
+
278
+ Correlated-v2 MQTT handover in3.0.38 verifies a uniquely shared input boundary
279
+ before releasing the source, including a late subscriber that missed older
280
+ packets. Both peers need format3; mixed old/new formats refuse before freeze.
281
+ Retain semantic contracts, accepted-work drain and restart fences. Missing or
282
+ ambiguous overlap and unknown activation results stay blocked.
283
+ See the [protocol, example and limits](https://github.com/uns-openhub/uns-kit/blob/master/docs/mqtt-stateful-handover.md)
284
+ and the version-bounded3.0.38 entry in `MIGRATIONS.md`. This does not transfer
285
+ persistent queues or promise replay of broker losses.
286
+
276
287
  ## Optional configuration-owned process groups
277
288
 
278
289
  Version3.0.29 adds optional shared contracts for immutable application-owned JSON
package/dist/index.d.ts CHANGED
@@ -17,4 +17,6 @@ export { registerService } from "./tools/datahub/runtime-service-registration.js
17
17
  export type { RegisterServiceOptions, RuntimeServiceDescriptor, RuntimeServiceRegistration, RuntimeServiceRegistrationClient, } from "./tools/datahub/runtime-service-registration.js";
18
18
  export { mqttPublishQueueSchema } from "./uns-mqtt/publish-queue-contract.js";
19
19
  export type { MqttPublishQueueOptions, MqttPublishQueueStatus } from "./uns-mqtt/publish-queue-contract.js";
20
+ export { ProcessWork } from "./runtime/process-work.js";
21
+ export { createApplicationHandoverContract, cloneApplicationHandoverState, type ApplicationHandoverState } from "./runtime/application-handover-state.js";
20
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACxE,YAAY,EACV,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACzF,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACzE,YAAY,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EACL,SAAS,EACT,eAAe,EACf,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,YAAY,EACZ,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,gCAAgC,EAChC,wCAAwC,EACxC,wCAAwC,GACzC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,iDAAiD,CAAC;AAClF,YAAY,EACV,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,iDAAiD,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACxE,YAAY,EACV,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACzF,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACzE,YAAY,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EACL,SAAS,EACT,eAAe,EACf,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,YAAY,EACZ,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,gCAAgC,EAChC,wCAAwC,EACxC,wCAAwC,GACzC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,iDAAiD,CAAC;AAClF,YAAY,EACV,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,iDAAiD,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE5G,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iCAAiC,EAAE,6BAA6B,EAAE,KAAK,wBAAwB,EAAE,MAAM,yCAAyC,CAAC"}
package/dist/index.js CHANGED
@@ -10,4 +10,6 @@ export { AuthClient, ServiceTokenProvider } from "./tools/auth/index.js";
10
10
  export { UnsClient, LastValueResult, ClientError, RangeResult, BatchRangeTopicResult, BatchRangeResponse, } from "./tools/datahub/datahub-client.js";
11
11
  export { registerService } from "./tools/datahub/runtime-service-registration.js";
12
12
  export { mqttPublishQueueSchema } from "./uns-mqtt/publish-queue-contract.js";
13
+ export { ProcessWork } from "./runtime/process-work.js";
14
+ export { createApplicationHandoverContract, cloneApplicationHandoverState } from "./runtime/application-handover-state.js";
13
15
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAOxE,cAAc,yBAAyB,CAAC;AAExC,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAEzF,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EACL,SAAS,EACT,eAAe,EACf,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,mCAAmC,CAAC;AAgB3C,OAAO,EAAE,eAAe,EAAE,MAAM,iDAAiD,CAAC;AAQlF,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC","sourcesContent":["export { default as UnsProxyProcess } from \"./uns/uns-proxy-process.js\";\nexport type {\n UnsProxyProcessPlugin,\n UnsProxyProcessPluginApi,\n UnsProxyProcessPluginMethod,\n UnsProxyProcessPluginMethods,\n} from \"./uns/uns-proxy-process.js\";\nexport * from \"./uns/uns-interfaces.js\";\nexport type { HandoverShutdownHooks } from \"./uns/handover-shutdown.js\";\nexport * from \"./uns/service-metadata.js\";\nexport { ConfigFile } from \"./config-file.js\";\nexport { default as logger } from \"./logger.js\";\nexport { getLogger } from \"./logger.js\";\nexport { resolveInfisicalConfig } from \"./uns-config/secret-resolver.js\";\nexport { mqttChannelParameters, resolveMqttChannel } from \"./uns-config/mqtt-channel.js\";\nexport type { MqttChannelConfig, ResolvedMqttChannel } from \"./uns-config/mqtt-channel.js\";\nexport { AuthClient, ServiceTokenProvider } from \"./tools/auth/index.js\";\nexport type { AccessTokenProvider, ServiceTokenProviderOptions } from \"./tools/auth/index.js\";\nexport {\n UnsClient,\n LastValueResult,\n ClientError,\n RangeResult,\n BatchRangeTopicResult,\n BatchRangeResponse,\n} from \"./tools/datahub/datahub-client.js\";\nexport type {\n LastValuePayload,\n CatchAllTimeField,\n CatchAllAggregate,\n RangeQueryOptions,\n RangeColumn,\n RangeStats,\n RangePayload,\n BatchRangeTopicPayload,\n BatchRangeResponsePayload,\n ProviderAssetIdentity,\n AssetIdentityPublicationMetadata,\n AssetProviderIdentityPublicationMetadata,\n AssetIdentityPublicationEvidenceMetadata,\n} from \"./tools/datahub/datahub-client.js\";\nexport { registerService } from \"./tools/datahub/runtime-service-registration.js\";\nexport type {\n RegisterServiceOptions,\n RuntimeServiceDescriptor,\n RuntimeServiceRegistration,\n RuntimeServiceRegistrationClient,\n} from \"./tools/datahub/runtime-service-registration.js\";\n\nexport { mqttPublishQueueSchema } from \"./uns-mqtt/publish-queue-contract.js\";\nexport type { MqttPublishQueueOptions, MqttPublishQueueStatus } from \"./uns-mqtt/publish-queue-contract.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAOxE,cAAc,yBAAyB,CAAC;AAExC,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAEzF,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EACL,SAAS,EACT,eAAe,EACf,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,mCAAmC,CAAC;AAgB3C,OAAO,EAAE,eAAe,EAAE,MAAM,iDAAiD,CAAC;AAQlF,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAG9E,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iCAAiC,EAAE,6BAA6B,EAAiC,MAAM,yCAAyC,CAAC","sourcesContent":["export { default as UnsProxyProcess } from \"./uns/uns-proxy-process.js\";\nexport type {\n UnsProxyProcessPlugin,\n UnsProxyProcessPluginApi,\n UnsProxyProcessPluginMethod,\n UnsProxyProcessPluginMethods,\n} from \"./uns/uns-proxy-process.js\";\nexport * from \"./uns/uns-interfaces.js\";\nexport type { HandoverShutdownHooks } from \"./uns/handover-shutdown.js\";\nexport * from \"./uns/service-metadata.js\";\nexport { ConfigFile } from \"./config-file.js\";\nexport { default as logger } from \"./logger.js\";\nexport { getLogger } from \"./logger.js\";\nexport { resolveInfisicalConfig } from \"./uns-config/secret-resolver.js\";\nexport { mqttChannelParameters, resolveMqttChannel } from \"./uns-config/mqtt-channel.js\";\nexport type { MqttChannelConfig, ResolvedMqttChannel } from \"./uns-config/mqtt-channel.js\";\nexport { AuthClient, ServiceTokenProvider } from \"./tools/auth/index.js\";\nexport type { AccessTokenProvider, ServiceTokenProviderOptions } from \"./tools/auth/index.js\";\nexport {\n UnsClient,\n LastValueResult,\n ClientError,\n RangeResult,\n BatchRangeTopicResult,\n BatchRangeResponse,\n} from \"./tools/datahub/datahub-client.js\";\nexport type {\n LastValuePayload,\n CatchAllTimeField,\n CatchAllAggregate,\n RangeQueryOptions,\n RangeColumn,\n RangeStats,\n RangePayload,\n BatchRangeTopicPayload,\n BatchRangeResponsePayload,\n ProviderAssetIdentity,\n AssetIdentityPublicationMetadata,\n AssetProviderIdentityPublicationMetadata,\n AssetIdentityPublicationEvidenceMetadata,\n} from \"./tools/datahub/datahub-client.js\";\nexport { registerService } from \"./tools/datahub/runtime-service-registration.js\";\nexport type {\n RegisterServiceOptions,\n RuntimeServiceDescriptor,\n RuntimeServiceRegistration,\n RuntimeServiceRegistrationClient,\n} from \"./tools/datahub/runtime-service-registration.js\";\n\nexport { mqttPublishQueueSchema } from \"./uns-mqtt/publish-queue-contract.js\";\nexport type { MqttPublishQueueOptions, MqttPublishQueueStatus } from \"./uns-mqtt/publish-queue-contract.js\";\n\nexport { ProcessWork } from \"./runtime/process-work.js\";\nexport { createApplicationHandoverContract, cloneApplicationHandoverState, type ApplicationHandoverState } from \"./runtime/application-handover-state.js\";\n"]}
@@ -0,0 +1,13 @@
1
+ /** Versioned application-owned RAM state; SDK owns bounds, peer binding and transport. */
2
+ export interface ApplicationHandoverState {
3
+ contract: string;
4
+ exportState(): unknown;
5
+ validateState(value: unknown): void;
6
+ importState(value: unknown): void | Promise<void>;
7
+ }
8
+ export declare function validateApplicationHandoverContract(state?: ApplicationHandoverState): void;
9
+ /** Plain bounded JSON only. No files, executable code, credentials or implicit truncation. */
10
+ export declare function cloneApplicationHandoverState(value: unknown): unknown;
11
+ /** Bind application-selected business resources without transmitting their contents. */
12
+ export declare function createApplicationHandoverContract(revision: string, resources: unknown): string;
13
+ //# sourceMappingURL=application-handover-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-handover-state.d.ts","sourceRoot":"","sources":["../../src/runtime/application-handover-state.ts"],"names":[],"mappings":"AAEA,0FAA0F;AAC1F,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACpC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAED,wBAAgB,mCAAmC,CAAC,KAAK,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAM1F;AAED,8FAA8F;AAC9F,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAiBrE;AAED,wFAAwF;AACxF,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAM9F"}
@@ -0,0 +1,43 @@
1
+ import { createHash } from 'node:crypto';
2
+ export function validateApplicationHandoverContract(state) {
3
+ if (!state)
4
+ return;
5
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9._:/-]{0,127}$/.test(state.contract) ||
6
+ [state.exportState, state.validateState, state.importState].some(fn => typeof fn !== "function")) {
7
+ throw new TypeError("Invalid application handover contract");
8
+ }
9
+ }
10
+ /** Plain bounded JSON only. No files, executable code, credentials or implicit truncation. */
11
+ export function cloneApplicationHandoverState(value) {
12
+ let nodes = 0;
13
+ const visit = (item, depth) => {
14
+ if (++nodes > 50000 || depth > 32)
15
+ throw new Error("Application handover state exceeds structural bounds");
16
+ if (item === null || typeof item === "string" || typeof item === "boolean")
17
+ return;
18
+ if (typeof item === "number" && Number.isFinite(item))
19
+ return;
20
+ if (!item || typeof item !== "object" || (!Array.isArray(item) && Object.getPrototypeOf(item) !== Object.prototype))
21
+ throw new TypeError("Application handover state must be plain JSON");
22
+ for (const [key, child] of Object.entries(item)) {
23
+ if (["__proto__", "constructor", "prototype"].includes(key))
24
+ throw new Error("Unsafe application state key");
25
+ visit(child, depth + 1);
26
+ }
27
+ };
28
+ visit(value, 0);
29
+ const json = JSON.stringify(value);
30
+ if (Buffer.byteLength(json) > 768 * 1024)
31
+ throw new Error("Application handover state exceeds byte bound");
32
+ return JSON.parse(json);
33
+ }
34
+ /** Bind application-selected business resources without transmitting their contents. */
35
+ export function createApplicationHandoverContract(revision, resources) {
36
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,59}$/.test(revision))
37
+ throw Error("Invalid application state revision");
38
+ const normalized = cloneApplicationHandoverState(resources);
39
+ const stable = (value) => Array.isArray(value) ? value.map(stable)
40
+ : value && typeof value === 'object' ? Object.fromEntries(Object.keys(value).sort().map(key => [key, stable(value[key])])) : value;
41
+ return revision + '/' + createHash('sha256').update(JSON.stringify(stable(normalized))).digest('hex');
42
+ }
43
+ //# sourceMappingURL=application-handover-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-handover-state.js","sourceRoot":"","sources":["../../src/runtime/application-handover-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\n\n/** Versioned application-owned RAM state; SDK owns bounds, peer binding and transport. */\nexport interface ApplicationHandoverState {\n contract: string;\n exportState(): unknown;\n validateState(value: unknown): void;\n importState(value: unknown): void | Promise<void>;\n}\n\nexport function validateApplicationHandoverContract(state?: ApplicationHandoverState): void {\n if (!state) return;\n if (!/^[a-zA-Z0-9][a-zA-Z0-9._:/-]{0,127}$/.test(state.contract) ||\n [state.exportState, state.validateState, state.importState].some(fn => typeof fn !== \"function\")) {\n throw new TypeError(\"Invalid application handover contract\");\n }\n}\n\n/** Plain bounded JSON only. No files, executable code, credentials or implicit truncation. */\nexport function cloneApplicationHandoverState(value: unknown): unknown {\n let nodes = 0;\n const visit = (item: unknown, depth: number): void => {\n if (++nodes > 50000 || depth > 32) throw new Error(\"Application handover state exceeds structural bounds\");\n if (item === null || typeof item === \"string\" || typeof item === \"boolean\") return;\n if (typeof item === \"number\" && Number.isFinite(item)) return;\n if (!item || typeof item !== \"object\" || (!Array.isArray(item) && Object.getPrototypeOf(item) !== Object.prototype))\n throw new TypeError(\"Application handover state must be plain JSON\");\n for (const [key, child] of Object.entries(item)) {\n if ([\"__proto__\", \"constructor\", \"prototype\"].includes(key)) throw new Error(\"Unsafe application state key\");\n visit(child, depth + 1);\n }\n };\n visit(value, 0);\n const json = JSON.stringify(value);\n if (Buffer.byteLength(json) > 768 * 1024) throw new Error(\"Application handover state exceeds byte bound\");\n return JSON.parse(json);\n}\n\n/** Bind application-selected business resources without transmitting their contents. */\nexport function createApplicationHandoverContract(revision: string, resources: unknown): string {\n if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,59}$/.test(revision)) throw Error(\"Invalid application state revision\");\n const normalized = cloneApplicationHandoverState(resources);\n const stable = (value: any): any => Array.isArray(value) ? value.map(stable)\n : value && typeof value === 'object' ? Object.fromEntries(Object.keys(value).sort().map(key => [key, stable(value[key])])) : value;\n return revision + '/' + createHash('sha256').update(JSON.stringify(stable(normalized))).digest('hex');\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ export declare const inputPreviewSchema: z.ZodArray<z.ZodString>;
3
+ export declare const inputCursorSchema: z.ZodObject<{
4
+ batchSize: z.ZodNumber;
5
+ referenceHash: z.ZodString;
6
+ processedTail: z.ZodOptional<z.ZodArray<z.ZodString>>;
7
+ }, z.core.$strict>;
8
+ export type InputQueueCursor = z.infer<typeof inputCursorSchema>;
9
+ export declare function inputFingerprint(item: {
10
+ topic: string;
11
+ message: string;
12
+ }): string;
13
+ /** Find an ordered common suffix. Neither a timestamp nor equal values alone authorize skipping. */
14
+ export declare function uniqueInputBoundary(processedTail: readonly string[], buffered: readonly string[]): number;
15
+ //# sourceMappingURL=input-queue-boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-queue-boundary.d.ts","sourceRoot":"","sources":["../../src/runtime/input-queue-boundary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB,yBAAuD,CAAC;AACvF,eAAO,MAAM,iBAAiB;;;;kBAI5B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACjE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEjF;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAezG"}
@@ -0,0 +1,33 @@
1
+ import { createHash } from "node:crypto";
2
+ import { z } from "zod";
3
+ export const inputPreviewSchema = z.array(z.string().regex(/^[a-f0-9]{64}$/)).max(100);
4
+ export const inputCursorSchema = z.strictObject({
5
+ batchSize: z.number().int().min(0).max(100),
6
+ referenceHash: z.string().regex(/^[a-f0-9]{64}$/),
7
+ processedTail: inputPreviewSchema.optional(),
8
+ });
9
+ export function inputFingerprint(item) {
10
+ return createHash("sha256").update(JSON.stringify({ topic: item.topic, message: item.message })).digest("hex");
11
+ }
12
+ /** Find an ordered common suffix. Neither a timestamp nor equal values alone authorize skipping. */
13
+ export function uniqueInputBoundary(processedTail, buffered) {
14
+ if (processedTail.length === 0)
15
+ return 0;
16
+ for (let size = Math.min(processedTail.length, buffered.length); size > 0; size--) {
17
+ const tail = processedTail.slice(-size);
18
+ const matches = (items) => {
19
+ const ends = [];
20
+ for (let start = 0; start <= items.length - size; start++)
21
+ if (tail.every((value, offset) => items[start + offset] === value))
22
+ ends.push(start + size);
23
+ return ends;
24
+ };
25
+ if (matches(processedTail).length !== 1)
26
+ continue;
27
+ const ends = matches(buffered);
28
+ if (ends.length === 1)
29
+ return ends[0];
30
+ }
31
+ throw Error("MQTT input overlap is missing or ambiguous; successor stays passive");
32
+ }
33
+ //# sourceMappingURL=input-queue-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-queue-boundary.js","sourceRoot":"","sources":["../../src/runtime/input-queue-boundary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,YAAY,CAAC;IAC9C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAC3C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;IACjD,aAAa,EAAE,kBAAkB,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAEH,MAAM,UAAU,gBAAgB,CAAC,IAAwC;IACvE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACjH,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,mBAAmB,CAAC,aAAgC,EAAE,QAA2B;IAC/F,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACzC,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QAClF,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,CAAC,KAAwB,EAAE,EAAE;YAC3C,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE;gBACvD,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,KAAK,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;YAC9F,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAClD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,KAAK,CAAC,qEAAqE,CAAC,CAAC;AACrF,CAAC","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\n\nexport const inputPreviewSchema = z.array(z.string().regex(/^[a-f0-9]{64}$/)).max(100);\nexport const inputCursorSchema = z.strictObject({\n batchSize: z.number().int().min(0).max(100),\n referenceHash: z.string().regex(/^[a-f0-9]{64}$/),\n processedTail: inputPreviewSchema.optional(),\n});\nexport type InputQueueCursor = z.infer<typeof inputCursorSchema>;\nexport function inputFingerprint(item: { topic: string; message: string }): string {\n return createHash(\"sha256\").update(JSON.stringify({ topic: item.topic, message: item.message })).digest(\"hex\");\n}\n\n/** Find an ordered common suffix. Neither a timestamp nor equal values alone authorize skipping. */\nexport function uniqueInputBoundary(processedTail: readonly string[], buffered: readonly string[]): number {\n if (processedTail.length === 0) return 0;\n for (let size = Math.min(processedTail.length, buffered.length); size > 0; size--) {\n const tail = processedTail.slice(-size);\n const matches = (items: readonly string[]) => {\n const ends: number[] = [];\n for (let start = 0; start <= items.length - size; start++)\n if (tail.every((value, offset) => items[start + offset] === value)) ends.push(start + size);\n return ends;\n };\n if (matches(processedTail).length !== 1) continue;\n const ends = matches(buffered);\n if (ends.length === 1) return ends[0];\n }\n throw Error(\"MQTT input overlap is missing or ambiguous; successor stays passive\");\n}\n"]}
@@ -1,9 +1,10 @@
1
1
  import { z } from 'zod';
2
- export declare const MQTT_HANDOVER_STATE_FORMAT = 2;
2
+ export declare const MQTT_HANDOVER_STATE_FORMAT = 3;
3
3
  export declare const MQTT_HANDOVER_STATE_MAX_BYTES: number;
4
4
  export declare const mqttHandoverOfferSchema: z.ZodArray<z.ZodObject<{
5
5
  instanceName: z.ZodString;
6
6
  compatibility: z.ZodString;
7
+ inputPreview: z.ZodOptional<z.ZodArray<z.ZodString>>;
7
8
  }, z.core.$strict>>;
8
9
  export declare const mqttProxyHandoverStateSchema: z.ZodObject<{
9
10
  instanceName: z.ZodString;
@@ -18,10 +19,15 @@ export declare const mqttProxyHandoverStateSchema: z.ZodObject<{
18
19
  cursor: z.ZodObject<{
19
20
  batchSize: z.ZodNumber;
20
21
  referenceHash: z.ZodString;
22
+ processedTail: z.ZodOptional<z.ZodArray<z.ZodString>>;
21
23
  }, z.core.$strict>;
22
24
  }, z.core.$strict>;
23
25
  export declare const mqttHandoverStateSchema: z.ZodObject<{
24
26
  protocol: z.ZodLiteral<1>;
27
+ application: z.ZodOptional<z.ZodObject<{
28
+ contract: z.ZodString;
29
+ data: z.ZodUnknown;
30
+ }, z.core.$strict>>;
25
31
  proxies: z.ZodArray<z.ZodObject<{
26
32
  instanceName: z.ZodString;
27
33
  compatibility: z.ZodString;
@@ -35,6 +41,7 @@ export declare const mqttHandoverStateSchema: z.ZodObject<{
35
41
  cursor: z.ZodObject<{
36
42
  batchSize: z.ZodNumber;
37
43
  referenceHash: z.ZodString;
44
+ processedTail: z.ZodOptional<z.ZodArray<z.ZodString>>;
38
45
  }, z.core.$strict>;
39
46
  }, z.core.$strict>>;
40
47
  }, z.core.$strict>;
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-handover-state.d.ts","sourceRoot":"","sources":["../../src/runtime/mqtt-handover-state.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAC5C,eAAO,MAAM,6BAA6B,QAAc,CAAC;AAIzD,eAAO,MAAM,uBAAuB;;;mBAG8E,CAAC;AACnH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;kBASvC,CAAC;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;kBAMlC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAClF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CAIxE;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAExE;AACD,eAAO,MAAM,4BAA4B;;kBAAoD,CAAC;AAC9F,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAS7E"}
1
+ {"version":3,"file":"mqtt-handover-state.d.ts","sourceRoot":"","sources":["../../src/runtime/mqtt-handover-state.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAC5C,eAAO,MAAM,6BAA6B,QAAc,CAAC;AAIzD,eAAO,MAAM,uBAAuB;;;;mBAI8E,CAAC;AACnH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;kBASvC,CAAC;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;kBAOlC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAClF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CAMxE;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAExE;AACD,eAAO,MAAM,4BAA4B;;kBAAoD,CAAC;AAC9F,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAS7E"}
@@ -2,9 +2,11 @@ import { createHash } from 'node:crypto';
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { z } from 'zod';
5
+ import { cloneApplicationHandoverState } from './application-handover-state.js';
6
+ import { inputCursorSchema, inputPreviewSchema } from './input-queue-boundary.js';
5
7
  // Same contract for every SDK MQTT consumer. No application/profile selectors.
6
- // Bound into peer compatibility so older required-unit readers reject before freeze.
7
- export const MQTT_HANDOVER_STATE_FORMAT = 2;
8
+ // Bound into peer compatibility so older cursor/state readers reject before freeze.
9
+ export const MQTT_HANDOVER_STATE_FORMAT = 3;
8
10
  export const MQTT_HANDOVER_STATE_MAX_BYTES = 1024 * 1024;
9
11
  const text = z.string().min(1).max(65535).refine(v => !v.includes('\0'));
10
12
  const scalar = z.union([z.number().finite(), z.string().max(65535)]);
@@ -12,13 +14,14 @@ const value = z.union([scalar, z.array(scalar).max(4096)]);
12
14
  export const mqttHandoverOfferSchema = z.array(z.strictObject({
13
15
  instanceName: z.string().min(1).max(256),
14
16
  compatibility: z.string().regex(/^[a-f0-9]{64}$/),
17
+ inputPreview: inputPreviewSchema.optional(),
15
18
  })).max(64).refine(offer => new Set(offer.map(p => p.instanceName)).size === offer.length, 'Duplicate MQTT proxy');
16
19
  export const mqttProxyHandoverStateSchema = z.strictObject({
17
20
  instanceName: z.string().min(1).max(256),
18
21
  compatibility: z.string().regex(/^[a-f0-9]{64}$/),
19
22
  values: z.array(z.strictObject({ topic: text, value, uom: z.string().max(256).optional(), timestamp: z.string().datetime() })).max(10000),
20
23
  sequences: z.array(z.tuple([text, z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER)])).max(10000),
21
- cursor: z.strictObject({ batchSize: z.number().int().min(0).max(100), referenceHash: z.string().regex(/^[a-f0-9]{64}$/) }),
24
+ cursor: inputCursorSchema,
22
25
  }).superRefine((state, ctx) => {
23
26
  for (const keys of [state.values.map(v => v.topic), state.sequences.map(v => v[0])])
24
27
  if (new Set(keys).size !== keys.length)
@@ -26,6 +29,7 @@ export const mqttProxyHandoverStateSchema = z.strictObject({
26
29
  });
27
30
  export const mqttHandoverStateSchema = z.strictObject({
28
31
  protocol: z.literal(1),
32
+ application: z.strictObject({ contract: z.string().min(1).max(128), data: z.unknown() }).optional(),
29
33
  proxies: z.array(mqttProxyHandoverStateSchema).max(64),
30
34
  }).superRefine((state, ctx) => {
31
35
  if (new Set(state.proxies.map(p => p.instanceName)).size !== state.proxies.length)
@@ -35,7 +39,10 @@ export function parseMqttHandoverState(input) {
35
39
  const json = JSON.stringify(input);
36
40
  if (!json || Buffer.byteLength(json) > MQTT_HANDOVER_STATE_MAX_BYTES)
37
41
  throw Error('MQTT handover state exceeds its bound');
38
- return mqttHandoverStateSchema.parse(input);
42
+ const state = mqttHandoverStateSchema.parse(input);
43
+ if (state.application)
44
+ state.application.data = cloneApplicationHandoverState(state.application.data);
45
+ return state;
39
46
  }
40
47
  export function mqttHandoverStateDigest(state) {
41
48
  return createHash('sha256').update(JSON.stringify(parseMqttHandoverState(state))).digest('hex');
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-handover-state.js","sourceRoot":"","sources":["../../src/runtime/mqtt-handover-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { z } from 'zod';\n\n// Same contract for every SDK MQTT consumer. No application/profile selectors.\n// Bound into peer compatibility so older required-unit readers reject before freeze.\nexport const MQTT_HANDOVER_STATE_FORMAT = 2;\nexport const MQTT_HANDOVER_STATE_MAX_BYTES = 1024 * 1024;\nconst text = z.string().min(1).max(65535).refine(v => !v.includes('\\0'));\nconst scalar = z.union([z.number().finite(), z.string().max(65535)]);\nconst value = z.union([scalar, z.array(scalar).max(4096)]);\nexport const mqttHandoverOfferSchema = z.array(z.strictObject({\n instanceName: z.string().min(1).max(256),\n compatibility: z.string().regex(/^[a-f0-9]{64}$/),\n})).max(64).refine(offer => new Set(offer.map(p => p.instanceName)).size === offer.length, 'Duplicate MQTT proxy');\nexport const mqttProxyHandoverStateSchema = z.strictObject({\n instanceName: z.string().min(1).max(256),\n compatibility: z.string().regex(/^[a-f0-9]{64}$/),\n values: z.array(z.strictObject({ topic: text, value, uom: z.string().max(256).optional(), timestamp: z.string().datetime() })).max(10000),\n sequences: z.array(z.tuple([text, z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER)])).max(10000),\n cursor: z.strictObject({ batchSize: z.number().int().min(0).max(100), referenceHash: z.string().regex(/^[a-f0-9]{64}$/) }),\n}).superRefine((state, ctx) => {\n for (const keys of [state.values.map(v => v.topic), state.sequences.map(v => v[0])])\n if (new Set(keys).size !== keys.length) ctx.addIssue({ code: 'custom', message: 'Duplicate MQTT state key' });\n});\nexport const mqttHandoverStateSchema = z.strictObject({\n protocol: z.literal(1),\n proxies: z.array(mqttProxyHandoverStateSchema).max(64),\n}).superRefine((state, ctx) => {\n if (new Set(state.proxies.map(p => p.instanceName)).size !== state.proxies.length)\n ctx.addIssue({ code: 'custom', message: 'Duplicate MQTT proxy' });\n});\nexport type MqttProxyHandoverState = z.infer<typeof mqttProxyHandoverStateSchema>;\nexport type MqttHandoverState = z.infer<typeof mqttHandoverStateSchema>;\nexport function parseMqttHandoverState(input: unknown): MqttHandoverState {\n const json = JSON.stringify(input);\n if (!json || Buffer.byteLength(json) > MQTT_HANDOVER_STATE_MAX_BYTES) throw Error('MQTT handover state exceeds its bound');\n return mqttHandoverStateSchema.parse(input);\n}\nexport function mqttHandoverStateDigest(state: MqttHandoverState): string {\n return createHash('sha256').update(JSON.stringify(parseMqttHandoverState(state))).digest('hex');\n}\nexport const mqttHandoverCapabilitySchema = z.strictObject({ protocolVersion: z.literal(2) });\nexport function readMqttHandoverCapability(packageRoot: string): 2 | undefined {\n const file = path.join(packageRoot, 'package.json');\n let stat: fs.Stats;\n try { stat = fs.lstatSync(file); } catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined; throw error; }\n if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 1048576) throw Error('Unsafe MQTT handover descriptor');\n const descriptor = JSON.parse(fs.readFileSync(file, 'utf8'))?.unsDatahub?.mqttHandover;\n if (descriptor === undefined) return undefined;\n mqttHandoverCapabilitySchema.parse(descriptor);\n return 2;\n}\n"]}
1
+ {"version":3,"file":"mqtt-handover-state.js","sourceRoot":"","sources":["../../src/runtime/mqtt-handover-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { cloneApplicationHandoverState } from './application-handover-state.js';\nimport { inputCursorSchema, inputPreviewSchema } from './input-queue-boundary.js';\n\n// Same contract for every SDK MQTT consumer. No application/profile selectors.\n// Bound into peer compatibility so older cursor/state readers reject before freeze.\nexport const MQTT_HANDOVER_STATE_FORMAT = 3;\nexport const MQTT_HANDOVER_STATE_MAX_BYTES = 1024 * 1024;\nconst text = z.string().min(1).max(65535).refine(v => !v.includes('\\0'));\nconst scalar = z.union([z.number().finite(), z.string().max(65535)]);\nconst value = z.union([scalar, z.array(scalar).max(4096)]);\nexport const mqttHandoverOfferSchema = z.array(z.strictObject({\n instanceName: z.string().min(1).max(256),\n compatibility: z.string().regex(/^[a-f0-9]{64}$/),\n inputPreview: inputPreviewSchema.optional(),\n})).max(64).refine(offer => new Set(offer.map(p => p.instanceName)).size === offer.length, 'Duplicate MQTT proxy');\nexport const mqttProxyHandoverStateSchema = z.strictObject({\n instanceName: z.string().min(1).max(256),\n compatibility: z.string().regex(/^[a-f0-9]{64}$/),\n values: z.array(z.strictObject({ topic: text, value, uom: z.string().max(256).optional(), timestamp: z.string().datetime() })).max(10000),\n sequences: z.array(z.tuple([text, z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER)])).max(10000),\n cursor: inputCursorSchema,\n}).superRefine((state, ctx) => {\n for (const keys of [state.values.map(v => v.topic), state.sequences.map(v => v[0])])\n if (new Set(keys).size !== keys.length) ctx.addIssue({ code: 'custom', message: 'Duplicate MQTT state key' });\n});\nexport const mqttHandoverStateSchema = z.strictObject({\n protocol: z.literal(1),\n application: z.strictObject({ contract: z.string().min(1).max(128), data: z.unknown() }).optional(),\n proxies: z.array(mqttProxyHandoverStateSchema).max(64),\n}).superRefine((state, ctx) => {\n if (new Set(state.proxies.map(p => p.instanceName)).size !== state.proxies.length)\n ctx.addIssue({ code: 'custom', message: 'Duplicate MQTT proxy' });\n});\nexport type MqttProxyHandoverState = z.infer<typeof mqttProxyHandoverStateSchema>;\nexport type MqttHandoverState = z.infer<typeof mqttHandoverStateSchema>;\nexport function parseMqttHandoverState(input: unknown): MqttHandoverState {\n const json = JSON.stringify(input);\n if (!json || Buffer.byteLength(json) > MQTT_HANDOVER_STATE_MAX_BYTES) throw Error('MQTT handover state exceeds its bound');\n const state = mqttHandoverStateSchema.parse(input);\n if (state.application) state.application.data = cloneApplicationHandoverState(state.application.data);\n return state;\n}\nexport function mqttHandoverStateDigest(state: MqttHandoverState): string {\n return createHash('sha256').update(JSON.stringify(parseMqttHandoverState(state))).digest('hex');\n}\nexport const mqttHandoverCapabilitySchema = z.strictObject({ protocolVersion: z.literal(2) });\nexport function readMqttHandoverCapability(packageRoot: string): 2 | undefined {\n const file = path.join(packageRoot, 'package.json');\n let stat: fs.Stats;\n try { stat = fs.lstatSync(file); } catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined; throw error; }\n if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 1048576) throw Error('Unsafe MQTT handover descriptor');\n const descriptor = JSON.parse(fs.readFileSync(file, 'utf8'))?.unsDatahub?.mqttHandover;\n if (descriptor === undefined) return undefined;\n mqttHandoverCapabilitySchema.parse(descriptor);\n return 2;\n}\n"]}
@@ -0,0 +1,16 @@
1
+ /** Accepted application work is separate from transport queues. Errors stay latched. */
2
+ export declare class ProcessWork {
3
+ private readonly active;
4
+ private pending;
5
+ private failed;
6
+ private paused;
7
+ constructor(active?: () => boolean);
8
+ /** Track work already admitted by a transport. Never drop it during release. */
9
+ track<T>(work: Promise<T>): Promise<T>;
10
+ /** Timers/pollers must enter through this ownership gate. */
11
+ run<T>(work: () => Promise<T>): Promise<T | undefined>;
12
+ pause(): void;
13
+ fail(): void;
14
+ drain(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=process-work.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-work.d.ts","sourceRoot":"","sources":["../../src/runtime/process-work.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,qBAAa,WAAW;IAKV,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEM,MAAM,GAAE,MAAM,OAAoB;IAE/D,gFAAgF;IAChF,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAStC,6DAA6D;IAC7D,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAKtD,KAAK,IAAI,IAAI;IACb,IAAI,IAAI,IAAI;IACN,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
@@ -0,0 +1,34 @@
1
+ /** Accepted application work is separate from transport queues. Errors stay latched. */
2
+ export class ProcessWork {
3
+ active;
4
+ pending = new Set();
5
+ failed = false;
6
+ paused = false;
7
+ constructor(active = () => true) {
8
+ this.active = active;
9
+ }
10
+ /** Track work already admitted by a transport. Never drop it during release. */
11
+ track(work) {
12
+ this.pending.add(work);
13
+ void work.then(() => this.pending.delete(work), () => {
14
+ this.failed = true;
15
+ this.pending.delete(work);
16
+ });
17
+ return work;
18
+ }
19
+ /** Timers/pollers must enter through this ownership gate. */
20
+ run(work) {
21
+ if (this.paused || !this.active())
22
+ return Promise.resolve(undefined);
23
+ return this.track(Promise.resolve().then(work));
24
+ }
25
+ pause() { this.paused = true; }
26
+ fail() { this.failed = true; }
27
+ async drain() {
28
+ while (this.pending.size)
29
+ await Promise.allSettled([...this.pending]);
30
+ if (this.failed)
31
+ throw new Error("Accepted application work is unconfirmed");
32
+ }
33
+ }
34
+ //# sourceMappingURL=process-work.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-work.js","sourceRoot":"","sources":["../../src/runtime/process-work.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,OAAO,WAAW;IAKO;IAJrB,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IACtC,MAAM,GAAG,KAAK,CAAC;IACf,MAAM,GAAG,KAAK,CAAC;IAEvB,YAA6B,SAAwB,GAAG,EAAE,CAAC,IAAI;QAAlC,WAAM,GAAN,MAAM,CAA4B;IAAG,CAAC;IAEnE,gFAAgF;IAChF,KAAK,CAAI,IAAgB;QACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE;YACnD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6DAA6D;IAC7D,GAAG,CAAI,IAAsB;QAC3B,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,KAAW,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACrC,IAAI,KAAW,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACpC,KAAK,CAAC,KAAK;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI;YAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC/E,CAAC;CACF","sourcesContent":["/** Accepted application work is separate from transport queues. Errors stay latched. */\nexport class ProcessWork {\n private pending = new Set<Promise<unknown>>();\n private failed = false;\n private paused = false;\n\n constructor(private readonly active: () => boolean = () => true) {}\n\n /** Track work already admitted by a transport. Never drop it during release. */\n track<T>(work: Promise<T>): Promise<T> {\n this.pending.add(work);\n void work.then(() => this.pending.delete(work), () => {\n this.failed = true;\n this.pending.delete(work);\n });\n return work;\n }\n\n /** Timers/pollers must enter through this ownership gate. */\n run<T>(work: () => Promise<T>): Promise<T | undefined> {\n if (this.paused || !this.active()) return Promise.resolve(undefined);\n return this.track(Promise.resolve().then(work));\n }\n\n pause(): void { this.paused = true; }\n fail(): void { this.failed = true; }\n async drain(): Promise<void> {\n while (this.pending.size) await Promise.allSettled([...this.pending]);\n if (this.failed) throw new Error(\"Accepted application work is unconfirmed\");\n }\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { type ApplicationHandoverState } from "../runtime/application-handover-state.js";
1
2
  import { type HandoverShutdownHooks } from "./handover-shutdown.js";
2
3
  import { HandoverManagerEvents } from "../uns-mqtt/mqtt-interfaces.js";
3
4
  import MqttProxy from "../uns-mqtt/mqtt-proxy.js";
@@ -11,6 +12,7 @@ import { UnsEvents } from "./uns-interfaces.js";
11
12
  */
12
13
  export declare class HandoverManager {
13
14
  private readonly statefulHandover;
15
+ private readonly applicationState?;
14
16
  event: HandoverManagerEventEmitter<HandoverManagerEvents>;
15
17
  private processName;
16
18
  private processId;
@@ -32,11 +34,14 @@ export declare class HandoverManager {
32
34
  private stateDigest;
33
35
  private acceptedStateDigest;
34
36
  private targetPreparation;
37
+ private targetStateApplied;
35
38
  private finRetry;
39
+ private requestRetry;
40
+ private sourceReviewInFlight;
36
41
  handoverRequestEnabled: boolean;
37
42
  handoverEnabled: boolean;
38
43
  forceStartEnabled: boolean;
39
- constructor(processName: string, processId: string, mqttProxy: MqttProxy, unsMqttProxies: UnsMqttProxy[], handoverRequestEnabled: boolean, handoverEnabled: boolean, forceStartEnabled: boolean, handoverId?: string, shutdownHooks?: HandoverShutdownHooks, statefulHandover?: boolean);
44
+ constructor(processName: string, processId: string, mqttProxy: MqttProxy, unsMqttProxies: UnsMqttProxy[], handoverRequestEnabled: boolean, handoverEnabled: boolean, forceStartEnabled: boolean, handoverId?: string, shutdownHooks?: HandoverShutdownHooks, statefulHandover?: boolean, applicationState?: ApplicationHandoverState);
40
45
  private getUserProperties;
41
46
  private handoverPayload;
42
47
  private getHandoverId;
@@ -56,6 +61,8 @@ export declare class HandoverManager {
56
61
  private prepareSourceHandover;
57
62
  private sendPreparedState;
58
63
  private acceptPreparedState;
64
+ private activateApplication;
65
+ private deactivateApplication;
59
66
  private finishSourceHandover;
60
67
  private handleHandover;
61
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"handover-manager.d.ts","sourceRoot":"","sources":["../../src/uns/handover-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiD,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACnH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,SAAS,MAAM,2BAA2B,CAAC;AAElD,OAAO,YAAY,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAElF,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAQhD;;;;GAIG;AACH,qBAAa,eAAe;IAqCxB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IApC5B,KAAK,EAAE,2BAA2B,CAAC,qBAAqB,CAAC,CAA4D;IAC5H,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoC;IAClE,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,QAAQ,CAA6B;IACtC,sBAAsB,EAAE,OAAO,CAAS;IACxC,eAAe,EAAE,OAAO,CAAQ;IAChC,iBAAiB,EAAE,OAAO,CAAS;gBAGxC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,YAAY,EAAE,EAC9B,sBAAsB,EAAE,OAAO,EAC/B,eAAe,EAAE,OAAO,EACxB,iBAAiB,EAAE,OAAO,EAC1B,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,qBAAqB,EACpB,gBAAgB,UAAQ;IAkC3C,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,oBAAoB;IAU5B;;;OAGG;IACU,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqFxE;;OAEG;IACH,OAAO,CAAC,UAAU;YAIJ,qBAAqB;YA8ErB,iBAAiB;YAOjB,mBAAmB;YAkBnB,oBAAoB;YA2BpB,cAAc;CAwH7B"}
1
+ {"version":3,"file":"handover-manager.d.ts","sourceRoot":"","sources":["../../src/uns/handover-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAGxH,OAAO,EAAiD,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACnH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,SAAS,MAAM,2BAA2B,CAAC;AAElD,OAAO,YAAY,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAElF,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAQhD;;;;GAIG;AACH,qBAAa,eAAe;IAwCxB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAxC7B,KAAK,EAAE,2BAA2B,CAAC,qBAAqB,CAAC,CAA4D;IAC5H,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoC;IAClE,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,oBAAoB,CAAS;IAC9B,sBAAsB,EAAE,OAAO,CAAS;IACxC,eAAe,EAAE,OAAO,CAAQ;IAChC,iBAAiB,EAAE,OAAO,CAAS;gBAGxC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,YAAY,EAAE,EAC9B,sBAAsB,EAAE,OAAO,EAC/B,eAAe,EAAE,OAAO,EACxB,iBAAiB,EAAE,OAAO,EAC1B,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,qBAAqB,EACpB,gBAAgB,UAAQ,EACxB,gBAAgB,CAAC,EAAE,wBAAwB;IAkC9D,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,oBAAoB;IAU5B;;;OAGG;IACU,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA+FxE;;OAEG;IACH,OAAO,CAAC,UAAU;YAIJ,qBAAqB;YAiFrB,iBAAiB;YAOjB,mBAAmB;YA8BnB,mBAAmB;YAQnB,qBAAqB;YAWrB,oBAAoB;YA2BpB,cAAc;CA+I7B"}