@uns-kit/core 3.0.31 → 3.0.33

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 (49) hide show
  1. package/MIGRATIONS.md +43 -0
  2. package/dist/config/app-config.d.ts +1 -0
  3. package/dist/config/app-config.d.ts.map +1 -1
  4. package/dist/config/app-config.js.map +1 -1
  5. package/dist/runtime/mqtt-drain.d.ts +29 -0
  6. package/dist/runtime/mqtt-drain.d.ts.map +1 -0
  7. package/dist/runtime/mqtt-drain.js +70 -0
  8. package/dist/runtime/mqtt-drain.js.map +1 -0
  9. package/dist/runtime/mqtt-output-state-contract.d.ts.map +1 -1
  10. package/dist/runtime/mqtt-output-state-contract.js +2 -0
  11. package/dist/runtime/mqtt-output-state-contract.js.map +1 -1
  12. package/dist/runtime/mqtt-output-state-program.d.mts +4 -0
  13. package/dist/runtime/mqtt-output-state-program.mjs +51 -0
  14. package/dist/runtime/process-group-configured-upgrade.d.ts +1 -0
  15. package/dist/runtime/process-group-configured-upgrade.d.ts.map +1 -1
  16. package/dist/runtime/process-group-configured-upgrade.js +21 -4
  17. package/dist/runtime/process-group-configured-upgrade.js.map +1 -1
  18. package/dist/runtime/process-group-mqtt-output.d.ts +63 -0
  19. package/dist/runtime/process-group-mqtt-output.d.ts.map +1 -0
  20. package/dist/runtime/process-group-mqtt-output.js +89 -0
  21. package/dist/runtime/process-group-mqtt-output.js.map +1 -0
  22. package/dist/runtime/process-group-upgrade.d.ts +85 -2
  23. package/dist/runtime/process-group-upgrade.d.ts.map +1 -1
  24. package/dist/runtime/process-group-upgrade.js +74 -9
  25. package/dist/runtime/process-group-upgrade.js.map +1 -1
  26. package/dist/uns/uns-proxy-process.d.ts +8 -4
  27. package/dist/uns/uns-proxy-process.d.ts.map +1 -1
  28. package/dist/uns/uns-proxy-process.js +41 -5
  29. package/dist/uns/uns-proxy-process.js.map +1 -1
  30. package/dist/uns-config/config-schema.d.ts +1 -0
  31. package/dist/uns-config/config-schema.d.ts.map +1 -1
  32. package/dist/uns-config/uns-core-schema.d.ts +2 -0
  33. package/dist/uns-config/uns-core-schema.d.ts.map +1 -1
  34. package/dist/uns-mqtt/disabled-publish-queue.d.ts +6 -0
  35. package/dist/uns-mqtt/disabled-publish-queue.d.ts.map +1 -0
  36. package/dist/uns-mqtt/disabled-publish-queue.js +64 -0
  37. package/dist/uns-mqtt/disabled-publish-queue.js.map +1 -0
  38. package/dist/uns-mqtt/publish-queue-contract.d.ts +11 -0
  39. package/dist/uns-mqtt/publish-queue-contract.d.ts.map +1 -1
  40. package/dist/uns-mqtt/publish-queue-contract.js +16 -0
  41. package/dist/uns-mqtt/publish-queue-contract.js.map +1 -1
  42. package/dist/uns-mqtt/publish-queue.d.ts.map +1 -1
  43. package/dist/uns-mqtt/publish-queue.js +2 -0
  44. package/dist/uns-mqtt/publish-queue.js.map +1 -1
  45. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts +3 -0
  46. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts.map +1 -1
  47. package/dist/uns-mqtt/uns-mqtt-proxy.js +19 -8
  48. package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
  49. package/package.json +1 -1
