@camstack/addon-pipeline 1.2.52 → 1.2.54

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.
Files changed (37) hide show
  1. package/dist/{addon-utils-DveoBR6G.js → addon-utils-CQs-AjTJ.js} +177 -177
  2. package/dist/{addon-utils-QuxtOdK1.mjs → addon-utils-CZ2xo67g.mjs} +177 -177
  3. package/dist/audio-analyzer/index.js +2 -2
  4. package/dist/audio-analyzer/index.mjs +2 -2
  5. package/dist/detection-pipeline/index.js +3 -3
  6. package/dist/detection-pipeline/index.mjs +3 -3
  7. package/dist/{dist-gB3o0cyM.mjs → dist-B55xTTsS.mjs} +368 -5
  8. package/dist/{dist-CzFJeiG1.js → dist-D8TX_P_A.js} +368 -5
  9. package/dist/{event-loop-stall-monitor-DSPDQYjc.js → event-loop-stall-monitor-Bs6d-u_F.js} +1 -1
  10. package/dist/{event-loop-stall-monitor-PxIaVeyh.mjs → event-loop-stall-monitor-Cq_KOlfb.mjs} +1 -1
  11. package/dist/motion-wasm/index.js +1 -1
  12. package/dist/motion-wasm/index.mjs +1 -1
  13. package/dist/pipeline-runner/index.js +75 -25
  14. package/dist/pipeline-runner/index.mjs +75 -25
  15. package/dist/recorder/index.js +2 -2
  16. package/dist/recorder/index.mjs +2 -2
  17. package/dist/session-decode/decode-worker-child.js +6 -2
  18. package/dist/session-decode/decode-worker-child.mjs +6 -2
  19. package/dist/stream-broker/_stub.js +2 -2
  20. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DAeBhR8B.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-C-9q6y1s.mjs} +3 -3
  21. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CAmiVOsA.mjs +26 -0
  22. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CaGsMvou.mjs +26 -0
  23. package/dist/stream-broker/{hostInit-DniAXKLy.mjs → hostInit-DiXYwnXH.mjs} +3 -3
  24. package/dist/stream-broker/index.js +2 -2
  25. package/dist/stream-broker/index.mjs +2 -2
  26. package/dist/stream-broker/remoteEntry.js +1 -1
  27. package/dist/{worker-protocol-BhhX7J4-.mjs → worker-protocol-Bol291_n.mjs} +1 -1
  28. package/dist/{worker-protocol-BQlELGzv.js → worker-protocol-C2uctCrd.js} +1 -1
  29. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-B1gpA9sI.js → MaskShapeCanvas-DI4BY7W2-DY1AX2y_.js} +1 -1
  30. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-DV6vvNDq.js → MotionZonesSettings-NcxxQN8r-D46Ft0YB.js} +1 -1
  31. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-BmUdRoZ9.js → PrivacyMaskSettings-APgPLF7p-BLD9p-W3.js} +1 -1
  32. package/embed-dist/assets/{index-ICnBEqOy.css → index-C68W664Z.css} +1 -1
  33. package/embed-dist/assets/{index-DsGzhGCW.js → index-CWxqVyhE.js} +12 -12
  34. package/embed-dist/index.html +2 -2
  35. package/package.json +1 -1
  36. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Bl9zivOk.mjs +0 -26
  37. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Czrsozsg.mjs +0 -26
@@ -6,7 +6,183 @@ let node_path = require("node:path");
6
6
  node_path = require_chunk.__toESM(node_path, 1);
7
7
  let node_util = require("node:util");
8
8
  let node_zlib = require("node:zlib");
