miravo 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/console-dist/assets/activity-DsWeRq4h.js +1 -0
- package/console-dist/assets/api-4AqKvsm9.js +1 -0
- package/console-dist/assets/arrow-right-Ea_UhTNi.js +1 -0
- package/console-dist/assets/arrow-up-down-DFSjzzl2.js +1 -0
- package/console-dist/assets/blueprint-card-classes-DBFCDy0M.js +1 -0
- package/console-dist/assets/box-C1WaoOMF.js +1 -0
- package/console-dist/assets/card-BjeP32PN.js +1 -0
- package/console-dist/assets/catalog-BJzyzbLR.js +1 -0
- package/console-dist/assets/catalog-DKjEm-c4.js +1 -0
- package/console-dist/assets/catalog-template-icons-BrUeHaCY.js +1 -0
- package/console-dist/assets/checkbox-DZlJXTE4.js +1 -0
- package/console-dist/assets/chunk-OE4NN4TA-CEjpfhS6.js +3 -0
- package/console-dist/assets/combobox-BGnuCYxO.js +1 -0
- package/console-dist/assets/control-CPhvwx9o.js +1 -0
- package/console-dist/assets/control-Cg2up9NA.js +1 -0
- package/console-dist/assets/copy-button-WkbNkMcd.js +1 -0
- package/console-dist/assets/createLucideIcon-Bwxw859K.js +1 -0
- package/console-dist/assets/deploy-tab-JeWDwPoZ.js +1 -0
- package/console-dist/assets/dist-BhbDML0a.js +1 -0
- package/console-dist/assets/dist-Cy8XTNFT.js +2 -0
- package/console-dist/assets/download-DQ6NH16U.js +1 -0
- package/console-dist/assets/engine-store-CrLnz692.js +1 -0
- package/console-dist/assets/events-CXm29Ok4.js +1 -0
- package/console-dist/assets/events-D01IxhnP.js +1 -0
- package/console-dist/assets/fleet-CfxbKXt9.js +1 -0
- package/console-dist/assets/fleet-lotMGVqe.js +1 -0
- package/console-dist/assets/format-kXTonpDJ.js +1 -0
- package/console-dist/assets/gauge-Ci8zNZlk.js +1 -0
- package/console-dist/assets/get-error-message-3Q5Q-2G5.js +1 -0
- package/console-dist/assets/index-CVPKSDvJ.js +12 -0
- package/console-dist/assets/index-DJkgDeun.css +2 -0
- package/console-dist/assets/input-BWEQFptx.js +1 -0
- package/console-dist/assets/instance-detail-C5IVwuh3.js +1 -0
- package/console-dist/assets/label-uephX5ZG.js +1 -0
- package/console-dist/assets/layers-CUsLQ1fq.js +1 -0
- package/console-dist/assets/login-C3RJli0m.js +126 -0
- package/console-dist/assets/models-B_UioWQ5.js +1 -0
- package/console-dist/assets/models-_IPlPiZ7.js +1 -0
- package/console-dist/assets/not-found-B8gAm08S.js +1 -0
- package/console-dist/assets/platform-targets-R3T-4eJ7.js +1 -0
- package/console-dist/assets/platforms-BWh0BQ3Y.js +1 -0
- package/console-dist/assets/platforms-DStNbtVc.js +1 -0
- package/console-dist/assets/proxy-CsnYqnPp.js +9 -0
- package/console-dist/assets/query-keys-BvtE7BMs.js +1 -0
- package/console-dist/assets/radio-CoHegOv5.js +1 -0
- package/console-dist/assets/rolldown-runtime-COnpUsM8.js +1 -0
- package/console-dist/assets/select-CeO4vP0G.js +1 -0
- package/console-dist/assets/select-display-items-CIzY8953.js +1 -0
- package/console-dist/assets/server-D9Kfn8fQ.js +1 -0
- package/console-dist/assets/shallow-6lGjQhtJ.js +1 -0
- package/console-dist/assets/tags-CiXOIHtY.js +4 -0
- package/console-dist/assets/tags-FQCXIxrP.js +1 -0
- package/console-dist/assets/tooltip-HGLF366Q.js +1 -0
- package/console-dist/assets/transition-nav-link-Df4Rk6vV.js +1 -0
- package/console-dist/assets/transition-types-CPlGtM8w.js +1 -0
- package/console-dist/assets/triangle-alert-adNk_sea.js +1 -0
- package/console-dist/assets/use-platform-stream-DGbK1k2L.js +2 -0
- package/console-dist/assets/use-transition-navigate-CCpcWXB0.js +2 -0
- package/console-dist/assets/validation-Blvud9_O.js +1 -0
- package/console-dist/assets/vendor-charts-CAZdaPlq.js +60 -0
- package/console-dist/assets/vendor-table-wd8JuMmT.js +4 -0
- package/console-dist/assets/vendor-ui-ByahnaY0.js +1 -0
- package/console-dist/index.html +70 -2
- package/package.json +9 -8
- package/src/__tests__/integration/executable-methods-runner.ts +7 -6
- package/src/__tests__/integration/executable-methods.integration.ts +214 -122
- package/src/__tests__/integration/opcua-concurrent-clients.integration.ts +314 -0
- package/src/commands/adapter.ts +180 -7
- package/src/commands/apply.test.ts +62 -0
- package/src/commands/apply.ts +216 -0
- package/src/commands/cleanup.test.ts +34 -0
- package/src/commands/cleanup.ts +201 -0
- package/src/commands/export.test.ts +51 -0
- package/src/commands/export.ts +404 -0
- package/src/commands/fork.ts +2 -2
- package/src/commands/inject.ts +2 -2
- package/src/commands/load.ts +1 -1
- package/src/commands/logs.ts +13 -15
- package/src/commands/models.test.ts +1 -1
- package/src/commands/models.ts +1 -1
- package/src/commands/pause.ts +3 -3
- package/src/commands/platforms.test.ts +186 -0
- package/src/commands/platforms.ts +371 -0
- package/src/commands/remove.ts +1 -1
- package/src/commands/reset.ts +2 -2
- package/src/commands/spawn.ts +2 -2
- package/src/commands/speed.ts +2 -2
- package/src/commands/start/adapter-config.ts +157 -0
- package/src/commands/start/catalog-le-dt.test.ts +50 -0
- package/src/commands/start/catalog-le-dt.ts +187 -0
- package/src/commands/start/catalog-model-schema.ts +89 -0
- package/src/commands/start/catalog-template-detail.ts +54 -0
- package/src/commands/start/daemon.ts +255 -0
- package/src/commands/start/display.ts +150 -0
- package/src/commands/start/engine-setup.ts +247 -0
- package/src/commands/start/events.ts +126 -0
- package/src/commands/start/index.ts +897 -0
- package/src/commands/start/protocol-plans.ts +239 -0
- package/src/commands/start/template-loader.ts +197 -0
- package/src/commands/start/template-resolver.ts +185 -0
- package/src/commands/start/types.ts +73 -0
- package/src/commands/start.test.ts +137 -16
- package/src/commands/status.ts +1 -1
- package/src/commands/stop.ts +19 -8
- package/src/commands/templates.test.ts +1 -1
- package/src/commands/templates.ts +1 -3
- package/src/index.ts +11 -3
- package/src/lib/admin-auth.ts +157 -0
- package/src/lib/admin-client.test.ts +31 -15
- package/src/lib/admin-client.ts +106 -6
- package/src/lib/admin-platform-routes.ts +1017 -0
- package/src/lib/admin-platform-stream.test.ts +434 -0
- package/src/lib/admin-platform-stream.ts +788 -0
- package/src/lib/admin-responses.ts +211 -0
- package/src/lib/admin-server.test.ts +274 -55
- package/src/lib/admin-server.ts +387 -248
- package/src/lib/auth-store.ts +87 -0
- package/src/lib/daemon-registry.ts +12 -14
- package/src/lib/le/le-apply.test.ts +591 -0
- package/src/lib/le/le-apply.ts +832 -0
- package/src/lib/le/le-auth.ts +89 -0
- package/src/lib/le/le-cleanup.test.ts +168 -0
- package/src/lib/le/le-cleanup.ts +399 -0
- package/src/lib/le/le-cli-helpers.ts +77 -0
- package/src/lib/le/le-client.ts +184 -0
- package/src/lib/le/le-concurrency.test.ts +157 -0
- package/src/lib/le/le-concurrency.ts +78 -0
- package/src/lib/le/le-connection-test.ts +42 -0
- package/src/lib/le/le-devicehub-properties.test.ts +53 -0
- package/src/lib/le/le-devicehub-properties.ts +33 -0
- package/src/lib/le/le-devicehub.ts +213 -0
- package/src/lib/le/le-digital-twins.ts +285 -0
- package/src/lib/le/le-drivers.ts +23 -0
- package/src/lib/le/le-endpoint.ts +40 -0
- package/src/lib/le/le-environments.test.ts +73 -0
- package/src/lib/le/le-environments.ts +156 -0
- package/src/lib/le/le-markers.ts +87 -0
- package/src/lib/le/le-plan.test.ts +26 -0
- package/src/lib/le/le-plan.ts +109 -0
- package/src/lib/le/le-platform-operations.test.ts +198 -0
- package/src/lib/le/le-platform-operations.ts +340 -0
- package/src/lib/le/le-static-model-schema.ts +78 -0
- package/src/lib/le/le-static-planner.test.ts +255 -0
- package/src/lib/le/le-static-planner.ts +442 -0
- package/src/lib/le/le-template-exporter.test.ts +527 -0
- package/src/lib/le/le-template-exporter.ts +459 -0
- package/src/lib/le/le-value-types.ts +23 -0
- package/src/lib/mqtt-client.ts +1 -2
- package/src/lib/resolve-simulation.ts +1 -6
- package/src/lib/session-store.ts +110 -0
- package/src/lib/shutdown.test.ts +184 -2
- package/src/lib/shutdown.ts +104 -34
- package/src/lib/template-category.ts +3 -3
- package/src/lib/template-locator.ts +8 -2
- package/src/lib/ws-hub.ts +72 -46
- package/src/logger.ts +39 -14
- package/src/output.ts +3 -0
- package/console-dist/assets/index-C3XMYq26.css +0 -2
- package/console-dist/assets/index-hUJSpKtB.js +0 -119
- package/src/commands/start.ts +0 -2023
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { Engine } from "@miravo/core";
|
|
2
|
+
import { colors } from "consola/utils";
|
|
3
|
+
import { printSummaryLine } from "../../lib/shutdown.ts";
|
|
4
|
+
import { engineLog, faultLog, lifecycleLog } from "../../logger.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Shorten a full instance ID path to the last two segments for terminal output.
|
|
8
|
+
* E.g. "area-1/line-2/pump-003" → "line-2/pump-003".
|
|
9
|
+
* Full IDs can be 40+ chars with deep area/line/twin hierarchies.
|
|
10
|
+
*/
|
|
11
|
+
function shortId(instanceId: string): string {
|
|
12
|
+
const parts = instanceId.split("/");
|
|
13
|
+
return parts.length > 2 ? parts.slice(-2).join("/") : instanceId;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Step 7: Event subscriptions + periodic summary
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
const MAX_ERROR_CONTEXT_KEYS = 256;
|
|
21
|
+
const ERROR_CONTEXT_OVERFLOW = "__overflow__";
|
|
22
|
+
|
|
23
|
+
export function subscribeToEvents(
|
|
24
|
+
engine: Engine,
|
|
25
|
+
errorContextCounts: Map<string, number>,
|
|
26
|
+
): () => void {
|
|
27
|
+
const onLifecycle = (event: {
|
|
28
|
+
instanceId: string;
|
|
29
|
+
from: string;
|
|
30
|
+
to: string;
|
|
31
|
+
operatingHours: number;
|
|
32
|
+
}): void => {
|
|
33
|
+
lifecycleLog.info(
|
|
34
|
+
`${shortId(event.instanceId)} ${event.from} ${colors.dim("\u2192")} ${event.to} ${colors.gray(`(${event.operatingHours.toFixed(0)}h)`)}`,
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const onFaultTriggered = (event: { instanceId: string; fault: string }): void => {
|
|
39
|
+
faultLog.warn(`${shortId(event.instanceId)} ${colors.bold(event.fault)} triggered`);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const onFaultCleared = (event: { instanceId: string; fault: string }): void => {
|
|
43
|
+
faultLog.info(`${shortId(event.instanceId)} ${colors.dim(event.fault)} cleared`);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const onWarn = (event: { message: string; context: string }): void => {
|
|
47
|
+
engineLog.debug(event.message, { context: event.context });
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const onReset = (event: {
|
|
51
|
+
instanceCount: number;
|
|
52
|
+
templateRunCount: number;
|
|
53
|
+
clearPersistence: boolean;
|
|
54
|
+
}): void => {
|
|
55
|
+
const suffix = event.clearPersistence ? " · saved state cleared" : "";
|
|
56
|
+
engineLog.info(
|
|
57
|
+
`simulation reset · ${colors.bold(String(event.instanceCount))} instances · ${colors.bold(String(event.templateRunCount))} template runs${suffix}`,
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const onError = (event: { context: string; error: Error }): void => {
|
|
62
|
+
incrementErrorContextCount(errorContextCounts, event.context);
|
|
63
|
+
engineLog.error(event.error.message, { context: event.context }, event.error);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const onStateChanged = (event: {
|
|
67
|
+
from: "idle" | "running" | "paused" | "stopped";
|
|
68
|
+
to: "idle" | "running" | "paused" | "stopped";
|
|
69
|
+
}): void => {
|
|
70
|
+
if (event.to === "paused") {
|
|
71
|
+
engineLog.info(`simulation paused`);
|
|
72
|
+
} else if (event.to === "running" && event.from === "paused") {
|
|
73
|
+
engineLog.info(`simulation resumed`);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
engine.bus.on("lifecycle:changed", onLifecycle);
|
|
78
|
+
engine.bus.on("fault:triggered", onFaultTriggered);
|
|
79
|
+
engine.bus.on("fault:cleared", onFaultCleared);
|
|
80
|
+
engine.bus.on("engine:warn", onWarn);
|
|
81
|
+
engine.bus.on("engine:error", onError);
|
|
82
|
+
engine.bus.on("engine:reset", onReset);
|
|
83
|
+
engine.bus.on("engine:state-changed", onStateChanged);
|
|
84
|
+
|
|
85
|
+
return () => {
|
|
86
|
+
engine.bus.off("lifecycle:changed", onLifecycle);
|
|
87
|
+
engine.bus.off("fault:triggered", onFaultTriggered);
|
|
88
|
+
engine.bus.off("fault:cleared", onFaultCleared);
|
|
89
|
+
engine.bus.off("engine:warn", onWarn);
|
|
90
|
+
engine.bus.off("engine:error", onError);
|
|
91
|
+
engine.bus.off("engine:reset", onReset);
|
|
92
|
+
engine.bus.off("engine:state-changed", onStateChanged);
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function normalizeErrorContext(raw: string): string {
|
|
97
|
+
return raw
|
|
98
|
+
.replace(/tick=\d+/g, "tick=*")
|
|
99
|
+
.replace(/instance="[^"]+"/g, 'instance="*"')
|
|
100
|
+
.replace(/model="[^"]+"/g, 'model="*"');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function incrementErrorContextCount(counts: Map<string, number>, rawContext: string): void {
|
|
104
|
+
const normalizedContext = normalizeErrorContext(rawContext);
|
|
105
|
+
if (counts.has(normalizedContext)) {
|
|
106
|
+
counts.set(normalizedContext, (counts.get(normalizedContext) ?? 0) + 1);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (counts.size < MAX_ERROR_CONTEXT_KEYS) {
|
|
111
|
+
counts.set(normalizedContext, 1);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
counts.set(ERROR_CONTEXT_OVERFLOW, (counts.get(ERROR_CONTEXT_OVERFLOW) ?? 0) + 1);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function startPeriodicSummary(
|
|
119
|
+
engine: Engine,
|
|
120
|
+
intervalSeconds: number,
|
|
121
|
+
): ReturnType<typeof setInterval> {
|
|
122
|
+
return setInterval(() => {
|
|
123
|
+
const metrics = engine.getMetrics();
|
|
124
|
+
printSummaryLine(metrics);
|
|
125
|
+
}, intervalSeconds * 1_000);
|
|
126
|
+
}
|