@camstack/addon-pipeline 1.2.65 → 1.2.67
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/audio-analyzer/index.js +1 -1
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +2 -2
- package/dist/detection-pipeline/index.mjs +2 -2
- package/dist/{dist-DKrqeIfS.js → dist-B6GWr9am.js} +151 -6
- package/dist/{dist-B9_C-QmC.mjs → dist-BEbyhqoG.mjs} +146 -7
- package/dist/{event-loop-stall-monitor-CnJ5JGA2.js → event-loop-stall-monitor-BHOEgVnP.js} +1 -1
- package/dist/{event-loop-stall-monitor-BucTbe9v.mjs → event-loop-stall-monitor-BNyf5yEt.mjs} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +144 -14
- package/dist/pipeline-runner/index.mjs +144 -14
- package/dist/recorder/index.js +114 -3
- package/dist/recorder/index.mjs +114 -3
- package/dist/remote-restream-BYbAsgUf.js +89 -0
- package/dist/remote-restream-Ci7RXNGb.mjs +66 -0
- package/dist/session-decode/decode-worker-child.js +1 -1
- package/dist/session-decode/decode-worker-child.mjs +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BCyIjQkw.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BkKnIpb0.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-ircnzt0s.mjs +26 -0
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CJAUKSrT.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DU7u9EJt.mjs} +1 -1
- package/dist/stream-broker/{hostInit-DqLdTCfo.mjs → hostInit-y3zWHWoe.mjs} +2 -2
- package/dist/stream-broker/index.js +54 -15
- package/dist/stream-broker/index.mjs +54 -15
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-CQHY2NeB.mjs → worker-protocol-CBg9bqCs.mjs} +1 -1
- package/dist/{worker-protocol-CDkbdSuM.js → worker-protocol-qzaozj7t.js} +1 -1
- package/package.json +1 -1
- package/dist/remote-restream-BeHi78PZ.mjs +0 -25
- package/dist/remote-restream-CO36Sr30.js +0 -36
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C2tu4c14.mjs +0 -26
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
6
|
+
const require_dist = require("../dist-B6GWr9am.js");
|
|
7
7
|
const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
|
|
8
8
|
const require_addon_utils = require("../addon-utils-CQs-AjTJ.js");
|
|
9
9
|
let node_fs = require("node:fs");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as __require } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { B as mapAudioLabelToMacro, E as audioAnalyzerCapability, T as audioAnalysisCapability, ft as hydrateSchema, m as HF_BASE_URL, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG, st as BaseAddon, tt as errMsg } from "../dist-BEbyhqoG.mjs";
|
|
3
3
|
import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
|
|
4
4
|
import { i as downloadFile } from "../addon-utils-CZ2xo67g.mjs";
|
|
5
5
|
import * as fs from "node:fs";
|
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
7
|
-
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-
|
|
6
|
+
const require_dist = require("../dist-B6GWr9am.js");
|
|
7
|
+
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-BHOEgVnP.js");
|
|
8
8
|
const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
|
|
9
9
|
const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
|
|
10
10
|
const require_addon_utils = require("../addon-utils-CQs-AjTJ.js");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as __require } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, n as startEventLoopStallMonitor, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep } from "../event-loop-stall-monitor-
|
|
2
|
+
import { $ as supportedRuntimes$1, A as defaultDeviceFor$1, At as string, C as YAMNET_TO_MACRO, G as pipelineExecutorCapability, L as enumerateInferenceDevices, Mt as EventCategory, Ot as object, P as detectionPipelineCapability, R as evaluateZoneRules, St as array, X as runtimeDevices$1, _t as parseJsonUnknown, bt as sleep, dt as createEvent, ft as hydrateSchema, gt as nodePin, jt as union, st as BaseAddon, t as APPLE_SA_TO_MACRO, tt as errMsg, u as DEVICE_BACKEND_TO_FORMAT } from "../dist-BEbyhqoG.mjs";
|
|
3
|
+
import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, n as startEventLoopStallMonitor, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep } from "../event-loop-stall-monitor-BNyf5yEt.mjs";
|
|
4
4
|
import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
|
|
5
5
|
import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
|
|
6
6
|
import { a as ensureModel, o as isModelDownloaded, r as deleteModelFromDisk } from "../addon-utils-CZ2xo67g.mjs";
|
|
@@ -8150,8 +8150,31 @@ var AdoptionJobSchema = object({
|
|
|
8150
8150
|
error: string().nullable()
|
|
8151
8151
|
});
|
|
8152
8152
|
/**
|
|
8153
|
-
* Per-camera FUNCTION SWITCHES
|
|
8154
|
-
*
|
|
8153
|
+
* Per-camera FUNCTION SWITCHES.
|
|
8154
|
+
*
|
|
8155
|
+
* ## The aggregate group is being withdrawn — the BADGE is not (D113)
|
|
8156
|
+
*
|
|
8157
|
+
* This file shipped as "the one coherent on/off surface over the pipeline
|
|
8158
|
+
* functions an operator thinks in terms of". The operator's verdict on
|
|
8159
|
+
* 2026-08-12 was that the coherent surface bought complexity and no clarity:
|
|
8160
|
+
* every function already had a settings page of its own, and a second place to
|
|
8161
|
+
* turn it off is a second place to look. Each switch is going back to its own
|
|
8162
|
+
* component's original options — detection to the detection-pipeline wrapper
|
|
8163
|
+
* binding, audio analysis to its own, recording to `RecordingConfig.enabled`
|
|
8164
|
+
* (which was always first-class; the switch was a veneer over
|
|
8165
|
+
* `recording.setDeviceConfig`), notifications to a notification-center
|
|
8166
|
+
* per-device setting, the two camera planes to their own components.
|
|
8167
|
+
*
|
|
8168
|
+
* What survives is {@link composeSwitchedOff}: `CameraStatus.switchedOff`, the
|
|
8169
|
+
* thing that lets a status surface say DISABLED instead of BROKEN, recomposed
|
|
8170
|
+
* straight from the authorities with no group in the middle. That rule was
|
|
8171
|
+
* never about a control panel.
|
|
8172
|
+
*
|
|
8173
|
+
* Everything else here — {@link CAMERA_SWITCH_CATALOG}, {@link CameraSwitch},
|
|
8174
|
+
* {@link deriveCameraSwitches}, the `pipelineOrchestrator.getCameraSwitches` /
|
|
8175
|
+
* `setCameraSwitch` pair — is a COMPATIBILITY surface for as long as deployed
|
|
8176
|
+
* viewers (v1.0.305) and the admin UI still call it. It is deleted when they
|
|
8177
|
+
* stop; nothing new may be built on it.
|
|
8155
8178
|
*
|
|
8156
8179
|
* ## This file adds no state
|
|
8157
8180
|
*
|
|
@@ -19571,9 +19594,16 @@ var CameraStatusSchema = object({
|
|
|
19571
19594
|
audio: CameraAudioStatusSchema.nullable(),
|
|
19572
19595
|
recording: CameraRecordingStatusSchema.nullable(),
|
|
19573
19596
|
/**
|
|
19574
|
-
* Per-camera
|
|
19597
|
+
* Per-camera functions an OPERATOR has turned off
|
|
19575
19598
|
* ([D61](../../../../docs/decisions/adr-0067.md)).
|
|
19576
19599
|
*
|
|
19600
|
+
* Composed from the AUTHORITIES themselves — the wrapper bindings,
|
|
19601
|
+
* `RecordingConfig.enabled`, the notification mute, the broker's audio
|
|
19602
|
+
* policy, the camera's own microphone — via `composeSwitchedOff`, not from
|
|
19603
|
+
* the deprecated `getCameraSwitches` group ([D113](../../../../docs/decisions/adr-0113.md)).
|
|
19604
|
+
* The badge outlives the control panel: the panel was a convenience, this is
|
|
19605
|
+
* the difference between a camera being off and a camera being dead.
|
|
19606
|
+
*
|
|
19577
19607
|
* This is the difference between DISABLED and BROKEN. A camera whose
|
|
19578
19608
|
* `detection` block reports zero fps and whose `switchedOff` contains
|
|
19579
19609
|
* `'object-detection'` was switched off by a person; the same camera with an
|
|
@@ -25467,10 +25497,42 @@ var recordingCapability = {
|
|
|
25467
25497
|
*/
|
|
25468
25498
|
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
25469
25499
|
var ExportSpeedSchema = number().min(.25).max(32);
|
|
25500
|
+
/**
|
|
25501
|
+
* One dense interval, in SECONDS FROM THE EXPORT'S OWN `fromMs`.
|
|
25502
|
+
*
|
|
25503
|
+
* Relative and not absolute epoch on purpose: the renderer's frame-select
|
|
25504
|
+
* expression sees ffmpeg's `t`, which starts at 0 for the export's source
|
|
25505
|
+
* playlist. Handing it absolute epochs would make every call site responsible
|
|
25506
|
+
* for the same subtraction, and the one that forgot would emit a filter that
|
|
25507
|
+
* selects nothing — silently, as a uniform timelapse.
|
|
25508
|
+
*/
|
|
25509
|
+
var ExportDenseRangeSchema = object({
|
|
25510
|
+
fromSec: number().nonnegative(),
|
|
25511
|
+
toSec: number().nonnegative()
|
|
25512
|
+
}).refine((r) => r.toSec > r.fromSec, { message: "dense range must have toSec > fromSec" });
|
|
25513
|
+
/**
|
|
25514
|
+
* Dense-interval overlay for a timelapse: sample at `dense.everyMs` INSIDE the
|
|
25515
|
+
* listed ranges and at the base `everyMs` everywhere else.
|
|
25516
|
+
*
|
|
25517
|
+
* `everyMs` must be strictly smaller than the base cadence — a dense rate that
|
|
25518
|
+
* is not denser renders a uniform timelapse the operator believes is two-rate.
|
|
25519
|
+
*/
|
|
25520
|
+
var ExportDenseSchema = object({
|
|
25521
|
+
everyMs: number().int().positive(),
|
|
25522
|
+
ranges: array(ExportDenseRangeSchema).min(1).max(200)
|
|
25523
|
+
});
|
|
25470
25524
|
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
25471
25525
|
var ExportTimelapseSchema = object({
|
|
25472
25526
|
everyMs: number().int().positive(),
|
|
25473
|
-
outputFps: number().int().min(1).max(60).optional()
|
|
25527
|
+
outputFps: number().int().min(1).max(60).optional(),
|
|
25528
|
+
/** Optional second, FASTER rate over the intervals that matter. */
|
|
25529
|
+
dense: ExportDenseSchema.optional()
|
|
25530
|
+
}).superRefine((v, ctx) => {
|
|
25531
|
+
if (v.dense !== void 0 && v.dense.everyMs >= v.everyMs) ctx.addIssue({
|
|
25532
|
+
code: ZodIssueCode.custom,
|
|
25533
|
+
message: "dense.everyMs must be strictly smaller than the base everyMs",
|
|
25534
|
+
path: ["dense", "everyMs"]
|
|
25535
|
+
});
|
|
25474
25536
|
});
|
|
25475
25537
|
/**
|
|
25476
25538
|
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
@@ -25528,6 +25590,38 @@ var ExportDownloadSchema = object({
|
|
|
25528
25590
|
url: string(),
|
|
25529
25591
|
endpoints: array(string())
|
|
25530
25592
|
});
|
|
25593
|
+
/**
|
|
25594
|
+
* Hard ceiling on ONE {@link recordingExportCapability} byte read — 50 MiB.
|
|
25595
|
+
*
|
|
25596
|
+
* Two independent reasons land on the same number, which is why it is this one
|
|
25597
|
+
* and not a rounder guess:
|
|
25598
|
+
*
|
|
25599
|
+
* - **Nobody would accept more.** The roomiest byte cap any notifier backend
|
|
25600
|
+
* declares is telegram's 50 MiB, and the degrade engine DROPS an over-cap
|
|
25601
|
+
* attachment outright rather than degrading it to a link. Bytes above this
|
|
25602
|
+
* are read, encoded and moved to be thrown away at the last step.
|
|
25603
|
+
* - **The envelope is unary.** A base64 payload is held whole, ~1.33× its
|
|
25604
|
+
* size, in the provider AND in the caller — on a hub this repo has already
|
|
25605
|
+
* OOM'd once (D9/D18). A bounded on-demand read at human speed is the shape
|
|
25606
|
+
* those records permit; an unbounded one is the shape they forbid.
|
|
25607
|
+
*
|
|
25608
|
+
* Above it the provider REFUSES with a log line rather than truncating: half a
|
|
25609
|
+
* video is worse than a notification that says there is no attachment.
|
|
25610
|
+
*/
|
|
25611
|
+
var RECORDING_EXPORT_MAX_READ_BYTES = 50 * 1024 * 1024;
|
|
25612
|
+
/**
|
|
25613
|
+
* A finished export's bytes, inline.
|
|
25614
|
+
*
|
|
25615
|
+
* `bytes` is the DECODED length — the number the caller bounds and logs
|
|
25616
|
+
* against, so nobody has to infer it from the base64 length.
|
|
25617
|
+
*/
|
|
25618
|
+
var ExportBytesSchema = object({
|
|
25619
|
+
base64: string(),
|
|
25620
|
+
contentType: string(),
|
|
25621
|
+
/** Suggested filename, extension included. */
|
|
25622
|
+
name: string(),
|
|
25623
|
+
bytes: number().int().nonnegative()
|
|
25624
|
+
});
|
|
25531
25625
|
var recordingExportCapability = {
|
|
25532
25626
|
name: "recordingExport",
|
|
25533
25627
|
scope: "system",
|
|
@@ -25567,6 +25661,27 @@ var recordingExportCapability = {
|
|
|
25567
25661
|
getDownloadUrl: method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
25568
25662
|
kind: "query",
|
|
25569
25663
|
auth: "protected"
|
|
25664
|
+
}),
|
|
25665
|
+
/**
|
|
25666
|
+
* The finished file's BYTES, base64, for a caller that must republish them
|
|
25667
|
+
* somewhere a session-less fetcher can reach.
|
|
25668
|
+
*
|
|
25669
|
+
* `getDownloadUrl` is the right answer for a human: the download route is
|
|
25670
|
+
* served `access: 'authenticated'`, which a browser satisfies and a
|
|
25671
|
+
* notifier BACKEND does not. It answers a RELATIVE path, so it is not even
|
|
25672
|
+
* a URL an outside fetcher could try. This method exists for the one case
|
|
25673
|
+
* that needs the other thing — a scheduled timelapse whose video has to
|
|
25674
|
+
* become a public attachment on the notification artifact plane.
|
|
25675
|
+
*
|
|
25676
|
+
* Deliberately narrow: `ready` only (a queued, rendering, failed, expired
|
|
25677
|
+
* or deleted export has no file, and answering "0 bytes" for one is how a
|
|
25678
|
+
* caller ships an empty attachment), still inside its lifetime, and under
|
|
25679
|
+
* {@link RECORDING_EXPORT_MAX_READ_BYTES}. Every refusal throws with the
|
|
25680
|
+
* reason — none of them is silent.
|
|
25681
|
+
*/
|
|
25682
|
+
readExportBytes: method(object({ exportId: string() }), ExportBytesSchema, {
|
|
25683
|
+
kind: "query",
|
|
25684
|
+
auth: "protected"
|
|
25570
25685
|
})
|
|
25571
25686
|
}
|
|
25572
25687
|
};
|
|
@@ -30925,6 +31040,12 @@ Object.freeze({
|
|
|
30925
31040
|
addonId: null,
|
|
30926
31041
|
access: "view"
|
|
30927
31042
|
},
|
|
31043
|
+
"recordingExport.readExportBytes": {
|
|
31044
|
+
capName: "recordingExport",
|
|
31045
|
+
capScope: "system",
|
|
31046
|
+
addonId: null,
|
|
31047
|
+
access: "view"
|
|
31048
|
+
},
|
|
30928
31049
|
"sceneMonitor.captureReference": {
|
|
30929
31050
|
capName: "scene-monitor",
|
|
30930
31051
|
capScope: "device",
|
|
@@ -32342,10 +32463,28 @@ TimelapseRuleInputSchema.extend({
|
|
|
32342
32463
|
*/
|
|
32343
32464
|
ownerUserId: string().optional(),
|
|
32344
32465
|
/**
|
|
32345
|
-
* Epoch-ms of the
|
|
32346
|
-
*
|
|
32466
|
+
* Epoch-ms of the NEWEST successful generation across every camera of this
|
|
32467
|
+
* rule. What a UI shows, and the compatibility floor for
|
|
32468
|
+
* {@link readTimelapseGeneratedAt}. Absent = never generated.
|
|
32347
32469
|
*/
|
|
32348
32470
|
lastGeneratedAt: number().optional(),
|
|
32471
|
+
/**
|
|
32472
|
+
* PER-CAMERA generation state, keyed by `String(deviceId)` — the
|
|
32473
|
+
* re-generation guard's real durable state.
|
|
32474
|
+
*
|
|
32475
|
+
* One rule covers several cameras and each renders its own video, so a rule
|
|
32476
|
+
* -wide stamp is wrong in the direction that DESTROYS work: camera A
|
|
32477
|
+
* succeeding at 06:05 tells camera B, whose render failed, that it is
|
|
32478
|
+
* already done — and B's night is gone for good, because the window will not
|
|
32479
|
+
* come back.
|
|
32480
|
+
*
|
|
32481
|
+
* ADDITIVE, so the migration is free: a row written before this field simply
|
|
32482
|
+
* has no map, and {@link readTimelapseGeneratedAt} falls back to
|
|
32483
|
+
* {@link TimelapseRuleSchema.shape.lastGeneratedAt}. Reading an old row as
|
|
32484
|
+
* "never generated" would re-render and re-notify every camera of every rule
|
|
32485
|
+
* once, on the deploy that shipped the map.
|
|
32486
|
+
*/
|
|
32487
|
+
generatedByDevice: record(string(), number()).optional(),
|
|
32349
32488
|
/** userId of the caller who created the rule (server-stamped). */
|
|
32350
32489
|
createdBy: string(),
|
|
32351
32490
|
createdAt: number(),
|
|
@@ -33229,6 +33368,12 @@ Object.defineProperty(exports, "RATE_CONTROL_TIGHT", {
|
|
|
33229
33368
|
return RATE_CONTROL_TIGHT;
|
|
33230
33369
|
}
|
|
33231
33370
|
});
|
|
33371
|
+
Object.defineProperty(exports, "RECORDING_EXPORT_MAX_READ_BYTES", {
|
|
33372
|
+
enumerable: true,
|
|
33373
|
+
get: function() {
|
|
33374
|
+
return RECORDING_EXPORT_MAX_READ_BYTES;
|
|
33375
|
+
}
|
|
33376
|
+
});
|
|
33232
33377
|
Object.defineProperty(exports, "RecordingConfigSchema", {
|
|
33233
33378
|
enumerable: true,
|
|
33234
33379
|
get: function() {
|
|
@@ -8150,8 +8150,31 @@ var AdoptionJobSchema = object({
|
|
|
8150
8150
|
error: string().nullable()
|
|
8151
8151
|
});
|
|
8152
8152
|
/**
|
|
8153
|
-
* Per-camera FUNCTION SWITCHES
|
|
8154
|
-
*
|
|
8153
|
+
* Per-camera FUNCTION SWITCHES.
|
|
8154
|
+
*
|
|
8155
|
+
* ## The aggregate group is being withdrawn — the BADGE is not (D113)
|
|
8156
|
+
*
|
|
8157
|
+
* This file shipped as "the one coherent on/off surface over the pipeline
|
|
8158
|
+
* functions an operator thinks in terms of". The operator's verdict on
|
|
8159
|
+
* 2026-08-12 was that the coherent surface bought complexity and no clarity:
|
|
8160
|
+
* every function already had a settings page of its own, and a second place to
|
|
8161
|
+
* turn it off is a second place to look. Each switch is going back to its own
|
|
8162
|
+
* component's original options — detection to the detection-pipeline wrapper
|
|
8163
|
+
* binding, audio analysis to its own, recording to `RecordingConfig.enabled`
|
|
8164
|
+
* (which was always first-class; the switch was a veneer over
|
|
8165
|
+
* `recording.setDeviceConfig`), notifications to a notification-center
|
|
8166
|
+
* per-device setting, the two camera planes to their own components.
|
|
8167
|
+
*
|
|
8168
|
+
* What survives is {@link composeSwitchedOff}: `CameraStatus.switchedOff`, the
|
|
8169
|
+
* thing that lets a status surface say DISABLED instead of BROKEN, recomposed
|
|
8170
|
+
* straight from the authorities with no group in the middle. That rule was
|
|
8171
|
+
* never about a control panel.
|
|
8172
|
+
*
|
|
8173
|
+
* Everything else here — {@link CAMERA_SWITCH_CATALOG}, {@link CameraSwitch},
|
|
8174
|
+
* {@link deriveCameraSwitches}, the `pipelineOrchestrator.getCameraSwitches` /
|
|
8175
|
+
* `setCameraSwitch` pair — is a COMPATIBILITY surface for as long as deployed
|
|
8176
|
+
* viewers (v1.0.305) and the admin UI still call it. It is deleted when they
|
|
8177
|
+
* stop; nothing new may be built on it.
|
|
8155
8178
|
*
|
|
8156
8179
|
* ## This file adds no state
|
|
8157
8180
|
*
|
|
@@ -19571,9 +19594,16 @@ var CameraStatusSchema = object({
|
|
|
19571
19594
|
audio: CameraAudioStatusSchema.nullable(),
|
|
19572
19595
|
recording: CameraRecordingStatusSchema.nullable(),
|
|
19573
19596
|
/**
|
|
19574
|
-
* Per-camera
|
|
19597
|
+
* Per-camera functions an OPERATOR has turned off
|
|
19575
19598
|
* ([D61](../../../../docs/decisions/adr-0067.md)).
|
|
19576
19599
|
*
|
|
19600
|
+
* Composed from the AUTHORITIES themselves — the wrapper bindings,
|
|
19601
|
+
* `RecordingConfig.enabled`, the notification mute, the broker's audio
|
|
19602
|
+
* policy, the camera's own microphone — via `composeSwitchedOff`, not from
|
|
19603
|
+
* the deprecated `getCameraSwitches` group ([D113](../../../../docs/decisions/adr-0113.md)).
|
|
19604
|
+
* The badge outlives the control panel: the panel was a convenience, this is
|
|
19605
|
+
* the difference between a camera being off and a camera being dead.
|
|
19606
|
+
*
|
|
19577
19607
|
* This is the difference between DISABLED and BROKEN. A camera whose
|
|
19578
19608
|
* `detection` block reports zero fps and whose `switchedOff` contains
|
|
19579
19609
|
* `'object-detection'` was switched off by a person; the same camera with an
|
|
@@ -25467,10 +25497,42 @@ var recordingCapability = {
|
|
|
25467
25497
|
*/
|
|
25468
25498
|
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
25469
25499
|
var ExportSpeedSchema = number().min(.25).max(32);
|
|
25500
|
+
/**
|
|
25501
|
+
* One dense interval, in SECONDS FROM THE EXPORT'S OWN `fromMs`.
|
|
25502
|
+
*
|
|
25503
|
+
* Relative and not absolute epoch on purpose: the renderer's frame-select
|
|
25504
|
+
* expression sees ffmpeg's `t`, which starts at 0 for the export's source
|
|
25505
|
+
* playlist. Handing it absolute epochs would make every call site responsible
|
|
25506
|
+
* for the same subtraction, and the one that forgot would emit a filter that
|
|
25507
|
+
* selects nothing — silently, as a uniform timelapse.
|
|
25508
|
+
*/
|
|
25509
|
+
var ExportDenseRangeSchema = object({
|
|
25510
|
+
fromSec: number().nonnegative(),
|
|
25511
|
+
toSec: number().nonnegative()
|
|
25512
|
+
}).refine((r) => r.toSec > r.fromSec, { message: "dense range must have toSec > fromSec" });
|
|
25513
|
+
/**
|
|
25514
|
+
* Dense-interval overlay for a timelapse: sample at `dense.everyMs` INSIDE the
|
|
25515
|
+
* listed ranges and at the base `everyMs` everywhere else.
|
|
25516
|
+
*
|
|
25517
|
+
* `everyMs` must be strictly smaller than the base cadence — a dense rate that
|
|
25518
|
+
* is not denser renders a uniform timelapse the operator believes is two-rate.
|
|
25519
|
+
*/
|
|
25520
|
+
var ExportDenseSchema = object({
|
|
25521
|
+
everyMs: number().int().positive(),
|
|
25522
|
+
ranges: array(ExportDenseRangeSchema).min(1).max(200)
|
|
25523
|
+
});
|
|
25470
25524
|
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
25471
25525
|
var ExportTimelapseSchema = object({
|
|
25472
25526
|
everyMs: number().int().positive(),
|
|
25473
|
-
outputFps: number().int().min(1).max(60).optional()
|
|
25527
|
+
outputFps: number().int().min(1).max(60).optional(),
|
|
25528
|
+
/** Optional second, FASTER rate over the intervals that matter. */
|
|
25529
|
+
dense: ExportDenseSchema.optional()
|
|
25530
|
+
}).superRefine((v, ctx) => {
|
|
25531
|
+
if (v.dense !== void 0 && v.dense.everyMs >= v.everyMs) ctx.addIssue({
|
|
25532
|
+
code: ZodIssueCode.custom,
|
|
25533
|
+
message: "dense.everyMs must be strictly smaller than the base everyMs",
|
|
25534
|
+
path: ["dense", "everyMs"]
|
|
25535
|
+
});
|
|
25474
25536
|
});
|
|
25475
25537
|
/**
|
|
25476
25538
|
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
@@ -25528,6 +25590,38 @@ var ExportDownloadSchema = object({
|
|
|
25528
25590
|
url: string(),
|
|
25529
25591
|
endpoints: array(string())
|
|
25530
25592
|
});
|
|
25593
|
+
/**
|
|
25594
|
+
* Hard ceiling on ONE {@link recordingExportCapability} byte read — 50 MiB.
|
|
25595
|
+
*
|
|
25596
|
+
* Two independent reasons land on the same number, which is why it is this one
|
|
25597
|
+
* and not a rounder guess:
|
|
25598
|
+
*
|
|
25599
|
+
* - **Nobody would accept more.** The roomiest byte cap any notifier backend
|
|
25600
|
+
* declares is telegram's 50 MiB, and the degrade engine DROPS an over-cap
|
|
25601
|
+
* attachment outright rather than degrading it to a link. Bytes above this
|
|
25602
|
+
* are read, encoded and moved to be thrown away at the last step.
|
|
25603
|
+
* - **The envelope is unary.** A base64 payload is held whole, ~1.33× its
|
|
25604
|
+
* size, in the provider AND in the caller — on a hub this repo has already
|
|
25605
|
+
* OOM'd once (D9/D18). A bounded on-demand read at human speed is the shape
|
|
25606
|
+
* those records permit; an unbounded one is the shape they forbid.
|
|
25607
|
+
*
|
|
25608
|
+
* Above it the provider REFUSES with a log line rather than truncating: half a
|
|
25609
|
+
* video is worse than a notification that says there is no attachment.
|
|
25610
|
+
*/
|
|
25611
|
+
var RECORDING_EXPORT_MAX_READ_BYTES = 50 * 1024 * 1024;
|
|
25612
|
+
/**
|
|
25613
|
+
* A finished export's bytes, inline.
|
|
25614
|
+
*
|
|
25615
|
+
* `bytes` is the DECODED length — the number the caller bounds and logs
|
|
25616
|
+
* against, so nobody has to infer it from the base64 length.
|
|
25617
|
+
*/
|
|
25618
|
+
var ExportBytesSchema = object({
|
|
25619
|
+
base64: string(),
|
|
25620
|
+
contentType: string(),
|
|
25621
|
+
/** Suggested filename, extension included. */
|
|
25622
|
+
name: string(),
|
|
25623
|
+
bytes: number().int().nonnegative()
|
|
25624
|
+
});
|
|
25531
25625
|
var recordingExportCapability = {
|
|
25532
25626
|
name: "recordingExport",
|
|
25533
25627
|
scope: "system",
|
|
@@ -25567,6 +25661,27 @@ var recordingExportCapability = {
|
|
|
25567
25661
|
getDownloadUrl: method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
25568
25662
|
kind: "query",
|
|
25569
25663
|
auth: "protected"
|
|
25664
|
+
}),
|
|
25665
|
+
/**
|
|
25666
|
+
* The finished file's BYTES, base64, for a caller that must republish them
|
|
25667
|
+
* somewhere a session-less fetcher can reach.
|
|
25668
|
+
*
|
|
25669
|
+
* `getDownloadUrl` is the right answer for a human: the download route is
|
|
25670
|
+
* served `access: 'authenticated'`, which a browser satisfies and a
|
|
25671
|
+
* notifier BACKEND does not. It answers a RELATIVE path, so it is not even
|
|
25672
|
+
* a URL an outside fetcher could try. This method exists for the one case
|
|
25673
|
+
* that needs the other thing — a scheduled timelapse whose video has to
|
|
25674
|
+
* become a public attachment on the notification artifact plane.
|
|
25675
|
+
*
|
|
25676
|
+
* Deliberately narrow: `ready` only (a queued, rendering, failed, expired
|
|
25677
|
+
* or deleted export has no file, and answering "0 bytes" for one is how a
|
|
25678
|
+
* caller ships an empty attachment), still inside its lifetime, and under
|
|
25679
|
+
* {@link RECORDING_EXPORT_MAX_READ_BYTES}. Every refusal throws with the
|
|
25680
|
+
* reason — none of them is silent.
|
|
25681
|
+
*/
|
|
25682
|
+
readExportBytes: method(object({ exportId: string() }), ExportBytesSchema, {
|
|
25683
|
+
kind: "query",
|
|
25684
|
+
auth: "protected"
|
|
25570
25685
|
})
|
|
25571
25686
|
}
|
|
25572
25687
|
};
|
|
@@ -30925,6 +31040,12 @@ Object.freeze({
|
|
|
30925
31040
|
addonId: null,
|
|
30926
31041
|
access: "view"
|
|
30927
31042
|
},
|
|
31043
|
+
"recordingExport.readExportBytes": {
|
|
31044
|
+
capName: "recordingExport",
|
|
31045
|
+
capScope: "system",
|
|
31046
|
+
addonId: null,
|
|
31047
|
+
access: "view"
|
|
31048
|
+
},
|
|
30928
31049
|
"sceneMonitor.captureReference": {
|
|
30929
31050
|
capName: "scene-monitor",
|
|
30930
31051
|
capScope: "device",
|
|
@@ -32342,10 +32463,28 @@ TimelapseRuleInputSchema.extend({
|
|
|
32342
32463
|
*/
|
|
32343
32464
|
ownerUserId: string().optional(),
|
|
32344
32465
|
/**
|
|
32345
|
-
* Epoch-ms of the
|
|
32346
|
-
*
|
|
32466
|
+
* Epoch-ms of the NEWEST successful generation across every camera of this
|
|
32467
|
+
* rule. What a UI shows, and the compatibility floor for
|
|
32468
|
+
* {@link readTimelapseGeneratedAt}. Absent = never generated.
|
|
32347
32469
|
*/
|
|
32348
32470
|
lastGeneratedAt: number().optional(),
|
|
32471
|
+
/**
|
|
32472
|
+
* PER-CAMERA generation state, keyed by `String(deviceId)` — the
|
|
32473
|
+
* re-generation guard's real durable state.
|
|
32474
|
+
*
|
|
32475
|
+
* One rule covers several cameras and each renders its own video, so a rule
|
|
32476
|
+
* -wide stamp is wrong in the direction that DESTROYS work: camera A
|
|
32477
|
+
* succeeding at 06:05 tells camera B, whose render failed, that it is
|
|
32478
|
+
* already done — and B's night is gone for good, because the window will not
|
|
32479
|
+
* come back.
|
|
32480
|
+
*
|
|
32481
|
+
* ADDITIVE, so the migration is free: a row written before this field simply
|
|
32482
|
+
* has no map, and {@link readTimelapseGeneratedAt} falls back to
|
|
32483
|
+
* {@link TimelapseRuleSchema.shape.lastGeneratedAt}. Reading an old row as
|
|
32484
|
+
* "never generated" would re-render and re-notify every camera of every rule
|
|
32485
|
+
* once, on the deploy that shipped the map.
|
|
32486
|
+
*/
|
|
32487
|
+
generatedByDevice: record(string(), number()).optional(),
|
|
32349
32488
|
/** userId of the caller who created the rule (server-stamped). */
|
|
32350
32489
|
createdBy: string(),
|
|
32351
32490
|
createdAt: number(),
|
|
@@ -33073,4 +33212,4 @@ function enumerateInferenceDevices(hw) {
|
|
|
33073
33212
|
return out;
|
|
33074
33213
|
}
|
|
33075
33214
|
//#endregion
|
|
33076
|
-
export {
|
|
33215
|
+
export { supportedRuntimes as $, defaultDeviceFor as A, string as At, mapAudioLabelToMacro as B, YAMNET_TO_MACRO as C, boolean as Ct, cameraStreamsCapability as D, number as Dt, audioAnalyzerCapability as E, literal as Et, egressTranscodeSharingKey as F, pipelineExecutorCapability as G, motionDetectionCapability as H, egressTransportFromRequest as I, recordingExportCapability as J, pipelineRunnerCapability as K, enumerateInferenceDevices as L, deriveDetailCropRect as M, EventCategory as Mt, deriveRecordingMode as N, createHwAccelCache as O, object as Ot, detectionPipelineCapability as P, streamBrokerCapability as Q, evaluateZoneRules as R, RingBuffer as S, array as St, audioAnalysisCapability as T, lazy as Tt, pickDetailCropConvention as U, maskUrlCredentials as V, pickNativeLeaseOverride as W, runtimeDevices as X, resolveEgressDecodeHwAccel as Y, storageEvictableCapability as Z, OpsLogEntrySchema as _, parseJsonUnknown as _t, COCO_TO_MACRO as a, invocationFromEncodeProfile as at, RECORDING_EXPORT_MAX_READ_BYTES as b, sleep as bt, DEFAULT_EVENTS_BAND_BUFFER_SEC as c, CAM_PROFILE_ORDER as ct, EVENT_PAD_MS as d, createEvent as dt, webrtcSessionCapability as et, EncodeProfileSchema as f, hydrateSchema as ft, NativeLeaseSettingsSchema as g, nodePin as gt, NativeLeaseAdmissionSchema as h, makeSourceBrokerId as ht, COCO_80_LABELS as i, buildFfmpegArgs as it, defineCustomActions as j, union as jt, customAction as k, record as kt, DEFAULT_NATIVE_LEASE_SETTINGS as l, DeviceFeature as lt, HF_BASE_URL as m, makeProfileBrokerId as mt, AUDIO_BACKEND_CHOICES as n, AUDIO_PRESETS as nt, DEFAULT_AUDIO_ANALYZER_CONFIG as o, isSoftwareDecode as ot, ExportRecordSchema as p, isEvent as pt, recordingCapability as q, AUDIO_MACRO_LABELS as r, Fmp4BoxSplitter as rt, DEFAULT_DETAIL_CROP_CONVENTION as s, BaseAddon as st, APPLE_SA_TO_MACRO as t, errMsg as tt, DEVICE_BACKEND_TO_FORMAT as u, DeviceType as ut, RATE_CONTROL_RELAXED as v, parseProfileBrokerId as vt, addonWidgetsSourceCapability as w, discriminatedUnion as wt, RecordingConfigSchema as x, _enum as xt, RATE_CONTROL_TIGHT as y, selectAssignedProfileSlots as yt, hfModelUrl as z };
|
package/dist/{event-loop-stall-monitor-BucTbe9v.mjs → event-loop-stall-monitor-BNyf5yEt.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS, z as hfModelUrl } from "./dist-BEbyhqoG.mjs";
|
|
2
2
|
import { PerformanceObserver } from "node:perf_hooks";
|
|
3
3
|
//#region src/detection-pipeline/registry/model-catalogs.ts
|
|
4
4
|
var HF_REPO = "camstack/camstack-models";
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-B6GWr9am.js");
|
|
6
6
|
const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { H as motionDetectionCapability, R as evaluateZoneRules, ft as hydrateSchema, st as BaseAddon, ut as DeviceType } from "../dist-BEbyhqoG.mjs";
|
|
2
2
|
import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|