@camstack/system 1.2.455 → 1.2.457
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 +96 -10
- package/dist/addon-runner.mjs +96 -10
- package/dist/{agent-https-CLWrOO3o.mjs → agent-https-CK9Z4sSR.mjs} +32 -5
- package/dist/{agent-https-CCvlRQKV.js → agent-https-CoyOZ3pC.js} +37 -4
- package/dist/auth/auth-manager.d.ts +9 -0
- package/dist/auth/legacy-token-tables.d.ts +16 -0
- package/dist/auth/user-management-internal.d.ts +9 -28
- 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 +2 -2
- package/dist/builtins/alerts/alerts.addon.mjs +2 -2
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/console-destination.d.ts +1 -2
- package/dist/builtins/console-logging/index.js +1 -4
- package/dist/builtins/console-logging/index.mjs +1 -4
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-history/capture/capture-engine.d.ts +6 -0
- package/dist/builtins/device-history/device-history.addon.js +441 -83
- package/dist/builtins/device-history/device-history.addon.mjs +441 -83
- package/dist/builtins/device-history/query/history-query.d.ts +35 -9
- package/dist/builtins/device-history/query/point-shape.d.ts +33 -0
- package/dist/builtins/device-history/retention/retention.d.ts +1 -1
- package/dist/builtins/device-history/rollup/rollup-engine.d.ts +2 -0
- package/dist/builtins/device-history/rollup/rollup-math.d.ts +6 -0
- package/dist/builtins/device-history/store/history-store.d.ts +7 -0
- package/dist/builtins/device-history/store/series-registry.d.ts +26 -1
- package/dist/builtins/device-manager/device-manager.addon.js +1 -1
- package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +1 -2
- package/dist/builtins/hub-forwarder/index.js +1 -4
- package/dist/builtins/hub-forwarder/index.mjs +1 -4
- package/dist/builtins/keychain/index.js +4 -4
- package/dist/builtins/keychain/index.mjs +4 -4
- 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/auth-schema.d.ts +4 -7
- package/dist/builtins/local-auth/local-auth.addon.d.ts +7 -8
- package/dist/builtins/local-auth/local-auth.addon.js +1086 -1329
- package/dist/builtins/local-auth/local-auth.addon.mjs +1085 -1326
- package/dist/builtins/local-auth/preferences-record-kinds.d.ts +27 -0
- package/dist/builtins/local-auth/record-kinds.d.ts +4 -3
- package/dist/builtins/local-auth/user-preferences-store.d.ts +56 -0
- package/dist/builtins/local-network/local-network.addon.d.ts +8 -0
- package/dist/builtins/local-network/local-network.addon.js +30 -5
- package/dist/builtins/local-network/local-network.addon.mjs +30 -5
- package/dist/builtins/loki-logging/index.js +323 -7
- package/dist/builtins/loki-logging/index.mjs +323 -7
- package/dist/builtins/loki-logging/loki-destination.d.ts +20 -3
- package/dist/builtins/loki-logging/loki-read.d.ts +51 -0
- package/dist/builtins/native-metrics/native-metrics.addon.js +290 -112
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +290 -112
- package/dist/builtins/native-metrics/node-metrics-history-recorder.d.ts +106 -35
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/record-entries/index.js +1 -1
- package/dist/builtins/record-entries/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/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/records/records-engine-types.d.ts +1 -0
- package/dist/builtins/sqlite-storage/records/records-provider.d.ts +13 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +52 -6
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +52 -6
- package/dist/builtins/storage-orchestrator/location-history-recorder.d.ts +76 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +9 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +144 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +144 -1
- package/dist/builtins/system-config/system-config.addon.js +3 -3
- package/dist/builtins/system-config/system-config.addon.mjs +3 -3
- package/dist/builtins/winston-logging/index.js +165 -3
- package/dist/builtins/winston-logging/index.mjs +165 -3
- package/dist/builtins/winston-logging/log-file-cursor.d.ts +12 -0
- package/dist/builtins/winston-logging/log-file-index-store.d.ts +11 -0
- package/dist/builtins/winston-logging/log-file-index.d.ts +77 -0
- package/dist/builtins/winston-logging/log-file-read-client.d.ts +44 -0
- package/dist/builtins/winston-logging/log-file-read-protocol.d.ts +41 -0
- package/dist/builtins/winston-logging/log-file-read-worker.d.ts +1 -0
- package/dist/builtins/winston-logging/log-file-reader.d.ts +51 -0
- package/dist/builtins/winston-logging/winston-destination.d.ts +20 -2
- package/dist/{composition-sources-CSzD5_qX.mjs → composition-sources-B_jeZDRJ.mjs} +1 -1
- package/dist/{composition-sources-BxUkLNSo.js → composition-sources-qKyvMAvc.js} +1 -1
- package/dist/{constants-DruwCkfp.js → constants-B_X9cWEK.js} +1 -1
- package/dist/{constants-DOlYt1t1.mjs → constants-cxKcZRMi.mjs} +1 -1
- package/dist/{device-ca-uFbTyY_o.mjs → device-ca-BB6nHAL5.mjs} +1 -1
- package/dist/{device-ca-QPBgfqVY.js → device-ca-CVK3YcR_.js} +1 -1
- package/dist/{dist-DjQ8C-ku.js → dist-C89nqNnn.js} +721 -154
- package/dist/{dist-BpSENkRJ.mjs → dist-Dhux90yB.mjs} +668 -155
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-DlgkFJVY.mjs → hub-mdns-ciao-B8olZqqd.mjs} +20 -13
- package/dist/{hub-mdns-ciao-Bkrvgnma.js → hub-mdns-ciao-DB1Y9agt.js} +20 -13
- package/dist/index.d.ts +3 -4
- package/dist/index.js +145 -24
- package/dist/index.mjs +138 -22
- package/dist/kernel/config-schema.d.ts +5 -0
- package/dist/kernel/moleculer/accessory-prune-gate.d.ts +55 -0
- package/dist/log-file-read-protocol-B7M3X3bT.mjs +785 -0
- package/dist/log-file-read-protocol-D0WcLbIV.js +817 -0
- package/dist/log-file-read-worker.js +64 -0
- package/dist/log-file-read-worker.mjs +64 -0
- package/dist/log-read-filter-Bi066jwU.js +134 -0
- package/dist/log-read-filter-D7Ev3zm-.mjs +93 -0
- package/dist/logging/log-manager.d.ts +10 -6
- package/dist/logging/log-read-filter.d.ts +43 -0
- package/dist/{phase6-declare-gate-DrmTtz7F.js → phase6-declare-gate-BO-_jLh_.js} +1 -1
- package/dist/{phase6-declare-gate-JQUqgQgq.mjs → phase6-declare-gate-x9ZCbQJP.mjs} +1 -1
- package/dist/{restore-archive-4OP0EYg6.js → restore-archive-4DOUR5Gu.js} +1 -1
- package/dist/{restore-archive-YFSJRtKy.mjs → restore-archive-DyOaPeAr.mjs} +1 -1
- package/dist/tls/cert-issue.d.ts +16 -1
- package/dist/tls/cert-manager.d.ts +6 -0
- package/dist/tls/index.d.ts +1 -1
- package/dist/{wal-maintenance-TyuOEVy1.mjs → wal-maintenance-BMiX6UIa.mjs} +0 -0
- package/dist/{wal-maintenance-Bl0ZKjVR.js → wal-maintenance-DVN-DiVP.js} +0 -0
- package/package.json +1 -1
- package/dist/auth/admin-token-manager.d.ts +0 -51
- package/dist/auth/scoped-token-manager.d.ts +0 -25
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dr as storageMigrationCapability, Er as storageCapability, Fn as legacyModeOf, Hn as mayReadLocation, Ki as defineRecordKinds, Kn as modeMayWrite, Oa as EventCategory, On as isLocationEnabled, Ri as collectSecretConfigKeys, Ta as transformSecretWrite, Un as mayWriteToLocation, ba as secretTreeFromPaths, br as settingsStoreCapability, ca as normalizeNodeId, dn as evictionPolicyOfLocation, ft as StorageCleanupJobSchema, ht as StorageMigrationJobSchema, mt as StorageLocationTypeSchema, na as isSecretMarker, ni as BaseAddon, pr as resolveLocationMode, pt as StorageLocationModeSchema, q as LegacyStorageLocationDefaultSchema, ua as parseJsonObject, va as resolveSecretMarkers, yi as REDACTED_SECRET, yn as gbToBytes, zr as withLocationMode } from "../../dist-Dhux90yB.mjs";
|
|
2
2
|
import { t as require_read_all_rows } from "../../read-all-rows-TaPqdWNF.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -3952,6 +3952,107 @@ var StorageLocationBandMonitor = class {
|
|
|
3952
3952
|
}
|
|
3953
3953
|
};
|
|
3954
3954
|
//#endregion
|
|
3955
|
+
//#region src/builtins/storage-orchestrator/location-history-recorder.ts
|
|
3956
|
+
var LOCATION_HISTORY_NAMES = {
|
|
3957
|
+
usedPercent: "location-used-percent",
|
|
3958
|
+
freeBytes: "location-free-bytes",
|
|
3959
|
+
ownedBytes: "location-owned-bytes"
|
|
3960
|
+
};
|
|
3961
|
+
var DECLARATIONS = [
|
|
3962
|
+
{
|
|
3963
|
+
name: LOCATION_HISTORY_NAMES.usedPercent,
|
|
3964
|
+
displayName: "Location volume used %",
|
|
3965
|
+
unit: "%"
|
|
3966
|
+
},
|
|
3967
|
+
{
|
|
3968
|
+
name: LOCATION_HISTORY_NAMES.freeBytes,
|
|
3969
|
+
displayName: "Location volume free",
|
|
3970
|
+
unit: "bytes"
|
|
3971
|
+
},
|
|
3972
|
+
{
|
|
3973
|
+
name: LOCATION_HISTORY_NAMES.ownedBytes,
|
|
3974
|
+
displayName: "Location held by CamStack",
|
|
3975
|
+
unit: "bytes"
|
|
3976
|
+
}
|
|
3977
|
+
];
|
|
3978
|
+
var LocationHistoryRecorder = class {
|
|
3979
|
+
deps;
|
|
3980
|
+
keys = /* @__PURE__ */ new Map();
|
|
3981
|
+
lastAt = /* @__PURE__ */ new Map();
|
|
3982
|
+
constructor(deps) {
|
|
3983
|
+
this.deps = deps;
|
|
3984
|
+
}
|
|
3985
|
+
async ensureDeclared() {
|
|
3986
|
+
if (this.keys.size === DECLARATIONS.length) return true;
|
|
3987
|
+
try {
|
|
3988
|
+
for (const d of DECLARATIONS) {
|
|
3989
|
+
const { key } = await this.deps.deviceHistory.declareSeries({
|
|
3990
|
+
name: d.name,
|
|
3991
|
+
subjectKind: "node",
|
|
3992
|
+
kind: "gauge",
|
|
3993
|
+
displayName: d.displayName,
|
|
3994
|
+
ingest: "points",
|
|
3995
|
+
unit: d.unit
|
|
3996
|
+
});
|
|
3997
|
+
this.keys.set(d.name, key);
|
|
3998
|
+
}
|
|
3999
|
+
return true;
|
|
4000
|
+
} catch (err) {
|
|
4001
|
+
this.keys.clear();
|
|
4002
|
+
this.deps.logger.warn("storage: location history declare failed — retried next sweep", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
4003
|
+
return false;
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
/** The points of one sweep; pure apart from the per-location rate memory. */
|
|
4007
|
+
pointsOf(readings, at) {
|
|
4008
|
+
const points = [];
|
|
4009
|
+
for (const r of readings) {
|
|
4010
|
+
const last = this.lastAt.get(r.locationId);
|
|
4011
|
+
if (last !== void 0 && at >= last && at - last < 6e4) continue;
|
|
4012
|
+
const add = (name, value) => {
|
|
4013
|
+
const key = this.keys.get(name);
|
|
4014
|
+
if (key === void 0 || !Number.isFinite(value)) return;
|
|
4015
|
+
points.push({
|
|
4016
|
+
key,
|
|
4017
|
+
subject: {
|
|
4018
|
+
kind: "node",
|
|
4019
|
+
nodeId: r.nodeId
|
|
4020
|
+
},
|
|
4021
|
+
scope: r.locationId,
|
|
4022
|
+
ts: at,
|
|
4023
|
+
value
|
|
4024
|
+
});
|
|
4025
|
+
};
|
|
4026
|
+
const before = points.length;
|
|
4027
|
+
if (r.capacity !== null && r.capacity.totalBytes > 0) {
|
|
4028
|
+
const used = r.capacity.totalBytes - r.capacity.availableBytes;
|
|
4029
|
+
add(LOCATION_HISTORY_NAMES.usedPercent, Math.round(used / r.capacity.totalBytes * 1e3) / 10);
|
|
4030
|
+
add(LOCATION_HISTORY_NAMES.freeBytes, r.capacity.availableBytes);
|
|
4031
|
+
}
|
|
4032
|
+
if (r.ownedBytes !== void 0) add(LOCATION_HISTORY_NAMES.ownedBytes, r.ownedBytes);
|
|
4033
|
+
if (points.length > before) this.lastAt.set(r.locationId, at);
|
|
4034
|
+
}
|
|
4035
|
+
return points;
|
|
4036
|
+
}
|
|
4037
|
+
async record(readings, at) {
|
|
4038
|
+
if (readings.length === 0 || !await this.ensureDeclared()) return;
|
|
4039
|
+
const points = this.pointsOf(readings, at);
|
|
4040
|
+
if (points.length === 0) return;
|
|
4041
|
+
try {
|
|
4042
|
+
const result = await this.deps.deviceHistory.record({ points });
|
|
4043
|
+
if (result.refused.length > 0) {
|
|
4044
|
+
if (result.refused.some((r) => r.reason === "undeclared")) this.keys.clear();
|
|
4045
|
+
this.deps.logger.warn("storage: location history points refused", { meta: {
|
|
4046
|
+
accepted: result.accepted,
|
|
4047
|
+
refused: result.refused
|
|
4048
|
+
} });
|
|
4049
|
+
}
|
|
4050
|
+
} catch (err) {
|
|
4051
|
+
this.deps.logger.warn("storage: location history not stored", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
};
|
|
4055
|
+
//#endregion
|
|
3955
4056
|
//#region src/builtins/storage-orchestrator/storage-orchestrator.addon.ts
|
|
3956
4057
|
/**
|
|
3957
4058
|
* `storage-orchestrator` builtin — singleton owner of the consumer-
|
|
@@ -4019,6 +4120,9 @@ var StorageOrchestratorAddon = class extends BaseAddon {
|
|
|
4019
4120
|
return this.occupancySlice;
|
|
4020
4121
|
}
|
|
4021
4122
|
pressureTimer = null;
|
|
4123
|
+
/** Occupancy over time (device-history). Created with the timer that feeds it. */
|
|
4124
|
+
locationHistory = null;
|
|
4125
|
+
locationHistoryInFlight = false;
|
|
4022
4126
|
pressureSweepInFlight = false;
|
|
4023
4127
|
migration = null;
|
|
4024
4128
|
/** Guards every single-location repoint and arbitrates movers per physical root. */
|
|
@@ -4435,8 +4539,16 @@ var StorageOrchestratorAddon = class extends BaseAddon {
|
|
|
4435
4539
|
}
|
|
4436
4540
|
}
|
|
4437
4541
|
});
|
|
4542
|
+
this.locationHistory = new LocationHistoryRecorder({
|
|
4543
|
+
deviceHistory: {
|
|
4544
|
+
declareSeries: (input) => this.ctx.api.deviceHistory.declareSeries.mutate(input),
|
|
4545
|
+
record: (input) => this.ctx.api.deviceHistory.record.mutate({ points: [...input.points] })
|
|
4546
|
+
},
|
|
4547
|
+
logger: this.ctx.logger
|
|
4548
|
+
});
|
|
4438
4549
|
this.pressureTimer = setInterval(() => {
|
|
4439
4550
|
this.runPressureSweep();
|
|
4551
|
+
this.recordLocationHistory();
|
|
4440
4552
|
}, PRESSURE_SWEEP_INTERVAL_MS);
|
|
4441
4553
|
this.ctx.logger.info("Storage orchestrator initialized");
|
|
4442
4554
|
return [
|
|
@@ -4583,6 +4695,37 @@ var StorageOrchestratorAddon = class extends BaseAddon {
|
|
|
4583
4695
|
}
|
|
4584
4696
|
}
|
|
4585
4697
|
/**
|
|
4698
|
+
* One occupancy reading per location this node can read, into device-history.
|
|
4699
|
+
* The volume figures come from the same probe `listLocations` serves, the
|
|
4700
|
+
* held bytes from the occupancy slice; an unknown figure is no point (D393).
|
|
4701
|
+
*/
|
|
4702
|
+
async recordLocationHistory() {
|
|
4703
|
+
const svc = this.service;
|
|
4704
|
+
const recorder = this.locationHistory;
|
|
4705
|
+
if (!svc || !recorder || this.locationHistoryInFlight) return;
|
|
4706
|
+
this.locationHistoryInFlight = true;
|
|
4707
|
+
try {
|
|
4708
|
+
this.occupancy.serveAndRevalidate();
|
|
4709
|
+
const localNode = svc.getLocalNodeId();
|
|
4710
|
+
const readings = [];
|
|
4711
|
+
for (const loc of svc.listLocations()) {
|
|
4712
|
+
if (!mayReadLocation(loc) || (loc.nodeId ?? HUB_NODE_ID) !== localNode) continue;
|
|
4713
|
+
const capacity = await this.localCapacityOf(loc).catch(() => null);
|
|
4714
|
+
readings.push({
|
|
4715
|
+
locationId: loc.id,
|
|
4716
|
+
nodeId: localNode,
|
|
4717
|
+
capacity,
|
|
4718
|
+
ownedBytes: this.occupancy.ownedFor(loc.id)?.bytes
|
|
4719
|
+
});
|
|
4720
|
+
}
|
|
4721
|
+
await recorder.record(readings, Date.now());
|
|
4722
|
+
} catch (err) {
|
|
4723
|
+
this.ctxIfReady?.logger.warn("storage: location history pass failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
4724
|
+
} finally {
|
|
4725
|
+
this.locationHistoryInFlight = false;
|
|
4726
|
+
}
|
|
4727
|
+
}
|
|
4728
|
+
/**
|
|
4586
4729
|
* Sample free space for every managed location and emit NC band edges.
|
|
4587
4730
|
* A failed capacity read stays `null` and changes no band — never folded to 0 (D393).
|
|
4588
4731
|
*/
|
|
@@ -3,11 +3,11 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-C89nqNnn.js");
|
|
7
7
|
const require_safe_buffer$1 = require("../../safe-buffer-D3aoa-7X.js");
|
|
8
8
|
const require_x509_es = require("../../x509.es-C4cOo48M.js");
|
|
9
|
-
const require_constants$8 = require("../../constants-
|
|
10
|
-
const require_agent_https = require("../../agent-https-
|
|
9
|
+
const require_constants$8 = require("../../constants-B_X9cWEK.js");
|
|
10
|
+
const require_agent_https = require("../../agent-https-CoyOZ3pC.js");
|
|
11
11
|
const require_src$1 = require("../../src-CnAqG6EF.js");
|
|
12
12
|
let zod = require("zod");
|
|
13
13
|
let node_crypto = require("node:crypto");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM, r as __exportAll, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { Gi as defineCustomActions, Ui as customAction, Zi as hydrateSchema, ni as BaseAddon, ti as errMsg, ut as ServerNameSchema, xr as shortHostname } from "../../dist-Dhux90yB.mjs";
|
|
3
3
|
import { t as require_safe_buffer } from "../../safe-buffer-B1OjL1I9.mjs";
|
|
4
4
|
import { c as Pkcs10CertificateRequest } from "../../x509.es-DK__ETIe.mjs";
|
|
5
|
-
import { a as MESH_CA_KEY_REF, i as MESH_CA_FIELD, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY } from "../../constants-
|
|
6
|
-
import { $ as
|
|
5
|
+
import { a as MESH_CA_KEY_REF, i as MESH_CA_FIELD, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY } from "../../constants-cxKcZRMi.mjs";
|
|
6
|
+
import { $ as generateMeshCa, B as setProcessAgentHttpsNames, H as MESH_NODE_CERTIFICATES_COLLECTION, I as AGENT_HTTPS_NAMES_COLLECTION, J as setProcessMeshCertificateRegistry, K as describeMeshLeaf, L as AGENT_HTTPS_NAMES_COLUMNS, M as isLocalOnlyHostname, Q as exportMeshPrivateKeyPem, R as AgentHttpsNames, U as MESH_NODE_CERTIFICATES_COLUMNS, V as systemConfigRecordKinds, W as MeshCertificateRegistry, X as caFingerprintCompact, Z as createMeshCsrPem, at as subjectCn, et as generateMeshKeyPair, it as loadMeshCa, nt as issueMeshLeafForNode, rt as issueMeshLeafFromCsr, tt as isValidAgentNodeId, u as isPrivateAddress, z as getProcessAgentHttpsNames } from "../../agent-https-CK9Z4sSR.mjs";
|
|
7
7
|
import { t as require_src } from "../../src-hG4grMU4.mjs";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { X509Certificate, createHash, createPrivateKey, randomBytes, randomInt, sign, timingSafeEqual, verify, webcrypto } from "node:crypto";
|
|
@@ -3,14 +3,132 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-C89nqNnn.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
|
+
const require_log_file_read_protocol = require("../../log-file-read-protocol-D0WcLbIV.js");
|
|
8
9
|
let node_path = require("node:path");
|
|
9
10
|
node_path = require_chunk.__toESM(node_path);
|
|
11
|
+
let node_module = require("node:module");
|
|
12
|
+
let node_worker_threads = require("node:worker_threads");
|
|
10
13
|
let winston = require("winston");
|
|
11
14
|
winston = require_chunk.__toESM(winston);
|
|
12
15
|
let winston_daily_rotate_file = require("winston-daily-rotate-file");
|
|
13
16
|
winston_daily_rotate_file = require_chunk.__toESM(winston_daily_rotate_file);
|
|
17
|
+
//#region src/builtins/winston-logging/log-file-read-client.ts
|
|
18
|
+
/**
|
|
19
|
+
* The parent side of the rotated-file reader thread (D898).
|
|
20
|
+
*
|
|
21
|
+
* The thread is spawned on the first read, not at boot: a hub nobody reads
|
|
22
|
+
* logs on pays nothing but the background index pass, which starts with the
|
|
23
|
+
* thread. A thread that dies fails its in-flight reads and is respawned on
|
|
24
|
+
* the next one.
|
|
25
|
+
*/
|
|
26
|
+
/** `dist/log-file-read-worker.js` at the package root, found through its own `package.json`. */
|
|
27
|
+
function defaultReaderWorkerPath() {
|
|
28
|
+
const require_ = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
29
|
+
const packageRoot = node_path.dirname(require_.resolve("@camstack/system/package.json"));
|
|
30
|
+
return node_path.join(packageRoot, "dist", "log-file-read-worker.js");
|
|
31
|
+
}
|
|
32
|
+
var LogFileReadClient = class {
|
|
33
|
+
logsDir;
|
|
34
|
+
backgroundPassMs;
|
|
35
|
+
spawn;
|
|
36
|
+
worker = null;
|
|
37
|
+
nextId = 1;
|
|
38
|
+
pending = /* @__PURE__ */ new Map();
|
|
39
|
+
local;
|
|
40
|
+
constructor(options) {
|
|
41
|
+
this.logsDir = options.logsDir;
|
|
42
|
+
this.backgroundPassMs = options.backgroundPassMs ?? 6e4;
|
|
43
|
+
if (options.inProcess === true) {
|
|
44
|
+
this.spawn = null;
|
|
45
|
+
this.local = {
|
|
46
|
+
store: new require_log_file_read_protocol.LogFileIndexStore(options.logsDir),
|
|
47
|
+
cancels: new require_log_file_read_protocol.CancelBook()
|
|
48
|
+
};
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.local = null;
|
|
52
|
+
const workerPath = options.workerPath ?? defaultReaderWorkerPath();
|
|
53
|
+
const execArgv = options.workerExecArgv;
|
|
54
|
+
this.spawn = options.workerFactory ?? ((workerData) => new node_worker_threads.Worker(workerPath, {
|
|
55
|
+
workerData,
|
|
56
|
+
...execArgv !== void 0 ? { execArgv: [...execArgv] } : {}
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
async read(query) {
|
|
60
|
+
if (this.local !== null) return (await require_log_file_read_protocol.serveRead(this.logsDir, this.local.store, this.local.cancels, query)).result;
|
|
61
|
+
const worker = this.ensureWorker();
|
|
62
|
+
const id = this.nextId++;
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
this.pending.set(id, {
|
|
65
|
+
resolve,
|
|
66
|
+
reject
|
|
67
|
+
});
|
|
68
|
+
worker.postMessage({
|
|
69
|
+
type: "read",
|
|
70
|
+
id,
|
|
71
|
+
query
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Start the thread now, so its background pass indexes the existing files
|
|
77
|
+
* before anyone reads them. The hub calls this; an agent, whose files
|
|
78
|
+
* nobody reads, leaves the thread unstarted.
|
|
79
|
+
*/
|
|
80
|
+
warm() {
|
|
81
|
+
if (this.local === null) this.ensureWorker();
|
|
82
|
+
}
|
|
83
|
+
cancel(requestId) {
|
|
84
|
+
if (this.local !== null) {
|
|
85
|
+
this.local.cancels.cancel(requestId);
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
if (this.worker === null) return false;
|
|
89
|
+
this.worker.postMessage({
|
|
90
|
+
type: "cancel",
|
|
91
|
+
requestId
|
|
92
|
+
});
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
stop() {
|
|
96
|
+
this.worker?.postMessage({ type: "stop" });
|
|
97
|
+
this.worker = null;
|
|
98
|
+
this.failAll(/* @__PURE__ */ new Error("log reader stopped"));
|
|
99
|
+
}
|
|
100
|
+
ensureWorker() {
|
|
101
|
+
if (this.worker !== null) return this.worker;
|
|
102
|
+
if (this.spawn === null) throw new Error("log reader has no worker factory");
|
|
103
|
+
const worker = this.spawn({
|
|
104
|
+
logsDir: this.logsDir,
|
|
105
|
+
backgroundPassMs: this.backgroundPassMs
|
|
106
|
+
});
|
|
107
|
+
worker.unref?.();
|
|
108
|
+
worker.on("message", (message) => {
|
|
109
|
+
if (!require_log_file_read_protocol.isFromReader(message)) return;
|
|
110
|
+
const waiter = this.pending.get(message.id);
|
|
111
|
+
if (waiter === void 0) return;
|
|
112
|
+
this.pending.delete(message.id);
|
|
113
|
+
if (message.type === "result") waiter.resolve(message.result);
|
|
114
|
+
else waiter.reject(new Error(message.message));
|
|
115
|
+
});
|
|
116
|
+
worker.on("error", (err) => {
|
|
117
|
+
this.failAll(err instanceof Error ? err : new Error(String(err)));
|
|
118
|
+
});
|
|
119
|
+
worker.on("exit", () => {
|
|
120
|
+
if (this.worker === worker) this.worker = null;
|
|
121
|
+
this.failAll(/* @__PURE__ */ new Error("log reader thread exited"));
|
|
122
|
+
});
|
|
123
|
+
this.worker = worker;
|
|
124
|
+
return worker;
|
|
125
|
+
}
|
|
126
|
+
failAll(error) {
|
|
127
|
+
for (const waiter of this.pending.values()) waiter.reject(error);
|
|
128
|
+
this.pending.clear();
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
//#endregion
|
|
14
132
|
//#region src/builtins/winston-logging/winston-destination.ts
|
|
15
133
|
/**
|
|
16
134
|
* Rotated-file log destination. Console output goes through the shared
|
|
@@ -19,9 +137,24 @@ winston_daily_rotate_file = require_chunk.__toESM(winston_daily_rotate_file);
|
|
|
19
137
|
* structured JSON shape so log tooling can query tags/meta.
|
|
20
138
|
*/
|
|
21
139
|
var WinstonDestination = class {
|
|
140
|
+
readerOptions;
|
|
22
141
|
logger = null;
|
|
142
|
+
reader = null;
|
|
143
|
+
retentionDays = 30;
|
|
144
|
+
/**
|
|
145
|
+
* `readerOptions` reaches the history reader (D898) — a spec runs it in
|
|
146
|
+
* process or points the thread at the TypeScript source.
|
|
147
|
+
*/
|
|
148
|
+
constructor(readerOptions = {}) {
|
|
149
|
+
this.readerOptions = readerOptions;
|
|
150
|
+
}
|
|
23
151
|
async initialize(config) {
|
|
24
152
|
const { level = "info", retentionDays = 30, logsDir = node_path.join("camstack-data", "logs") } = config ?? {};
|
|
153
|
+
this.retentionDays = retentionDays;
|
|
154
|
+
this.reader = new LogFileReadClient({
|
|
155
|
+
...this.readerOptions,
|
|
156
|
+
logsDir
|
|
157
|
+
});
|
|
25
158
|
winston.format.printf((info) => {
|
|
26
159
|
const rendered = info._rendered;
|
|
27
160
|
return typeof rendered === "string" ? rendered : String(info.message);
|
|
@@ -47,6 +180,7 @@ var WinstonDestination = class {
|
|
|
47
180
|
const ts = entry.timestamp instanceof Date ? entry.timestamp.toISOString() : String(entry.timestamp);
|
|
48
181
|
const rendered = require_formatter.formatLogLine(entry, { colorize: true });
|
|
49
182
|
this.logger.log({
|
|
183
|
+
...entry.id !== void 0 ? { id: entry.id } : {},
|
|
50
184
|
level: entry.level,
|
|
51
185
|
message: entry.message,
|
|
52
186
|
_rendered: rendered,
|
|
@@ -56,10 +190,37 @@ var WinstonDestination = class {
|
|
|
56
190
|
...entry.meta ? { meta: entry.meta } : {}
|
|
57
191
|
});
|
|
58
192
|
}
|
|
59
|
-
|
|
60
|
-
|
|
193
|
+
/** The rotated files ARE the hub's history (D898): every filter is applied here. */
|
|
194
|
+
async describeRead() {
|
|
195
|
+
return {
|
|
196
|
+
readable: this.reader !== null,
|
|
197
|
+
reason: this.reader !== null ? null : "Not initialized",
|
|
198
|
+
filters: {
|
|
199
|
+
deviceId: true,
|
|
200
|
+
addonId: true,
|
|
201
|
+
nodeId: true,
|
|
202
|
+
tags: true,
|
|
203
|
+
level: true,
|
|
204
|
+
text: true,
|
|
205
|
+
timeRange: true
|
|
206
|
+
},
|
|
207
|
+
retentionDays: this.retentionDays
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/** Index the existing files in the background now (the hub's history). */
|
|
211
|
+
startBackgroundIndexing() {
|
|
212
|
+
this.reader?.warm();
|
|
213
|
+
}
|
|
214
|
+
async read(query) {
|
|
215
|
+
if (this.reader === null) throw new Error("winston-logging: not initialized");
|
|
216
|
+
return this.reader.read(query);
|
|
217
|
+
}
|
|
218
|
+
async cancelRead(input) {
|
|
219
|
+
return { cancelled: this.reader?.cancel(input.requestId) ?? false };
|
|
61
220
|
}
|
|
62
221
|
async shutdown() {
|
|
222
|
+
this.reader?.stop();
|
|
223
|
+
this.reader = null;
|
|
63
224
|
if (!this.logger) return;
|
|
64
225
|
await new Promise((resolve) => {
|
|
65
226
|
this.logger.on("finish", resolve);
|
|
@@ -89,6 +250,7 @@ var WinstonLoggingAddon = class extends require_dist.BaseAddon {
|
|
|
89
250
|
...this.config,
|
|
90
251
|
logsDir
|
|
91
252
|
});
|
|
253
|
+
if (this.ctx.kernel.localNodeId === "hub") this.destination.startBackgroundIndexing();
|
|
92
254
|
this.ctx.logger.info("Winston logging initialized");
|
|
93
255
|
return [{
|
|
94
256
|
capability: require_dist.logDestinationCapability,
|
|
@@ -1,9 +1,127 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ni as BaseAddon, zn as logDestinationCapability } from "../../dist-Dhux90yB.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
|
+
import { a as LogFileIndexStore, i as serveRead, n as isFromReader, t as CancelBook } from "../../log-file-read-protocol-B7M3X3bT.mjs";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
3
5
|
import * as path$1 from "node:path";
|
|
4
6
|
import path from "node:path";
|
|
7
|
+
import { Worker } from "node:worker_threads";
|
|
5
8
|
import * as winston from "winston";
|
|
6
9
|
import DailyRotateFile from "winston-daily-rotate-file";
|
|
10
|
+
//#region src/builtins/winston-logging/log-file-read-client.ts
|
|
11
|
+
/**
|
|
12
|
+
* The parent side of the rotated-file reader thread (D898).
|
|
13
|
+
*
|
|
14
|
+
* The thread is spawned on the first read, not at boot: a hub nobody reads
|
|
15
|
+
* logs on pays nothing but the background index pass, which starts with the
|
|
16
|
+
* thread. A thread that dies fails its in-flight reads and is respawned on
|
|
17
|
+
* the next one.
|
|
18
|
+
*/
|
|
19
|
+
/** `dist/log-file-read-worker.js` at the package root, found through its own `package.json`. */
|
|
20
|
+
function defaultReaderWorkerPath() {
|
|
21
|
+
const require_ = createRequire(import.meta.url);
|
|
22
|
+
const packageRoot = path$1.dirname(require_.resolve("@camstack/system/package.json"));
|
|
23
|
+
return path$1.join(packageRoot, "dist", "log-file-read-worker.js");
|
|
24
|
+
}
|
|
25
|
+
var LogFileReadClient = class {
|
|
26
|
+
logsDir;
|
|
27
|
+
backgroundPassMs;
|
|
28
|
+
spawn;
|
|
29
|
+
worker = null;
|
|
30
|
+
nextId = 1;
|
|
31
|
+
pending = /* @__PURE__ */ new Map();
|
|
32
|
+
local;
|
|
33
|
+
constructor(options) {
|
|
34
|
+
this.logsDir = options.logsDir;
|
|
35
|
+
this.backgroundPassMs = options.backgroundPassMs ?? 6e4;
|
|
36
|
+
if (options.inProcess === true) {
|
|
37
|
+
this.spawn = null;
|
|
38
|
+
this.local = {
|
|
39
|
+
store: new LogFileIndexStore(options.logsDir),
|
|
40
|
+
cancels: new CancelBook()
|
|
41
|
+
};
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.local = null;
|
|
45
|
+
const workerPath = options.workerPath ?? defaultReaderWorkerPath();
|
|
46
|
+
const execArgv = options.workerExecArgv;
|
|
47
|
+
this.spawn = options.workerFactory ?? ((workerData) => new Worker(workerPath, {
|
|
48
|
+
workerData,
|
|
49
|
+
...execArgv !== void 0 ? { execArgv: [...execArgv] } : {}
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
async read(query) {
|
|
53
|
+
if (this.local !== null) return (await serveRead(this.logsDir, this.local.store, this.local.cancels, query)).result;
|
|
54
|
+
const worker = this.ensureWorker();
|
|
55
|
+
const id = this.nextId++;
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
this.pending.set(id, {
|
|
58
|
+
resolve,
|
|
59
|
+
reject
|
|
60
|
+
});
|
|
61
|
+
worker.postMessage({
|
|
62
|
+
type: "read",
|
|
63
|
+
id,
|
|
64
|
+
query
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Start the thread now, so its background pass indexes the existing files
|
|
70
|
+
* before anyone reads them. The hub calls this; an agent, whose files
|
|
71
|
+
* nobody reads, leaves the thread unstarted.
|
|
72
|
+
*/
|
|
73
|
+
warm() {
|
|
74
|
+
if (this.local === null) this.ensureWorker();
|
|
75
|
+
}
|
|
76
|
+
cancel(requestId) {
|
|
77
|
+
if (this.local !== null) {
|
|
78
|
+
this.local.cancels.cancel(requestId);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
if (this.worker === null) return false;
|
|
82
|
+
this.worker.postMessage({
|
|
83
|
+
type: "cancel",
|
|
84
|
+
requestId
|
|
85
|
+
});
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
stop() {
|
|
89
|
+
this.worker?.postMessage({ type: "stop" });
|
|
90
|
+
this.worker = null;
|
|
91
|
+
this.failAll(/* @__PURE__ */ new Error("log reader stopped"));
|
|
92
|
+
}
|
|
93
|
+
ensureWorker() {
|
|
94
|
+
if (this.worker !== null) return this.worker;
|
|
95
|
+
if (this.spawn === null) throw new Error("log reader has no worker factory");
|
|
96
|
+
const worker = this.spawn({
|
|
97
|
+
logsDir: this.logsDir,
|
|
98
|
+
backgroundPassMs: this.backgroundPassMs
|
|
99
|
+
});
|
|
100
|
+
worker.unref?.();
|
|
101
|
+
worker.on("message", (message) => {
|
|
102
|
+
if (!isFromReader(message)) return;
|
|
103
|
+
const waiter = this.pending.get(message.id);
|
|
104
|
+
if (waiter === void 0) return;
|
|
105
|
+
this.pending.delete(message.id);
|
|
106
|
+
if (message.type === "result") waiter.resolve(message.result);
|
|
107
|
+
else waiter.reject(new Error(message.message));
|
|
108
|
+
});
|
|
109
|
+
worker.on("error", (err) => {
|
|
110
|
+
this.failAll(err instanceof Error ? err : new Error(String(err)));
|
|
111
|
+
});
|
|
112
|
+
worker.on("exit", () => {
|
|
113
|
+
if (this.worker === worker) this.worker = null;
|
|
114
|
+
this.failAll(/* @__PURE__ */ new Error("log reader thread exited"));
|
|
115
|
+
});
|
|
116
|
+
this.worker = worker;
|
|
117
|
+
return worker;
|
|
118
|
+
}
|
|
119
|
+
failAll(error) {
|
|
120
|
+
for (const waiter of this.pending.values()) waiter.reject(error);
|
|
121
|
+
this.pending.clear();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
//#endregion
|
|
7
125
|
//#region src/builtins/winston-logging/winston-destination.ts
|
|
8
126
|
/**
|
|
9
127
|
* Rotated-file log destination. Console output goes through the shared
|
|
@@ -12,9 +130,24 @@ import DailyRotateFile from "winston-daily-rotate-file";
|
|
|
12
130
|
* structured JSON shape so log tooling can query tags/meta.
|
|
13
131
|
*/
|
|
14
132
|
var WinstonDestination = class {
|
|
133
|
+
readerOptions;
|
|
15
134
|
logger = null;
|
|
135
|
+
reader = null;
|
|
136
|
+
retentionDays = 30;
|
|
137
|
+
/**
|
|
138
|
+
* `readerOptions` reaches the history reader (D898) — a spec runs it in
|
|
139
|
+
* process or points the thread at the TypeScript source.
|
|
140
|
+
*/
|
|
141
|
+
constructor(readerOptions = {}) {
|
|
142
|
+
this.readerOptions = readerOptions;
|
|
143
|
+
}
|
|
16
144
|
async initialize(config) {
|
|
17
145
|
const { level = "info", retentionDays = 30, logsDir = path$1.join("camstack-data", "logs") } = config ?? {};
|
|
146
|
+
this.retentionDays = retentionDays;
|
|
147
|
+
this.reader = new LogFileReadClient({
|
|
148
|
+
...this.readerOptions,
|
|
149
|
+
logsDir
|
|
150
|
+
});
|
|
18
151
|
winston.format.printf((info) => {
|
|
19
152
|
const rendered = info._rendered;
|
|
20
153
|
return typeof rendered === "string" ? rendered : String(info.message);
|
|
@@ -40,6 +173,7 @@ var WinstonDestination = class {
|
|
|
40
173
|
const ts = entry.timestamp instanceof Date ? entry.timestamp.toISOString() : String(entry.timestamp);
|
|
41
174
|
const rendered = formatLogLine(entry, { colorize: true });
|
|
42
175
|
this.logger.log({
|
|
176
|
+
...entry.id !== void 0 ? { id: entry.id } : {},
|
|
43
177
|
level: entry.level,
|
|
44
178
|
message: entry.message,
|
|
45
179
|
_rendered: rendered,
|
|
@@ -49,10 +183,37 @@ var WinstonDestination = class {
|
|
|
49
183
|
...entry.meta ? { meta: entry.meta } : {}
|
|
50
184
|
});
|
|
51
185
|
}
|
|
52
|
-
|
|
53
|
-
|
|
186
|
+
/** The rotated files ARE the hub's history (D898): every filter is applied here. */
|
|
187
|
+
async describeRead() {
|
|
188
|
+
return {
|
|
189
|
+
readable: this.reader !== null,
|
|
190
|
+
reason: this.reader !== null ? null : "Not initialized",
|
|
191
|
+
filters: {
|
|
192
|
+
deviceId: true,
|
|
193
|
+
addonId: true,
|
|
194
|
+
nodeId: true,
|
|
195
|
+
tags: true,
|
|
196
|
+
level: true,
|
|
197
|
+
text: true,
|
|
198
|
+
timeRange: true
|
|
199
|
+
},
|
|
200
|
+
retentionDays: this.retentionDays
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/** Index the existing files in the background now (the hub's history). */
|
|
204
|
+
startBackgroundIndexing() {
|
|
205
|
+
this.reader?.warm();
|
|
206
|
+
}
|
|
207
|
+
async read(query) {
|
|
208
|
+
if (this.reader === null) throw new Error("winston-logging: not initialized");
|
|
209
|
+
return this.reader.read(query);
|
|
210
|
+
}
|
|
211
|
+
async cancelRead(input) {
|
|
212
|
+
return { cancelled: this.reader?.cancel(input.requestId) ?? false };
|
|
54
213
|
}
|
|
55
214
|
async shutdown() {
|
|
215
|
+
this.reader?.stop();
|
|
216
|
+
this.reader = null;
|
|
56
217
|
if (!this.logger) return;
|
|
57
218
|
await new Promise((resolve) => {
|
|
58
219
|
this.logger.on("finish", resolve);
|
|
@@ -82,6 +243,7 @@ var WinstonLoggingAddon = class extends BaseAddon {
|
|
|
82
243
|
...this.config,
|
|
83
244
|
logsDir
|
|
84
245
|
});
|
|
246
|
+
if (this.ctx.kernel.localNodeId === "hub") this.destination.startBackgroundIndexing();
|
|
85
247
|
this.ctx.logger.info("Winston logging initialized");
|
|
86
248
|
return [{
|
|
87
249
|
capability: logDestinationCapability,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** `camstack-YYYY-MM-DD.log`, as `winston-daily-rotate-file` names them. */
|
|
2
|
+
export declare const LOG_FILE_NAME_RE: RegExp;
|
|
3
|
+
/** A position in one daily file. */
|
|
4
|
+
export interface FileCursor {
|
|
5
|
+
/** The daily file's name (never a path). */
|
|
6
|
+
readonly f: string;
|
|
7
|
+
/** A line-start byte offset in that file. */
|
|
8
|
+
readonly o: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function encodeFileCursor(cursor: FileCursor): string;
|
|
11
|
+
/** Null for anything this provider did not mint. */
|
|
12
|
+
export declare function decodeFileCursor(raw: string): FileCursor | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FileIndex } from "./log-file-index.js";
|
|
2
|
+
export declare class LogFileIndexStore {
|
|
3
|
+
private readonly logsDir;
|
|
4
|
+
private readonly files;
|
|
5
|
+
constructor(logsDir: string);
|
|
6
|
+
indexOf(fileName: string, opts?: {
|
|
7
|
+
readonly wait?: boolean;
|
|
8
|
+
}): Promise<FileIndex | null>;
|
|
9
|
+
/** Index everything, newest first; drop orphaned sidecars. */
|
|
10
|
+
backgroundPass(shouldStop: () => boolean): Promise<void>;
|
|
11
|
+
}
|