@camstack/system 1.2.159 → 1.2.161
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/dist/addon-runner.js +1 -1
- package/dist/addon-runner.mjs +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +10 -7
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +50 -12
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +50 -12
- package/dist/builtins/backup-orchestrator/write-targets.d.ts +63 -0
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-bindings-store.d.ts +56 -10
- package/dist/builtins/device-manager/device-manager.addon.d.ts +11 -0
- package/dist/builtins/device-manager/device-manager.addon.js +216 -81
- package/dist/builtins/device-manager/device-manager.addon.mjs +216 -81
- package/dist/builtins/device-manager/device-meta-actions.d.ts +9 -3
- package/dist/builtins/device-manager/device-meta-store.d.ts +32 -5
- package/dist/builtins/device-manager/device-queries.d.ts +7 -3
- package/dist/builtins/device-manager/write-lock.d.ts +17 -0
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/filter-compiler.d.ts +41 -2
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +15 -7
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-migration-coordinator.d.ts +3 -2
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +63 -8
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +63 -8
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +19 -0
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-DLh4_rn3.mjs → dist-D4xNBlJM.mjs} +383 -214
- package/dist/{dist-Ck2jkBZk.js → dist-Keu5TDO7.js} +383 -214
- package/dist/index.js +29 -7
- package/dist/index.mjs +29 -8
- package/dist/kernel/index.d.ts +2 -2
- package/dist/kernel/lifecycle/lifecycle-job-engine.d.ts +13 -0
- package/dist/kernel/moleculer/cap-usage-registry.d.ts +132 -7
- package/dist/kernel/transport/local-child-registry.d.ts +57 -0
- package/dist/{manifest-system-deps-tZZYG3RR.mjs → manifest-system-deps-CiCuev2R.mjs} +271 -77
- package/dist/{manifest-system-deps-8boi90D9.js → manifest-system-deps-DYv4ZPo2.js} +276 -76
- package/dist/{retired-settings-keys-Dp_CyuCW.js → retired-settings-keys-BBohF-eC.js} +1 -1
- package/dist/{retired-settings-keys-Bi0ZKBjb.mjs → retired-settings-keys-COQMNlOJ.mjs} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("./dist-
|
|
3
|
+
const require_dist = require("./dist-Keu5TDO7.js");
|
|
4
4
|
const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
|
|
5
5
|
require("./builtins/alerts/index.js");
|
|
6
6
|
const require_formatter = require("./formatter-DqAKDlvN.js");
|
|
@@ -26,7 +26,7 @@ require("./builtins/system-config/index.js");
|
|
|
26
26
|
const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
|
|
27
27
|
const require_file_data_plane = require("./file-data-plane-DO8KbxCe.js");
|
|
28
28
|
const require_tls$1 = require("./tls-BxQlomxd.js");
|
|
29
|
-
const require_manifest_system_deps = require("./manifest-system-deps-
|
|
29
|
+
const require_manifest_system_deps = require("./manifest-system-deps-DYv4ZPo2.js");
|
|
30
30
|
const require_resource_monitor = require("./resource-monitor-CdnzxBLP.js");
|
|
31
31
|
const require_custom_action_registry = require("./custom-action-registry-jY0NOZK8.js");
|
|
32
32
|
let zod = require("zod");
|
|
@@ -95162,6 +95162,19 @@ var LifecycleJobEngine = class {
|
|
|
95162
95162
|
* per-task abort timeout. On success the resolved `stagedPath` is returned; on
|
|
95163
95163
|
* failure the task is marked `failed` and `null` is returned (so the apply
|
|
95164
95164
|
* phase skips it). Other tasks are unaffected.
|
|
95165
|
+
*
|
|
95166
|
+
* **`toVersion` is REWRITTEN here, to the version that was actually
|
|
95167
|
+
* fetched.** A task's `toVersion` starts as the REQUEST, and the request is
|
|
95168
|
+
* routinely a dist-tag: `addons.updatePackage` with no version resolves to
|
|
95169
|
+
* the literal `'latest'`. The staging area already resolves it — it reads
|
|
95170
|
+
* the version out of the unpacked tarball and returns `resolvedVersion` —
|
|
95171
|
+
* and dropping that answer sent the string `'latest'` onward as if it were a
|
|
95172
|
+
* version. It became the manifest's recorded version, the version the Addons
|
|
95173
|
+
* page displayed, and the `toVersion` on the `addon.updated` event, which an
|
|
95174
|
+
* operator read on his phone as "@camstack/addon-terminal 0.0.0 → latest"
|
|
95175
|
+
* (2026-08-30). Everything downstream of the apply reads a version; none of
|
|
95176
|
+
* it can resolve a tag, and none of it could tell that it had been handed
|
|
95177
|
+
* one.
|
|
95165
95178
|
*/
|
|
95166
95179
|
async fetchAddonTask(job, task) {
|
|
95167
95180
|
try {
|
|
@@ -95171,20 +95184,28 @@ var LifecycleJobEngine = class {
|
|
|
95171
95184
|
});
|
|
95172
95185
|
const ac = new AbortController();
|
|
95173
95186
|
const timer = setTimeout(() => ac.abort(), this.deps.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS);
|
|
95174
|
-
let
|
|
95187
|
+
let staged;
|
|
95175
95188
|
try {
|
|
95176
|
-
|
|
95189
|
+
staged = await this.deps.staging.fetchAndStage({
|
|
95177
95190
|
jobId: job.jobId,
|
|
95178
95191
|
name: task.packageName,
|
|
95179
95192
|
version: task.toVersion,
|
|
95180
95193
|
signal: ac.signal
|
|
95181
|
-
})
|
|
95194
|
+
});
|
|
95182
95195
|
} finally {
|
|
95183
95196
|
clearTimeout(timer);
|
|
95184
95197
|
}
|
|
95185
|
-
|
|
95198
|
+
const stagedPath = staged.stagedPath;
|
|
95199
|
+
const resolved = {
|
|
95200
|
+
...task,
|
|
95201
|
+
toVersion: staged.resolvedVersion
|
|
95202
|
+
};
|
|
95203
|
+
this.advance(job.jobId, task, "staged", {
|
|
95204
|
+
stagedPath,
|
|
95205
|
+
toVersion: resolved.toVersion
|
|
95206
|
+
});
|
|
95186
95207
|
return {
|
|
95187
|
-
task,
|
|
95208
|
+
task: resolved,
|
|
95188
95209
|
stagedPath
|
|
95189
95210
|
};
|
|
95190
95211
|
} catch (err) {
|
|
@@ -95437,6 +95458,7 @@ exports.NativeMetricsAddon = require_builtins_native_metrics_native_metrics_addo
|
|
|
95437
95458
|
exports.NativeMetricsProvider = require_builtins_native_metrics_native_metrics_addon.NativeMetricsProvider;
|
|
95438
95459
|
exports.NetworkQualityTracker = NetworkQualityTracker;
|
|
95439
95460
|
exports.NotificationService = NotificationService;
|
|
95461
|
+
exports.PARENT_ROUTED_PROVIDER_ADDON_ID = require_manifest_system_deps.PARENT_ROUTED_PROVIDER_ADDON_ID;
|
|
95440
95462
|
Object.defineProperty(exports, "PYTHON_VERSION", {
|
|
95441
95463
|
enumerable: true,
|
|
95442
95464
|
get: function() {
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { $ as isObjectInput, $t as parseJsonUnknown$1, Bt as ReadinessTimeoutError, Ft as DEVICE_STATUS_METHOD, Gt as createEvent, Ht as asJsonObject$1, J as extractNestedAddonId, Jt as expandCapMethods, Kt as emitDownForOwnedCaps, Nt as DATAPLANE_SECRET_HEADER$1, Pt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, Q as isCollectionArrayMethod, Qt as parseJsonObject, T as addonSettingsCapability, Ut as asNumber, Wt as asString$1, Z as isArrayOutputSchema, _t as resolveMethodAuth, bt as scopesAllowDeviceCap, ct as looseSchema, dt as objectInputDeclaresAddonId, en as readinessKey, f as LOG_LEVEL_RANK, h as RUNTIME_DEFAULTS, in as EventCategory$1, it as lifecycleJobSchema, jt as errMsg$1, mt as procedureAuthKey, nn as scopeKey, nt as isVoidInput, p as METHOD_ACCESS_MAP, rt as kebabToCamel, st as logLevelAtMost, t as ALL_CAPABILITY_DEFINITIONS, tn as resolveCapMount, yt as scopesAllowAddon, zt as ReadinessRegistry } from "./dist-
|
|
2
|
+
import { $ as isObjectInput, $t as parseJsonUnknown$1, Bt as ReadinessTimeoutError, Ft as DEVICE_STATUS_METHOD, Gt as createEvent, Ht as asJsonObject$1, J as extractNestedAddonId, Jt as expandCapMethods, Kt as emitDownForOwnedCaps, Nt as DATAPLANE_SECRET_HEADER$1, Pt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, Q as isCollectionArrayMethod, Qt as parseJsonObject, T as addonSettingsCapability, Ut as asNumber, Wt as asString$1, Z as isArrayOutputSchema, _t as resolveMethodAuth, bt as scopesAllowDeviceCap, ct as looseSchema, dt as objectInputDeclaresAddonId, en as readinessKey, f as LOG_LEVEL_RANK, h as RUNTIME_DEFAULTS, in as EventCategory$1, it as lifecycleJobSchema, jt as errMsg$1, mt as procedureAuthKey, nn as scopeKey, nt as isVoidInput, p as METHOD_ACCESS_MAP, rt as kebabToCamel, st as logLevelAtMost, t as ALL_CAPABILITY_DEFINITIONS, tn as resolveCapMount, yt as scopesAllowAddon, zt as ReadinessRegistry } from "./dist-D4xNBlJM.mjs";
|
|
3
3
|
import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
|
|
4
4
|
import "./builtins/alerts/index.mjs";
|
|
5
5
|
import { t as formatLogLine } from "./formatter-B7qW8bPJ.mjs";
|
|
@@ -25,7 +25,7 @@ import "./builtins/system-config/index.mjs";
|
|
|
25
25
|
import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
|
|
26
26
|
import { a as parseTokenizedUrl, c as collectModelFiles, d as downloadModel, f as ensureModel, h as isModelDownloaded, i as parseRangeHeader, l as deleteModelFromDisk, m as getModelFilePath, n as contentTypeFor, o as resolveFilePath, p as fetchJson, r as createAuthenticatedFileServer, s as ModelDownloadService, t as createFileDataPlaneHandler, u as downloadFile } from "./file-data-plane-BhKdxJgf.mjs";
|
|
27
27
|
import { C as registerLanHttpHandler, S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, b as bindPendingLanHttp, c as loadTlsCert, d as collectCertIdentity, f as CA_VALIDITY_DAYS, g as evaluateExistingCert, h as SERVER_AUTH_OID, i as writeExtraSans, l as reissueTlsLeaf, m as MAX_LEAF_VALIDITY_DAYS, n as readTlsAccessStatus, o as validateUploadedTls, p as LEAF_RENEWAL_WINDOW_DAYS, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, u as CA_COMMON_NAME, v as allFamiliesListenHost, x as closeLanHttp, y as applyLanHttp } from "./tls-DOTmtLCW.mjs";
|
|
28
|
-
import { $ as
|
|
28
|
+
import { $ as FrameDecoder, $t as DECISIVE_HEAP_SPACES, A as createUdsEventBus, At as HEAP_WATCH_INTERVAL_MS, B as CapRouteError, Bt as buildHeapSample, C as ipcParentLink, Cn as diffEventPlane, Ct as resolveAddonClass, D as createHubCapForwardService, Dt as HEAP_RECLAIM_MIN_INTERVAL_MS, E as HUB_CAP_FWD_SERVICE, Et as createAddonDataPlaneFacility, F as LocalChildRegistry, Ft as RSS_BUDGET_REANNOUNCE_MIN_MS, G as PARENT_ROUTED_PROVIDER_ADDON_ID, Gt as hubMainRssBudget, H as callWithServiceDiscovery, Ht as createLoopDelayMeter, I as UDS_NO_ROUTE_PREFIX, It as RSS_BUDGET_RELEASE_RATIO, J as createLocalTransport, Jt as reclaimIntervalMs, K as __resetCapUsageRegistryForTests, Kt as nextRssBudgetState, L as AGENT_CAP_FWD_ACTION, Lt as RUNNER_HEAP_WATCH_INTERVAL_MS, M as createUdsLogger, Mt as HUB_MAIN_HEAP_WATCH_LABEL, N as createUdsLoggerWithControl, Nt as HUB_MAIN_RSS_BUDGET_MB, O as createParentUnownedCallHandler, Ot as HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, P as LocalChildClient, Pt as HUB_RSS_BUDGET_ENV, Q as localEndpointPath, Qt as strandedMb, R as AGENT_CAP_FWD_SERVICE, Rt as RUNNER_RSS_BUDGET_ENV, S as buildLinkChain, Sn as createEventPlaneReader, St as installManifestNativeDeps, T as HUB_CAP_FWD_ACTION, Tt as runNpm, U as readMoleculerFanoutMode, Ut as createV8Reclaimer, V as classifyCapRoute, Vt as createDeferredHeapWatchSink, W as CapUsageRegistry, Wt as describeRss, X as UdsLocalTransportServer, Xt as startHeapWatch, Y as UdsLocalTransportClient, Yt as shouldReclaim, Z as SocketChannel, Zt as startRunnerHeapWatch, _ as AddonDepsManager, _n as sampleSocketDirection, _t as serializeTypedArrays, a as createUdsAddonContext, an as heapSpaceField, b as brokerCallForCap, bn as EVENT_PLANE_TOP_N, bt as CapabilityUnavailableError, c as getOrInitReadinessRegistryForClient, cn as EMPTY_SOCKET_PLANE_BASELINE, ct as createAddonService, d as clusterEventTopic, dn as createSocketPlaneReader, dt as capActionName, en as HEAP_SPACE_REPORT_MIN_MB, et as encodeFrame, f as getBrokerEventBus, fn as diffSocketPlane, ft as capActionSuffix, g as subscribePassthrough, gn as recordSocketFrame, gt as deserializeTypedArrays, h as setNodeEventInterest, hn as createSocketDirectionCounters, ht as parseCapAction, i as createAddonContext, in as heapSnapshotAuthorised, j as udsChildLogToWorkerEntry, jt as HEAP_WATCH_WARN_RATIO, k as createUdsEventBridge, kt as HEAP_RECLAIM_TRIGGER_MB, l as setHubConnected, ln as SOCKET_PLANE_TOP_N, lt as validateProviderRegistrations, m as registerEventBusService, mn as EMPTY_SOCKET_DIRECTION, mt as capServiceName, n as installManifestPythonDeps, nn as emitHeapDiagnosticReport, nt as buildUdsNativeCapProxy, o as getWorkerDeviceRegistry, on as readHeapSpaces, ot as mountNativeCapService, p as getMoleculerEventStats, pn as formatSocketPlane, pt as capBareAction, q as getCapUsageRegistry, qt as parseRssBudgetMb, r as adaptBrokerToCluster, rn as formatHeapSpaces, rt as createBrokerDeviceManagerApi, s as getOrInitReadinessRegistry, sn as selectReportedSpaces, t as installManifestSystemDeps, tn as RUNNER_HEAP_SNAPSHOT_ENV, tt as buildNativeCapProxy, u as EVENT_TOPIC_PREFIX, un as createSocketPlaneMeter, ut as NATIVE_PROVIDER_SERVICE_INFIX, v as createKernelHwAccel, vn as socketDirectionBytes, vt as DeviceRegistry, w as localProviderLink, wn as formatEventPlane, wt as resolveNpmInvocation, x as brokerTransportLink, xn as createEventPlaneMeter, xt as copyBundledNativeModules, y as resolveHwAccel, yn as socketDirectionMessages, yt as CapabilityHandle, z as CapRouteResolver, zt as ZERO_LOOP_DELAY } from "./manifest-system-deps-CiCuev2R.mjs";
|
|
29
29
|
import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-BWmQ5i-o.mjs";
|
|
30
30
|
import { t as CustomActionRegistry } from "./custom-action-registry-F__gp_VX.mjs";
|
|
31
31
|
import { z } from "zod";
|
|
@@ -95155,6 +95155,19 @@ var LifecycleJobEngine = class {
|
|
|
95155
95155
|
* per-task abort timeout. On success the resolved `stagedPath` is returned; on
|
|
95156
95156
|
* failure the task is marked `failed` and `null` is returned (so the apply
|
|
95157
95157
|
* phase skips it). Other tasks are unaffected.
|
|
95158
|
+
*
|
|
95159
|
+
* **`toVersion` is REWRITTEN here, to the version that was actually
|
|
95160
|
+
* fetched.** A task's `toVersion` starts as the REQUEST, and the request is
|
|
95161
|
+
* routinely a dist-tag: `addons.updatePackage` with no version resolves to
|
|
95162
|
+
* the literal `'latest'`. The staging area already resolves it — it reads
|
|
95163
|
+
* the version out of the unpacked tarball and returns `resolvedVersion` —
|
|
95164
|
+
* and dropping that answer sent the string `'latest'` onward as if it were a
|
|
95165
|
+
* version. It became the manifest's recorded version, the version the Addons
|
|
95166
|
+
* page displayed, and the `toVersion` on the `addon.updated` event, which an
|
|
95167
|
+
* operator read on his phone as "@camstack/addon-terminal 0.0.0 → latest"
|
|
95168
|
+
* (2026-08-30). Everything downstream of the apply reads a version; none of
|
|
95169
|
+
* it can resolve a tag, and none of it could tell that it had been handed
|
|
95170
|
+
* one.
|
|
95158
95171
|
*/
|
|
95159
95172
|
async fetchAddonTask(job, task) {
|
|
95160
95173
|
try {
|
|
@@ -95164,20 +95177,28 @@ var LifecycleJobEngine = class {
|
|
|
95164
95177
|
});
|
|
95165
95178
|
const ac = new AbortController();
|
|
95166
95179
|
const timer = setTimeout(() => ac.abort(), this.deps.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS);
|
|
95167
|
-
let
|
|
95180
|
+
let staged;
|
|
95168
95181
|
try {
|
|
95169
|
-
|
|
95182
|
+
staged = await this.deps.staging.fetchAndStage({
|
|
95170
95183
|
jobId: job.jobId,
|
|
95171
95184
|
name: task.packageName,
|
|
95172
95185
|
version: task.toVersion,
|
|
95173
95186
|
signal: ac.signal
|
|
95174
|
-
})
|
|
95187
|
+
});
|
|
95175
95188
|
} finally {
|
|
95176
95189
|
clearTimeout(timer);
|
|
95177
95190
|
}
|
|
95178
|
-
|
|
95191
|
+
const stagedPath = staged.stagedPath;
|
|
95192
|
+
const resolved = {
|
|
95193
|
+
...task,
|
|
95194
|
+
toVersion: staged.resolvedVersion
|
|
95195
|
+
};
|
|
95196
|
+
this.advance(job.jobId, task, "staged", {
|
|
95197
|
+
stagedPath,
|
|
95198
|
+
toVersion: resolved.toVersion
|
|
95199
|
+
});
|
|
95179
95200
|
return {
|
|
95180
|
-
task,
|
|
95201
|
+
task: resolved,
|
|
95181
95202
|
stagedPath
|
|
95182
95203
|
};
|
|
95183
95204
|
} catch (err) {
|
|
@@ -95335,4 +95356,4 @@ var LifecycleJobEngine = class {
|
|
|
95335
95356
|
}
|
|
95336
95357
|
};
|
|
95337
95358
|
//#endregion
|
|
95338
|
-
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LokiDestination, LokiLoggingAddon, MAX_LEAF_VALIDITY_DAYS, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_SNAPSHOT_ENV, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatEventPlane, formatHeapSpaces, formatLogLine, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSnapshotAuthorised, heapSpaceField, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextRssBudgetState, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, socketDirectionBytes, socketDirectionMessages, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|
|
95359
|
+
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LokiDestination, LokiLoggingAddon, MAX_LEAF_VALIDITY_DAYS, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_SNAPSHOT_ENV, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatEventPlane, formatHeapSpaces, formatLogLine, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSnapshotAuthorised, heapSpaceField, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextRssBudgetState, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, socketDirectionBytes, socketDirectionMessages, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|
package/dist/kernel/index.d.ts
CHANGED
|
@@ -73,8 +73,8 @@ export { localProviderLink, brokerTransportLink, ipcParentLink, buildLinkChain,
|
|
|
73
73
|
export type { LocalProviderResolver, BrokerCapCallOpts } from './moleculer/trpc-links.js';
|
|
74
74
|
export { createProcessService } from './moleculer/process-service.js';
|
|
75
75
|
export type { ProcessInfo } from './moleculer/process-service.js';
|
|
76
|
-
export { CapUsageRegistry, getCapUsageRegistry, __resetCapUsageRegistryForTests, } from './moleculer/cap-usage-registry.js';
|
|
77
|
-
export type { CapUsageCallRecord, CapUsageEdge, CapUsageRegistryOptions, } from './moleculer/cap-usage-registry.js';
|
|
76
|
+
export { CapUsageRegistry, getCapUsageRegistry, PARENT_ROUTED_PROVIDER_ADDON_ID, __resetCapUsageRegistryForTests, } from './moleculer/cap-usage-registry.js';
|
|
77
|
+
export type { CapUsageCallRecord, CapUsageEdge, CapUsageRegistryOptions, CapUsageStats, } from './moleculer/cap-usage-registry.js';
|
|
78
78
|
export { createScopedProcessManager } from './moleculer/process-context.js';
|
|
79
79
|
export type { IAddonProcessManager } from '@camstack/types';
|
|
80
80
|
export { callWithServiceDiscovery } from './moleculer/resilient-cap-call.js';
|
|
@@ -31,6 +31,19 @@ export declare class LifecycleJobEngine {
|
|
|
31
31
|
* per-task abort timeout. On success the resolved `stagedPath` is returned; on
|
|
32
32
|
* failure the task is marked `failed` and `null` is returned (so the apply
|
|
33
33
|
* phase skips it). Other tasks are unaffected.
|
|
34
|
+
*
|
|
35
|
+
* **`toVersion` is REWRITTEN here, to the version that was actually
|
|
36
|
+
* fetched.** A task's `toVersion` starts as the REQUEST, and the request is
|
|
37
|
+
* routinely a dist-tag: `addons.updatePackage` with no version resolves to
|
|
38
|
+
* the literal `'latest'`. The staging area already resolves it — it reads
|
|
39
|
+
* the version out of the unpacked tarball and returns `resolvedVersion` —
|
|
40
|
+
* and dropping that answer sent the string `'latest'` onward as if it were a
|
|
41
|
+
* version. It became the manifest's recorded version, the version the Addons
|
|
42
|
+
* page displayed, and the `toVersion` on the `addon.updated` event, which an
|
|
43
|
+
* operator read on his phone as "@camstack/addon-terminal 0.0.0 → latest"
|
|
44
|
+
* (2026-08-30). Everything downstream of the apply reads a version; none of
|
|
45
|
+
* it can resolve a tag, and none of it could tell that it had been handed
|
|
46
|
+
* one.
|
|
34
47
|
*/
|
|
35
48
|
private fetchAddonTask;
|
|
36
49
|
/**
|
|
@@ -1,15 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* In-memory observation of tRPC cap calls between addons
|
|
2
|
+
* In-memory observation of tRPC cap calls between addons — the store behind
|
|
3
|
+
* `nodes.getCapUsageGraph`.
|
|
3
4
|
*
|
|
4
5
|
* Storage: `Map<callerAddonId, Map<providerAddonId, Map<capName, RollingWindow>>>`.
|
|
5
6
|
* `RollingWindow` is a fixed-size ring of 1-second buckets — default 300
|
|
6
|
-
* buckets = 5 minutes retention. Queries narrower than the retention
|
|
7
|
-
*
|
|
7
|
+
* buckets = 5 minutes retention. Queries narrower than the retention window
|
|
8
|
+
* filter buckets at read time.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* ── The ring ages, and that is not free decoration ─────────────────────────
|
|
11
|
+
* Buckets are indexed `second % retention`, so a bucket written at second S is
|
|
12
|
+
* hit again at S + retention·k forever. Until 2026-08-30 nothing ever zeroed
|
|
13
|
+
* them: the `lastCallAtMs` guard hid it while a triple was fully idle, but ONE
|
|
14
|
+
* fresh call re-armed the entire stale ring. A triple that made 1000 calls and
|
|
15
|
+
* then one call five minutes later reported **1001 calls/min instead of 1**.
|
|
16
|
+
* An over-counted edge is worse than the empty graph this instrument shipped
|
|
17
|
+
* with — silence invites doubt, a confident wrong number sends the next
|
|
18
|
+
* investigation at the wrong addon.
|
|
19
|
+
*
|
|
20
|
+
* The fix is clear-forward: on each record, zero the buckets the ring has
|
|
21
|
+
* ADVANCED over since the previous write, and never read past the last written
|
|
22
|
+
* second. Amortised O(1) — a busy triple clears 0–1 buckets per call, and an
|
|
23
|
+
* idle one clears at most `retention` once, when it wakes.
|
|
24
|
+
*
|
|
25
|
+
* ── Cardinality is bounded, because this map lives on hub-main ─────────────
|
|
26
|
+
* The previous docblock claimed "~22 MB worst case … under 200 KB at ~10 active
|
|
27
|
+
* triples". Both numbers were written for a smaller machine and the second was
|
|
28
|
+
* an assumption, not a bound: the key space is caller × provider × cap, and on
|
|
29
|
+
* the live hub that is 64 addons × 64 runners × ~150 caps. Nothing capped it.
|
|
30
|
+
*
|
|
31
|
+
* Today a ring is one `Uint32Array(retention)` — 1.2 KB of ArrayBuffer at the
|
|
32
|
+
* default — plus the three Map entries that reach it. MEASURED (`heapUsed` +
|
|
33
|
+
* `arrayBuffers`, node 24, `--expose-gc`): **1.7 KB per triple**, so ≈1.0 MB at
|
|
34
|
+
* the realistic hub figure (64 callers × a handful of caps each, ≈600 triples)
|
|
35
|
+
* and **6.3 MB at the {@link DEFAULT_MAX_TRIPLES} ceiling**. `recordCall` costs
|
|
36
|
+
* ≈46 ns (1e6 calls in 46 ms) — at the 39 717 calls/min that started this
|
|
37
|
+
* investigation, ≈30 µs of hub-main per second.
|
|
38
|
+
*
|
|
39
|
+
* Reclamation is what keeps it at the low end: a triple whose ring has entirely
|
|
40
|
+
* aged out is dead data and is dropped on the next admission sweep. The hard
|
|
41
|
+
* cap only exists so that a pathological key space (a caller id derived from
|
|
42
|
+
* something unbounded) cannot take hub-main's heap with it — and when it bites,
|
|
43
|
+
* {@link CapUsageRegistry.getStats} says how often, because an instrument that
|
|
44
|
+
* truncates silently is the defect this whole file exists to fix (D237).
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* Provider placeholder for a call the PARENT routed rather than short-
|
|
48
|
+
* circuiting to a sibling runner: hub-in-process (`settings-store`,
|
|
49
|
+
* `device-manager`, the `$core-caps` bridge), or a remote node. At the layer
|
|
50
|
+
* that records — the parent's `cap-call-out` handler — the sibling id IS the
|
|
51
|
+
* provider and everything else has not been resolved yet.
|
|
52
|
+
*
|
|
53
|
+
* It is a NAMED unknown, not a dropped observation, for the reason D237 was
|
|
54
|
+
* written: the caller is always known, and "who is hammering `settings-store`"
|
|
55
|
+
* is the question this graph exists to answer. Sibling to
|
|
56
|
+
* `UNRESOLVED_PROVIDER_ADDON_ID` in `trpc-links.ts`, which names the same kind
|
|
57
|
+
* of unknown one layer up.
|
|
12
58
|
*/
|
|
59
|
+
export declare const PARENT_ROUTED_PROVIDER_ADDON_ID = "(unresolved: parent-routed)";
|
|
13
60
|
export interface CapUsageCallRecord {
|
|
14
61
|
readonly callerAddonId: string;
|
|
15
62
|
readonly providerAddonId: string;
|
|
@@ -17,6 +64,17 @@ export interface CapUsageCallRecord {
|
|
|
17
64
|
readonly methodName: string;
|
|
18
65
|
readonly atMs: number;
|
|
19
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* One observed caller → provider → cap edge.
|
|
69
|
+
*
|
|
70
|
+
* There is deliberately no `methodName`: the ring is keyed by CAPABILITY, so
|
|
71
|
+
* `deviceManager.getAllBindings` (the whole fleet) and
|
|
72
|
+
* `deviceManager.getBindings` (one camera) collapse into the same edge. The
|
|
73
|
+
* method IS recorded on the way in ({@link CapUsageCallRecord.methodName}) and
|
|
74
|
+
* discarded here. Splitting the key by method would multiply cardinality by the
|
|
75
|
+
* per-cap method count — worth doing, but it is a schema change to
|
|
76
|
+
* `nodes.getCapUsageGraph`, not a quiet widening of a map on hub-main.
|
|
77
|
+
*/
|
|
20
78
|
export interface CapUsageEdge {
|
|
21
79
|
readonly callerAddonId: string;
|
|
22
80
|
readonly providerAddonId: string;
|
|
@@ -27,20 +85,87 @@ export interface CapUsageEdge {
|
|
|
27
85
|
export interface CapUsageRegistryOptions {
|
|
28
86
|
/** Max retention in seconds (ring length). Default 300. */
|
|
29
87
|
readonly retentionSeconds?: number;
|
|
88
|
+
/**
|
|
89
|
+
* Ceiling on live `(caller, provider, cap)` triples. Default
|
|
90
|
+
* {@link DEFAULT_MAX_TRIPLES}. Reaching it drops NEW triples (counted in
|
|
91
|
+
* {@link CapUsageStats.droppedTriples}); triples already being watched keep
|
|
92
|
+
* counting exactly.
|
|
93
|
+
*/
|
|
94
|
+
readonly maxTriples?: number;
|
|
95
|
+
}
|
|
96
|
+
/** What the registry knows about its own coverage. Never a guess. */
|
|
97
|
+
export interface CapUsageStats {
|
|
98
|
+
/** Live `(caller, provider, cap)` triples held right now. */
|
|
99
|
+
readonly triples: number;
|
|
100
|
+
/** Ceiling in force. */
|
|
101
|
+
readonly maxTriples: number;
|
|
102
|
+
/**
|
|
103
|
+
* New triples refused since process start because the ceiling was full.
|
|
104
|
+
* Non-zero means the graph is INCOMPLETE — some caller→cap edge exists and
|
|
105
|
+
* is not shown. Nothing else in this file can be incomplete without saying so.
|
|
106
|
+
*/
|
|
107
|
+
readonly droppedTriples: number;
|
|
30
108
|
}
|
|
31
109
|
export declare class CapUsageRegistry {
|
|
32
110
|
private readonly retentionSeconds;
|
|
111
|
+
private readonly maxTriples;
|
|
33
112
|
private readonly map;
|
|
113
|
+
private triples;
|
|
114
|
+
private droppedTriples;
|
|
34
115
|
constructor(opts?: CapUsageRegistryOptions);
|
|
116
|
+
/**
|
|
117
|
+
* Record one observed cap call.
|
|
118
|
+
*
|
|
119
|
+
* On the hot path: this runs once per cross-process cap call on hub-main's
|
|
120
|
+
* event loop, which is the cluster's only queue (D181). Three Map lookups, an
|
|
121
|
+
* integer increment, and — only when the wall clock has moved on — a bounded
|
|
122
|
+
* clear. No allocation once a triple exists, and it NEVER throws into the
|
|
123
|
+
* call it observes.
|
|
124
|
+
*/
|
|
35
125
|
recordCall(rec: CapUsageCallRecord): void;
|
|
36
126
|
getGraph(opts: {
|
|
37
127
|
windowSeconds: number;
|
|
38
128
|
nowMs: number;
|
|
39
129
|
}): readonly CapUsageEdge[];
|
|
130
|
+
/** See {@link CapUsageStats}. Cheap — three counters, no scan. */
|
|
131
|
+
getStats(): CapUsageStats;
|
|
40
132
|
/** Test / diagnostic helper — drops all recorded calls. */
|
|
41
133
|
clear(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Sum the buckets covering `(nowSec - windowSeconds, nowSec]`.
|
|
136
|
+
*
|
|
137
|
+
* The scan starts at `lastSec`, never at `nowSec`. `recordCall` clears the
|
|
138
|
+
* buckets the ring has advanced OVER, which by definition stops at the last
|
|
139
|
+
* write: the buckets for the seconds since then still hold whatever the
|
|
140
|
+
* previous pass left in them, and reading `nowSec` down would count it. A
|
|
141
|
+
* triple that went quiet for a couple of minutes and then made one call would
|
|
142
|
+
* report the burst it made five minutes earlier.
|
|
143
|
+
*
|
|
144
|
+
* No lower bound is needed beyond the window itself: every bucket at or below
|
|
145
|
+
* `lastSec - retention` was cleared by the advance that reached `lastSec`, so
|
|
146
|
+
* it reads zero anyway. The loop is bounded by `windowSeconds ≤ retention`.
|
|
147
|
+
*/
|
|
148
|
+
private sumWindow;
|
|
149
|
+
/**
|
|
150
|
+
* The ring for this triple, creating it if the ceiling allows. `null` means
|
|
151
|
+
* the observation is dropped — counted, never silent (see
|
|
152
|
+
* {@link CapUsageStats.droppedTriples}).
|
|
153
|
+
*/
|
|
154
|
+
private windowFor;
|
|
155
|
+
/**
|
|
156
|
+
* Drop every triple whose whole ring has aged out — its last call is older
|
|
157
|
+
* than the retention window, so it can contribute to no query. O(triples),
|
|
158
|
+
* and only reachable when the ceiling is full, so it is amortised away by the
|
|
159
|
+
* admissions it enables.
|
|
160
|
+
*/
|
|
161
|
+
private reclaimExpired;
|
|
42
162
|
}
|
|
43
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* The registry for THIS process. Deliberately per-process: the reader
|
|
165
|
+
* (`nodes.getCapUsageGraph` → `cap-providers.ts`) runs on hub-main, so only
|
|
166
|
+
* writes made on hub-main are ever visible. See the blind-spot list on
|
|
167
|
+
* `LocalChildRegistryOptions.capUsageObserver` for what that excludes.
|
|
168
|
+
*/
|
|
44
169
|
export declare function getCapUsageRegistry(): CapUsageRegistry;
|
|
45
170
|
/** Test helper — clears the singleton (kept module-private elsewhere). */
|
|
46
171
|
export declare function __resetCapUsageRegistryForTests(): void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IReadinessRegistryRecord, SystemEvent } from '@camstack/types';
|
|
2
|
+
import { CapUsageCallRecord } from '../moleculer/cap-usage-registry.js';
|
|
2
3
|
import { AddonCallInput, CapCallInput, ChildLogMessage, RegisteredChild } from './child-cap-protocol.js';
|
|
3
4
|
import { LocalTransportServer } from './local-transport.js';
|
|
4
5
|
import { SocketTrafficSample } from './socket-traffic.js';
|
|
@@ -129,6 +130,49 @@ export interface LocalChildRegistryOptions {
|
|
|
129
130
|
* channel default for every cap call.
|
|
130
131
|
*/
|
|
131
132
|
readonly capTimeoutMs?: (capName: string, method: string) => number | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* Sink for observed cap calls — the ONE place a forked addon's outbound
|
|
135
|
+
* `ctx.api` traffic can be recorded in the process that also holds the reader.
|
|
136
|
+
*
|
|
137
|
+
* ── Why here, and not in the caller ───────────────────────────────────────
|
|
138
|
+
* `getCapUsageRegistry()` is a per-process module singleton and the reader
|
|
139
|
+
* (`nodes.getCapUsageGraph`) runs on hub-main. The only writer used to be
|
|
140
|
+
* `addon-context-factory.ts`'s `localProviderLink` observer, which runs in
|
|
141
|
+
* the FORKED RUNNER — so every observation it made was written to an object
|
|
142
|
+
* hub-main can never read, and it fired only for co-located providers anyway
|
|
143
|
+
* (`ipcParentLink`, which carries every cross-process call, takes no
|
|
144
|
+
* observer). `nodes.getCapUsageGraph` therefore returned `[]` in 0.21 s
|
|
145
|
+
* against a hub running 64 addons and 1019 devices.
|
|
146
|
+
*
|
|
147
|
+
* ── Why here, and not in `onUnownedCall` ──────────────────────────────────
|
|
148
|
+
* Because most inter-addon traffic never gets there. `resolveChildId`
|
|
149
|
+
* short-circuits a cap owned by a sibling runner straight to `callCap`, and
|
|
150
|
+
* on the hub every addon IS a sibling runner. Recording in `onUnownedCall`
|
|
151
|
+
* would have seen `ctx.settings.*` (hub-in-process `settings-store`) and
|
|
152
|
+
* missed every addon→addon call — a graph with a whole plane silently
|
|
153
|
+
* missing, which is the defect it was meant to end.
|
|
154
|
+
*
|
|
155
|
+
* This handler is strictly upstream of BOTH branches, and it is where
|
|
156
|
+
* `callerAddonId` is already stamped off the UDS connection the frame
|
|
157
|
+
* arrived on — a caller identity the child cannot spoof.
|
|
158
|
+
*
|
|
159
|
+
* ── What it still cannot see (say it, do not hide it) ─────────────────────
|
|
160
|
+
* 1. **hub-main → hub-main.** An in-process builtin's `ctx.api` is
|
|
161
|
+
* `AddonRegistryService.getBrokerApi()` — ONE lazily-built tRPC client
|
|
162
|
+
* shared by every addon, so there is no per-caller identity to record.
|
|
163
|
+
* Giving it an observer needs a per-addon client first.
|
|
164
|
+
* 2. **A runner's co-located calls.** `localProviderLink` answers inside the
|
|
165
|
+
* runner and the frame never reaches this socket. Only the `detection` /
|
|
166
|
+
* `ml` execution groups have co-located providers at all (D9, D29).
|
|
167
|
+
* 3. **An agent's own runners.** Their parent is the agent process, whose
|
|
168
|
+
* `LocalChildRegistry` writes to the agent's singleton. Aggregating that
|
|
169
|
+
* needs a transport hop; `$hub-cap-fwd`'s envelope carries no
|
|
170
|
+
* `callerAddonId` today, so an agent-originated call reaching the hub is
|
|
171
|
+
* recorded with no caller at all — i.e. not recorded.
|
|
172
|
+
*
|
|
173
|
+
* MUST NOT throw; the call site catches anyway (see the record site).
|
|
174
|
+
*/
|
|
175
|
+
readonly capUsageObserver?: (obs: CapUsageCallRecord) => void;
|
|
132
176
|
}
|
|
133
177
|
/**
|
|
134
178
|
* Parent-side authority for local addon-runners reachable over a
|
|
@@ -157,6 +201,8 @@ export declare class LocalChildRegistry {
|
|
|
157
201
|
private readonly isAddonPinnedCall?;
|
|
158
202
|
/** See {@link LocalChildRegistryOptions.capTimeoutMs}. */
|
|
159
203
|
private readonly capTimeoutMs?;
|
|
204
|
+
/** See {@link LocalChildRegistryOptions.capUsageObserver}. */
|
|
205
|
+
private readonly capUsageObserver?;
|
|
160
206
|
/** Tracks capNames already logged as UDS-routed; one INFO line per capName per process. */
|
|
161
207
|
private readonly egressRoutedCaps;
|
|
162
208
|
/** Active event fan-out mode, read once from `CAMSTACK_UDS_EVENT_FANOUT`. */
|
|
@@ -274,6 +320,17 @@ export declare class LocalChildRegistry {
|
|
|
274
320
|
* compete for the same capName.
|
|
275
321
|
*/
|
|
276
322
|
resolveChildId(capName: string, deviceId?: number): string | null;
|
|
323
|
+
/**
|
|
324
|
+
* Publish one cap-usage observation, if a sink is wired.
|
|
325
|
+
*
|
|
326
|
+
* Cost discipline — this is on the hot path (D181: hub-main's event loop is
|
|
327
|
+
* the cluster's only queue): no sink means one undefined check; with a sink
|
|
328
|
+
* it is one object literal and one `Date.now()`, and the sink itself is O(1).
|
|
329
|
+
* Wrapped so a broken observer can never fail the call it observes — the
|
|
330
|
+
* registry swallows too, and BOTH matter: this catch also covers a sink that
|
|
331
|
+
* is not the registry.
|
|
332
|
+
*/
|
|
333
|
+
private recordCapUsage;
|
|
277
334
|
/** First child whose cap manifest contains a descriptor matching `predicate`. */
|
|
278
335
|
private findChildId;
|
|
279
336
|
/** Every child whose cap manifest contains a descriptor matching `predicate`. */
|