9
- //#region ../system/dist/model-download-service-CTBHzORJ.mjs
9
+ //#region ../system/dist/file-data-plane-CuE_hBli.mjs
10
+ function isNonEmptyFile(filePath) {
11
+ return node_fs.existsSync(filePath) && node_fs.statSync(filePath).size > 0;
12
+ }
13
+ /**
14
+ * Sibling files of a single-file (non-directory) format — extra files the
15
+ * format needs, fetched from the same remote directory as `url` and stored
16
+ * flat alongside the main file in `modelsDir`. Catalog-declared via
17
+ * `formatEntry.files`, e.g. OpenVINO IR lists its `.bin` weights next to the
18
+ * `.xml`. The downloader stays format-agnostic; the convention lives in the
19
+ * catalog data (like `MLPACKAGE_FILES` for the directory case).
20
+ */
21
+ function siblingFilesFor(formatEntry) {
22
+ return formatEntry.isDirectory ? [] : formatEntry.files ?? [];
23
+ }
24
+ /** Resolve a sibling's remote URL relative to the main file's directory. */
25
+ function siblingUrl(mainUrl, sibling) {
26
+ return mainUrl.replace(/[^/]+$/, sibling);
27
+ }
28
+ /** Build fetch headers, including HF auth token for huggingface.co URLs */
29
+ function buildHeaders(url) {
30
+ const headers = { "User-Agent": "CamStack/1.0" };
31
+ const hfToken = process.env["HF_TOKEN"] ?? process.env["HUGGING_FACE_HUB_TOKEN"];
32
+ if (hfToken && url.includes("huggingface.co")) headers["Authorization"] = `Bearer ${hfToken}`;
33
+ return headers;
34
+ }
35
+ /**
36
+ * Download a single file from a URL to a destination path.
37
+ * Uses native fetch() (Node 22+) which handles redirects natively.
38
+ * Streams to disk with optional progress callback.
39
+ * Returns the destination path. Skips download if file already exists.
40
+ */
41
+ async function downloadFile(url, destPath, onProgress) {
42
+ if (node_fs.existsSync(destPath)) return destPath;
43
+ node_fs.mkdirSync(node_path.dirname(destPath), { recursive: true });
44
+ const tmpPath = destPath + ".downloading";
45
+ try {
46
+ const response = await fetch(url, {
47
+ redirect: "follow",
48
+ headers: buildHeaders(url)
49
+ });
50
+ if (!response.ok) throw new Error(`HTTP ${response.status} downloading ${url}`);
51
+ if (!response.body) throw new Error(`No response body from ${url}`);
52
+ const total = parseInt(response.headers.get("content-length") ?? "0", 10);
53
+ let downloaded = 0;
54
+ const fileStream = node_fs.createWriteStream(tmpPath);
55
+ const reader = response.body.getReader();
56
+ try {
57
+ for (;;) {
58
+ const { done, value } = await reader.read();
59
+ if (done || !value) break;
60
+ fileStream.write(value);
61
+ downloaded += value.length;
62
+ onProgress?.(downloaded, total);
63
+ }
64
+ } finally {
65
+ fileStream.end();
66
+ await new Promise((resolve, reject) => {
67
+ fileStream.on("finish", resolve);
68
+ fileStream.on("error", reject);
69
+ });
70
+ }
71
+ node_fs.renameSync(tmpPath, destPath);
72
+ return destPath;
73
+ } catch (err) {
74
+ try {
75
+ node_fs.unlinkSync(tmpPath);
76
+ } catch {}
77
+ throw err;
78
+ }
79
+ }
80
+ /**
81
+ * Download every file in a HuggingFace directory bundle (e.g.,
82
+ * `.mlpackage` / OpenVINO IR pair) atomically. `knownFiles` lists the
83
+ * relative paths inside the directory; the function fetches each from
84
+ * `${url}/${file}` and renames the staging directory only on full
85
+ * success. Mirrors `ModelDownloadService.downloadDirectory` but
86
+ * exposed as a standalone for catalog-less callers.
87
+ */
88
+ async function downloadDirectory(url, destDir, knownFiles, onProgress) {
89
+ const match = url.match(/huggingface\.co\/([^/]+\/[^/]+)\/resolve\/main\/(.+)/);
90
+ if (!match) throw new Error(`Cannot parse HuggingFace URL: ${url}`);
91
+ const [, repo, dirPath] = match;
92
+ const files = (knownFiles ?? []).map((f) => ({
93
+ relativePath: f,
94
+ fileUrl: `https://huggingface.co/${repo}/resolve/main/${dirPath}/${f}`
95
+ }));
96
+ if (files.length === 0) throw new Error(`Directory bundle requires explicit \`files\` list (got none for ${url})`);
97
+ const tmpDir = destDir + ".downloading";
98
+ node_fs.rmSync(tmpDir, {
99
+ recursive: true,
100
+ force: true
101
+ });
102
+ node_fs.mkdirSync(tmpDir, { recursive: true });
103
+ let totalDownloaded = 0;
104
+ try {
105
+ for (const file of files) {
106
+ const destPath = node_path.join(tmpDir, file.relativePath);
107
+ node_fs.mkdirSync(node_path.dirname(destPath), { recursive: true });
108
+ await downloadFile(file.fileUrl, destPath, (downloaded, _total) => {
109
+ onProgress?.(totalDownloaded + downloaded, void 0);
110
+ });
111
+ totalDownloaded += node_fs.statSync(destPath).size;
112
+ }
113
+ node_fs.rmSync(destDir, {
114
+ recursive: true,
115
+ force: true
116
+ });
117
+ node_fs.renameSync(tmpDir, destDir);
118
+ } catch (err) {
119
+ node_fs.rmSync(tmpDir, {
120
+ recursive: true,
121
+ force: true
122
+ });
123
+ throw err;
124
+ }
125
+ }
126
+ /**
127
+ * Resolve a `ModelCatalogEntry` against `modelsDir`: download model file
128
+ * (or directory bundle) + extra files (labels JSON, charset dict, …),
129
+ * skip if already on disk. Returns the local model path.
130
+ */
131
+ async function ensureModel(modelsDir, entry, format, onProgress) {
132
+ const formatEntry = entry.formats[format];
133
+ if (!formatEntry) throw new Error(`Model "${entry.id}" has no ${format} format. Available: ${Object.keys(entry.formats).join(", ")}`);
134
+ if (entry.extraFiles) for (const extra of entry.extraFiles) await downloadFile(extra.url, node_path.join(modelsDir, extra.filename));
135
+ const filename = formatEntry.url.split("/").pop() ?? `${entry.id}.${format}`;
136
+ const modelPath = node_path.join(modelsDir, filename);
137
+ const siblings = siblingFilesFor(formatEntry);
138
+ if (node_fs.existsSync(modelPath)) if (formatEntry.isDirectory && !node_fs.existsSync(node_path.join(modelPath, "Manifest.json"))) node_fs.rmSync(modelPath, {
139
+ recursive: true,
140
+ force: true
141
+ });
142
+ else if (siblings.some((f) => !isNonEmptyFile(node_path.join(modelsDir, f)))) {} else return modelPath;
143
+ node_fs.mkdirSync(modelsDir, { recursive: true });
144
+ if (formatEntry.isDirectory) await downloadDirectory(formatEntry.url, modelPath, formatEntry.files, onProgress);
145
+ else {
146
+ await downloadFile(formatEntry.url, modelPath, (downloaded, total) => onProgress?.(downloaded, total === 0 ? void 0 : total));
147
+ for (const sibling of siblings) await downloadFile(siblingUrl(formatEntry.url, sibling), node_path.join(modelsDir, sibling));
148
+ }
149
+ return modelPath;
150
+ }
151
+ /** Compute the on-disk path for a given model + format, even when not yet downloaded. */
152
+ function getModelFilePath(modelsDir, entry, format) {
153
+ const formatEntry = entry.formats[format];
154
+ if (!formatEntry) return null;
155
+ const filename = formatEntry.url.split("/").pop() ?? `${entry.id}.${format}`;
156
+ return node_path.join(modelsDir, filename);
157
+ }
158
+ /** True iff the model file (or `Manifest.json` for directory bundles) exists and is non-empty. */
159
+ function isModelDownloaded(modelsDir, entry, format) {
160
+ const formatEntry = entry.formats[format];
161
+ if (!formatEntry) return false;
162
+ const modelPath = getModelFilePath(modelsDir, entry, format);
163
+ if (!modelPath || !node_fs.existsSync(modelPath)) return false;
164
+ if (formatEntry.isDirectory) return node_fs.existsSync(node_path.join(modelPath, "Manifest.json"));
165
+ if (node_fs.statSync(modelPath).size <= 0) return false;
166
+ return siblingFilesFor(formatEntry).every((f) => isNonEmptyFile(node_path.join(modelsDir, f)));
167
+ }
168
+ /** Remove the on-disk model file/directory. Returns true if something was deleted. */
169
+ function deleteModelFromDisk(modelsDir, entry, format) {
170
+ const modelPath = getModelFilePath(modelsDir, entry, format);
171
+ if (!modelPath || !node_fs.existsSync(modelPath)) return false;
172
+ const formatEntry = entry.formats[format];
173
+ if (formatEntry?.isDirectory) node_fs.rmSync(modelPath, {
174
+ recursive: true,
175
+ force: true
176
+ });
177
+ else {
178
+ node_fs.unlinkSync(modelPath);
179
+ if (formatEntry) for (const sibling of siblingFilesFor(formatEntry)) {
180
+ const sibPath = node_path.join(modelsDir, sibling);
181
+ if (node_fs.existsSync(sibPath)) node_fs.unlinkSync(sibPath);
182
+ }
183
+ }
184
+ return true;
185
+ }
10
186
  /**
11
187
  * Map a rel path to one candidate absolute path PER root, keeping only roots the
12
188
  * path stays within (traversal guard). The handler serves the first candidate
@@ -368,182 +544,6 @@ function createFileDataPlaneHandler(opts) {
368
544
  (0, node_fs.createReadStream)(absPath).pipe(res);
369
545
  };
370
546
  }
371
- function isNonEmptyFile(filePath) {
372
- return node_fs.existsSync(filePath) && node_fs.statSync(filePath).size > 0;
373
- }
374
- /**
375
- * Sibling files of a single-file (non-directory) format — extra files the
376
- * format needs, fetched from the same remote directory as `url` and stored
377
- * flat alongside the main file in `modelsDir`. Catalog-declared via
378
- * `formatEntry.files`, e.g. OpenVINO IR lists its `.bin` weights next to the
379
- * `.xml`. The downloader stays format-agnostic; the convention lives in the
380
- * catalog data (like `MLPACKAGE_FILES` for the directory case).
381
- */
382
- function siblingFilesFor(formatEntry) {
383
- return formatEntry.isDirectory ? [] : formatEntry.files ?? [];
384
- }
385
- /** Resolve a sibling's remote URL relative to the main file's directory. */
386
- function siblingUrl(mainUrl, sibling) {
387
- return mainUrl.replace(/[^/]+$/, sibling);
388
- }
389
- /** Build fetch headers, including HF auth token for huggingface.co URLs */
390
- function buildHeaders(url) {
391
- const headers = { "User-Agent": "CamStack/1.0" };
392
- const hfToken = process.env["HF_TOKEN"] ?? process.env["HUGGING_FACE_HUB_TOKEN"];
393
- if (hfToken && url.includes("huggingface.co")) headers["Authorization"] = `Bearer ${hfToken}`;
394
- return headers;
395
- }
396
- /**
397
- * Download a single file from a URL to a destination path.
398
- * Uses native fetch() (Node 22+) which handles redirects natively.
399
- * Streams to disk with optional progress callback.
400
- * Returns the destination path. Skips download if file already exists.
401
- */
402
- async function downloadFile(url, destPath, onProgress) {
403
- if (node_fs.existsSync(destPath)) return destPath;
404
- node_fs.mkdirSync(node_path.dirname(destPath), { recursive: true });
405
- const tmpPath = destPath + ".downloading";
406
- try {
407
- const response = await fetch(url, {
408
- redirect: "follow",
409
- headers: buildHeaders(url)
410
- });
411
- if (!response.ok) throw new Error(`HTTP ${response.status} downloading ${url}`);
412
- if (!response.body) throw new Error(`No response body from ${url}`);
413
- const total = parseInt(response.headers.get("content-length") ?? "0", 10);
414
- let downloaded = 0;
415
- const fileStream = node_fs.createWriteStream(tmpPath);
416
- const reader = response.body.getReader();
417
- try {
418
- for (;;) {
419
- const { done, value } = await reader.read();
420
- if (done || !value) break;
421
- fileStream.write(value);
422
- downloaded += value.length;
423
- onProgress?.(downloaded, total);
424
- }
425
- } finally {
426
- fileStream.end();
427
- await new Promise((resolve, reject) => {
428
- fileStream.on("finish", resolve);
429
- fileStream.on("error", reject);
430
- });
431
- }
432
- node_fs.renameSync(tmpPath, destPath);
433
- return destPath;
434
- } catch (err) {
435
- try {
436
- node_fs.unlinkSync(tmpPath);
437
- } catch {}
438
- throw err;
439
- }
440
- }
441
- /**
442
- * Download every file in a HuggingFace directory bundle (e.g.,
443
- * `.mlpackage` / OpenVINO IR pair) atomically. `knownFiles` lists the
444
- * relative paths inside the directory; the function fetches each from
445
- * `${url}/${file}` and renames the staging directory only on full
446
- * success. Mirrors `ModelDownloadService.downloadDirectory` but
447
- * exposed as a standalone for catalog-less callers.
448
- */
449
- async function downloadDirectory(url, destDir, knownFiles, onProgress) {
450
- const match = url.match(/huggingface\.co\/([^/]+\/[^/]+)\/resolve\/main\/(.+)/);
451
- if (!match) throw new Error(`Cannot parse HuggingFace URL: ${url}`);
452
- const [, repo, dirPath] = match;
453
- const files = (knownFiles ?? []).map((f) => ({
454
- relativePath: f,
455
- fileUrl: `https://huggingface.co/${repo}/resolve/main/${dirPath}/${f}`
456
- }));
457
- if (files.length === 0) throw new Error(`Directory bundle requires explicit \`files\` list (got none for ${url})`);
458
- const tmpDir = destDir + ".downloading";
459
- node_fs.rmSync(tmpDir, {
460
- recursive: true,
461
- force: true
462
- });
463
- node_fs.mkdirSync(tmpDir, { recursive: true });
464
- let totalDownloaded = 0;
465
- try {
466
- for (const file of files) {
467
- const destPath = node_path.join(tmpDir, file.relativePath);
468
- node_fs.mkdirSync(node_path.dirname(destPath), { recursive: true });
469
- await downloadFile(file.fileUrl, destPath, (downloaded, _total) => {
470
- onProgress?.(totalDownloaded + downloaded, void 0);
471
- });
472
- totalDownloaded += node_fs.statSync(destPath).size;
473
- }
474
- node_fs.rmSync(destDir, {
475
- recursive: true,
476
- force: true
477
- });
478
- node_fs.renameSync(tmpDir, destDir);
479
- } catch (err) {
480
- node_fs.rmSync(tmpDir, {
481
- recursive: true,
482
- force: true
483
- });
484
- throw err;
485
- }
486
- }
487
- /**
488
- * Resolve a `ModelCatalogEntry` against `modelsDir`: download model file
489
- * (or directory bundle) + extra files (labels JSON, charset dict, …),
490
- * skip if already on disk. Returns the local model path.
491
- */
492
- async function ensureModel(modelsDir, entry, format, onProgress) {
493
- const formatEntry = entry.formats[format];
494
- if (!formatEntry) throw new Error(`Model "${entry.id}" has no ${format} format. Available: ${Object.keys(entry.formats).join(", ")}`);
495
- if (entry.extraFiles) for (const extra of entry.extraFiles) await downloadFile(extra.url, node_path.join(modelsDir, extra.filename));
496
- const filename = formatEntry.url.split("/").pop() ?? `${entry.id}.${format}`;
497
- const modelPath = node_path.join(modelsDir, filename);
498
- const siblings = siblingFilesFor(formatEntry);
499
- if (node_fs.existsSync(modelPath)) if (formatEntry.isDirectory && !node_fs.existsSync(node_path.join(modelPath, "Manifest.json"))) node_fs.rmSync(modelPath, {
500
- recursive: true,
501
- force: true
502
- });
503
- else if (siblings.some((f) => !isNonEmptyFile(node_path.join(modelsDir, f)))) {} else return modelPath;
504
- node_fs.mkdirSync(modelsDir, { recursive: true });
505
- if (formatEntry.isDirectory) await downloadDirectory(formatEntry.url, modelPath, formatEntry.files, onProgress);
506
- else {
507
- await downloadFile(formatEntry.url, modelPath, (downloaded, total) => onProgress?.(downloaded, total === 0 ? void 0 : total));
508
- for (const sibling of siblings) await downloadFile(siblingUrl(formatEntry.url, sibling), node_path.join(modelsDir, sibling));
509
- }
510
- return modelPath;
511
- }
512
- /** Compute the on-disk path for a given model + format, even when not yet downloaded. */
513
- function getModelFilePath(modelsDir, entry, format) {
514
- const formatEntry = entry.formats[format];
515
- if (!formatEntry) return null;
516
- const filename = formatEntry.url.split("/").pop() ?? `${entry.id}.${format}`;
517
- return node_path.join(modelsDir, filename);
518
- }
519
- /** True iff the model file (or `Manifest.json` for directory bundles) exists and is non-empty. */
520
- function isModelDownloaded(modelsDir, entry, format) {
521
- const formatEntry = entry.formats[format];
522
- if (!formatEntry) return false;
523
- const modelPath = getModelFilePath(modelsDir, entry, format);
524
- if (!modelPath || !node_fs.existsSync(modelPath)) return false;
525
- if (formatEntry.isDirectory) return node_fs.existsSync(node_path.join(modelPath, "Manifest.json"));
526
- if (node_fs.statSync(modelPath).size <= 0) return false;
527
- return siblingFilesFor(formatEntry).every((f) => isNonEmptyFile(node_path.join(modelsDir, f)));
528
- }
529
- /** Remove the on-disk model file/directory. Returns true if something was deleted. */
530
- function deleteModelFromDisk(modelsDir, entry, format) {
531
- const modelPath = getModelFilePath(modelsDir, entry, format);
532
- if (!modelPath || !node_fs.existsSync(modelPath)) return false;
533
- const formatEntry = entry.formats[format];
534
- if (formatEntry?.isDirectory) node_fs.rmSync(modelPath, {
535
- recursive: true,
536
- force: true
537
- });
538
- else {
539
- node_fs.unlinkSync(modelPath);
540
- if (formatEntry) for (const sibling of siblingFilesFor(formatEntry)) {
541
- const sibPath = node_path.join(modelsDir, sibling);
542
- if (node_fs.existsSync(sibPath)) node_fs.unlinkSync(sibPath);
543
- }
544
- }
545
- return true;
546
- }
547
547
  //#endregion
548
548
  Object.defineProperty(exports, "contentTypeFor", {
549
549
  enumerable: true,