package/MIGRATIONS.md CHANGED
@@ -9,6 +9,49 @@ 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.33 - Explicit queue disablement and generic clean MQTT migration
13
+
14
+ When crossing `<3.0.33` to `>=3.0.33`, existing applications require no change.
15
+ An existing `publishQueue` remains enabled unless explicitly configured otherwise.
16
+ Use `enabled: false` only for an initial RAM-only deployment or a verified empty
17
+ old queue: pending state, another identity or a live owner blocks disabling.
18
+
19
+ Applications opting into ordinary clean MQTT migration declare `unsDatahub.mqttDrain`
20
+ protocol1 and call `UnsProxyProcess.enableMigrationDrain()` after preparation.
21
+ Provide `handoverShutdown` hooks that stop background admission and await all
22
+ accepted application work; report publication failures instead of silently losing
23
+ them. Hosts must wait for the bound SDK drain receipt and clean original exit;
24
+ PM2 online/stopped alone is insufficient. Unknown results block the successor.
25
+ Keep standalone shutdown functional. This does not retire paired input journals
26
+ or imply automatic queue transfer. See [the capability and example](https://github.com/uns-openhub/uns-kit/blob/master/docs/mqtt-migration-drain.md).
27
+
28
+ ## 3.0.32 - Reviewed process-group MQTT output enablement
29
+
30
+ When crossing `<3.0.32` to `>=3.0.32`, ordinary services, input journals and
31
+ existing outboxes remain unchanged. Output persistence is never enabled by a
32
+ package update. Hosts may explicitly review nested paired transition protocol 3
33
+ through `runtime/process-group-upgrade.js`; ordinary version/generation reviews
34
+ retain their strict configuration comparison.
35
+
36
+ Applications opting in declare
37
+ `unsDatahub.processGroupMqttOutputRuntime = { protocolVersion: 1, instanceName }`,
38
+ matching the actual SDK output proxy. Keep parsing, profiles, resources, paths and
39
+ units in the application; do not add a service-name branch to a host.
40
+
41
+ Use a separate reviewed permanent output mount and retain the exact input journal.
42
+ On rollback, stop admission and drain already admitted input before stopping the
43
+ publisher. Pending output, changed storage/owner/destination and unknown outcomes
44
+ block restoration; preserve both journals and reconcile the same operation. Never
45
+ rename an owner, choose another directory or remove data to bypass these checks.
46
+ The managed outbox format remains schema2 and the stable identity serialization
47
+ is byte compatible with3.0.31. A matching host implementation is required for the
48
+ optional transition; applications without the capability require no migration.
49
+
50
+ See the SDK developer guide
51
+ [reviewed MQTT output enablement](https://github.com/uns-openhub/uns-kit/blob/master/docs/process-group-mqtt-output-transition.md)
52
+ for declarations, proxy configuration, review examples and recovery limits.
53
+ Source preparation and owner-operated npm publication are separate steps.
54
+
12
55
  ## 3.0.31 - Explicit Runtime-managed MQTT outbox storage
13
56
 
14
57
  For an optional Runtime-managed MQTT outbox set `output.publishQueue.storage` to
@@ -114,6 +114,7 @@ export interface ProjectAppConfig {
114
114
  servername?: string | undefined;
115
115
  /** Opt-in MQTT output persistence; does not persist input subscriptions. */
116
116
  publishQueue?: {
117
+ enabled?: boolean;
117
118
  mode: "buffered" | "durable";
118
119
  storage?: "local" | "runtime";
119
120
  directory: string;
@@ -1 +1 @@
1
- {"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../../src/config/app-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../../src/config/app-config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../src/config/app-config.ts"],"names":[],"mappings":"","sourcesContent":["/* Auto-generated. Do not edit by hand. */\nexport interface ProjectAppConfig {\n uns: {\n graphql: string;\n rest: string;\n /** Bearer token used for service-to-service access to the UNS instance. */\n token?: string | undefined;\n /** Email used when authenticating to graphql endpoint of the UNS instance. */\n email?: string | undefined;\n /** Password or secret value paired with the UNS email. */\n password?: string | undefined;\n instanceMode?: \"wait\" | \"force\" | \"handover\";\n /** Process name used in MQTT topics and logs. */\n processName: string;\n handover?: boolean;\n /** Opt-in controller-correlated MQTT handover protocol. */\n handoverProtocol?: \"correlated-v1\" | undefined;\n /** Optional PM2/controller supervisor guard settings for this RTT instance. */\n supervisor?: {\n /** Enable controller/PM2 supervisor handling for this RTT instance. */\n enabled?: boolean;\n /** Let PM2 restart the process when it exits unexpectedly. */\n restartOnExit?: boolean;\n /** Optional PM2 memory restart limit in megabytes. */\n maxMemoryMb?: number | undefined;\n /** Let the controller auto-start this instance when required system-service runtime signals are absent. */\n restartOnUnhealthy?: boolean;\n /** How long runtime signals must stay unhealthy before the controller supervisor can act. */\n unhealthyAfterMs?: number;\n /** Minimum time between controller supervisor restart attempts for this instance. */\n restartCooldownMs?: number;\n } | undefined;\n jwksWellKnownUrl?: string | undefined;\n kidWellKnownUrl?: string | undefined;\n env?: \"dev\" | \"staging\" | \"test\" | \"prod\";\n };\n logging?: {\n adapter?: string;\n host: string;\n port?: number;\n level?: \"error\" | \"warn\" | \"info\" | \"http\" | \"verbose\" | \"debug\" | \"silly\";\n } | undefined;\n input?: {\n host?: string | undefined;\n hosts?: string[] | undefined;\n servers?: {\n host: string;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n }[] | undefined;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n username?: string | undefined;\n password?: string | undefined;\n clientId?: string | undefined;\n clean?: boolean | undefined;\n keepalive?: number | undefined;\n connectTimeout?: number | undefined;\n reconnectPeriod?: number | undefined;\n reconnectOnConnackError?: boolean | undefined;\n resubscribe?: boolean | undefined;\n queueQoSZero?: boolean | undefined;\n rejectUnauthorized?: boolean | undefined;\n properties?: {\n sessionExpiryInterval?: number | undefined;\n receiveMaximum?: number | undefined;\n maximumPacketSize?: number | undefined;\n topicAliasMaximum?: number | undefined;\n requestResponseInformation?: boolean | undefined;\n requestProblemInformation?: boolean | undefined;\n userProperties?: {\n [x: string]: string;\n } | undefined;\n } | undefined;\n ca?: string | undefined;\n cert?: string | undefined;\n key?: string | undefined;\n servername?: string | undefined;\n } | undefined;\n output?: {\n host?: string | undefined;\n hosts?: string[] | undefined;\n servers?: {\n host: string;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n }[] | undefined;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n username?: string | undefined;\n password?: string | undefined;\n clientId?: string | undefined;\n clean?: boolean | undefined;\n keepalive?: number | undefined;\n connectTimeout?: number | undefined;\n reconnectPeriod?: number | undefined;\n reconnectOnConnackError?: boolean | undefined;\n resubscribe?: boolean | undefined;\n queueQoSZero?: boolean | undefined;\n rejectUnauthorized?: boolean | undefined;\n properties?: {\n sessionExpiryInterval?: number | undefined;\n receiveMaximum?: number | undefined;\n maximumPacketSize?: number | undefined;\n topicAliasMaximum?: number | undefined;\n requestResponseInformation?: boolean | undefined;\n requestProblemInformation?: boolean | undefined;\n userProperties?: {\n [x: string]: string;\n } | undefined;\n } | undefined;\n ca?: string | undefined;\n cert?: string | undefined;\n key?: string | undefined;\n servername?: string | undefined;\n /** Opt-in MQTT output persistence; does not persist input subscriptions. */\n publishQueue?: {\n mode: \"buffered\" | \"durable\";\n storage?: \"local\" | \"runtime\";\n directory: string;\n maxRecords?: number;\n maxBytes?: number;\n memoryRecords?: number;\n memoryBytes?: number;\n maxMessageBytes?: number;\n maxDiskBytes?: number;\n minFreeBytes?: number;\n retryIntervalMs?: number;\n publishTimeoutMs?: number;\n } | undefined;\n } | undefined;\n infra: {\n host?: string | undefined;\n hosts?: string[] | undefined;\n servers?: {\n host: string;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n }[] | undefined;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n username?: string | undefined;\n password?: string | undefined;\n clientId?: string | undefined;\n clean?: boolean | undefined;\n keepalive?: number | undefined;\n connectTimeout?: number | undefined;\n reconnectPeriod?: number | undefined;\n reconnectOnConnackError?: boolean | undefined;\n resubscribe?: boolean | undefined;\n queueQoSZero?: boolean | undefined;\n rejectUnauthorized?: boolean | undefined;\n properties?: {\n sessionExpiryInterval?: number | undefined;\n receiveMaximum?: number | undefined;\n maximumPacketSize?: number | undefined;\n topicAliasMaximum?: number | undefined;\n requestResponseInformation?: boolean | undefined;\n requestProblemInformation?: boolean | undefined;\n userProperties?: {\n [x: string]: string;\n } | undefined;\n } | undefined;\n ca?: string | undefined;\n cert?: string | undefined;\n key?: string | undefined;\n servername?: string | undefined;\n };\n devops?: {\n provider?: \"azure-devops\";\n organization: string;\n project?: string | undefined;\n } | undefined;\n}\n\nexport interface AppConfig extends ProjectAppConfig {}\n"]}
1
+ {"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../src/config/app-config.ts"],"names":[],"mappings":"","sourcesContent":["/* Auto-generated. Do not edit by hand. */\nexport interface ProjectAppConfig {\n uns: {\n graphql: string;\n rest: string;\n /** Bearer token used for service-to-service access to the UNS instance. */\n token?: string | undefined;\n /** Email used when authenticating to graphql endpoint of the UNS instance. */\n email?: string | undefined;\n /** Password or secret value paired with the UNS email. */\n password?: string | undefined;\n instanceMode?: \"wait\" | \"force\" | \"handover\";\n /** Process name used in MQTT topics and logs. */\n processName: string;\n handover?: boolean;\n /** Opt-in controller-correlated MQTT handover protocol. */\n handoverProtocol?: \"correlated-v1\" | undefined;\n /** Optional PM2/controller supervisor guard settings for this RTT instance. */\n supervisor?: {\n /** Enable controller/PM2 supervisor handling for this RTT instance. */\n enabled?: boolean;\n /** Let PM2 restart the process when it exits unexpectedly. */\n restartOnExit?: boolean;\n /** Optional PM2 memory restart limit in megabytes. */\n maxMemoryMb?: number | undefined;\n /** Let the controller auto-start this instance when required system-service runtime signals are absent. */\n restartOnUnhealthy?: boolean;\n /** How long runtime signals must stay unhealthy before the controller supervisor can act. */\n unhealthyAfterMs?: number;\n /** Minimum time between controller supervisor restart attempts for this instance. */\n restartCooldownMs?: number;\n } | undefined;\n jwksWellKnownUrl?: string | undefined;\n kidWellKnownUrl?: string | undefined;\n env?: \"dev\" | \"staging\" | \"test\" | \"prod\";\n };\n logging?: {\n adapter?: string;\n host: string;\n port?: number;\n level?: \"error\" | \"warn\" | \"info\" | \"http\" | \"verbose\" | \"debug\" | \"silly\";\n } | undefined;\n input?: {\n host?: string | undefined;\n hosts?: string[] | undefined;\n servers?: {\n host: string;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n }[] | undefined;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n username?: string | undefined;\n password?: string | undefined;\n clientId?: string | undefined;\n clean?: boolean | undefined;\n keepalive?: number | undefined;\n connectTimeout?: number | undefined;\n reconnectPeriod?: number | undefined;\n reconnectOnConnackError?: boolean | undefined;\n resubscribe?: boolean | undefined;\n queueQoSZero?: boolean | undefined;\n rejectUnauthorized?: boolean | undefined;\n properties?: {\n sessionExpiryInterval?: number | undefined;\n receiveMaximum?: number | undefined;\n maximumPacketSize?: number | undefined;\n topicAliasMaximum?: number | undefined;\n requestResponseInformation?: boolean | undefined;\n requestProblemInformation?: boolean | undefined;\n userProperties?: {\n [x: string]: string;\n } | undefined;\n } | undefined;\n ca?: string | undefined;\n cert?: string | undefined;\n key?: string | undefined;\n servername?: string | undefined;\n } | undefined;\n output?: {\n host?: string | undefined;\n hosts?: string[] | undefined;\n servers?: {\n host: string;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n }[] | undefined;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n username?: string | undefined;\n password?: string | undefined;\n clientId?: string | undefined;\n clean?: boolean | undefined;\n keepalive?: number | undefined;\n connectTimeout?: number | undefined;\n reconnectPeriod?: number | undefined;\n reconnectOnConnackError?: boolean | undefined;\n resubscribe?: boolean | undefined;\n queueQoSZero?: boolean | undefined;\n rejectUnauthorized?: boolean | undefined;\n properties?: {\n sessionExpiryInterval?: number | undefined;\n receiveMaximum?: number | undefined;\n maximumPacketSize?: number | undefined;\n topicAliasMaximum?: number | undefined;\n requestResponseInformation?: boolean | undefined;\n requestProblemInformation?: boolean | undefined;\n userProperties?: {\n [x: string]: string;\n } | undefined;\n } | undefined;\n ca?: string | undefined;\n cert?: string | undefined;\n key?: string | undefined;\n servername?: string | undefined;\n /** Opt-in MQTT output persistence; does not persist input subscriptions. */\n publishQueue?: {\n enabled?: boolean;\n mode: \"buffered\" | \"durable\";\n storage?: \"local\" | \"runtime\";\n directory: string;\n maxRecords?: number;\n maxBytes?: number;\n memoryRecords?: number;\n memoryBytes?: number;\n maxMessageBytes?: number;\n maxDiskBytes?: number;\n minFreeBytes?: number;\n retryIntervalMs?: number;\n publishTimeoutMs?: number;\n } | undefined;\n } | undefined;\n infra: {\n host?: string | undefined;\n hosts?: string[] | undefined;\n servers?: {\n host: string;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n }[] | undefined;\n port?: number | undefined;\n protocol?: (\"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\") | undefined;\n username?: string | undefined;\n password?: string | undefined;\n clientId?: string | undefined;\n clean?: boolean | undefined;\n keepalive?: number | undefined;\n connectTimeout?: number | undefined;\n reconnectPeriod?: number | undefined;\n reconnectOnConnackError?: boolean | undefined;\n resubscribe?: boolean | undefined;\n queueQoSZero?: boolean | undefined;\n rejectUnauthorized?: boolean | undefined;\n properties?: {\n sessionExpiryInterval?: number | undefined;\n receiveMaximum?: number | undefined;\n maximumPacketSize?: number | undefined;\n topicAliasMaximum?: number | undefined;\n requestResponseInformation?: boolean | undefined;\n requestProblemInformation?: boolean | undefined;\n userProperties?: {\n [x: string]: string;\n } | undefined;\n } | undefined;\n ca?: string | undefined;\n cert?: string | undefined;\n key?: string | undefined;\n servername?: string | undefined;\n };\n devops?: {\n provider?: \"azure-devops\";\n organization: string;\n project?: string | undefined;\n } | undefined;\n}\n\nexport interface AppConfig extends ProjectAppConfig {}\n"]}
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ import type { MqttPublishQueueStatus } from "../uns-mqtt/publish-queue-contract.js";
3
+ /** Generic process-local handshake. The host supplies identity and durable receipts. */
4
+ export declare const MQTT_DRAIN_HANDLER: unique symbol;
5
+ export declare const MQTT_DRAIN_READY_EVENT = "uns-kit:mqtt-drain-ready";
6
+ export declare const mqttDrainReceiptSchema: z.ZodObject<{
7
+ protocol: z.ZodLiteral<1>;
8
+ state: z.ZodLiteral<"drained">;
9
+ pendingRecords: z.ZodLiteral<0>;
10
+ outputs: z.ZodNumber;
11
+ }, z.core.$strict>;
12
+ export type MqttDrainReceipt = z.infer<typeof mqttDrainReceiptSchema>;
13
+ export declare const mqttDrainCapabilitySchema: z.ZodObject<{
14
+ protocolVersion: z.ZodLiteral<1>;
15
+ }, z.core.$strict>;
16
+ export declare function readMqttDrainCapability(packageRoot: string): 1 | undefined;
17
+ export interface MqttDrainOutput {
18
+ flush(timeoutMs: number): Promise<void>;
19
+ sealPublishes(): void;
20
+ getPublishQueueStatus(): MqttPublishQueueStatus | undefined;
21
+ }
22
+ /** Quiesce before flushing. A timeout is a blocked attempt, never a clean exit. */
23
+ export declare function drainMqttForMigration(options: {
24
+ quiesce(): Promise<void>;
25
+ finishAccepted(): Promise<void>;
26
+ outputs: readonly MqttDrainOutput[];
27
+ timeoutMs?: number;
28
+ }): Promise<MqttDrainReceipt>;
29
+ //# sourceMappingURL=mqtt-drain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mqtt-drain.d.ts","sourceRoot":"","sources":["../../src/runtime/mqtt-drain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAEpF,wFAAwF;AACxF,eAAO,MAAM,kBAAkB,eAAsC,CAAC;AACtE,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AACjE,eAAO,MAAM,sBAAsB;;;;;kBAKjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,eAAO,MAAM,yBAAyB;;kBAAoD,CAAC;AAC3F,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAa1E;AACD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,aAAa,IAAI,IAAI,CAAC;IACtB,qBAAqB,IAAI,sBAAsB,GAAG,SAAS,CAAC;CAC7D;AAED,mFAAmF;AACnF,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IACnD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA8B5B"}
@@ -0,0 +1,70 @@
1
+ import { z } from "zod";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ /** Generic process-local handshake. The host supplies identity and durable receipts. */
5
+ export const MQTT_DRAIN_HANDLER = Symbol.for("uns-kit.mqtt-drain.v1");
6
+ export const MQTT_DRAIN_READY_EVENT = "uns-kit:mqtt-drain-ready";
7
+ export const mqttDrainReceiptSchema = z.strictObject({
8
+ protocol: z.literal(1),
9
+ state: z.literal("drained"),
10
+ pendingRecords: z.literal(0),
11
+ outputs: z.number().int().min(0).max(64),
12
+ });
13
+ export const mqttDrainCapabilitySchema = z.strictObject({ protocolVersion: z.literal(1) });
14
+ export function readMqttDrainCapability(packageRoot) {
15
+ const file = path.join(packageRoot, "package.json");
16
+ let stat;
17
+ try {
18
+ stat = fs.lstatSync(file);
19
+ }
20
+ catch (error) {
21
+ if (error.code === "ENOENT")
22
+ return undefined;
23
+ throw error;
24
+ }
25
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 1048576)
26
+ throw Error("Unsafe installed MQTT drain descriptor");
27
+ const value = JSON.parse(fs.readFileSync(file, "utf8"))?.unsDatahub?.mqttDrain;
28
+ if (value === undefined)
29
+ return undefined;
30
+ mqttDrainCapabilitySchema.parse(value);
31
+ return 1;
32
+ }
33
+ /** Quiesce before flushing. A timeout is a blocked attempt, never a clean exit. */
34
+ export async function drainMqttForMigration(options) {
35
+ const timeoutMs = options.timeoutMs ?? 30_000;
36
+ if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 300_000 || options.outputs.length > 64)
37
+ throw Error("Invalid bounded MQTT migration drain");
38
+ let timer;
39
+ const deadline = Date.now() + timeoutMs;
40
+ let expired = false;
41
+ const work = (async () => {
42
+ await options.quiesce();
43
+ await options.finishAccepted();
44
+ const remaining = deadline - Date.now();
45
+ if (remaining <= 0)
46
+ throw Error("MQTT migration drain timed out; retain the original owner");
47
+ await Promise.all(options.outputs.map(output => output.flush(remaining)));
48
+ for (const output of options.outputs) {
49
+ const status = output.getPublishQueueStatus();
50
+ if (status && (status.pendingRecords !== 0 || status.memoryRecords !== 0 || status.diskRecords !== 0 || status.inFlight || status.state === "blocked"))
51
+ throw Error("MQTT output is not confirmed empty; migration remains blocked");
52
+ }
53
+ if (expired || Date.now() > deadline)
54
+ throw Error("MQTT migration drain expired; outcome must be reconciled");
55
+ // No await between the final checks and admission fences.
56
+ for (const output of options.outputs)
57
+ output.sealPublishes();
58
+ return mqttDrainReceiptSchema.parse({ protocol: 1, state: "drained", pendingRecords: 0, outputs: options.outputs.length });
59
+ })();
60
+ try {
61
+ return await Promise.race([work, new Promise((_, reject) => {
62
+ timer = setTimeout(() => { expired = true; reject(Error("MQTT migration drain timed out; pending work retained")); }, timeoutMs);
63
+ })]);
64
+ }
65
+ finally {
66
+ if (timer)
67
+ clearTimeout(timer);
68
+ }
69
+ }
70
+ //# sourceMappingURL=mqtt-drain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mqtt-drain.js","sourceRoot":"","sources":["../../src/runtime/mqtt-drain.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { MqttPublishQueueStatus } from \"../uns-mqtt/publish-queue-contract.js\";\n\n/** Generic process-local handshake. The host supplies identity and durable receipts. */\nexport const MQTT_DRAIN_HANDLER = Symbol.for(\"uns-kit.mqtt-drain.v1\");\nexport const MQTT_DRAIN_READY_EVENT = \"uns-kit:mqtt-drain-ready\";\nexport const mqttDrainReceiptSchema = z.strictObject({\n protocol: z.literal(1),\n state: z.literal(\"drained\"),\n pendingRecords: z.literal(0),\n outputs: z.number().int().min(0).max(64),\n});\nexport type MqttDrainReceipt = z.infer<typeof mqttDrainReceiptSchema>;\nexport const mqttDrainCapabilitySchema = z.strictObject({ protocolVersion: z.literal(1) });\nexport function readMqttDrainCapability(packageRoot: string): 1 | undefined {\n const file = path.join(packageRoot, \"package.json\");\n let stat: fs.Stats;\n try { stat = fs.lstatSync(file); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw error;\n }\n if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 1048576) throw Error(\"Unsafe installed MQTT drain descriptor\");\n const value = JSON.parse(fs.readFileSync(file, \"utf8\"))?.unsDatahub?.mqttDrain;\n if (value === undefined) return undefined;\n mqttDrainCapabilitySchema.parse(value);\n return 1;\n}\nexport interface MqttDrainOutput {\n flush(timeoutMs: number): Promise<void>;\n sealPublishes(): void;\n getPublishQueueStatus(): MqttPublishQueueStatus | undefined;\n}\n\n/** Quiesce before flushing. A timeout is a blocked attempt, never a clean exit. */\nexport async function drainMqttForMigration(options: {\n quiesce(): Promise<void>;\n finishAccepted(): Promise<void>;\n outputs: readonly MqttDrainOutput[];\n timeoutMs?: number;\n}): Promise<MqttDrainReceipt> {\n const timeoutMs = options.timeoutMs ?? 30_000;\n if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 300_000 || options.outputs.length > 64)\n throw Error(\"Invalid bounded MQTT migration drain\");\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = Date.now() + timeoutMs;\n let expired = false;\n const work = (async () => {\n await options.quiesce();\n await options.finishAccepted();\n const remaining = deadline - Date.now();\n if (remaining <= 0) throw Error(\"MQTT migration drain timed out; retain the original owner\");\n await Promise.all(options.outputs.map(output => output.flush(remaining)));\n for (const output of options.outputs) {\n const status = output.getPublishQueueStatus();\n if (status && (status.pendingRecords !== 0 || status.memoryRecords !== 0 || status.diskRecords !== 0 || status.inFlight || status.state === \"blocked\"))\n throw Error(\"MQTT output is not confirmed empty; migration remains blocked\");\n }\n if (expired || Date.now() > deadline) throw Error(\"MQTT migration drain expired; outcome must be reconciled\");\n // No await between the final checks and admission fences.\n for (const output of options.outputs) output.sealPublishes();\n return mqttDrainReceiptSchema.parse({ protocol: 1, state: \"drained\", pendingRecords: 0, outputs: options.outputs.length });\n })();\n try {\n return await Promise.race([work, new Promise<never>((_, reject) => {\n timer = setTimeout(() => { expired = true; reject(Error(\"MQTT migration drain timed out; pending work retained\")); }, timeoutMs);\n })]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-output-state-contract.d.ts","sourceRoot":"","sources":["../../src/runtime/mqtt-output-state-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,qBAAqB;;;;;;;EAA2B,CAAC;AAC9D,eAAO,MAAM,2BAA2B;;;;;;;;;;;kBAcqD,CAAC;AAE9F,qFAAqF;AACrF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAOvI"}
1
+ {"version":3,"file":"mqtt-output-state-contract.d.ts","sourceRoot":"","sources":["../../src/runtime/mqtt-output-state-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,qBAAqB;;;;;;;EAA2B,CAAC;AAC9D,eAAO,MAAM,2BAA2B;;;;;;;;;;;kBAcqD,CAAC;AAE9F,qFAAqF;AACrF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQvI"}
@@ -25,6 +25,8 @@ export function managedMqttOutputBinding(config, root) {
25
25
  if (value?.output?.publishQueue === undefined)
26
26
  return undefined;
27
27
  const queue = mqttPublishQueueSchema.parse(value.output.publishQueue);
28
+ if (queue.enabled === false)
29
+ return undefined;
28
30
  if (queue.storage !== "runtime" || !root)
29
31
  throw Error("Controller-managed MQTT output requires storage=runtime and a reviewed persistent Runtime mount");
30
32
  return { directory: queue.directory, relative: outputStateRelative(root, queue.directory) };
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-output-state-contract.js","sourceRoot":"","sources":["../../src/runtime/mqtt-output-state-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,MAAM,mCAAmC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;AAC9D,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC;KACzC,YAAY,CAAC;IACZ,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC9C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,aAAa,CAAC;IACxE,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,qBAAqB,CAAC,aAAa,GAAG,qBAAqB,CAAC,sBAAsB,CAAC;IAC1F,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC,mBAAmB,CAAC;IACjF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;CAC3C,CAAC;KACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAE9F,qFAAqF;AACrF,MAAM,UAAU,wBAAwB,CAAC,MAAe,EAAE,IAAwB;IAChF,MAAM,KAAK,GAAG,MAAiD,CAAC;IAChE,IAAI,KAAK,EAAE,MAAM,EAAE,YAAY,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,KAAK,GAAG,sBAAsB,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACtE,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,IAAI;QACtC,MAAM,KAAK,CAAC,iGAAiG,CAAC,CAAC;IACjH,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;AAC9F,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { mqttPublishQueueSchema } from \"../uns-mqtt/publish-queue-contract.js\";\nimport fixed from \"./mqtt-output-state-contract.json\" with { type: \"json\" };\nimport { outputStateLimits } from \"./mqtt-output-state-program.mjs\";\nimport { outputStateRelative } from \"./mqtt-output-state-program.mjs\";\n\nexport const mqttOutputStateLimits = outputStateLimits(fixed);\nexport const mqttOutputStateBackupSchema = z\n .strictObject({\n schemaVersion: z.literal(1),\n state: z.enum([\"included\", \"empty\"]),\n rootSha256: z.string().regex(/^[a-f0-9]{64}$/),\n queues: z.number().int().min(0).max(mqttOutputStateLimits.maximumQueues),\n records: z\n .number()\n .int()\n .min(0)\n .max(mqttOutputStateLimits.maximumQueues * mqttOutputStateLimits.maximumRecordsPerQueue),\n bytes: z.number().int().positive().max(mqttOutputStateLimits.maximumCapsuleBytes),\n sha256: z.string().regex(/^[a-f0-9]{64}$/),\n })\n .refine((v) => (v.state === \"included\" ? v.queues > 0 : v.queues === 0 && v.records === 0));\n\n/** Controller inspection of standard SDK configuration, without application code. */\nexport function managedMqttOutputBinding(config: unknown, root: string | undefined): { directory: string; relative: string } | undefined {\n const value = config as { output?: { publishQueue?: unknown } };\n if (value?.output?.publishQueue === undefined) return undefined;\n const queue = mqttPublishQueueSchema.parse(value.output.publishQueue);\n if (queue.storage !== \"runtime\" || !root)\n throw Error(\"Controller-managed MQTT output requires storage=runtime and a reviewed persistent Runtime mount\");\n return { directory: queue.directory, relative: outputStateRelative(root, queue.directory) };\n}\n"]}
1
+ {"version":3,"file":"mqtt-output-state-contract.js","sourceRoot":"","sources":["../../src/runtime/mqtt-output-state-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,MAAM,mCAAmC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;AAC9D,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC;KACzC,YAAY,CAAC;IACZ,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC9C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,aAAa,CAAC;IACxE,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,qBAAqB,CAAC,aAAa,GAAG,qBAAqB,CAAC,sBAAsB,CAAC;IAC1F,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC,mBAAmB,CAAC;IACjF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;CAC3C,CAAC;KACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAE9F,qFAAqF;AACrF,MAAM,UAAU,wBAAwB,CAAC,MAAe,EAAE,IAAwB;IAChF,MAAM,KAAK,GAAG,MAAiD,CAAC;IAChE,IAAI,KAAK,EAAE,MAAM,EAAE,YAAY,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,KAAK,GAAG,sBAAsB,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACtE,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IAC9C,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,IAAI;QACtC,MAAM,KAAK,CAAC,iGAAiG,CAAC,CAAC;IACjH,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;AAC9F,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { mqttPublishQueueSchema } from \"../uns-mqtt/publish-queue-contract.js\";\nimport fixed from \"./mqtt-output-state-contract.json\" with { type: \"json\" };\nimport { outputStateLimits } from \"./mqtt-output-state-program.mjs\";\nimport { outputStateRelative } from \"./mqtt-output-state-program.mjs\";\n\nexport const mqttOutputStateLimits = outputStateLimits(fixed);\nexport const mqttOutputStateBackupSchema = z\n .strictObject({\n schemaVersion: z.literal(1),\n state: z.enum([\"included\", \"empty\"]),\n rootSha256: z.string().regex(/^[a-f0-9]{64}$/),\n queues: z.number().int().min(0).max(mqttOutputStateLimits.maximumQueues),\n records: z\n .number()\n .int()\n .min(0)\n .max(mqttOutputStateLimits.maximumQueues * mqttOutputStateLimits.maximumRecordsPerQueue),\n bytes: z.number().int().positive().max(mqttOutputStateLimits.maximumCapsuleBytes),\n sha256: z.string().regex(/^[a-f0-9]{64}$/),\n })\n .refine((v) => (v.state === \"included\" ? v.queues > 0 : v.queues === 0 && v.records === 0));\n\n/** Controller inspection of standard SDK configuration, without application code. */\nexport function managedMqttOutputBinding(config: unknown, root: string | undefined): { directory: string; relative: string } | undefined {\n const value = config as { output?: { publishQueue?: unknown } };\n if (value?.output?.publishQueue === undefined) return undefined;\n const queue = mqttPublishQueueSchema.parse(value.output.publishQueue);\n if (queue.enabled === false) return undefined;\n if (queue.storage !== \"runtime\" || !root)\n throw Error(\"Controller-managed MQTT output requires storage=runtime and a reviewed persistent Runtime mount\");\n return { directory: queue.directory, relative: outputStateRelative(root, queue.directory) };\n}\n"]}
@@ -26,3 +26,7 @@ export function validateOutputSnapshot(directory: string, limits: unknown): { qu
26
26
  export function outputStateRelative(root: string, directory: string): string;
27
27
 
28
28
  export function outputStateMain(args?: string[]): Promise<void>;
29
+
30
+ export function inspectManagedOutputQueue(root: string, directory: string, identity: string, limits: unknown, requireStopped?: boolean): {
31
+ rootId: string; relative: string; identity: string; records: number; bytes: number; exists: boolean; ownerActive:boolean;
32
+ };
@@ -187,6 +187,56 @@ export function openManagedOutputRoot(directory, root) {
187
187
  throw e;
188
188
  }
189
189
  }
