@camstack/addon-pipeline 1.2.125 → 1.2.127
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/detection-pipeline/index.js +1 -1
- package/dist/detection-pipeline/index.mjs +1 -1
- package/dist/{lazy-sharp-6oymT_yf.mjs → lazy-sharp-BtT5x-qP.mjs} +37 -4
- package/dist/{lazy-sharp-BxMwCkCA.js → lazy-sharp-DTDXrhMG.js} +37 -4
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +1 -1
- package/dist/pipeline-runner/index.mjs +1 -1
- package/dist/recorder/index.js +69 -63
- package/dist/recorder/index.mjs +69 -63
- package/dist/session-decode/decode-worker-child.js +1 -1
- package/dist/session-decode/decode-worker-child.mjs +1 -1
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ Object.defineProperties(exports, {
|
|
|
4
4
|
});
|
|
5
5
|
const require_dist = require("../dist-BZUXb5S5.js");
|
|
6
6
|
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-BdArVUlx.js");
|
|
7
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
7
|
+
const require_lazy_sharp = require("../lazy-sharp-DTDXrhMG.js");
|
|
8
8
|
const require_process_memory = require("../process-memory-Dh1SyzdJ.js");
|
|
9
9
|
const require_addon_utils = require("../addon-utils-BnprivSs.js");
|
|
10
10
|
let sharp = require("sharp");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as __require } from "../chunk-DnnnRqeS.mjs";
|
|
2
2
|
import { $ as pickClusterStepModels, D as YAMNET_TO_MACRO, Dt as hydrateSchema, Et as createEvent, Ft as sleep, G as evaluateZoneRules, Gt as string, I as defaultDeviceFor$1, Kt as union, Lt as array, Mt as parseJsonUnknown, St as BaseAddon, Ut as object, V as detectionPipelineCapability, W as enumerateInferenceDevices, Z as overlayClusterStepSettings, c as DEFAULT_CLUSTER_STEP_MODELS, dt as runtimeDevices$1, et as pickClusterStepSettings, gt as errMsg, jt as nodePin, l as DEFAULT_CLUSTER_STEP_SETTINGS, lt as resolvePoolMemoryPolicy, mt as supportedRuntimes$1, p as DEVICE_BACKEND_TO_FORMAT, q as inferModelProvider, qt as EventCategory, rt as pipelineExecutorCapability, st as resolveClusterStepModelId, t as APPLE_SA_TO_MACRO, x as PoolMemoryWatchdog } from "../dist-HLAOw6Pe.mjs";
|
|
3
3
|
import { a as ALL_PIPELINE_STEPS, c as getDefaultModelForFormatFromDef, d as resolveModelForFormat, f as landmarkPrecisionVerdict, l as getStep, n as startEventLoopStallMonitor, o as ALL_STEPS, r as localFrameRegistry, s as getDefaultModelForFormat, u as getStepDefinition } from "../event-loop-stall-monitor-BH-cL_hg.mjs";
|
|
4
|
-
import { t as getSharp } from "../lazy-sharp-
|
|
4
|
+
import { t as getSharp } from "../lazy-sharp-BtT5x-qP.mjs";
|
|
5
5
|
import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-CDPRLalN.mjs";
|
|
6
6
|
import { a as ensureModel, o as isModelDownloaded, r as deleteModelFromDisk } from "../addon-utils-CgBCF-mE.mjs";
|
|
7
7
|
import sharp from "sharp";
|
|
@@ -47,9 +47,10 @@ import * as path$1 from "node:path";
|
|
|
47
47
|
* `CAMSTACK_FRAMEWORK_DIR` (`<frameworkDir>/node_modules/<pkg>`). The
|
|
48
48
|
* launcher points this at the ACTIVE closure in data-root mode and forked
|
|
49
49
|
* children inherit it (`server/backend/src/launcher.ts`).
|
|
50
|
-
* - **ELECTRON agent** — the app bundle
|
|
51
|
-
* (`<resources>/
|
|
52
|
-
* `app.asar.unpacked`
|
|
50
|
+
* - **ELECTRON agent** — the app bundle around `CAMSTACK_BUNDLED_ADDONS_DIR`
|
|
51
|
+
* (`<resources>/node_modules/@camstack` since 2026-08-25, `<resources>/addons`
|
|
52
|
+
* before it): `<resources>/node_modules/<pkg>` and the `app.asar.unpacked`
|
|
53
|
+
* mirror. See {@link electronResourcesRoot} — the depth is NOT assumed.
|
|
53
54
|
* - **the process cwd** — always tried last, and it is NOT redundant:
|
|
54
55
|
* `CAMSTACK_FRAMEWORK_DIR` is only exported on some boots (the Docker
|
|
55
56
|
* entrypoint sets it in its fallback branch; the launcher only in data-root
|
|
@@ -108,6 +109,38 @@ function isModuleResolutionError(err) {
|
|
|
108
109
|
return err.message.includes("Cannot find package") || err.message.includes("Cannot find module");
|
|
109
110
|
}
|
|
110
111
|
/**
|
|
112
|
+
* Path segments that are containers on the way to a package dir, never the
|
|
113
|
+
* Electron `Resources` dir itself. Walking past them is what makes the anchor
|
|
114
|
+
* derivation independent of WHICH dir the shell chose to seed addons from.
|
|
115
|
+
*/
|
|
116
|
+
var SEED_CONTAINER_SEGMENTS = [
|
|
117
|
+
"@camstack",
|
|
118
|
+
"node_modules",
|
|
119
|
+
"addons"
|
|
120
|
+
];
|
|
121
|
+
/**
|
|
122
|
+
* The Electron `Contents/Resources` dir, derived from `CAMSTACK_BUNDLED_ADDONS_DIR`.
|
|
123
|
+
*
|
|
124
|
+
* That variable names the dir the launcher SEEDS addons from, and its shape has
|
|
125
|
+
* moved: it was `<resources>/addons` (a second, hand-copied tree) and is now
|
|
126
|
+
* `<resources>/node_modules/@camstack`, the closure's own scope dir — one copy
|
|
127
|
+
* (D45). What this function needs is neither: it needs the sibling
|
|
128
|
+
* `<resources>/node_modules`, where the hoisted `sharp` / `node-av` actually
|
|
129
|
+
* live. A plain `path.dirname` answered the first shape and would have silently
|
|
130
|
+
* answered `<resources>/node_modules/node_modules` for the second, losing both
|
|
131
|
+
* packages in every forked decode worker on a desktop agent. So: climb past the
|
|
132
|
+
* container segments instead of assuming a depth.
|
|
133
|
+
*/
|
|
134
|
+
function electronResourcesRoot(bundledAddonsDir) {
|
|
135
|
+
let dir = path$1.resolve(bundledAddonsDir);
|
|
136
|
+
while (SEED_CONTAINER_SEGMENTS.includes(path$1.basename(dir))) {
|
|
137
|
+
const parent = path$1.dirname(dir);
|
|
138
|
+
if (parent === dir) break;
|
|
139
|
+
dir = parent;
|
|
140
|
+
}
|
|
141
|
+
return dir;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
111
144
|
* The files a resolution is anchored at, in the order they are tried. Each is a
|
|
112
145
|
* path INSIDE a candidate `node_modules` (so `<dir>/node_modules/<pkg>` is on
|
|
113
146
|
* the walk), except the cwd anchor, which walks up from the cwd itself.
|
|
@@ -120,7 +153,7 @@ function hostExternalAnchors(env, cwd) {
|
|
|
120
153
|
if (frameworkDir !== void 0 && frameworkDir.length > 0) anchors.push(path$1.join(frameworkDir, "node_modules", ANCHOR_FILE));
|
|
121
154
|
const bundledAddons = env["CAMSTACK_BUNDLED_ADDONS_DIR"];
|
|
122
155
|
if (bundledAddons !== void 0 && bundledAddons.length > 0) {
|
|
123
|
-
const resourcesRoot =
|
|
156
|
+
const resourcesRoot = electronResourcesRoot(bundledAddons);
|
|
124
157
|
anchors.push(path$1.join(resourcesRoot, "node_modules", ANCHOR_FILE));
|
|
125
158
|
anchors.push(path$1.join(resourcesRoot, "app.asar.unpacked", "node_modules", ANCHOR_FILE));
|
|
126
159
|
}
|
|
@@ -49,9 +49,10 @@ node_path = require_dist.__toESM(node_path);
|
|
|
49
49
|
* `CAMSTACK_FRAMEWORK_DIR` (`<frameworkDir>/node_modules/<pkg>`). The
|
|
50
50
|
* launcher points this at the ACTIVE closure in data-root mode and forked
|
|
51
51
|
* children inherit it (`server/backend/src/launcher.ts`).
|
|
52
|
-
* - **ELECTRON agent** — the app bundle
|
|
53
|
-
* (`<resources>/
|
|
54
|
-
* `app.asar.unpacked`
|
|
52
|
+
* - **ELECTRON agent** — the app bundle around `CAMSTACK_BUNDLED_ADDONS_DIR`
|
|
53
|
+
* (`<resources>/node_modules/@camstack` since 2026-08-25, `<resources>/addons`
|
|
54
|
+
* before it): `<resources>/node_modules/<pkg>` and the `app.asar.unpacked`
|
|
55
|
+
* mirror. See {@link electronResourcesRoot} — the depth is NOT assumed.
|
|
55
56
|
* - **the process cwd** — always tried last, and it is NOT redundant:
|
|
56
57
|
* `CAMSTACK_FRAMEWORK_DIR` is only exported on some boots (the Docker
|
|
57
58
|
* entrypoint sets it in its fallback branch; the launcher only in data-root
|
|
@@ -110,6 +111,38 @@ function isModuleResolutionError(err) {
|
|
|
110
111
|
return err.message.includes("Cannot find package") || err.message.includes("Cannot find module");
|
|
111
112
|
}
|
|
112
113
|
/**
|
|
114
|
+
* Path segments that are containers on the way to a package dir, never the
|
|
115
|
+
* Electron `Resources` dir itself. Walking past them is what makes the anchor
|
|
116
|
+
* derivation independent of WHICH dir the shell chose to seed addons from.
|
|
117
|
+
*/
|
|
118
|
+
var SEED_CONTAINER_SEGMENTS = [
|
|
119
|
+
"@camstack",
|
|
120
|
+
"node_modules",
|
|
121
|
+
"addons"
|
|
122
|
+
];
|
|
123
|
+
/**
|
|
124
|
+
* The Electron `Contents/Resources` dir, derived from `CAMSTACK_BUNDLED_ADDONS_DIR`.
|
|
125
|
+
*
|
|
126
|
+
* That variable names the dir the launcher SEEDS addons from, and its shape has
|
|
127
|
+
* moved: it was `<resources>/addons` (a second, hand-copied tree) and is now
|
|
128
|
+
* `<resources>/node_modules/@camstack`, the closure's own scope dir — one copy
|
|
129
|
+
* (D45). What this function needs is neither: it needs the sibling
|
|
130
|
+
* `<resources>/node_modules`, where the hoisted `sharp` / `node-av` actually
|
|
131
|
+
* live. A plain `path.dirname` answered the first shape and would have silently
|
|
132
|
+
* answered `<resources>/node_modules/node_modules` for the second, losing both
|
|
133
|
+
* packages in every forked decode worker on a desktop agent. So: climb past the
|
|
134
|
+
* container segments instead of assuming a depth.
|
|
135
|
+
*/
|
|
136
|
+
function electronResourcesRoot(bundledAddonsDir) {
|
|
137
|
+
let dir = node_path.resolve(bundledAddonsDir);
|
|
138
|
+
while (SEED_CONTAINER_SEGMENTS.includes(node_path.basename(dir))) {
|
|
139
|
+
const parent = node_path.dirname(dir);
|
|
140
|
+
if (parent === dir) break;
|
|
141
|
+
dir = parent;
|
|
142
|
+
}
|
|
143
|
+
return dir;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
113
146
|
* The files a resolution is anchored at, in the order they are tried. Each is a
|
|
114
147
|
* path INSIDE a candidate `node_modules` (so `<dir>/node_modules/<pkg>` is on
|
|
115
148
|
* the walk), except the cwd anchor, which walks up from the cwd itself.
|
|
@@ -122,7 +155,7 @@ function hostExternalAnchors(env, cwd) {
|
|
|
122
155
|
if (frameworkDir !== void 0 && frameworkDir.length > 0) anchors.push(node_path.join(frameworkDir, "node_modules", ANCHOR_FILE));
|
|
123
156
|
const bundledAddons = env["CAMSTACK_BUNDLED_ADDONS_DIR"];
|
|
124
157
|
if (bundledAddons !== void 0 && bundledAddons.length > 0) {
|
|
125
|
-
const resourcesRoot =
|
|
158
|
+
const resourcesRoot = electronResourcesRoot(bundledAddons);
|
|
126
159
|
anchors.push(node_path.join(resourcesRoot, "node_modules", ANCHOR_FILE));
|
|
127
160
|
anchors.push(node_path.join(resourcesRoot, "app.asar.unpacked", "node_modules", ANCHOR_FILE));
|
|
128
161
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_dist = require("../dist-BZUXb5S5.js");
|
|
6
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
6
|
+
const require_lazy_sharp = require("../lazy-sharp-DTDXrhMG.js");
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
//#region src/motion-wasm/wasm-motion-detector.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Dt as hydrateSchema, G as evaluateZoneRules, St as BaseAddon, Tt as DeviceType, X as motionDetectionCapability } from "../dist-HLAOw6Pe.mjs";
|
|
2
|
-
import { t as getSharp } from "../lazy-sharp-
|
|
2
|
+
import { t as getSharp } from "../lazy-sharp-BtT5x-qP.mjs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { readFileSync } from "node:fs";
|
|
5
5
|
//#region src/motion-wasm/wasm-motion-detector.ts
|
|
@@ -6,7 +6,7 @@ const require_dist = require("../dist-BZUXb5S5.js");
|
|
|
6
6
|
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-BdArVUlx.js");
|
|
7
7
|
const require_worker_protocol = require("../worker-protocol-BxkCoVjw.js");
|
|
8
8
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
9
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
9
|
+
const require_lazy_sharp = require("../lazy-sharp-DTDXrhMG.js");
|
|
10
10
|
const require_restream_intent = require("../restream-intent-Cv9x3jmu.js");
|
|
11
11
|
const require_remote_restream = require("../remote-restream-CO36Sr30.js");
|
|
12
12
|
let sharp = require("sharp");
|
|
@@ -2,7 +2,7 @@ import { Bt as lazy, Et as createEvent, F as customAction, Gt as string, Ht as n
|
|
|
2
2
|
import { i as resolveFrameViewGeometry, r as localFrameRegistry, t as attributeStall, u as getStepDefinition } from "../event-loop-stall-monitor-BH-cL_hg.mjs";
|
|
3
3
|
import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-h7Smb_0i.mjs";
|
|
4
4
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
5
|
-
import { t as getSharp } from "../lazy-sharp-
|
|
5
|
+
import { t as getSharp } from "../lazy-sharp-BtT5x-qP.mjs";
|
|
6
6
|
import { n as withDetectionIntent } from "../restream-intent-B4BXZra7.mjs";
|
|
7
7
|
import { n as profileForStreamId, t as isRemoteRestream } from "../remote-restream-BeHi78PZ.mjs";
|
|
8
8
|
import sharp from "sharp";
|
package/dist/recorder/index.js
CHANGED
|
@@ -3151,65 +3151,6 @@ function buildExportArgs(input) {
|
|
|
3151
3151
|
];
|
|
3152
3152
|
}
|
|
3153
3153
|
//#endregion
|
|
3154
|
-
//#region src/recorder/addon/export-timelapse-chunks.ts
|
|
3155
|
-
/** One hour of concatenated footage — not one hour of wall clock. */
|
|
3156
|
-
var TIMELAPSE_CHUNK_MS = 36e5;
|
|
3157
|
-
/**
|
|
3158
|
-
* Split a concat list into hour-sized chunks. A single file longer than the
|
|
3159
|
-
* chunk stays whole — it is already one open, and cutting it would need a
|
|
3160
|
-
* second demux we do not have.
|
|
3161
|
-
*/
|
|
3162
|
-
function splitTimelapseChunks(entries, chunkMs = TIMELAPSE_CHUNK_MS) {
|
|
3163
|
-
if (entries.length === 0) return [];
|
|
3164
|
-
const chunks = [];
|
|
3165
|
-
let current = [];
|
|
3166
|
-
let currentDur = 0;
|
|
3167
|
-
let streamStartMs = 0;
|
|
3168
|
-
for (const entry of entries) {
|
|
3169
|
-
if (current.length > 0 && currentDur + entry.durMs > chunkMs) {
|
|
3170
|
-
chunks.push({
|
|
3171
|
-
entries: current,
|
|
3172
|
-
streamStartMs
|
|
3173
|
-
});
|
|
3174
|
-
streamStartMs += currentDur;
|
|
3175
|
-
current = [];
|
|
3176
|
-
currentDur = 0;
|
|
3177
|
-
}
|
|
3178
|
-
current.push(entry);
|
|
3179
|
-
currentDur += entry.durMs;
|
|
3180
|
-
}
|
|
3181
|
-
if (current.length > 0) chunks.push({
|
|
3182
|
-
entries: current,
|
|
3183
|
-
streamStartMs
|
|
3184
|
-
});
|
|
3185
|
-
return chunks;
|
|
3186
|
-
}
|
|
3187
|
-
/**
|
|
3188
|
-
* Move stream-time dense ranges onto a chunk's own `t=0`. Ranges that miss
|
|
3189
|
-
* the chunk disappear; a range that straddles the edge is clipped. Empty →
|
|
3190
|
-
* `undefined` so the select stays the single-rate form.
|
|
3191
|
-
*/
|
|
3192
|
-
function denseRangesForChunk(dense, chunkStreamStartMs, chunkDurMs) {
|
|
3193
|
-
if (dense === void 0 || dense.ranges.length === 0) return void 0;
|
|
3194
|
-
const startSec = chunkStreamStartMs / 1e3;
|
|
3195
|
-
const endSec = (chunkStreamStartMs + chunkDurMs) / 1e3;
|
|
3196
|
-
const ranges = [];
|
|
3197
|
-
for (const r of dense.ranges) {
|
|
3198
|
-
const from = Math.max(r.fromSec, startSec);
|
|
3199
|
-
const to = Math.min(r.toSec, endSec);
|
|
3200
|
-
if (to <= from) continue;
|
|
3201
|
-
ranges.push({
|
|
3202
|
-
fromSec: from - startSec,
|
|
3203
|
-
toSec: to - startSec
|
|
3204
|
-
});
|
|
3205
|
-
}
|
|
3206
|
-
if (ranges.length === 0) return void 0;
|
|
3207
|
-
return {
|
|
3208
|
-
everyMs: dense.everyMs,
|
|
3209
|
-
ranges
|
|
3210
|
-
};
|
|
3211
|
-
}
|
|
3212
|
-
//#endregion
|
|
3213
3154
|
//#region src/recorder/addon/export-store.ts
|
|
3214
3155
|
/**
|
|
3215
3156
|
* Recording-export persistence for the recorder addon.
|
|
@@ -3371,6 +3312,65 @@ async function listExportsFor(state, deviceId) {
|
|
|
3371
3312
|
})).map((entry) => entry.value);
|
|
3372
3313
|
}
|
|
3373
3314
|
//#endregion
|
|
3315
|
+
//#region src/recorder/addon/export-timelapse-chunks.ts
|
|
3316
|
+
/** One hour of concatenated footage — not one hour of wall clock. */
|
|
3317
|
+
var TIMELAPSE_CHUNK_MS = 36e5;
|
|
3318
|
+
/**
|
|
3319
|
+
* Split a concat list into hour-sized chunks. A single file longer than the
|
|
3320
|
+
* chunk stays whole — it is already one open, and cutting it would need a
|
|
3321
|
+
* second demux we do not have.
|
|
3322
|
+
*/
|
|
3323
|
+
function splitTimelapseChunks(entries, chunkMs = TIMELAPSE_CHUNK_MS) {
|
|
3324
|
+
if (entries.length === 0) return [];
|
|
3325
|
+
const chunks = [];
|
|
3326
|
+
let current = [];
|
|
3327
|
+
let currentDur = 0;
|
|
3328
|
+
let streamStartMs = 0;
|
|
3329
|
+
for (const entry of entries) {
|
|
3330
|
+
if (current.length > 0 && currentDur + entry.durMs > chunkMs) {
|
|
3331
|
+
chunks.push({
|
|
3332
|
+
entries: current,
|
|
3333
|
+
streamStartMs
|
|
3334
|
+
});
|
|
3335
|
+
streamStartMs += currentDur;
|
|
3336
|
+
current = [];
|
|
3337
|
+
currentDur = 0;
|
|
3338
|
+
}
|
|
3339
|
+
current.push(entry);
|
|
3340
|
+
currentDur += entry.durMs;
|
|
3341
|
+
}
|
|
3342
|
+
if (current.length > 0) chunks.push({
|
|
3343
|
+
entries: current,
|
|
3344
|
+
streamStartMs
|
|
3345
|
+
});
|
|
3346
|
+
return chunks;
|
|
3347
|
+
}
|
|
3348
|
+
/**
|
|
3349
|
+
* Move stream-time dense ranges onto a chunk's own `t=0`. Ranges that miss
|
|
3350
|
+
* the chunk disappear; a range that straddles the edge is clipped. Empty →
|
|
3351
|
+
* `undefined` so the select stays the single-rate form.
|
|
3352
|
+
*/
|
|
3353
|
+
function denseRangesForChunk(dense, chunkStreamStartMs, chunkDurMs) {
|
|
3354
|
+
if (dense === void 0 || dense.ranges.length === 0) return void 0;
|
|
3355
|
+
const startSec = chunkStreamStartMs / 1e3;
|
|
3356
|
+
const endSec = (chunkStreamStartMs + chunkDurMs) / 1e3;
|
|
3357
|
+
const ranges = [];
|
|
3358
|
+
for (const r of dense.ranges) {
|
|
3359
|
+
const from = Math.max(r.fromSec, startSec);
|
|
3360
|
+
const to = Math.min(r.toSec, endSec);
|
|
3361
|
+
if (to <= from) continue;
|
|
3362
|
+
ranges.push({
|
|
3363
|
+
fromSec: from - startSec,
|
|
3364
|
+
toSec: to - startSec
|
|
3365
|
+
});
|
|
3366
|
+
}
|
|
3367
|
+
if (ranges.length === 0) return void 0;
|
|
3368
|
+
return {
|
|
3369
|
+
everyMs: dense.everyMs,
|
|
3370
|
+
ranges
|
|
3371
|
+
};
|
|
3372
|
+
}
|
|
3373
|
+
//#endregion
|
|
3374
3374
|
//#region src/recorder/addon/spawn-failure.ts
|
|
3375
3375
|
/**
|
|
3376
3376
|
* How the recorder reads a `child_process` `'error'` — ONE owner of the
|
|
@@ -3649,12 +3649,11 @@ var ExportEngine = class {
|
|
|
3649
3649
|
const survivors = [];
|
|
3650
3650
|
const sidecars = [];
|
|
3651
3651
|
try {
|
|
3652
|
-
for (
|
|
3652
|
+
for (const [i, chunk] of chunks.entries()) {
|
|
3653
3653
|
if (this.cancelled.has(id)) {
|
|
3654
3654
|
await this.fail(id, "cancelled");
|
|
3655
3655
|
return;
|
|
3656
3656
|
}
|
|
3657
|
-
const chunk = chunks[i];
|
|
3658
3657
|
const chunkDur = chunk.entries.reduce((s, e) => s + e.durMs, 0);
|
|
3659
3658
|
const listPath = `${outPath}.chunk${i}.ffconcat`;
|
|
3660
3659
|
const concatPath = `${outPath}.chunk${i}.concat.ts`;
|
|
@@ -3687,8 +3686,8 @@ var ExportEngine = class {
|
|
|
3687
3686
|
await this.fail(id, "every timelapse hour failed");
|
|
3688
3687
|
return;
|
|
3689
3688
|
}
|
|
3690
|
-
|
|
3691
|
-
|
|
3689
|
+
const only = survivors[0];
|
|
3690
|
+
if (survivors.length === 1 && only !== void 0) {
|
|
3692
3691
|
const copyArgs = buildExportArgs({
|
|
3693
3692
|
inputPlaylist: only,
|
|
3694
3693
|
outPath,
|
|
@@ -12044,6 +12043,13 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
12044
12043
|
/**
|
|
12045
12044
|
* Opt-in fleet walk — NOT armed at boot (2026-08-22: starved scrub/play).
|
|
12046
12045
|
* Kept so an operator path can still request a full reconcile later.
|
|
12046
|
+
*
|
|
12047
|
+
* ⚠ That operator path DOES NOT EXIST YET. This is the only caller of
|
|
12048
|
+
* `runFullArchiveWalk`, so today the whole walk is unreachable — `tsc` was
|
|
12049
|
+
* flagging it as unused and it was one of the errors keeping this package
|
|
12050
|
+
* red. Made public rather than deleted, because deleting it would have taken
|
|
12051
|
+
* the 100-line walk with it; but a comment promising a path nobody built is
|
|
12052
|
+
* exactly the leftover that reads as verification. Wire it or drop it.
|
|
12047
12053
|
*/
|
|
12048
12054
|
scheduleDeferredFullWalk(deviceIds) {
|
|
12049
12055
|
if (this.fullWalkTimer !== null || this.fullWalkInFlight) return;
|
package/dist/recorder/index.mjs
CHANGED
|
@@ -3150,65 +3150,6 @@ function buildExportArgs(input) {
|
|
|
3150
3150
|
];
|
|
3151
3151
|
}
|
|
3152
3152
|
//#endregion
|
|
3153
|
-
//#region src/recorder/addon/export-timelapse-chunks.ts
|
|
3154
|
-
/** One hour of concatenated footage — not one hour of wall clock. */
|
|
3155
|
-
var TIMELAPSE_CHUNK_MS = 36e5;
|
|
3156
|
-
/**
|
|
3157
|
-
* Split a concat list into hour-sized chunks. A single file longer than the
|
|
3158
|
-
* chunk stays whole — it is already one open, and cutting it would need a
|
|
3159
|
-
* second demux we do not have.
|
|
3160
|
-
*/
|
|
3161
|
-
function splitTimelapseChunks(entries, chunkMs = TIMELAPSE_CHUNK_MS) {
|
|
3162
|
-
if (entries.length === 0) return [];
|
|
3163
|
-
const chunks = [];
|
|
3164
|
-
let current = [];
|
|
3165
|
-
let currentDur = 0;
|
|
3166
|
-
let streamStartMs = 0;
|
|
3167
|
-
for (const entry of entries) {
|
|
3168
|
-
if (current.length > 0 && currentDur + entry.durMs > chunkMs) {
|
|
3169
|
-
chunks.push({
|
|
3170
|
-
entries: current,
|
|
3171
|
-
streamStartMs
|
|
3172
|
-
});
|
|
3173
|
-
streamStartMs += currentDur;
|
|
3174
|
-
current = [];
|
|
3175
|
-
currentDur = 0;
|
|
3176
|
-
}
|
|
3177
|
-
current.push(entry);
|
|
3178
|
-
currentDur += entry.durMs;
|
|
3179
|
-
}
|
|
3180
|
-
if (current.length > 0) chunks.push({
|
|
3181
|
-
entries: current,
|
|
3182
|
-
streamStartMs
|
|
3183
|
-
});
|
|
3184
|
-
return chunks;
|
|
3185
|
-
}
|
|
3186
|
-
/**
|
|
3187
|
-
* Move stream-time dense ranges onto a chunk's own `t=0`. Ranges that miss
|
|
3188
|
-
* the chunk disappear; a range that straddles the edge is clipped. Empty →
|
|
3189
|
-
* `undefined` so the select stays the single-rate form.
|
|
3190
|
-
*/
|
|
3191
|
-
function denseRangesForChunk(dense, chunkStreamStartMs, chunkDurMs) {
|
|
3192
|
-
if (dense === void 0 || dense.ranges.length === 0) return void 0;
|
|
3193
|
-
const startSec = chunkStreamStartMs / 1e3;
|
|
3194
|
-
const endSec = (chunkStreamStartMs + chunkDurMs) / 1e3;
|
|
3195
|
-
const ranges = [];
|
|
3196
|
-
for (const r of dense.ranges) {
|
|
3197
|
-
const from = Math.max(r.fromSec, startSec);
|
|
3198
|
-
const to = Math.min(r.toSec, endSec);
|
|
3199
|
-
if (to <= from) continue;
|
|
3200
|
-
ranges.push({
|
|
3201
|
-
fromSec: from - startSec,
|
|
3202
|
-
toSec: to - startSec
|
|
3203
|
-
});
|
|
3204
|
-
}
|
|
3205
|
-
if (ranges.length === 0) return void 0;
|
|
3206
|
-
return {
|
|
3207
|
-
everyMs: dense.everyMs,
|
|
3208
|
-
ranges
|
|
3209
|
-
};
|
|
3210
|
-
}
|
|
3211
|
-
//#endregion
|
|
3212
3153
|
//#region src/recorder/addon/export-store.ts
|
|
3213
3154
|
/**
|
|
3214
3155
|
* Recording-export persistence for the recorder addon.
|
|
@@ -3370,6 +3311,65 @@ async function listExportsFor(state, deviceId) {
|
|
|
3370
3311
|
})).map((entry) => entry.value);
|
|
3371
3312
|
}
|
|
3372
3313
|
//#endregion
|
|
3314
|
+
//#region src/recorder/addon/export-timelapse-chunks.ts
|
|
3315
|
+
/** One hour of concatenated footage — not one hour of wall clock. */
|
|
3316
|
+
var TIMELAPSE_CHUNK_MS = 36e5;
|
|
3317
|
+
/**
|
|
3318
|
+
* Split a concat list into hour-sized chunks. A single file longer than the
|
|
3319
|
+
* chunk stays whole — it is already one open, and cutting it would need a
|
|
3320
|
+
* second demux we do not have.
|
|
3321
|
+
*/
|
|
3322
|
+
function splitTimelapseChunks(entries, chunkMs = TIMELAPSE_CHUNK_MS) {
|
|
3323
|
+
if (entries.length === 0) return [];
|
|
3324
|
+
const chunks = [];
|
|
3325
|
+
let current = [];
|
|
3326
|
+
let currentDur = 0;
|
|
3327
|
+
let streamStartMs = 0;
|
|
3328
|
+
for (const entry of entries) {
|
|
3329
|
+
if (current.length > 0 && currentDur + entry.durMs > chunkMs) {
|
|
3330
|
+
chunks.push({
|
|
3331
|
+
entries: current,
|
|
3332
|
+
streamStartMs
|
|
3333
|
+
});
|
|
3334
|
+
streamStartMs += currentDur;
|
|
3335
|
+
current = [];
|
|
3336
|
+
currentDur = 0;
|
|
3337
|
+
}
|
|
3338
|
+
current.push(entry);
|
|
3339
|
+
currentDur += entry.durMs;
|
|
3340
|
+
}
|
|
3341
|
+
if (current.length > 0) chunks.push({
|
|
3342
|
+
entries: current,
|
|
3343
|
+
streamStartMs
|
|
3344
|
+
});
|
|
3345
|
+
return chunks;
|
|
3346
|
+
}
|
|
3347
|
+
/**
|
|
3348
|
+
* Move stream-time dense ranges onto a chunk's own `t=0`. Ranges that miss
|
|
3349
|
+
* the chunk disappear; a range that straddles the edge is clipped. Empty →
|
|
3350
|
+
* `undefined` so the select stays the single-rate form.
|
|
3351
|
+
*/
|
|
3352
|
+
function denseRangesForChunk(dense, chunkStreamStartMs, chunkDurMs) {
|
|
3353
|
+
if (dense === void 0 || dense.ranges.length === 0) return void 0;
|
|
3354
|
+
const startSec = chunkStreamStartMs / 1e3;
|
|
3355
|
+
const endSec = (chunkStreamStartMs + chunkDurMs) / 1e3;
|
|
3356
|
+
const ranges = [];
|
|
3357
|
+
for (const r of dense.ranges) {
|
|
3358
|
+
const from = Math.max(r.fromSec, startSec);
|
|
3359
|
+
const to = Math.min(r.toSec, endSec);
|
|
3360
|
+
if (to <= from) continue;
|
|
3361
|
+
ranges.push({
|
|
3362
|
+
fromSec: from - startSec,
|
|
3363
|
+
toSec: to - startSec
|
|
3364
|
+
});
|
|
3365
|
+
}
|
|
3366
|
+
if (ranges.length === 0) return void 0;
|
|
3367
|
+
return {
|
|
3368
|
+
everyMs: dense.everyMs,
|
|
3369
|
+
ranges
|
|
3370
|
+
};
|
|
3371
|
+
}
|
|
3372
|
+
//#endregion
|
|
3373
3373
|
//#region src/recorder/addon/spawn-failure.ts
|
|
3374
3374
|
/**
|
|
3375
3375
|
* How the recorder reads a `child_process` `'error'` — ONE owner of the
|
|
@@ -3648,12 +3648,11 @@ var ExportEngine = class {
|
|
|
3648
3648
|
const survivors = [];
|
|
3649
3649
|
const sidecars = [];
|
|
3650
3650
|
try {
|
|
3651
|
-
for (
|
|
3651
|
+
for (const [i, chunk] of chunks.entries()) {
|
|
3652
3652
|
if (this.cancelled.has(id)) {
|
|
3653
3653
|
await this.fail(id, "cancelled");
|
|
3654
3654
|
return;
|
|
3655
3655
|
}
|
|
3656
|
-
const chunk = chunks[i];
|
|
3657
3656
|
const chunkDur = chunk.entries.reduce((s, e) => s + e.durMs, 0);
|
|
3658
3657
|
const listPath = `${outPath}.chunk${i}.ffconcat`;
|
|
3659
3658
|
const concatPath = `${outPath}.chunk${i}.concat.ts`;
|
|
@@ -3686,8 +3685,8 @@ var ExportEngine = class {
|
|
|
3686
3685
|
await this.fail(id, "every timelapse hour failed");
|
|
3687
3686
|
return;
|
|
3688
3687
|
}
|
|
3689
|
-
|
|
3690
|
-
|
|
3688
|
+
const only = survivors[0];
|
|
3689
|
+
if (survivors.length === 1 && only !== void 0) {
|
|
3691
3690
|
const copyArgs = buildExportArgs({
|
|
3692
3691
|
inputPlaylist: only,
|
|
3693
3692
|
outPath,
|
|
@@ -12043,6 +12042,13 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
12043
12042
|
/**
|
|
12044
12043
|
* Opt-in fleet walk — NOT armed at boot (2026-08-22: starved scrub/play).
|
|
12045
12044
|
* Kept so an operator path can still request a full reconcile later.
|
|
12045
|
+
*
|
|
12046
|
+
* ⚠ That operator path DOES NOT EXIST YET. This is the only caller of
|
|
12047
|
+
* `runFullArchiveWalk`, so today the whole walk is unreachable — `tsc` was
|
|
12048
|
+
* flagging it as unused and it was one of the errors keeping this package
|
|
12049
|
+
* red. Made public rather than deleted, because deleting it would have taken
|
|
12050
|
+
* the 100-line walk with it; but a comment promising a path nobody built is
|
|
12051
|
+
* exactly the leftover that reads as verification. Wire it or drop it.
|
|
12046
12052
|
*/
|
|
12047
12053
|
scheduleDeferredFullWalk(deviceIds) {
|
|
12048
12054
|
if (this.fullWalkTimer !== null || this.fullWalkInFlight) return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_worker_protocol = require("../worker-protocol-BxkCoVjw.js");
|
|
3
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
3
|
+
const require_lazy_sharp = require("../lazy-sharp-DTDXrhMG.js");
|
|
4
4
|
//#region src/session-decode/color-conversion.ts
|
|
5
5
|
/**
|
|
6
6
|
* Explicit YUV→RGB colorspace/range resolution for the session-decode worker.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as formatNativeLeaseKnobs, n as isWorkerRequest, o as resolveNativeLeaseKnobs, r as logLevelForLine } from "../worker-protocol-h7Smb_0i.mjs";
|
|
2
|
-
import { n as setSharpWarnSink, r as hostExternalEntryUrls, t as getSharp } from "../lazy-sharp-
|
|
2
|
+
import { n as setSharpWarnSink, r as hostExternalEntryUrls, t as getSharp } from "../lazy-sharp-BtT5x-qP.mjs";
|
|
3
3
|
//#region src/session-decode/color-conversion.ts
|
|
4
4
|
/**
|
|
5
5
|
* Explicit YUV→RGB colorspace/range resolution for the session-decode worker.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-pipeline",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.127",
|
|
4
4
|
"description": "Pipeline bundle — runner, detection, motion, audio + stream broker. Multi-entry npm package shipping pipeline addons under a single bundle.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|