@camstack/addon-post-analysis 1.2.224 → 1.2.225
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/{dist-CxPGPwcy.mjs → dist-B-cXIX_e.mjs} +176 -11
- package/dist/{dist-iJA2F7_d.js → dist-BypQW8jz.js} +193 -10
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-B3K65b9h.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-CpDC7X_O.mjs} +3 -3
- package/dist/pipeline-analytics/{hostInit-DoL6NTW5.mjs → hostInit-CchqWIpc.mjs} +3 -3
- package/dist/pipeline-analytics/index.js +1158 -296
- package/dist/pipeline-analytics/index.mjs +1158 -296
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
|
@@ -7491,6 +7491,34 @@ function errMsg(err) {
|
|
|
7491
7491
|
if (typeof err === "string") return err;
|
|
7492
7492
|
return String(err);
|
|
7493
7493
|
}
|
|
7494
|
+
new Set([
|
|
7495
|
+
"track",
|
|
7496
|
+
"summary",
|
|
7497
|
+
"face",
|
|
7498
|
+
"identity",
|
|
7499
|
+
"plate",
|
|
7500
|
+
"vehicle",
|
|
7501
|
+
"scene",
|
|
7502
|
+
"motion",
|
|
7503
|
+
"object",
|
|
7504
|
+
"audio"
|
|
7505
|
+
]);
|
|
7506
|
+
/** Build a media key. The timestamp segment is omitted when there is none. */
|
|
7507
|
+
function formatMediaOwnerKey(key) {
|
|
7508
|
+
const head = `${key.ownerType}:${key.ownerId}:${key.fileKind}`;
|
|
7509
|
+
return key.timestampMs === void 0 ? head : `${head}:${key.timestampMs}`;
|
|
7510
|
+
}
|
|
7511
|
+
/**
|
|
7512
|
+
* The owner types that are event tables, in the order the event-media resolver
|
|
7513
|
+
* should consider them. Exported so a consumer asking "is this key an event?"
|
|
7514
|
+
* does not re-spell the list and drift from it.
|
|
7515
|
+
*/
|
|
7516
|
+
var EVENT_OWNER_TYPES = [
|
|
7517
|
+
"motion",
|
|
7518
|
+
"object",
|
|
7519
|
+
"audio"
|
|
7520
|
+
];
|
|
7521
|
+
new Set(EVENT_OWNER_TYPES);
|
|
7494
7522
|
var EncodeProfileSchema = object({
|
|
7495
7523
|
video: object({
|
|
7496
7524
|
codec: _enum([
|
|
@@ -13096,8 +13124,17 @@ method(object({
|
|
|
13096
13124
|
}), array(SettingsRecordSchema).readonly()), method(object({
|
|
13097
13125
|
namespace: string().optional(),
|
|
13098
13126
|
collection: string(),
|
|
13099
|
-
record:
|
|
13100
|
-
|
|
13127
|
+
record: object({
|
|
13128
|
+
id: string().optional(),
|
|
13129
|
+
data: record(string(), unknown())
|
|
13130
|
+
})
|
|
13131
|
+
}), object({
|
|
13132
|
+
/**
|
|
13133
|
+
* The id the row ACTUALLY got (D473): the one supplied, the UUID minted
|
|
13134
|
+
* for an absent one, or the ROWID SQLite assigned on an `INTEGER`
|
|
13135
|
+
* primary key — which is the only place an auto key is knowable.
|
|
13136
|
+
*/
|
|
13137
|
+
id: union([string(), number()]) }), { kind: "mutation" }), method(object({
|
|
13101
13138
|
namespace: string().optional(),
|
|
13102
13139
|
collection: string(),
|
|
13103
13140
|
records: array(BulkRecordSchema).readonly()
|
|
@@ -13206,8 +13243,17 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
|
|
|
13206
13243
|
}), array(SettingsRecordSchema).readonly(), { auth: "admin" }), method(object({
|
|
13207
13244
|
namespace: string().optional(),
|
|
13208
13245
|
collection: string(),
|
|
13209
|
-
record:
|
|
13210
|
-
|
|
13246
|
+
record: object({
|
|
13247
|
+
id: string().optional(),
|
|
13248
|
+
data: record(string(), unknown())
|
|
13249
|
+
})
|
|
13250
|
+
}), object({
|
|
13251
|
+
/**
|
|
13252
|
+
* The id the row ACTUALLY got (D473): the one supplied, the UUID minted
|
|
13253
|
+
* for an absent one, or the ROWID SQLite assigned on an `INTEGER`
|
|
13254
|
+
* primary key — which is the only place an auto key is knowable.
|
|
13255
|
+
*/
|
|
13256
|
+
id: union([string(), number()]) }), {
|
|
13211
13257
|
kind: "mutation",
|
|
13212
13258
|
auth: "admin"
|
|
13213
13259
|
}), method(object({
|
|
@@ -20701,7 +20747,20 @@ var TrackSchema = object({
|
|
|
20701
20747
|
...TrackRetrainFields
|
|
20702
20748
|
});
|
|
20703
20749
|
var BaseEventFields = {
|
|
20704
|
-
|
|
20750
|
+
/**
|
|
20751
|
+
* A SQLite ROWID, assigned by the database (D474).
|
|
20752
|
+
*
|
|
20753
|
+
* Was a 36-character UUID and cost 263 MB of a 1 117 MB database — paid
|
|
20754
|
+
* TWICE per row, in the row and in the primary-key index, across 2.1 million
|
|
20755
|
+
* motion, audio and object events. An `INTEGER PRIMARY KEY` in SQLite **is**
|
|
20756
|
+
* the rowid: the table itself is that B-tree, so the index stops existing
|
|
20757
|
+
* rather than getting smaller. No shorter string does that.
|
|
20758
|
+
*
|
|
20759
|
+
* Defined once here for all three event kinds, which is why they move
|
|
20760
|
+
* together: a per-table migration would have forked this and
|
|
20761
|
+
* `COMMON_BASE_COLUMNS` and reunited them two stages later.
|
|
20762
|
+
*/
|
|
20763
|
+
id: number().int(),
|
|
20705
20764
|
deviceId: number(),
|
|
20706
20765
|
timestamp: number()
|
|
20707
20766
|
};
|
|
@@ -20720,7 +20779,34 @@ var MotionEventSchema = object({
|
|
|
20720
20779
|
/** Omitted in slim projection. */
|
|
20721
20780
|
frameHeight: number().optional(),
|
|
20722
20781
|
/** Populated by B5 (recording playback URL for this event). */
|
|
20723
|
-
mediaUrl: string().optional()
|
|
20782
|
+
mediaUrl: string().optional(),
|
|
20783
|
+
/**
|
|
20784
|
+
* One row per motion EPISODE, not one per push (D475). `null` while the
|
|
20785
|
+
* episode is still open — a further rising edge extends it in place rather
|
|
20786
|
+
* than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
|
|
20787
|
+
* (the span from the first rising edge to the LAST one, deliberately NOT
|
|
20788
|
+
* `closedAt - startedAt` — the close delay is a quiet CONFIRMATION, not
|
|
20789
|
+
* movement, and folding it in would report `MOTION_CLOSE_AFTER_MS` of
|
|
20790
|
+
* motion for an instantaneous trigger).
|
|
20791
|
+
*
|
|
20792
|
+
* **Absent** (not merely `null`) on a row written before D475 — that means
|
|
20793
|
+
* "closed the old way, before this column existed", never "still open".
|
|
20794
|
+
* Nothing in this codebase may read an absent `durationMs` as an open
|
|
20795
|
+
* episode; only `null` means open.
|
|
20796
|
+
*/
|
|
20797
|
+
durationMs: number().nullable().optional(),
|
|
20798
|
+
/**
|
|
20799
|
+
* Ms offsets from `timestamp` (the episode's own first rising edge, so the
|
|
20800
|
+
* first entry is always `0`) of every genuine off→on transition the
|
|
20801
|
+
* episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
|
|
20802
|
+
* push: a firmware source that keepalives at ~1 Hz for the whole burst
|
|
20803
|
+
* (Reolink, Hikvision) produces exactly one edge; a source that reports an
|
|
20804
|
+
* explicit `false` mid-episode and then resumes before the quiet window
|
|
20805
|
+
* elapses produces another. Stored compactly — see `motion-edge-codec.ts`
|
|
20806
|
+
* — and decoded back to this shape on read. Absent/empty on a legacy row,
|
|
20807
|
+
* which must never be read as "no episode happened here".
|
|
20808
|
+
*/
|
|
20809
|
+
edges: array(number()).readonly().optional()
|
|
20724
20810
|
});
|
|
20725
20811
|
/**
|
|
20726
20812
|
* Which detection SOURCE produced an object event. `pipeline` = the ML
|
|
@@ -20775,6 +20861,23 @@ var ObjectEventSchema = object({
|
|
|
20775
20861
|
* includes it (it is light). Absent on rows written before this field.
|
|
20776
20862
|
*/
|
|
20777
20863
|
frameId: string().optional(),
|
|
20864
|
+
/**
|
|
20865
|
+
* A PRODUCER-chosen key that makes a synthetic event's emission idempotent
|
|
20866
|
+
* (D474).
|
|
20867
|
+
*
|
|
20868
|
+
* Only the package detector writes it, and it exists because the event id
|
|
20869
|
+
* stopped being choosable: the delivery and pick-up rows used to BE their
|
|
20870
|
+
* dedupe key (`pa-pkg-<entryId>-delivered`), which is how "never emit a
|
|
20871
|
+
* second delivery for this entry" survived a restart. An `INTEGER` rowid is
|
|
20872
|
+
* assigned by SQLite, so that key had to move off the primary key rather
|
|
20873
|
+
* than be dropped — a detector that cannot recognise its own row re-delivers
|
|
20874
|
+
* every parcel on every boot.
|
|
20875
|
+
*
|
|
20876
|
+
* Absent on every other object event, and on every row written before this
|
|
20877
|
+
* field. Never a substitute for `id`: it is unique per (producer, occasion),
|
|
20878
|
+
* not per row, and nothing addresses a row by it.
|
|
20879
|
+
*/
|
|
20880
|
+
idempotencyKey: string().optional(),
|
|
20778
20881
|
/** Omitted in slim projection. */
|
|
20779
20882
|
trackId: string().optional(),
|
|
20780
20883
|
className: string(),
|
|
@@ -29734,14 +29837,72 @@ authKey: string().optional() }), object({
|
|
|
29734
29837
|
* (alert-center, advanced-notifier) can subscribe once and receive
|
|
29735
29838
|
* motion from every camera.
|
|
29736
29839
|
*/
|
|
29840
|
+
/**
|
|
29841
|
+
* How long after a camera's last rising edge `pipeline-analytics` closes the
|
|
29842
|
+
* motion EPISODE row it kept open for it (D475) — "il delay della cap", in
|
|
29843
|
+
* the operator's words. One authority for the whole system: every provider
|
|
29844
|
+
* that seeds `autoClearAfterMs` on a `Camera` device writes this SAME
|
|
29845
|
+
* constant while `detected: true` (never its own number — Hikvision used to
|
|
29846
|
+
* seed its internal 3 s inactivity timer here, which is a different clock for
|
|
29847
|
+
* a different purpose), and `MotionEpisodeTracker` imports it directly rather
|
|
29848
|
+
* than reading the live cap value on the hot path. A `Sensor` device (HA
|
|
29849
|
+
* binary sensor, Homematic) gets a genuine push both ways and has no episode
|
|
29850
|
+
* to close on a timer, so it writes `null`, never this constant.
|
|
29851
|
+
*/
|
|
29852
|
+
var MOTION_CLOSE_AFTER_MS = 15e3;
|
|
29737
29853
|
var MotionStatusSchema = object({
|
|
29738
29854
|
detected: boolean(),
|
|
29739
29855
|
/** Ms epoch of the last detected-true observation. Null if never detected. */
|
|
29740
29856
|
lastDetectedAt: number().nullable(),
|
|
29741
29857
|
/**
|
|
29742
|
-
*
|
|
29743
|
-
*
|
|
29744
|
-
*
|
|
29858
|
+
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device,
|
|
29859
|
+
* `null` while false and on every `Sensor` device (D475) — see that
|
|
29860
|
+
* constant's doc for the one-authority rule.
|
|
29861
|
+
*
|
|
29862
|
+
* ## Reading this field still arms nothing
|
|
29863
|
+
*
|
|
29864
|
+
* It reads like an instruction to the consumer ("revert after N ms if
|
|
29865
|
+
* no fresh push arrives") and it is not one: nothing in this repo reads
|
|
29866
|
+
* the LIVE cap value to drive a timer. `pipeline-analytics`'s motion-episode
|
|
29867
|
+
* close DOES now use the same number — `MOTION_CLOSE_AFTER_MS` — but as an
|
|
29868
|
+
* imported constant, not as a read of `device.state.motion.value`, so this
|
|
29869
|
+
* field stays what it always was: DESCRIPTIVE output, mirroring an answer
|
|
29870
|
+
* computed elsewhere. Building a self-clear timer out of a READ of this
|
|
29871
|
+
* field would add a second falling-edge authority beside whichever one
|
|
29872
|
+
* already owns the device, and two that can disagree are worse than one.
|
|
29873
|
+
* Consumers that need a falling edge SHAPED differently — held open across
|
|
29874
|
+
* a flapping source — debounce on their own side and say so, as
|
|
29875
|
+
* `addon-export-alexa/src/motion-clear-hold.ts` and
|
|
29876
|
+
* `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
|
|
29877
|
+
*
|
|
29878
|
+
* ## Who writes it
|
|
29879
|
+
*
|
|
29880
|
+
* - **Cameras** — the runner's phase machine, `active → watching` on
|
|
29881
|
+
* `cooldown_expired`, which then writes this slice with
|
|
29882
|
+
* `detected: false` (`handlePhaseChanged` in
|
|
29883
|
+
* `pipeline-runner/index.ts`). It produces the FALLING edge, which
|
|
29884
|
+
* matters most for the sources that only ever push a rising one:
|
|
29885
|
+
* Reolink emits `MotionOnMotionChanged { detected: true }` and never
|
|
29886
|
+
* a false.
|
|
29887
|
+
* - **Sensors** (Home Assistant binary sensors, Homematic) — the
|
|
29888
|
+
* provider pushes the false itself, from the upstream system's own
|
|
29889
|
+
* state change. No phase machine is involved.
|
|
29890
|
+
*
|
|
29891
|
+
* ### The phase machine is CANONICAL, not sole — and that is a defect
|
|
29892
|
+
*
|
|
29893
|
+
* An earlier revision of this docblock (mine, 2026-09-12) claimed the
|
|
29894
|
+
* phase machine is the sole writer for a camera. It is not.
|
|
29895
|
+
* `hikvision-camera.ts:3464` and `amcrest-camera.ts:445` both call
|
|
29896
|
+
* `setCapSlice(motionCapability, …)` on their own rising edge, and
|
|
29897
|
+
* Hikvision's comment says why: it read THIS docblock, agreed the
|
|
29898
|
+
* runner is canonical, and wrote anyway to avoid per-tick churn. So
|
|
29899
|
+
* two authorities can disagree about one slice, which this repo
|
|
29900
|
+
* forbids, and the doc said otherwise — which is worse than saying
|
|
29901
|
+
* nothing, because it reads as verification.
|
|
29902
|
+
*
|
|
29903
|
+
* This predates D475 and is not fixed there: the fix touches every
|
|
29904
|
+
* camera provider. Recorded in D475's Consequences. Do not restore the
|
|
29905
|
+
* "sole writer" wording without also removing the other writers.
|
|
29745
29906
|
*/
|
|
29746
29907
|
autoClearAfterMs: number().nullable()
|
|
29747
29908
|
});
|
|
@@ -29811,7 +29972,11 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
29811
29972
|
*/
|
|
29812
29973
|
runtimeState: MotionStatusSchema,
|
|
29813
29974
|
/**
|
|
29814
|
-
* Runtime-state durability: **session** —
|
|
29975
|
+
* Runtime-state durability: **session** — every writer of this slice
|
|
29976
|
+
* writes only on an EDGE, so a restored `detected: true` would stay
|
|
29977
|
+
* frozen until the next one instead of being corrected. The next edge
|
|
29978
|
+
* re-publishes the real state. (On who the writers are, and why there
|
|
29979
|
+
* is more than one, see `autoClearAfterMs` above.)
|
|
29815
29980
|
*
|
|
29816
29981
|
* See `RuntimeStateDurability`. Enforced by
|
|
29817
29982
|
* `scripts/check-runtime-state-durability.ts`.
|
|
@@ -45672,4 +45837,4 @@ function vectorDimFromBase64(encoded) {
|
|
|
45672
45837
|
return Math.floor(Buffer.from(encoded, "base64").byteLength / 4);
|
|
45673
45838
|
}
|
|
45674
45839
|
//#endregion
|
|
45675
|
-
export {
|
|
45840
|
+
export { TimelapseRuleSchema as $, discriminatedUnion as $t, NcConditionDescriptorSchema as A, readDeviceStateFrom as At, NcTaxonomySchema as B, zoneAnalyticsCapability as Bt, MOTION_CLOSE_AFTER_MS as C, kebabToCamel as Ct, NC_DEFAULT_SNOOZE_MINUTES as D, pickClusterStepModels as Dt, NC_CONDITION_CATALOG as E, parseProcStatus as Et, NcScheduleSchema as F, storageOccupancyCapability as Ft, SCENE_CONFIRM_DEFAULT_TIMEOUT_MS as G, createEvent as Gt, PoolMemoryWatchdog as H, BaseAddon as Ht, NcSnoozeInputSchema as I, subKindsOf as It, SCENE_DIVERGED as J, nodePin as Jt, SCENE_DEFAULT_ANCHOR_THRESHOLD as K, hydrateSchema as Kt, NcSnoozeSchema as L, systemEventFilterApplies as Lt, NcRulePatchSchema as M, resolveLocationMode as Mt, NcRuleSchema as N, resolvePoolMemoryPolicy as Nt, NC_SNOOZE_MAX_MINUTES as O, pipelineAnalyticsCapability as Ot, NcRuleTargetSchema as P, sceneMonitorCapability as Pt, TimelapseRulePatchSchema as Q, boolean as Qt, NcSnoozeSuppressedSchema as R, vectorDimFromBase64 as Rt, MAX_BIRTH_LATENCY_PROXY_MS as S, isSourceCap as St, NC_ALARM_SYSTEM_EVENT_KINDS as T, notificationRulesCapability as Tt, RECORDING_EXPORT_MAX_READ_BYTES as U, CamProfileSchema as Ut, OpsLogEntrySchema as V, errMsg as Vt, RetrainStatusSchema as W, DeviceType as Wt, TIMELAPSE_DENSE_FLOOR_SEC as X, _enum as Xt, SceneMonitorSchema as Y, sleep as Yt, TimelapseRuleInputSchema as Z, array as Zt, FULL_IMAGE_BBOX as _, failureContributionCapability as _t, CLUSTER_MODEL_SCOPED_STEPS as a, string as an, audioMetricsCapability as at, MAX_ARCHIVED_DEBUG_NOTES as b, isDetectionMacroClass as bt, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as c, cosineSimilarity as ct, DETECTION_PIPELINE_CAP_NAME as d, deriveRecordingMode as dt, literal as en, TrackSourceSchema as et, DeclaredDevices as f, embeddingEncoderCapability as ft, FIRST_LEVEL_MACRO_CLASSES as g, faceGalleryCapability as gt, EVENT_PAD_MS as h, evictionPolicyOfLocation as ht, BirthDecisionRecordSchema as i, record as in, assertTimelapseCadences as it, NcRuleInputSchema as j, readTimelapseGeneratedAt as jt, NC_TAXONOMY as k, plateGalleryCapability as kt, DEFAULT_TIMELAPSE_PREVIEW_TEXT as l, customAction as lt, EVENT_OWNER_TYPES as m, evaluateSensorEdge as mt, ArchivedDebugNoteSchema as n, object as nn, addonWidgetsSourceCapability as nt, COCO_TO_MACRO as o, unknown as on, audioModeOf as ot, EVENT_KIND_BY_CAP as p, encodeVectorBase64 as pt, SCENE_DEFAULT_UNCOVERED_POLICY as q, isDeviceScopedCap as qt, BaseDevice as r, partialRecord as rn, alarmPanelCapability as rt, DEFAULT_EVENT_COLOR as s, EventCategory as sn, buildEventKindDescriptor as st, AUDIO_MACRO_LABELS as t, number as tn, VISIT_MERGE_GAP_MS as tt, DETECTION_MACRO_CLASSES as u, defineCustomActions as ut, FailureCounters as v, formatMediaOwnerKey as vt, MediaFileKindEnum as w, mayWriteToLocation as wt, MAX_BIRTH_DECISION_RECORDS as x, isScheduleActive as xt, LabelAttributionSchema as y, hfModelUrl as yt, NcSystemEventKindSchema as z, videoclipsCapability as zt };
|
|
@@ -7522,6 +7522,34 @@ function errMsg(err) {
|
|
|
7522
7522
|
if (typeof err === "string") return err;
|
|
7523
7523
|
return String(err);
|
|
7524
7524
|
}
|
|
7525
|
+
new Set([
|
|
7526
|
+
"track",
|
|
7527
|
+
"summary",
|
|
7528
|
+
"face",
|
|
7529
|
+
"identity",
|
|
7530
|
+
"plate",
|
|
7531
|
+
"vehicle",
|
|
7532
|
+
"scene",
|
|
7533
|
+
"motion",
|
|
7534
|
+
"object",
|
|
7535
|
+
"audio"
|
|
7536
|
+
]);
|
|
7537
|
+
/** Build a media key. The timestamp segment is omitted when there is none. */
|
|
7538
|
+
function formatMediaOwnerKey(key) {
|
|
7539
|
+
const head = `${key.ownerType}:${key.ownerId}:${key.fileKind}`;
|
|
7540
|
+
return key.timestampMs === void 0 ? head : `${head}:${key.timestampMs}`;
|
|
7541
|
+
}
|
|
7542
|
+
/**
|
|
7543
|
+
* The owner types that are event tables, in the order the event-media resolver
|
|
7544
|
+
* should consider them. Exported so a consumer asking "is this key an event?"
|
|
7545
|
+
* does not re-spell the list and drift from it.
|
|
7546
|
+
*/
|
|
7547
|
+
var EVENT_OWNER_TYPES = [
|
|
7548
|
+
"motion",
|
|
7549
|
+
"object",
|
|
7550
|
+
"audio"
|
|
7551
|
+
];
|
|
7552
|
+
new Set(EVENT_OWNER_TYPES);
|
|
7525
7553
|
var EncodeProfileSchema = object({
|
|
7526
7554
|
video: object({
|
|
7527
7555
|
codec: _enum([
|
|
@@ -13127,8 +13155,17 @@ method(object({
|
|
|
13127
13155
|
}), array(SettingsRecordSchema).readonly()), method(object({
|
|
13128
13156
|
namespace: string().optional(),
|
|
13129
13157
|
collection: string(),
|
|
13130
|
-
record:
|
|
13131
|
-
|
|
13158
|
+
record: object({
|
|
13159
|
+
id: string().optional(),
|
|
13160
|
+
data: record(string(), unknown())
|
|
13161
|
+
})
|
|
13162
|
+
}), object({
|
|
13163
|
+
/**
|
|
13164
|
+
* The id the row ACTUALLY got (D473): the one supplied, the UUID minted
|
|
13165
|
+
* for an absent one, or the ROWID SQLite assigned on an `INTEGER`
|
|
13166
|
+
* primary key — which is the only place an auto key is knowable.
|
|
13167
|
+
*/
|
|
13168
|
+
id: union([string(), number()]) }), { kind: "mutation" }), method(object({
|
|
13132
13169
|
namespace: string().optional(),
|
|
13133
13170
|
collection: string(),
|
|
13134
13171
|
records: array(BulkRecordSchema).readonly()
|
|
@@ -13237,8 +13274,17 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
|
|
|
13237
13274
|
}), array(SettingsRecordSchema).readonly(), { auth: "admin" }), method(object({
|
|
13238
13275
|
namespace: string().optional(),
|
|
13239
13276
|
collection: string(),
|
|
13240
|
-
record:
|
|
13241
|
-
|
|
13277
|
+
record: object({
|
|
13278
|
+
id: string().optional(),
|
|
13279
|
+
data: record(string(), unknown())
|
|
13280
|
+
})
|
|
13281
|
+
}), object({
|
|
13282
|
+
/**
|
|
13283
|
+
* The id the row ACTUALLY got (D473): the one supplied, the UUID minted
|
|
13284
|
+
* for an absent one, or the ROWID SQLite assigned on an `INTEGER`
|
|
13285
|
+
* primary key — which is the only place an auto key is knowable.
|
|
13286
|
+
*/
|
|
13287
|
+
id: union([string(), number()]) }), {
|
|
13242
13288
|
kind: "mutation",
|
|
13243
13289
|
auth: "admin"
|
|
13244
13290
|
}), method(object({
|
|
@@ -20732,7 +20778,20 @@ var TrackSchema = object({
|
|
|
20732
20778
|
...TrackRetrainFields
|
|
20733
20779
|
});
|
|
20734
20780
|
var BaseEventFields = {
|
|
20735
|
-
|
|
20781
|
+
/**
|
|
20782
|
+
* A SQLite ROWID, assigned by the database (D474).
|
|
20783
|
+
*
|
|
20784
|
+
* Was a 36-character UUID and cost 263 MB of a 1 117 MB database — paid
|
|
20785
|
+
* TWICE per row, in the row and in the primary-key index, across 2.1 million
|
|
20786
|
+
* motion, audio and object events. An `INTEGER PRIMARY KEY` in SQLite **is**
|
|
20787
|
+
* the rowid: the table itself is that B-tree, so the index stops existing
|
|
20788
|
+
* rather than getting smaller. No shorter string does that.
|
|
20789
|
+
*
|
|
20790
|
+
* Defined once here for all three event kinds, which is why they move
|
|
20791
|
+
* together: a per-table migration would have forked this and
|
|
20792
|
+
* `COMMON_BASE_COLUMNS` and reunited them two stages later.
|
|
20793
|
+
*/
|
|
20794
|
+
id: number().int(),
|
|
20736
20795
|
deviceId: number(),
|
|
20737
20796
|
timestamp: number()
|
|
20738
20797
|
};
|
|
@@ -20751,7 +20810,34 @@ var MotionEventSchema = object({
|
|
|
20751
20810
|
/** Omitted in slim projection. */
|
|
20752
20811
|
frameHeight: number().optional(),
|
|
20753
20812
|
/** Populated by B5 (recording playback URL for this event). */
|
|
20754
|
-
mediaUrl: string().optional()
|
|
20813
|
+
mediaUrl: string().optional(),
|
|
20814
|
+
/**
|
|
20815
|
+
* One row per motion EPISODE, not one per push (D475). `null` while the
|
|
20816
|
+
* episode is still open — a further rising edge extends it in place rather
|
|
20817
|
+
* than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
|
|
20818
|
+
* (the span from the first rising edge to the LAST one, deliberately NOT
|
|
20819
|
+
* `closedAt - startedAt` — the close delay is a quiet CONFIRMATION, not
|
|
20820
|
+
* movement, and folding it in would report `MOTION_CLOSE_AFTER_MS` of
|
|
20821
|
+
* motion for an instantaneous trigger).
|
|
20822
|
+
*
|
|
20823
|
+
* **Absent** (not merely `null`) on a row written before D475 — that means
|
|
20824
|
+
* "closed the old way, before this column existed", never "still open".
|
|
20825
|
+
* Nothing in this codebase may read an absent `durationMs` as an open
|
|
20826
|
+
* episode; only `null` means open.
|
|
20827
|
+
*/
|
|
20828
|
+
durationMs: number().nullable().optional(),
|
|
20829
|
+
/**
|
|
20830
|
+
* Ms offsets from `timestamp` (the episode's own first rising edge, so the
|
|
20831
|
+
* first entry is always `0`) of every genuine off→on transition the
|
|
20832
|
+
* episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
|
|
20833
|
+
* push: a firmware source that keepalives at ~1 Hz for the whole burst
|
|
20834
|
+
* (Reolink, Hikvision) produces exactly one edge; a source that reports an
|
|
20835
|
+
* explicit `false` mid-episode and then resumes before the quiet window
|
|
20836
|
+
* elapses produces another. Stored compactly — see `motion-edge-codec.ts`
|
|
20837
|
+
* — and decoded back to this shape on read. Absent/empty on a legacy row,
|
|
20838
|
+
* which must never be read as "no episode happened here".
|
|
20839
|
+
*/
|
|
20840
|
+
edges: array(number()).readonly().optional()
|
|
20755
20841
|
});
|
|
20756
20842
|
/**
|
|
20757
20843
|
* Which detection SOURCE produced an object event. `pipeline` = the ML
|
|
@@ -20806,6 +20892,23 @@ var ObjectEventSchema = object({
|
|
|
20806
20892
|
* includes it (it is light). Absent on rows written before this field.
|
|
20807
20893
|
*/
|
|
20808
20894
|
frameId: string().optional(),
|
|
20895
|
+
/**
|
|
20896
|
+
* A PRODUCER-chosen key that makes a synthetic event's emission idempotent
|
|
20897
|
+
* (D474).
|
|
20898
|
+
*
|
|
20899
|
+
* Only the package detector writes it, and it exists because the event id
|
|
20900
|
+
* stopped being choosable: the delivery and pick-up rows used to BE their
|
|
20901
|
+
* dedupe key (`pa-pkg-<entryId>-delivered`), which is how "never emit a
|
|
20902
|
+
* second delivery for this entry" survived a restart. An `INTEGER` rowid is
|
|
20903
|
+
* assigned by SQLite, so that key had to move off the primary key rather
|
|
20904
|
+
* than be dropped — a detector that cannot recognise its own row re-delivers
|
|
20905
|
+
* every parcel on every boot.
|
|
20906
|
+
*
|
|
20907
|
+
* Absent on every other object event, and on every row written before this
|
|
20908
|
+
* field. Never a substitute for `id`: it is unique per (producer, occasion),
|
|
20909
|
+
* not per row, and nothing addresses a row by it.
|
|
20910
|
+
*/
|
|
20911
|
+
idempotencyKey: string().optional(),
|
|
20809
20912
|
/** Omitted in slim projection. */
|
|
20810
20913
|
trackId: string().optional(),
|
|
20811
20914
|
className: string(),
|
|
@@ -29765,14 +29868,72 @@ authKey: string().optional() }), object({
|
|
|
29765
29868
|
* (alert-center, advanced-notifier) can subscribe once and receive
|
|
29766
29869
|
* motion from every camera.
|
|
29767
29870
|
*/
|
|
29871
|
+
/**
|
|
29872
|
+
* How long after a camera's last rising edge `pipeline-analytics` closes the
|
|
29873
|
+
* motion EPISODE row it kept open for it (D475) — "il delay della cap", in
|
|
29874
|
+
* the operator's words. One authority for the whole system: every provider
|
|
29875
|
+
* that seeds `autoClearAfterMs` on a `Camera` device writes this SAME
|
|
29876
|
+
* constant while `detected: true` (never its own number — Hikvision used to
|
|
29877
|
+
* seed its internal 3 s inactivity timer here, which is a different clock for
|
|
29878
|
+
* a different purpose), and `MotionEpisodeTracker` imports it directly rather
|
|
29879
|
+
* than reading the live cap value on the hot path. A `Sensor` device (HA
|
|
29880
|
+
* binary sensor, Homematic) gets a genuine push both ways and has no episode
|
|
29881
|
+
* to close on a timer, so it writes `null`, never this constant.
|
|
29882
|
+
*/
|
|
29883
|
+
var MOTION_CLOSE_AFTER_MS = 15e3;
|
|
29768
29884
|
var MotionStatusSchema = object({
|
|
29769
29885
|
detected: boolean(),
|
|
29770
29886
|
/** Ms epoch of the last detected-true observation. Null if never detected. */
|
|
29771
29887
|
lastDetectedAt: number().nullable(),
|
|
29772
29888
|
/**
|
|
29773
|
-
*
|
|
29774
|
-
*
|
|
29775
|
-
*
|
|
29889
|
+
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device,
|
|
29890
|
+
* `null` while false and on every `Sensor` device (D475) — see that
|
|
29891
|
+
* constant's doc for the one-authority rule.
|
|
29892
|
+
*
|
|
29893
|
+
* ## Reading this field still arms nothing
|
|
29894
|
+
*
|
|
29895
|
+
* It reads like an instruction to the consumer ("revert after N ms if
|
|
29896
|
+
* no fresh push arrives") and it is not one: nothing in this repo reads
|
|
29897
|
+
* the LIVE cap value to drive a timer. `pipeline-analytics`'s motion-episode
|
|
29898
|
+
* close DOES now use the same number — `MOTION_CLOSE_AFTER_MS` — but as an
|
|
29899
|
+
* imported constant, not as a read of `device.state.motion.value`, so this
|
|
29900
|
+
* field stays what it always was: DESCRIPTIVE output, mirroring an answer
|
|
29901
|
+
* computed elsewhere. Building a self-clear timer out of a READ of this
|
|
29902
|
+
* field would add a second falling-edge authority beside whichever one
|
|
29903
|
+
* already owns the device, and two that can disagree are worse than one.
|
|
29904
|
+
* Consumers that need a falling edge SHAPED differently — held open across
|
|
29905
|
+
* a flapping source — debounce on their own side and say so, as
|
|
29906
|
+
* `addon-export-alexa/src/motion-clear-hold.ts` and
|
|
29907
|
+
* `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
|
|
29908
|
+
*
|
|
29909
|
+
* ## Who writes it
|
|
29910
|
+
*
|
|
29911
|
+
* - **Cameras** — the runner's phase machine, `active → watching` on
|
|
29912
|
+
* `cooldown_expired`, which then writes this slice with
|
|
29913
|
+
* `detected: false` (`handlePhaseChanged` in
|
|
29914
|
+
* `pipeline-runner/index.ts`). It produces the FALLING edge, which
|
|
29915
|
+
* matters most for the sources that only ever push a rising one:
|
|
29916
|
+
* Reolink emits `MotionOnMotionChanged { detected: true }` and never
|
|
29917
|
+
* a false.
|
|
29918
|
+
* - **Sensors** (Home Assistant binary sensors, Homematic) — the
|
|
29919
|
+
* provider pushes the false itself, from the upstream system's own
|
|
29920
|
+
* state change. No phase machine is involved.
|
|
29921
|
+
*
|
|
29922
|
+
* ### The phase machine is CANONICAL, not sole — and that is a defect
|
|
29923
|
+
*
|
|
29924
|
+
* An earlier revision of this docblock (mine, 2026-09-12) claimed the
|
|
29925
|
+
* phase machine is the sole writer for a camera. It is not.
|
|
29926
|
+
* `hikvision-camera.ts:3464` and `amcrest-camera.ts:445` both call
|
|
29927
|
+
* `setCapSlice(motionCapability, …)` on their own rising edge, and
|
|
29928
|
+
* Hikvision's comment says why: it read THIS docblock, agreed the
|
|
29929
|
+
* runner is canonical, and wrote anyway to avoid per-tick churn. So
|
|
29930
|
+
* two authorities can disagree about one slice, which this repo
|
|
29931
|
+
* forbids, and the doc said otherwise — which is worse than saying
|
|
29932
|
+
* nothing, because it reads as verification.
|
|
29933
|
+
*
|
|
29934
|
+
* This predates D475 and is not fixed there: the fix touches every
|
|
29935
|
+
* camera provider. Recorded in D475's Consequences. Do not restore the
|
|
29936
|
+
* "sole writer" wording without also removing the other writers.
|
|
29776
29937
|
*/
|
|
29777
29938
|
autoClearAfterMs: number().nullable()
|
|
29778
29939
|
});
|
|
@@ -29842,7 +30003,11 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
29842
30003
|
*/
|
|
29843
30004
|
runtimeState: MotionStatusSchema,
|
|
29844
30005
|
/**
|
|
29845
|
-
* Runtime-state durability: **session** —
|
|
30006
|
+
* Runtime-state durability: **session** — every writer of this slice
|
|
30007
|
+
* writes only on an EDGE, so a restored `detected: true` would stay
|
|
30008
|
+
* frozen until the next one instead of being corrected. The next edge
|
|
30009
|
+
* re-publishes the real state. (On who the writers are, and why there
|
|
30010
|
+
* is more than one, see `autoClearAfterMs` above.)
|
|
29846
30011
|
*
|
|
29847
30012
|
* See `RuntimeStateDurability`. Enforced by
|
|
29848
30013
|
* `scripts/check-runtime-state-durability.ts`.
|
|
@@ -45799,6 +45964,12 @@ Object.defineProperty(exports, "EVENT_KIND_BY_CAP", {
|
|
|
45799
45964
|
return EVENT_KIND_BY_CAP;
|
|
45800
45965
|
}
|
|
45801
45966
|
});
|
|
45967
|
+
Object.defineProperty(exports, "EVENT_OWNER_TYPES", {
|
|
45968
|
+
enumerable: true,
|
|
45969
|
+
get: function() {
|
|
45970
|
+
return EVENT_OWNER_TYPES;
|
|
45971
|
+
}
|
|
45972
|
+
});
|
|
45802
45973
|
Object.defineProperty(exports, "EVENT_PAD_MS", {
|
|
45803
45974
|
enumerable: true,
|
|
45804
45975
|
get: function() {
|
|
@@ -45853,6 +46024,12 @@ Object.defineProperty(exports, "MAX_BIRTH_LATENCY_PROXY_MS", {
|
|
|
45853
46024
|
return MAX_BIRTH_LATENCY_PROXY_MS;
|
|
45854
46025
|
}
|
|
45855
46026
|
});
|
|
46027
|
+
Object.defineProperty(exports, "MOTION_CLOSE_AFTER_MS", {
|
|
46028
|
+
enumerable: true,
|
|
46029
|
+
get: function() {
|
|
46030
|
+
return MOTION_CLOSE_AFTER_MS;
|
|
46031
|
+
}
|
|
46032
|
+
});
|
|
45856
46033
|
Object.defineProperty(exports, "MediaFileKindEnum", {
|
|
45857
46034
|
enumerable: true,
|
|
45858
46035
|
get: function() {
|
|
@@ -46189,6 +46366,12 @@ Object.defineProperty(exports, "failureContributionCapability", {
|
|
|
46189
46366
|
return failureContributionCapability;
|
|
46190
46367
|
}
|
|
46191
46368
|
});
|
|
46369
|
+
Object.defineProperty(exports, "formatMediaOwnerKey", {
|
|
46370
|
+
enumerable: true,
|
|
46371
|
+
get: function() {
|
|
46372
|
+
return formatMediaOwnerKey;
|
|
46373
|
+
}
|
|
46374
|
+
});
|
|
46192
46375
|
Object.defineProperty(exports, "hfModelUrl", {
|
|
46193
46376
|
enumerable: true,
|
|
46194
46377
|
get: function() {
|
|
@@ -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-BypQW8jz.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
node_fs = require_dist.__toESM(node_fs);
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Et as parseProcStatus, H as PoolMemoryWatchdog, Ht as BaseAddon, Nt as resolvePoolMemoryPolicy, ft as embeddingEncoderCapability, yt as hfModelUrl } from "../dist-B-cXIX_e.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ import "./dist-CYZr2fwk.mjs";
|
|
|
3
3
|
var e = {
|
|
4
4
|
"@camstack/sdk": {
|
|
5
5
|
name: "@camstack/sdk",
|
|
6
|
-
version: "1.2.
|
|
6
|
+
version: "1.2.101",
|
|
7
7
|
scope: ["default"],
|
|
8
8
|
loaded: !1,
|
|
9
9
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.2.
|
|
21
|
+
version: "1.2.181",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.2.
|
|
36
|
+
version: "1.2.149",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.2.
|
|
39
|
+
version: "1.2.181",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -45,7 +45,7 @@ async function r() {
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"@camstack/sdk": {
|
|
48
|
-
version: "1.2.
|
|
48
|
+
version: "1.2.101",
|
|
49
49
|
scope: "default",
|
|
50
50
|
shareConfig: {
|
|
51
51
|
singleton: !0,
|
|
@@ -81,7 +81,7 @@ async function r() {
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"@camstack/ui-library": {
|
|
84
|
-
version: "1.2.
|
|
84
|
+
version: "1.2.149",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|