190
+ /** Read-only reviewed handoff evidence. Never initializes, deletes or rebinds a queue. */
191
+ export function inspectManagedOutputQueue(root, directory, identity, limits, requireStopped = true) {
192
+ outputStateLimits(limits);
193
+ assertOutputStateRoot(root);
194
+ const relative = outputStateRelative(root, directory);
195
+ noLinks(directory);
196
+ const { DatabaseSync } = sqlite();
197
+ const file = path.join(root, guardName);
198
+ check(file);
199
+ check(file + "-journal", false, true);
200
+ const guard = new DatabaseSync(file, { readOnly: true });
201
+ let owner;
202
+ try {
203
+ guard.exec("PRAGMA busy_timeout=1000; BEGIN");
204
+ const meta = Object.fromEntries(guard.prepare("SELECT key,value FROM metadata").all().map(r => [r.key,r.value]));
205
+ if (!exactKeys(meta, ["schema", "id"]) || meta.schema !== "mqtt-output-root-1" || !uuid.test(meta.id)) fail();
206
+ const marker = path.join(root, markerName);
207
+ if (fs.existsSync(marker)) {
208
+ const m = privateJson(marker);
209
+ if (!exactKeys(m,["schemaVersion","state","sourceSha","rootId"]) || m.schemaVersion !== 1 ||
210
+ m.state !== "complete" || !hex.test(m.sourceSha) || m.rootId !== meta.id) fail();
211
+ }
212
+ if (fs.existsSync(path.join(root, stageName))) fail();
213
+ check(path.dirname(directory), true, true);
214
+ const base = {rootId: meta.id, relative, identity};
215
+ if (!check(directory, true, true)) return {...base, records:0, bytes:0, exists:false, ownerActive:false};
216
+ const entries = fs.opendirSync(directory);
217
+ const names = [];
218
+ try { let e; while ((e=entries.readSync())) { if (names.length >= 5) fail(); names.push(e.name); } }
219
+ finally { entries.closeSync(); }
220
+ if (names.length === 0) return {...base, records:0, bytes:0, exists:false, ownerActive:false};
221
+ if (names.some(n => !["mqtt-outbox.sqlite","mqtt-outbox.sqlite-wal","mqtt-outbox.sqlite-shm","mqtt-outbox-owner.sqlite","mqtt-outbox-owner.sqlite-journal"].includes(n))) fail();
222
+ let physicalBytes=0;
223
+ for (const name of names) { physicalBytes+=check(path.join(directory,name)).size; if(physicalBytes>limits.maximumSnapshotBytes) fail(); }
224
+ const ownerFile = path.join(directory,"mqtt-outbox-owner.sqlite");
225
+ check(ownerFile);
226
+ // Existing writer's exclusive lease must be released, even when usage is zero.
227
+ let ownerActive=false;
228
+ owner = new DatabaseSync(ownerFile);
229
+ try { owner.exec("PRAGMA busy_timeout=0; BEGIN EXCLUSIVE"); }
230
+ catch(e) { if(requireStopped || e.errcode!==5) throw e; ownerActive=true; }
231
+
232
+ const dbFile = path.join(directory,"mqtt-outbox.sqlite");
233
+ if (check(dbFile).size > limits.maximumSnapshotBytes) fail();
234
+ const status = inspectDatabase(dbFile,{rootId:meta.id,relative},limits);
235
+ if (status.identity !== identity) fail();
236
+ return {...base, records:status.records, bytes:status.bytes, exists:true, ownerActive};
237
+ } finally { owner?.close(); guard.close(); }
238
+ }
239
+
190
240
  export function validateOutputRow(row) {
191
241
  if (typeof row.record !== "string" || sha(row.record) !== row.sha256) throw Error("MQTT outbox integrity check failed; pending work preserved");
192
242
  const r = JSON.parse(row.record);
@@ -219,6 +269,7 @@ function inspectDatabase(file, binding, limits) {
219
269
  const { DatabaseSync } = sqlite(),
220
270
  db = new DatabaseSync(file, { readOnly: true });
221
271
  try {
272
+ db.exec("PRAGMA busy_timeout=1000; BEGIN");
222
273
  if (db.prepare("PRAGMA quick_check").get().quick_check !== "ok") fail();
223
274
  const meta = Object.fromEntries(
224
275
  db
@@ -1,4 +1,5 @@
1
1
  import type { PreparedGroupUpgrade, UpgradeConfigurations } from "./process-group-upgrade.js";
2
2
  /** Same generation, different paired artifacts. Never initializes or rewrites the journal. */
3
3
  export declare function reviewInstalledConfigurationGroupUpgrade(configs: UpgradeConfigurations, controllerName: string, stateRoot: string, excludedUnsFields?: readonly string[]): PreparedGroupUpgrade;
4
+ export declare function reviewInstalledConfigurationGroupMqttOutput(configs: UpgradeConfigurations, controllerName: string, stateRoot: string, excludedUnsFields?: readonly string[]): PreparedGroupUpgrade;
4
5
  //# sourceMappingURL=process-group-configured-upgrade.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-group-configured-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAA6B,oBAAoB,EAAwB,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAE/I,8FAA8F;AAC9F,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,qBAAqB,EAC9B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACxC,oBAAoB,CAyGtB"}
1
+ {"version":3,"file":"process-group-configured-upgrade.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAGV,oBAAoB,EAEpB,qBAAqB,EACtB,MAAM,4BAA4B,CAAC;AAEpC,8FAA8F;AAC9F,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,qBAAqB,EAC9B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACxC,oBAAoB,CAEtB;AACD,wBAAgB,2CAA2C,CACzD,OAAO,EAAE,qBAAqB,EAC9B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACxC,oBAAoB,CAYtB"}
@@ -4,9 +4,26 @@ import { configurationResourceHash } from "./configuration-group-contract.js";
4
4
  import { authorizeProcessGroupRuntime, processGroupAuthorizationFile, validateProcessGroupPolicyCandidate } from "./process-group-authorization.js";
5
5
  import { resolvedProcessGroupChannels } from "./process-group-contract.js";
6
6
  import { describeInstalledProcessGroupGeneration, inspectGenerationJournal } from "./process-group-generation.js";
7
+ import { mqttOutputPortableConfiguration, reviewProcessGroupMqttOutput } from "./process-group-mqtt-output.js";
7
8
  import { groupArtifactHash, groupChannelsHash, configurationAuthorizationHash as hash, readProcessGroupResource as read, sha256, } from "./process-group-resources.js";
8
9
  /** Same generation, different paired artifacts. Never initializes or rewrites the journal. */
9
10
  export function reviewInstalledConfigurationGroupUpgrade(configs, controllerName, stateRoot, excludedUnsFields = []) {
11
+ return reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, false);
12
+ }
13
+ export function reviewInstalledConfigurationGroupMqttOutput(configs, controllerName, stateRoot, excludedUnsFields = []) {
14
+ const mqttOutput = reviewProcessGroupMqttOutput(configs, process.env["UNS_MQTT_OUTPUT_STATE_ROOT"], stateRoot);
15
+ const result = reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, true);
16
+ return {
17
+ ...result,
18
+ review: {
19
+ ...result.review,
20
+ protocolVersion: 3,
21
+ mqttOutput,
22
+ delivery: { inputPausePossible: true, exactlyOnceOutput: false, pendingOutputBlocksRollback: true },
23
+ },
24
+ };
25
+ }
26
+ function reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, mqttOutput) {
10
27
  const context = (c) => ({
11
28
  packageRoot: c.packageRoot,
12
29
  instanceDirectory: c.instanceDirectory,
@@ -19,12 +36,12 @@ export function reviewInstalledConfigurationGroupUpgrade(configs, controllerName
19
36
  if (a.d.protocolVersion !== 2 || b.d.protocolVersion !== 2 || a.d.namespace !== b.d.namespace || hash(a.reference) !== hash(b.reference))
20
37
  throw Error("Unchanged configuration generation required; review resource changes as a separate generation");
21
38
  const pkg = (c) => JSON.parse(read(path.join(c.packageRoot, "package.json")).toString()), sourcePackage = pkg(source), targetPackage = pkg(target);
22
- if (!sourcePackage.version || !targetPackage.version || sourcePackage.version === targetPackage.version)
39
+ if (!sourcePackage.version || !targetPackage.version || (!mqttOutput && sourcePackage.version === targetPackage.version))
23
40
  throw Error("Two different installed paired versions required");
24
41
  const old = authorizeProcessGroupRuntime(context(source));
25
42
  const sourcePolicy = read(old.file, true), previous = configurationGroupAuthorizationSchema.parse(JSON.parse(sourcePolicy.toString()));
26
- const portable = (raw) => {
27
- const copy = structuredClone(raw), uns = { ...copy["uns"] };
43
+ const portable = (raw, role) => {
44
+ const copy = mqttOutput ? mqttOutputPortableConfiguration(raw, role) : structuredClone(raw), uns = { ...copy["uns"] };
28
45
  for (const key of excludedUnsFields)
29
46
  delete uns[key];
30
47
  copy["uns"] = uns;
@@ -46,7 +63,7 @@ export function reviewInstalledConfigurationGroupUpgrade(configs, controllerName
46
63
  (role === "receiver"
47
64
  ? g.normalized.runtimeRole !== "admission"
48
65
  : g.normalized.runtimeRole !== undefined && g.normalized.runtimeRole !== "publisher") ||
49
- portable(c.raw) !== portable(configs.source[role].raw) ||
66
+ portable(c.raw, role) !== portable(configs.source[role].raw, role) ||
50
67
  groupChannelsHash(g.channels) !== groupChannelsHash(a.channels) ||
51
68
  processGroupAuthorizationFile(context(c)) !== old.file)
52
69
  throw Error("Exact paired configuration, resources, broker identity and retained journal required");
@@ -1 +1 @@
1
- {"version":3,"file":"process-group-configured-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\n\nimport { configurationGroupAuthorizationSchema } from \"./configuration-group-authorization.js\";\nimport { configurationResourceHash } from \"./configuration-group-contract.js\";\nimport { authorizeProcessGroupRuntime, processGroupAuthorizationFile, validateProcessGroupPolicyCandidate } from \"./process-group-authorization.js\";\nimport { resolvedProcessGroupChannels } from \"./process-group-contract.js\";\nimport { describeInstalledProcessGroupGeneration, inspectGenerationJournal } from \"./process-group-generation.js\";\nimport {\n groupArtifactHash,\n groupChannelsHash,\n configurationAuthorizationHash as hash,\n readProcessGroupResource as read,\n sha256,\n} from \"./process-group-resources.js\";\nimport type { GroupVersionUpgradeReview, PreparedGroupUpgrade, UpgradeConfiguration, UpgradeConfigurations } from \"./process-group-upgrade.js\";\n\n/** Same generation, different paired artifacts. Never initializes or rewrites the journal. */\nexport function reviewInstalledConfigurationGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n const context = (c: UpgradeConfiguration) => ({\n packageRoot: c.packageRoot,\n instanceDirectory: c.instanceDirectory,\n rawConfiguration: c.raw,\n channels: resolvedProcessGroupChannels(c.resolved),\n controllerName,\n stateRoot,\n });\n const source = configs.source.publisher,\n target = configs.target.publisher,\n a = describeInstalledProcessGroupGeneration(source),\n b = describeInstalledProcessGroupGeneration(target);\n if (a.d.protocolVersion !== 2 || b.d.protocolVersion !== 2 || a.d.namespace !== b.d.namespace || hash(a.reference) !== hash(b.reference))\n throw Error(\"Unchanged configuration generation required; review resource changes as a separate generation\");\n const pkg = (c: UpgradeConfiguration) => JSON.parse(read(path.join(c.packageRoot, \"package.json\")).toString()),\n sourcePackage = pkg(source),\n targetPackage = pkg(target);\n if (!sourcePackage.version || !targetPackage.version || sourcePackage.version === targetPackage.version)\n throw Error(\"Two different installed paired versions required\");\n const old = authorizeProcessGroupRuntime(context(source));\n const sourcePolicy = read(old.file, true),\n previous = configurationGroupAuthorizationSchema.parse(JSON.parse(sourcePolicy.toString()));\n const portable = (raw: Record<string, unknown>) => {\n const copy = structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const key of excludedUnsFields) delete uns[key];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n const members: GroupVersionUpgradeReview[\"members\"] = [];\n const directories = new Set<string>();\n for (const side of [\"source\", \"target\"] as const)\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const c = configs[side][role],\n g = describeInstalledProcessGroupGeneration(c),\n installed = pkg(c);\n if (\n g.d.protocolVersion !== 2 ||\n g.d.namespace !== a.d.namespace ||\n installed.name !== sourcePackage.name ||\n installed.version !== (side === \"source\" ? sourcePackage.version : targetPackage.version) ||\n c.packageRoot !== configs[side].publisher.packageRoot ||\n directories.has(c.instanceDirectory) ||\n hash(g.reference) !== hash(a.reference) ||\n g.normalized.uns[\"processName\"] !== (role === \"publisher\" ? a.processName : a.receiverProcessName) ||\n (role === \"receiver\"\n ? g.normalized.runtimeRole !== \"admission\"\n : g.normalized.runtimeRole !== undefined && g.normalized.runtimeRole !== \"publisher\") ||\n portable(c.raw) !== portable(configs.source[role].raw) ||\n groupChannelsHash(g.channels) !== groupChannelsHash(a.channels) ||\n processGroupAuthorizationFile(context(c)) !== old.file\n )\n throw Error(\"Exact paired configuration, resources, broker identity and retained journal required\");\n directories.add(c.instanceDirectory);\n if (side === \"source\") {\n const proof = authorizeProcessGroupRuntime(context(c));\n if (proof.role !== (role === \"publisher\" ? \"target\" : \"receiver\") || proof.sha256 !== sha256(sourcePolicy))\n throw Error(\"Exact authorized source pair required\");\n }\n members.push({\n side,\n role,\n processName: String(g.normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n const policy = configurationGroupAuthorizationSchema.parse({\n ...previous,\n packageRoot: target.packageRoot,\n descriptorSha256: configurationResourceHash(targetPackage.unsDatahub.processGroupConfigurationRuntime),\n artifactSha256: groupArtifactHash(target.packageRoot),\n placements: [\n ...previous.placements.filter((p) => p.role === \"source\"),\n ...([\"publisher\", \"receiver\"] as const).map((role) => ({\n instanceId: path.basename(configs.target[role].instanceDirectory),\n processName: members.find((m) => m.side === \"target\" && m.role === role)!.processName,\n role: role === \"publisher\" ? \"target\" : \"receiver\",\n configurationSha256: configurationResourceHash(configs.target[role].raw),\n })),\n ],\n });\n const targetPolicy = Buffer.from(JSON.stringify(policy));\n for (const role of [\"publisher\", \"receiver\"] as const) validateProcessGroupPolicyCandidate(context(configs.target[role]), targetPolicy);\n inspectGenerationJournal(a.reference); // Pending, previously completed work is valid and must remain bound.\n if (sha256(read(old.file, true)) !== sha256(sourcePolicy)) throw Error(\"Source policy changed during review\");\n return {\n review: {\n protocolVersion: 1,\n namespace: a.d.namespace,\n groupId: a.id,\n policyFile: old.file,\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: a.reference.journalId,\n directory: a.reference.directory,\n journalContractSha256: a.reference.journalContractSha256,\n profiles: a.reference.profiles,\n retainedJournal: a.reference,\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n"]}
1
+ {"version":3,"file":"process-group-configured-upgrade.js","sourceRoot":"","sources":["../../src/runtime/process-group-configured-upgrade.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\n\nimport { configurationGroupAuthorizationSchema } from \"./configuration-group-authorization.js\";\nimport { configurationResourceHash } from \"./configuration-group-contract.js\";\nimport { authorizeProcessGroupRuntime, processGroupAuthorizationFile, validateProcessGroupPolicyCandidate } from \"./process-group-authorization.js\";\nimport { resolvedProcessGroupChannels } from \"./process-group-contract.js\";\nimport { describeInstalledProcessGroupGeneration, inspectGenerationJournal } from \"./process-group-generation.js\";\nimport { mqttOutputPortableConfiguration, reviewProcessGroupMqttOutput } from \"./process-group-mqtt-output.js\";\nimport {\n groupArtifactHash,\n groupChannelsHash,\n configurationAuthorizationHash as hash,\n readProcessGroupResource as read,\n sha256,\n} from \"./process-group-resources.js\";\nimport type {\n GroupMqttOutputReview,\n GroupVersionUpgradeReview,\n PreparedGroupUpgrade,\n UpgradeConfiguration,\n UpgradeConfigurations,\n} from \"./process-group-upgrade.js\";\n\n/** Same generation, different paired artifacts. Never initializes or rewrites the journal. */\nexport function reviewInstalledConfigurationGroupUpgrade(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n return reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, false);\n}\nexport function reviewInstalledConfigurationGroupMqttOutput(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[] = [],\n): PreparedGroupUpgrade {\n const mqttOutput = reviewProcessGroupMqttOutput(configs, process.env[\"UNS_MQTT_OUTPUT_STATE_ROOT\"], stateRoot);\n const result = reviewConfigurationGroup(configs, controllerName, stateRoot, excludedUnsFields, true);\n return {\n ...result,\n review: {\n ...result.review,\n protocolVersion: 3,\n mqttOutput,\n delivery: { inputPausePossible: true, exactlyOnceOutput: false, pendingOutputBlocksRollback: true },\n } as GroupMqttOutputReview,\n };\n}\nfunction reviewConfigurationGroup(\n configs: UpgradeConfigurations,\n controllerName: string,\n stateRoot: string,\n excludedUnsFields: readonly string[],\n mqttOutput: boolean,\n): PreparedGroupUpgrade {\n const context = (c: UpgradeConfiguration) => ({\n packageRoot: c.packageRoot,\n instanceDirectory: c.instanceDirectory,\n rawConfiguration: c.raw,\n channels: resolvedProcessGroupChannels(c.resolved),\n controllerName,\n stateRoot,\n });\n const source = configs.source.publisher,\n target = configs.target.publisher,\n a = describeInstalledProcessGroupGeneration(source),\n b = describeInstalledProcessGroupGeneration(target);\n if (a.d.protocolVersion !== 2 || b.d.protocolVersion !== 2 || a.d.namespace !== b.d.namespace || hash(a.reference) !== hash(b.reference))\n throw Error(\"Unchanged configuration generation required; review resource changes as a separate generation\");\n const pkg = (c: UpgradeConfiguration) => JSON.parse(read(path.join(c.packageRoot, \"package.json\")).toString()),\n sourcePackage = pkg(source),\n targetPackage = pkg(target);\n if (!sourcePackage.version || !targetPackage.version || (!mqttOutput && sourcePackage.version === targetPackage.version))\n throw Error(\"Two different installed paired versions required\");\n const old = authorizeProcessGroupRuntime(context(source));\n const sourcePolicy = read(old.file, true),\n previous = configurationGroupAuthorizationSchema.parse(JSON.parse(sourcePolicy.toString()));\n const portable = (raw: Record<string, unknown>, role: \"publisher\" | \"receiver\") => {\n const copy = mqttOutput ? mqttOutputPortableConfiguration(raw, role) : structuredClone(raw),\n uns = { ...(copy[\"uns\"] as Record<string, unknown>) };\n for (const key of excludedUnsFields) delete uns[key];\n copy[\"uns\"] = uns;\n return hash(copy);\n };\n const members: GroupVersionUpgradeReview[\"members\"] = [];\n const directories = new Set<string>();\n for (const side of [\"source\", \"target\"] as const)\n for (const role of [\"publisher\", \"receiver\"] as const) {\n const c = configs[side][role],\n g = describeInstalledProcessGroupGeneration(c),\n installed = pkg(c);\n if (\n g.d.protocolVersion !== 2 ||\n g.d.namespace !== a.d.namespace ||\n installed.name !== sourcePackage.name ||\n installed.version !== (side === \"source\" ? sourcePackage.version : targetPackage.version) ||\n c.packageRoot !== configs[side].publisher.packageRoot ||\n directories.has(c.instanceDirectory) ||\n hash(g.reference) !== hash(a.reference) ||\n g.normalized.uns[\"processName\"] !== (role === \"publisher\" ? a.processName : a.receiverProcessName) ||\n (role === \"receiver\"\n ? g.normalized.runtimeRole !== \"admission\"\n : g.normalized.runtimeRole !== undefined && g.normalized.runtimeRole !== \"publisher\") ||\n portable(c.raw, role) !== portable(configs.source[role].raw, role) ||\n groupChannelsHash(g.channels) !== groupChannelsHash(a.channels) ||\n processGroupAuthorizationFile(context(c)) !== old.file\n )\n throw Error(\"Exact paired configuration, resources, broker identity and retained journal required\");\n directories.add(c.instanceDirectory);\n if (side === \"source\") {\n const proof = authorizeProcessGroupRuntime(context(c));\n if (proof.role !== (role === \"publisher\" ? \"target\" : \"receiver\") || proof.sha256 !== sha256(sourcePolicy))\n throw Error(\"Exact authorized source pair required\");\n }\n members.push({\n side,\n role,\n processName: String(g.normalized.uns[\"processName\"]),\n configurationSha256: hash(c.raw),\n artifactSha256: groupArtifactHash(c.packageRoot),\n });\n }\n const policy = configurationGroupAuthorizationSchema.parse({\n ...previous,\n packageRoot: target.packageRoot,\n descriptorSha256: configurationResourceHash(targetPackage.unsDatahub.processGroupConfigurationRuntime),\n artifactSha256: groupArtifactHash(target.packageRoot),\n placements: [\n ...previous.placements.filter((p) => p.role === \"source\"),\n ...([\"publisher\", \"receiver\"] as const).map((role) => ({\n instanceId: path.basename(configs.target[role].instanceDirectory),\n processName: members.find((m) => m.side === \"target\" && m.role === role)!.processName,\n role: role === \"publisher\" ? \"target\" : \"receiver\",\n configurationSha256: configurationResourceHash(configs.target[role].raw),\n })),\n ],\n });\n const targetPolicy = Buffer.from(JSON.stringify(policy));\n for (const role of [\"publisher\", \"receiver\"] as const) validateProcessGroupPolicyCandidate(context(configs.target[role]), targetPolicy);\n inspectGenerationJournal(a.reference); // Pending, previously completed work is valid and must remain bound.\n if (sha256(read(old.file, true)) !== sha256(sourcePolicy)) throw Error(\"Source policy changed during review\");\n return {\n review: {\n protocolVersion: 1,\n namespace: a.d.namespace,\n groupId: a.id,\n policyFile: old.file,\n sourcePolicySha256: sha256(sourcePolicy),\n targetPolicySha256: sha256(targetPolicy),\n journalId: a.reference.journalId,\n directory: a.reference.directory,\n journalContractSha256: a.reference.journalContractSha256,\n profiles: a.reference.profiles,\n retainedJournal: a.reference,\n members,\n },\n sourcePolicy,\n targetPolicy,\n };\n}\n"]}
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+ import type { UpgradeConfigurations } from "./process-group-upgrade.js";
3
+ export declare const processGroupMqttOutputRuntimeSchema: z.ZodObject<{
4
+ protocolVersion: z.ZodLiteral<1>;
5
+ instanceName: z.ZodString;
6
+ }, z.core.$strict>;
7
+ /** An explicit output enablement, never an incidental version/configuration change. */
8
+ export declare const processGroupMqttOutputInputSchema: z.ZodObject<{
9
+ protocolVersion: z.ZodLiteral<3>;
10
+ source: z.ZodObject<{
11
+ publisher: z.ZodObject<{
12
+ controller: z.ZodString;
13
+ rttNode: z.ZodString;
14
+ version: z.ZodString;
15
+ instanceId: z.ZodString;
16
+ }, z.core.$strict>;
17
+ receiver: z.ZodObject<{
18
+ controller: z.ZodString;
19
+ rttNode: z.ZodString;
20
+ version: z.ZodString;
21
+ instanceId: z.ZodString;
22
+ }, z.core.$strict>;
23
+ }, z.core.$strict>;
24
+ target: z.ZodObject<{
25
+ publisher: z.ZodObject<{
26
+ controller: z.ZodString;
27
+ rttNode: z.ZodString;
28
+ version: z.ZodString;
29
+ instanceId: z.ZodString;
30
+ }, z.core.$strict>;
31
+ receiver: z.ZodObject<{
32
+ controller: z.ZodString;
33
+ rttNode: z.ZodString;
34
+ version: z.ZodString;
35
+ instanceId: z.ZodString;
36
+ }, z.core.$strict>;
37
+ }, z.core.$strict>;
38
+ acknowledgeInputPause: z.ZodLiteral<true>;
39
+ acknowledgePossibleReplay: z.ZodLiteral<true>;
40
+ acknowledgePendingOutputBlocksRollback: z.ZodLiteral<true>;
41
+ }, z.core.$strict>;
42
+ export type GroupMqttOutputReference = {
43
+ root: string;
44
+ directory: string;
45
+ rootId: string;
46
+ relative: string;
47
+ identity: string;
48
+ optionsSha256: string;
49
+ };
50
+ /** Only these explicitly reviewed output fields can differ; all other portable data remains exact. */
51
+ export declare function mqttOutputPortableConfiguration(raw: Record<string, unknown>, role: "publisher" | "receiver"): Record<string, unknown>;
52
+ export declare function reviewProcessGroupMqttOutput(configs: UpgradeConfigurations, root: string | undefined, stateRoot: string): GroupMqttOutputReference;
53
+ /** Recheck after proven exit and immediately before policy/start. Unknown state is never empty. */
54
+ export declare function inspectReviewedProcessGroupMqttOutput(reference: GroupMqttOutputReference, requireStopped?: boolean): {
55
+ rootId: string;
56
+ relative: string;
57
+ identity: string;
58
+ records: number;
59
+ bytes: number;
60
+ exists: boolean;
61
+ ownerActive: boolean;
62
+ };
63
+ //# sourceMappingURL=process-group-mqtt-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-group-mqtt-output.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-mqtt-output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE,eAAO,MAAM,mCAAmC;;;kBAG9C,CAAC;AAEH,uFAAuF;AACvF,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkB1C,CAAC;AACL,MAAM,MAAM,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AACtJ,sGAAsG;AACtG,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,2BAe3G;AACD,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,wBAAwB,CA6BlJ;AACD,mGAAmG;AACnG,wBAAgB,qCAAqC,CAAC,SAAS,EAAE,wBAAwB,EAAE,cAAc,UAAO;;;;;;;;EAI/G"}