@camstack/system 1.2.328 → 1.2.330
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/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/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +7 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +294 -79
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +294 -79
- 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/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- 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-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- 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/sqlite-settings.addon.d.ts +4 -0
- 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/sqlite-storage/sqlite-snapshot-protocol.d.ts +49 -0
- package/dist/builtins/sqlite-storage/sqlite-snapshot-worker.d.ts +33 -0
- package/dist/builtins/sqlite-storage/sqlite-snapshotter.d.ts +98 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-backup/system-backup.service.d.ts +74 -20
- 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/{composition-sources-GkgXF6B9.js → composition-sources-2XxNEet3.js} +1 -1
- package/dist/{composition-sources-I8Rx7woY.mjs → composition-sources-Wj2kWund.mjs} +1 -1
- package/dist/{dist-BUejKKBm.js → dist-Bx4zxM9N.js} +534 -341
- package/dist/{dist-DWq17vC8.mjs → dist-Dp043AI0.mjs} +505 -342
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{retired-settings-keys-DBPEzGop.js → retired-settings-keys-DR2WMe5d.js} +1 -1
- package/dist/{retired-settings-keys-BfHclEyd.mjs → retired-settings-keys-Dxf9vELs.mjs} +1 -1
- package/dist/sqlite-snapshot-protocol-2QaTouWV.mjs +34 -0
- package/dist/sqlite-snapshot-protocol-B9OndqZv.js +51 -0
- package/dist/sqlite-snapshot-worker.js +185 -0
- package/dist/sqlite-snapshot-worker.mjs +179 -0
- package/package.json +6 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { K as backupCapability, Sn as storageOccupancyCapability, Sr as EventCategory, Yt as mayWriteToLocation, Zn as BaseAddon, m as DATABASE_SNAPSHOT_SUFFIX, mr as nodePin, xr as toNodeId } from "../../dist-Dp043AI0.mjs";
|
|
2
2
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
3
|
import { Buffer as Buffer$1 } from "buffer";
|
|
4
4
|
import * as fsp from "node:fs/promises";
|
|
@@ -2859,8 +2859,7 @@ var Tr = Symbol("onEntry"), gs = Symbol("checkFs"), xr = Symbol("checkFs2"), bs
|
|
|
2859
2859
|
return this[O$1](o, t);
|
|
2860
2860
|
}
|
|
2861
2861
|
}
|
|
2862
|
-
}
|
|
2863
|
-
var co = (s) => {
|
|
2862
|
+
}, co = (s) => {
|
|
2864
2863
|
let t = new Te(s), e = s.file, i = Kt.statSync(e);
|
|
2865
2864
|
new Me(e, {
|
|
2866
2865
|
readSize: s.maxReadSize || 16 * 1024 * 1024,
|
|
@@ -2880,7 +2879,8 @@ var co = (s) => {
|
|
|
2880
2879
|
}
|
|
2881
2880
|
});
|
|
2882
2881
|
});
|
|
2883
|
-
}
|
|
2882
|
+
};
|
|
2883
|
+
K(co, fo, (s) => new Te(s), (s) => new Xt(s), (s, t) => {
|
|
2884
2884
|
t?.length && Xi(s, t);
|
|
2885
2885
|
});
|
|
2886
2886
|
var mo = (s, t) => {
|
|
@@ -3001,6 +3001,44 @@ var BackupCancelledError = class extends Error {
|
|
|
3001
3001
|
this.name = "BackupCancelledError";
|
|
3002
3002
|
}
|
|
3003
3003
|
};
|
|
3004
|
+
/**
|
|
3005
|
+
* Thrown when an archive would carry a live database and its owner could not
|
|
3006
|
+
* produce a verified snapshot of it (D693). Nothing was built: a run that
|
|
3007
|
+
* "succeeded" without the database — or with a torn copy of it — would push
|
|
3008
|
+
* the oldest good archive out of every destination's retention.
|
|
3009
|
+
*/
|
|
3010
|
+
var BackupSnapshotRefusedError = class extends Error {
|
|
3011
|
+
constructor(reason) {
|
|
3012
|
+
super(`settings database snapshot failed — no archive built, nothing uploaded, retention untouched: ${reason}`);
|
|
3013
|
+
this.name = "BackupSnapshotRefusedError";
|
|
3014
|
+
}
|
|
3015
|
+
};
|
|
3016
|
+
/**
|
|
3017
|
+
* Settle with `pending`, or reject with {@link BackupCancelledError} as soon as
|
|
3018
|
+
* `signal` fires. A pending call abandoned by the cancel still settles later:
|
|
3019
|
+
* `onAbandoned` runs then, to clean up what it produced.
|
|
3020
|
+
*/
|
|
3021
|
+
function raceAbort(pending, signal, onAbandoned) {
|
|
3022
|
+
if (signal === void 0) return pending;
|
|
3023
|
+
return new Promise((resolve, reject) => {
|
|
3024
|
+
let abandoned = false;
|
|
3025
|
+
const onAbort = () => {
|
|
3026
|
+
abandoned = true;
|
|
3027
|
+
reject(new BackupCancelledError());
|
|
3028
|
+
};
|
|
3029
|
+
if (signal.aborted) onAbort();
|
|
3030
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
3031
|
+
pending.then((value) => {
|
|
3032
|
+
signal.removeEventListener("abort", onAbort);
|
|
3033
|
+
if (abandoned) onAbandoned();
|
|
3034
|
+
else resolve(value);
|
|
3035
|
+
}, (err) => {
|
|
3036
|
+
signal.removeEventListener("abort", onAbort);
|
|
3037
|
+
if (abandoned) onAbandoned();
|
|
3038
|
+
else reject(err);
|
|
3039
|
+
});
|
|
3040
|
+
});
|
|
3041
|
+
}
|
|
3004
3042
|
/** Throw `BackupCancelledError` when the signal has fired. */
|
|
3005
3043
|
function throwIfCancelled(signal) {
|
|
3006
3044
|
if (signal?.aborted) throw new BackupCancelledError();
|
|
@@ -3053,11 +3091,48 @@ var EXCLUDED_DIR_NAME = "node_modules";
|
|
|
3053
3091
|
* trailing `/`) and backslash separators.
|
|
3054
3092
|
*/
|
|
3055
3093
|
function isExcludedFromBackup(relPath) {
|
|
3056
|
-
const norm = relPath
|
|
3094
|
+
const norm = normalizeArchivePath(relPath);
|
|
3057
3095
|
if (norm.length === 0) return false;
|
|
3058
|
-
|
|
3096
|
+
const segments = norm.split("/");
|
|
3097
|
+
if (segments.includes(EXCLUDED_DIR_NAME)) return true;
|
|
3098
|
+
if (segments.some((seg) => seg.endsWith(".backup-snapshot-partial"))) return true;
|
|
3099
|
+
if (norm.endsWith(".backup-snapshot")) return true;
|
|
3059
3100
|
return DEFAULT_BACKUP_EXCLUDES.some((prefix) => norm === prefix || norm.startsWith(`${prefix}/`));
|
|
3060
3101
|
}
|
|
3102
|
+
/** `./a/b/` and `a\\b` → `a/b`: the one spelling every archive-path comparison uses. */
|
|
3103
|
+
function normalizeArchivePath(relPath) {
|
|
3104
|
+
return relPath.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+$/, "");
|
|
3105
|
+
}
|
|
3106
|
+
/** The files SQLite keeps beside a database. A live one is never archived. */
|
|
3107
|
+
var SQLITE_SIDECAR_SUFFIXES = [
|
|
3108
|
+
"-wal",
|
|
3109
|
+
"-shm",
|
|
3110
|
+
"-journal"
|
|
3111
|
+
];
|
|
3112
|
+
var SQLITE_DATABASE_SUFFIXES = [
|
|
3113
|
+
".db",
|
|
3114
|
+
".sqlite",
|
|
3115
|
+
".sqlite3"
|
|
3116
|
+
];
|
|
3117
|
+
/**
|
|
3118
|
+
* The database a `-wal` / `-shm` / `-journal` belongs to, or null for any other
|
|
3119
|
+
* path. The base must name a database (`.db` / `.sqlite` / `.sqlite3`): a
|
|
3120
|
+
* `build-journal` is not a sidecar, and must not stop every backup as a "live
|
|
3121
|
+
* database" that does not exist.
|
|
3122
|
+
*/
|
|
3123
|
+
function databaseOfSidecar(relPath) {
|
|
3124
|
+
for (const suffix of SQLITE_SIDECAR_SUFFIXES) {
|
|
3125
|
+
if (!relPath.endsWith(suffix)) continue;
|
|
3126
|
+
const db = relPath.slice(0, -suffix.length);
|
|
3127
|
+
return SQLITE_DATABASE_SUFFIXES.some((dbSuffix) => db.endsWith(dbSuffix)) ? db : null;
|
|
3128
|
+
}
|
|
3129
|
+
return null;
|
|
3130
|
+
}
|
|
3131
|
+
/** A SQLite database file, or a sidecar of one. */
|
|
3132
|
+
function isSqlitePath(relPath) {
|
|
3133
|
+
const db = databaseOfSidecar(relPath) ?? relPath;
|
|
3134
|
+
return SQLITE_DATABASE_SUFFIXES.some((suffix) => db.endsWith(suffix));
|
|
3135
|
+
}
|
|
3061
3136
|
/** Path of the manifest file embedded inside every archive. */
|
|
3062
3137
|
var ARCHIVE_MANIFEST_NAME = ".camstack-backup-manifest.json";
|
|
3063
3138
|
var DEFAULT_STAT_CACHE_TTL_MS = 6e4;
|
|
@@ -3153,28 +3228,75 @@ var SystemBackupService = class {
|
|
|
3153
3228
|
}
|
|
3154
3229
|
if (present.length === 0) throw new Error(`createArchive: no locations from {${requested.join(", ")}} exist under ${this.dataDir}`);
|
|
3155
3230
|
fs.mkdirSync(path$1.dirname(opts.archivePath), { recursive: true });
|
|
3156
|
-
const
|
|
3231
|
+
const walked = [];
|
|
3157
3232
|
for (const loc of present) {
|
|
3158
3233
|
throwIfCancelled(opts.signal);
|
|
3159
3234
|
const abs = path$1.join(this.dataDir, loc);
|
|
3160
3235
|
const stat = await fsp.stat(abs);
|
|
3161
|
-
if (stat.isDirectory()) for (const e of await walkAbs(abs, this.dataDir, this.exclusionPredicate(), opts.signal))
|
|
3162
|
-
else
|
|
3236
|
+
if (stat.isDirectory()) for (const e of await walkAbs(abs, this.dataDir, this.exclusionPredicate(), opts.signal)) walked.push(e);
|
|
3237
|
+
else if (!isExcludedFromBackup(path$1.relative(this.dataDir, abs))) walked.push(toArchiveEntry(abs, this.dataDir, stat));
|
|
3238
|
+
}
|
|
3239
|
+
const walkedPaths = new Set(walked.map((e) => e.path));
|
|
3240
|
+
const owned = walked.some((e) => isSqlitePath(e.path)) ? await this.ownedDatabasesInScope(opts.owner, walkedPaths) : /* @__PURE__ */ new Set();
|
|
3241
|
+
const unowned = /* @__PURE__ */ new Set();
|
|
3242
|
+
for (const e of walked) {
|
|
3243
|
+
const db = databaseOfSidecar(e.path);
|
|
3244
|
+
if (db !== null && !owned.has(db)) unowned.add(db);
|
|
3245
|
+
}
|
|
3246
|
+
if (unowned.size > 0) {
|
|
3247
|
+
const databases = [...unowned].sort();
|
|
3248
|
+
this.logger.error("createArchive: a live SQLite database has no owner snapshot — no archive built", { meta: {
|
|
3249
|
+
databases,
|
|
3250
|
+
archivePath: opts.archivePath
|
|
3251
|
+
} });
|
|
3252
|
+
throw new BackupSnapshotRefusedError(`live SQLite database ${databases.join(", ")} has no owner that can snapshot it — a copy of its files would be torn; remove its stale -wal/-shm/-journal if nothing has it open, or leave its location out of the backup`);
|
|
3163
3253
|
}
|
|
3164
|
-
const
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3254
|
+
const snapshot = owned.size > 0 && opts.owner ? await this.takeOwnerSnapshot(opts.owner, owned, opts.signal) : null;
|
|
3255
|
+
try {
|
|
3256
|
+
const liveFiles = /* @__PURE__ */ new Set();
|
|
3257
|
+
for (const db of owned) {
|
|
3258
|
+
liveFiles.add(db);
|
|
3259
|
+
for (const suffix of SQLITE_SIDECAR_SUFFIXES) liveFiles.add(db + suffix);
|
|
3260
|
+
}
|
|
3261
|
+
const entries = walked.filter((e) => !liveFiles.has(e.path));
|
|
3262
|
+
if (snapshot !== null) entries.push(snapshot.entry);
|
|
3263
|
+
const manifest = {
|
|
3264
|
+
archiveVersion: 1,
|
|
3265
|
+
createdAt: Date.now(),
|
|
3266
|
+
dataDir: this.dataDir,
|
|
3267
|
+
locations: present,
|
|
3268
|
+
entries,
|
|
3269
|
+
totalBytes: entries.reduce((acc, e) => acc + e.sizeBytes, 0),
|
|
3270
|
+
totalFiles: entries.filter((e) => e.kind === "file").length,
|
|
3271
|
+
...snapshot !== null ? { sqliteSnapshots: [snapshot.archived] } : {}
|
|
3272
|
+
};
|
|
3273
|
+
const carriedSnapshot = snapshot?.archived.snapshotPath ?? null;
|
|
3274
|
+
return await this.writeArchive({
|
|
3275
|
+
archivePath: opts.archivePath,
|
|
3276
|
+
present,
|
|
3277
|
+
manifest,
|
|
3278
|
+
excluded: (rel) => {
|
|
3279
|
+
if (rel === carriedSnapshot) return false;
|
|
3280
|
+
return liveFiles.has(rel) || isExcludedFromBackup(rel);
|
|
3281
|
+
},
|
|
3282
|
+
...opts.signal ? { signal: opts.signal } : {},
|
|
3283
|
+
...opts.onArchiveBytes ? { onArchiveBytes: opts.onArchiveBytes } : {}
|
|
3284
|
+
});
|
|
3285
|
+
} finally {
|
|
3286
|
+
if (snapshot !== null) await this.removeSnapshot(snapshot.absPath);
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
/**
|
|
3290
|
+
* Tar `present` (filtered by `excluded`) plus the staged manifest into
|
|
3291
|
+
* `archivePath`.
|
|
3292
|
+
*/
|
|
3293
|
+
async writeArchive(opts) {
|
|
3294
|
+
const { present, manifest } = opts;
|
|
3173
3295
|
const manifestStagePath = `${opts.archivePath}.${process.pid}.manifest.json`;
|
|
3174
3296
|
fs.writeFileSync(manifestStagePath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
3175
3297
|
this.logger.info("createArchive: tarring", { meta: {
|
|
3176
3298
|
archivePath: opts.archivePath,
|
|
3177
|
-
locations: present,
|
|
3299
|
+
locations: [...present],
|
|
3178
3300
|
totalFiles: manifest.totalFiles,
|
|
3179
3301
|
totalBytes: manifest.totalBytes
|
|
3180
3302
|
} });
|
|
@@ -3190,8 +3312,8 @@ var SystemBackupService = class {
|
|
|
3190
3312
|
follow: true,
|
|
3191
3313
|
portable: true,
|
|
3192
3314
|
filter: (entryPath) => {
|
|
3193
|
-
const norm = entryPath
|
|
3194
|
-
if (
|
|
3315
|
+
const norm = normalizeArchivePath(entryPath);
|
|
3316
|
+
if (opts.excluded(norm)) return false;
|
|
3195
3317
|
if (!excludePrefix) return true;
|
|
3196
3318
|
return norm !== excludePrefix && !norm.startsWith(`${excludePrefix}/`);
|
|
3197
3319
|
}
|
|
@@ -3219,7 +3341,7 @@ var SystemBackupService = class {
|
|
|
3219
3341
|
const sizeBytes = fs.statSync(opts.archivePath).size;
|
|
3220
3342
|
return {
|
|
3221
3343
|
archivePath: opts.archivePath,
|
|
3222
|
-
includedLocations: present,
|
|
3344
|
+
includedLocations: [...present],
|
|
3223
3345
|
sizeBytes,
|
|
3224
3346
|
manifest
|
|
3225
3347
|
};
|
|
@@ -3272,41 +3394,11 @@ var SystemBackupService = class {
|
|
|
3272
3394
|
});
|
|
3273
3395
|
}
|
|
3274
3396
|
/**
|
|
3275
|
-
* Extract a previously-created archive over `targetDir`. Used at boot
|
|
3276
|
-
* by the restore hook — never call from a running server (would
|
|
3277
|
-
* corrupt sqlite mid-run).
|
|
3278
|
-
*
|
|
3279
|
-
* `locations` is an optional whitelist: only entries whose path
|
|
3280
|
-
* starts with one of the locations get extracted. Used by the
|
|
3281
|
-
* partial-restore flow where the operator picks a subset of the
|
|
3282
|
-
* archive contents to apply (e.g. "restore my devices but keep
|
|
3283
|
-
* my current TLS certs").
|
|
3284
|
-
*/
|
|
3285
|
-
async extractArchive(opts) {
|
|
3286
|
-
if (!fs.existsSync(opts.archivePath)) throw new Error(`extractArchive: ${opts.archivePath} does not exist`);
|
|
3287
|
-
fs.mkdirSync(opts.targetDir, { recursive: true });
|
|
3288
|
-
this.logger.info("extractArchive: untarring", { meta: {
|
|
3289
|
-
archivePath: opts.archivePath,
|
|
3290
|
-
targetDir: opts.targetDir,
|
|
3291
|
-
locations: opts.locations
|
|
3292
|
-
} });
|
|
3293
|
-
const allowedPrefixes = opts.locations ? opts.locations.map(normalizeLocation) : null;
|
|
3294
|
-
await uo({
|
|
3295
|
-
file: opts.archivePath,
|
|
3296
|
-
cwd: opts.targetDir,
|
|
3297
|
-
filter: (p) => {
|
|
3298
|
-
if (p === ".camstack-backup-manifest.json" || p === `./.camstack-backup-manifest.json`) return false;
|
|
3299
|
-
if (!allowedPrefixes) return true;
|
|
3300
|
-
const normalized = p.replace(/^\.\//, "");
|
|
3301
|
-
return allowedPrefixes.some((prefix) => entryMatchesLocation(normalized, prefix));
|
|
3302
|
-
}
|
|
3303
|
-
});
|
|
3304
|
-
}
|
|
3305
|
-
/**
|
|
3306
3397
|
* Schedule a restore for the next boot by writing a marker file.
|
|
3307
|
-
* `locations` (optional) carries through to the boot-time
|
|
3308
|
-
*
|
|
3309
|
-
* choice survives the process
|
|
3398
|
+
* `locations` (optional) carries through to the launcher's boot-time
|
|
3399
|
+
* restore (`server/backend/src/launcher.ts`, the only restore there is)
|
|
3400
|
+
* so the operator's "restore only X and Y" choice survives the process
|
|
3401
|
+
* restart.
|
|
3310
3402
|
*/
|
|
3311
3403
|
scheduleRestoreMarker(opts) {
|
|
3312
3404
|
if (!fs.existsSync(opts.archivePath)) throw new Error(`scheduleRestoreMarker: ${opts.archivePath} missing`);
|
|
@@ -3339,6 +3431,117 @@ var SystemBackupService = class {
|
|
|
3339
3431
|
const markerPath = this.getRestoreMarkerPath();
|
|
3340
3432
|
if (fs.existsSync(markerPath)) fs.rmSync(markerPath, { force: true });
|
|
3341
3433
|
}
|
|
3434
|
+
/**
|
|
3435
|
+
* The databases the owner declares, archive-relative, that this walk found.
|
|
3436
|
+
* One outside this data root is not in scope. An owner that cannot answer
|
|
3437
|
+
* stops the archive: without the answer, nothing says which file is live.
|
|
3438
|
+
*/
|
|
3439
|
+
async ownedDatabasesInScope(owner, walked) {
|
|
3440
|
+
if (owner === void 0) return /* @__PURE__ */ new Set();
|
|
3441
|
+
let declared;
|
|
3442
|
+
try {
|
|
3443
|
+
declared = await owner.listDatabases();
|
|
3444
|
+
} catch (err) {
|
|
3445
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
3446
|
+
this.logger.error("createArchive: the database owner did not say what it owns — no archive built", { meta: { error: reason } });
|
|
3447
|
+
throw new BackupSnapshotRefusedError(`the database owner could not be asked: ${reason}`);
|
|
3448
|
+
}
|
|
3449
|
+
const inScope = /* @__PURE__ */ new Set();
|
|
3450
|
+
for (const abs of declared) {
|
|
3451
|
+
const rel = this.archiveRelative(abs);
|
|
3452
|
+
if (rel !== null && walked.has(rel)) inScope.add(rel);
|
|
3453
|
+
}
|
|
3454
|
+
return inScope;
|
|
3455
|
+
}
|
|
3456
|
+
/**
|
|
3457
|
+
* Ask the owner for its snapshot, and place it in this archive. The snapshot
|
|
3458
|
+
* must sit on THIS data root — the call is pinned to this node, so a path
|
|
3459
|
+
* elsewhere means it reached another host, and that file is not ours to
|
|
3460
|
+
* read — beside an owned database in scope, and it must cover EVERY owned
|
|
3461
|
+
* database in scope. Anything else is refused.
|
|
3462
|
+
*
|
|
3463
|
+
* Only ever DELETED here: `<owned db>.backup-snapshot` under this data root,
|
|
3464
|
+
* a name this process derives itself. A path the owner ANSWERS is never
|
|
3465
|
+
* deleted on its word — answering the live database as the snapshot would
|
|
3466
|
+
* otherwise delete the live database. A file at any other path is left to
|
|
3467
|
+
* the owner's own sweep.
|
|
3468
|
+
*
|
|
3469
|
+
* A cancel is honoured while the owner is still copying; the copy it may
|
|
3470
|
+
* finish afterwards is removed when that call settles.
|
|
3471
|
+
*/
|
|
3472
|
+
async takeOwnerSnapshot(owner, owned, signal) {
|
|
3473
|
+
const removeOwnedSnapshots = async () => {
|
|
3474
|
+
for (const db of owned) await this.removeSnapshot(path$1.join(this.dataDir, db + DATABASE_SNAPSHOT_SUFFIX));
|
|
3475
|
+
};
|
|
3476
|
+
let result;
|
|
3477
|
+
try {
|
|
3478
|
+
result = await raceAbort(owner.writeSnapshot(), signal, () => {
|
|
3479
|
+
this.logger.info("createArchive: run cancelled while the owner copied — its copy is removed when it lands", { meta: { databases: [...owned] } });
|
|
3480
|
+
return removeOwnedSnapshots();
|
|
3481
|
+
});
|
|
3482
|
+
} catch (err) {
|
|
3483
|
+
if (err instanceof BackupCancelledError) throw err;
|
|
3484
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
3485
|
+
this.logger.error("createArchive: the owner could not snapshot its live database — no archive built", { meta: {
|
|
3486
|
+
databases: [...owned],
|
|
3487
|
+
error: reason
|
|
3488
|
+
} });
|
|
3489
|
+
await removeOwnedSnapshots();
|
|
3490
|
+
throw new BackupSnapshotRefusedError(reason);
|
|
3491
|
+
}
|
|
3492
|
+
try {
|
|
3493
|
+
const livePath = this.archiveRelative(result.livePath);
|
|
3494
|
+
const snapshotPath = this.archiveRelative(result.snapshotPath);
|
|
3495
|
+
if (livePath === null || snapshotPath === null) {
|
|
3496
|
+
this.logger.warn("createArchive: the owner answered a snapshot outside this data root — not touched, left to its sweep", { meta: {
|
|
3497
|
+
snapshot: result.snapshotPath,
|
|
3498
|
+
dataDir: this.dataDir
|
|
3499
|
+
} });
|
|
3500
|
+
throw new BackupSnapshotRefusedError(`snapshot ${result.snapshotPath} is not under this archive's data root ${this.dataDir}`);
|
|
3501
|
+
}
|
|
3502
|
+
if (snapshotPath !== livePath + ".backup-snapshot") throw new BackupSnapshotRefusedError(`snapshot ${snapshotPath} does not sit beside the database ${livePath} it copies`);
|
|
3503
|
+
const uncovered = [...owned].filter((db) => db !== livePath);
|
|
3504
|
+
if (!owned.has(livePath) || uncovered.length > 0) throw new BackupSnapshotRefusedError(`snapshot copies ${livePath}, but the owned database(s) in this archive are ${[...owned].join(", ")}`);
|
|
3505
|
+
const absPath = path$1.join(this.dataDir, snapshotPath);
|
|
3506
|
+
const stat = await fsp.stat(absPath);
|
|
3507
|
+
this.logger.info("createArchive: carrying the owner snapshot in place of the live database", { meta: {
|
|
3508
|
+
database: livePath,
|
|
3509
|
+
snapshot: snapshotPath,
|
|
3510
|
+
sizeBytes: stat.size,
|
|
3511
|
+
tables: result.tables.length,
|
|
3512
|
+
copyMs: result.copyMs,
|
|
3513
|
+
verifyMs: result.verifyMs
|
|
3514
|
+
} });
|
|
3515
|
+
return {
|
|
3516
|
+
absPath,
|
|
3517
|
+
archived: {
|
|
3518
|
+
...result,
|
|
3519
|
+
livePath,
|
|
3520
|
+
snapshotPath
|
|
3521
|
+
},
|
|
3522
|
+
entry: toArchiveEntry(absPath, this.dataDir, stat)
|
|
3523
|
+
};
|
|
3524
|
+
} catch (err) {
|
|
3525
|
+
await removeOwnedSnapshots();
|
|
3526
|
+
throw err;
|
|
3527
|
+
}
|
|
3528
|
+
}
|
|
3529
|
+
async removeSnapshot(absPath) {
|
|
3530
|
+
try {
|
|
3531
|
+
await fsp.rm(absPath, { force: true });
|
|
3532
|
+
} catch (err) {
|
|
3533
|
+
this.logger.warn("createArchive: owner snapshot could not be removed", { meta: {
|
|
3534
|
+
snapshot: absPath,
|
|
3535
|
+
error: err instanceof Error ? err.message : String(err)
|
|
3536
|
+
} });
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
/** `abs` relative to the data root, or null when it lies outside it. */
|
|
3540
|
+
archiveRelative(abs) {
|
|
3541
|
+
const rel = path$1.relative(path$1.resolve(this.dataDir), path$1.resolve(abs));
|
|
3542
|
+
if (rel.length === 0 || rel.startsWith("..") || path$1.isAbsolute(rel)) return null;
|
|
3543
|
+
return normalizeArchivePath(rel);
|
|
3544
|
+
}
|
|
3342
3545
|
getRestoreMarkerPath() {
|
|
3343
3546
|
return path$1.join(this.dataDir, ".pending-restore.json");
|
|
3344
3547
|
}
|
|
@@ -3405,23 +3608,6 @@ function toArchiveEntry(abs, dataDir, stat) {
|
|
|
3405
3608
|
mtime: stat.mtimeMs
|
|
3406
3609
|
};
|
|
3407
3610
|
}
|
|
3408
|
-
/**
|
|
3409
|
-
* Strip leading `./` and trailing `/` so location prefix matching is
|
|
3410
|
-
* order-of-comparison invariant. Same shape on both sides of the
|
|
3411
|
-
* `entry.path.startsWith(prefix)` test in the extract filter.
|
|
3412
|
-
*/
|
|
3413
|
-
function normalizeLocation(loc) {
|
|
3414
|
-
return loc.replace(/^\.\//, "").replace(/\/+$/, "");
|
|
3415
|
-
}
|
|
3416
|
-
/**
|
|
3417
|
-
* Match an archive entry path against a location whitelist prefix.
|
|
3418
|
-
* `addons` matches `addons` (file) and `addons/foo/bar.txt` (path
|
|
3419
|
-
* inside the dir). The trailing `/` test is what prevents `addons`
|
|
3420
|
-
* from spuriously matching `addons-data`.
|
|
3421
|
-
*/
|
|
3422
|
-
function entryMatchesLocation(entryPath, prefix) {
|
|
3423
|
-
return entryPath === prefix || entryPath.startsWith(`${prefix}/`);
|
|
3424
|
-
}
|
|
3425
3611
|
//#endregion
|
|
3426
3612
|
//#region ../../node_modules/croner/dist/croner.js
|
|
3427
3613
|
function T(s) {
|
|
@@ -5698,12 +5884,22 @@ var BackupOrchestratorAddon = class extends BaseAddon {
|
|
|
5698
5884
|
const archiveId = randomUUID();
|
|
5699
5885
|
const archiveFilename = `${archiveId}.tar.gz`;
|
|
5700
5886
|
const cachePath = await this.stagingPath(archiveFilename);
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5887
|
+
let result;
|
|
5888
|
+
try {
|
|
5889
|
+
result = await this.systemBackup.createArchive({
|
|
5890
|
+
archivePath: cachePath,
|
|
5891
|
+
...input.locations ? { locations: [...input.locations] } : {},
|
|
5892
|
+
signal,
|
|
5893
|
+
onArchiveBytes: (bytes) => progress.setStagedBytes(bytes),
|
|
5894
|
+
owner: this.databaseOwner()
|
|
5895
|
+
});
|
|
5896
|
+
} catch (err) {
|
|
5897
|
+
if (err instanceof BackupSnapshotRefusedError) for (const dest of targets) {
|
|
5898
|
+
progress.destinationFailed(dest.id);
|
|
5899
|
+
await this.recordDestinationOutcome(dest.id, Date.now(), err.message);
|
|
5900
|
+
}
|
|
5901
|
+
throw err;
|
|
5902
|
+
}
|
|
5707
5903
|
progress.setArchiveSize(result.sizeBytes);
|
|
5708
5904
|
progress.setPhase("uploading");
|
|
5709
5905
|
try {
|
|
@@ -5784,6 +5980,25 @@ var BackupOrchestratorAddon = class extends BaseAddon {
|
|
|
5784
5980
|
}
|
|
5785
5981
|
}
|
|
5786
5982
|
/**
|
|
5983
|
+
* THIS node's database owner (D693), reached through `database-snapshot`
|
|
5984
|
+
* pinned to the local node: the paths it answers must be on this host,
|
|
5985
|
+
* because this process archives them. No local node id means no pin, and an
|
|
5986
|
+
* unpinned singleton call could be answered by another host — refuse.
|
|
5987
|
+
*/
|
|
5988
|
+
databaseOwner() {
|
|
5989
|
+
const pin = () => {
|
|
5990
|
+
const localNodeId = this.ctx.kernel.localNodeId;
|
|
5991
|
+
if (localNodeId === void 0 || localNodeId.length === 0) throw new Error("no local node id — the database owner cannot be pinned to this host");
|
|
5992
|
+
return nodePin(toNodeId(localNodeId));
|
|
5993
|
+
};
|
|
5994
|
+
return {
|
|
5995
|
+
listDatabases: async () => {
|
|
5996
|
+
return (await this.ctx.api.databaseSnapshot.listDatabases.query({}, pin())).databases.map((d) => d.livePath);
|
|
5997
|
+
},
|
|
5998
|
+
writeSnapshot: async () => this.ctx.api.databaseSnapshot.writeSnapshot.mutate({}, pin())
|
|
5999
|
+
};
|
|
6000
|
+
}
|
|
6001
|
+
/**
|
|
5787
6002
|
* Push the staged archive to a single destination via chunked
|
|
5788
6003
|
* upload, then update the per-location manifest. Applies the
|
|
5789
6004
|
* destination's retention policy as part of the same lock-protected
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bx4zxM9N.js");
|
|
7
7
|
let zod = require("zod");
|
|
8
8
|
let _camstack_types_node = require("@camstack/types/node");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $t as motionCapability, Fn as buildFfmpegArgs, O as MOTION_CLOSE_AFTER_MS, Q as cameraGridLayoutCapability, Sr as EventCategory, Xn as errMsg, Xt as memoizePinnedFfmpeg, Yn as DeviceType, Zn as BaseAddon, _ as DERIVED_CAMERA_SILENCED_CAP_NAMES, dr as hydrateSchema, dt as declarationOwnerNodeId, i as BaseDevice, qn as DeviceFeature, sr as createEvent, v as DeclaredDevices, wn as streamCatalogCapability, yn as snapshotCapability } from "../../dist-Dp043AI0.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { FfmpegProcess } from "@camstack/types/node";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bx4zxM9N.js");
|
|
7
7
|
const require_device_state_changed = require("../../device-state-changed-Bk7cvTnz.js");
|
|
8
|
-
const require_composition_sources = require("../../composition-sources-
|
|
8
|
+
const require_composition_sources = require("../../composition-sources-2XxNEet3.js");
|
|
9
9
|
//#region src/builtins/composer/composed-device.ts
|
|
10
10
|
/**
|
|
11
11
|
* A composed device: an ordinary `BaseDevice` whose caps are served by the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Bn as compositionItemFieldPath, Hn as compositionSourceKey, In as cloneStatefulExpressionMemory, Kn as toExpressionValue, Ln as composedDeviceRef, Mn as COMPOSER_ADDON_ID, Rn as composedDeviceStableId, Sr as EventCategory, Tt as evaluateCompositionField, Un as createStatefulExpressionMemory, Vn as compositionSliceKey, Xn as errMsg, Y as buildCapabilityLookup, Yn as DeviceType, Zn as BaseAddon, c as COMPOSED_ITEM_FIXED_FIELDS, et as composerCapability, i as BaseDevice, in as planComposition, sr as createEvent, t as ALL_CAPABILITY_DEFINITIONS, tt as compositionFieldKey, v as DeclaredDevices, zn as compositionFeatureEnabled } from "../../dist-Dp043AI0.mjs";
|
|
2
2
|
import { n as parseDeviceStateChanged, t as isRecord$2 } from "../../device-state-changed-DoBbkyEI.mjs";
|
|
3
|
-
import { n as normalizedNativeOwner } from "../../composition-sources-
|
|
3
|
+
import { n as normalizedNativeOwner } from "../../composition-sources-Wj2kWund.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/builtins/composer/composed-device.ts
|
|
6
6
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bx4zxM9N.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/console-logging/console-destination.ts
|
|
9
9
|
var LEVEL_RANK = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Gt as logDestinationCapability, Zn as BaseAddon } from "../../dist-Dp043AI0.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/console-logging/console-destination.ts
|
|
4
4
|
var LEVEL_RANK = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
4
|
-
const require_composition_sources = require("../../composition-sources-
|
|
3
|
+
const require_dist = require("../../dist-Bx4zxM9N.js");
|
|
4
|
+
const require_composition_sources = require("../../composition-sources-2XxNEet3.js");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
6
6
|
let _camstack_types_node = require("@camstack/types/node");
|
|
7
7
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as describeCompositionSources } from "../../composition-sources-
|
|
1
|
+
import { Dn as validateComposition, Hn as compositionSourceKey, Ln as composedDeviceRef, Xn as errMsg, Y as buildCapabilityLookup, Zn as BaseAddon, at as coreBlockIdFromAddonId, d as CORE_BLOCK_ADDON_PREFIX, f as CoreBlockSchema, ht as describeComposableCaps, in as planComposition, it as coreBlockComposition, l as COMPOSER_RUNNER_ID, ln as replacedFieldKeys, nt as compositionSourceRefs, ot as coreBlockSourceKind, rt as coreBlockAddonId, st as coreBlocksCapability, t as ALL_CAPABILITY_DEFINITIONS, u as CORE_BLOCKS_ADDON_ID, v as DeclaredDevices } from "../../dist-Dp043AI0.mjs";
|
|
2
|
+
import { t as describeCompositionSources } from "../../composition-sources-Wj2kWund.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { customizationBlockName } from "@camstack/types/node";
|
|
5
5
|
import * as fs from "node:fs/promises";
|
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
7
|
-
const require_retired_settings_keys = require("../../retired-settings-keys-
|
|
6
|
+
const require_dist = require("../../dist-Bx4zxM9N.js");
|
|
7
|
+
const require_retired_settings_keys = require("../../retired-settings-keys-DR2WMe5d.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
10
10
|
let _camstack_types_node = require("@camstack/types/node");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-
|
|
1
|
+
import { Bt as legacyAutoLinkIds, Ct as enumerateItemArrayFields, D as MINUTES_PER_DAY, Dt as expandContainer, Jn as DeviceRole, P as STREAM_PROFILE_META, S as FieldClaimSchema, Sr as EventCategory, T as LocationIconIdSchema, Wt as locationIconKey, Xn as errMsg, Yn as DeviceType, Z as buildStreamParamsConfigSchema, Zn as BaseAddon, _t as deviceManagerCapability, br as sleep$1, ct as createDeviceExtensionProvider, en as normalizeUnit, fr as isDeviceConfigCap, g as DAY_NAMES, gt as deviceExtensionCapability, jt as formatMinutes, o as CAMERA_SWITCH_ORDER, pn as runtimeStatePolicyFor, pt as defineExtensionSlotProvider, qn as DeviceFeature, rn as parseStreamParamsFormPatch, rr as WELL_KNOWN_TAB_MAP, s as CAP_NAMES_WITH_STATUS, t as ALL_CAPABILITY_DEFINITIONS, vn as siteZoneKey, vt as deviceStateCapability, wt as enumerateSchemaFields, x as FieldClaimModeSchema, y as DeviceStatusSchema, yt as deviceStatusCapability } from "../../dist-Dp043AI0.mjs";
|
|
2
|
+
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-Dxf9vELs.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bx4zxM9N.js");
|
|
7
7
|
const require_device_state_changed = require("../../device-state-changed-Bk7cvTnz.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Gn as isSourceCap, Lt as isSameAddonId, Pn as SOURCE_CAPS, Sr as EventCategory, Wn as evaluateSensorEdge, X as buildDoorbellCompositionFeature, Xn as errMsg, Yn as DeviceType, Zn as BaseAddon, bt as doorbellCapability, ct as createDeviceExtensionProvider, gt as deviceExtensionCapability, pt as defineExtensionSlotProvider, q as bareAddonId, sr as createEvent, xt as doorbellFeatureSources } from "../../dist-Dp043AI0.mjs";
|
|
2
2
|
import { n as parseDeviceStateChanged } from "../../device-state-changed-DoBbkyEI.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bx4zxM9N.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Gt as logDestinationCapability, Zn as BaseAddon } from "../../dist-Dp043AI0.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-Bx4zxM9N.js");
|
|
4
4
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
5
5
|
var NO_DEVICES = "liveness:no-devices";
|
|
6
6
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { M as RecordingStatusSchema, Sr as EventCategory, Xn as errMsg, Zn as BaseAddon, k as RECORDING_SOURCE_CAMSTACK_ADDON, sr as createEvent } from "../../dist-Dp043AI0.mjs";
|
|
2
2
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
3
3
|
var NO_DEVICES = "liveness:no-devices";
|
|
4
4
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -3,7 +3,7 @@ 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-Bx4zxM9N.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
9
9
|
let crypto$1 = require("crypto");
|