@camstack/addon-provider-onvif 1.2.98 → 1.2.100

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 (3) hide show
  1. package/dist/addon.js +292 -58
  2. package/dist/addon.mjs +292 -58
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region \0rolldown/runtime.js
3
3
  var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
4
4
  //#endregion
5
- //#region ../types/dist/event-category-DAXzJeTX.mjs
5
+ //#region ../types/dist/event-category-ZyX6jcse.mjs
6
6
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
7
7
  EventCategory["SystemBoot"] = "system.boot";
8
8
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -563,7 +563,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
563
563
  * a package zone — a newly-appeared stationary object of a package class
564
564
  * that cleared the class / zone / dwell / size gates. Payload:
565
565
  * `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
566
- * entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
566
+ * entryId, className, zoneIds, keyFrameMediaId?, bbox, timestamp }`.
567
567
  * Telemetry (D8): the durable record is the `package-events` store row;
568
568
  * this bus topic drives notifier rules + live UI. See
569
569
  * docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
@@ -5349,7 +5349,7 @@ var ZodIssueCode = {
5349
5349
  var ZodFirstPartyTypeKind;
5350
5350
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5351
5351
  //#endregion
5352
- //#region ../types/dist/sleep-BnujYGPe.mjs
5352
+ //#region ../types/dist/sleep-DBKu2-U5.mjs
5353
5353
  /**
5354
5354
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5355
5355
  * window to float samples (D455).
@@ -7312,13 +7312,30 @@ new Set([
7312
7312
  "scene",
7313
7313
  "motion",
7314
7314
  "object",
7315
- "audio"
7315
+ "audio",
7316
+ "mosaic"
7316
7317
  ]);
7317
- new Set([
7318
+ /**
7319
+ * The owner types that are event tables, in the order the event-media resolver
7320
+ * should consider them. Exported so a consumer asking "is this key an event?"
7321
+ * does not re-spell the list and drift from it.
7322
+ */
7323
+ var EVENT_OWNER_TYPES = [
7318
7324
  "motion",
7319
7325
  "object",
7320
7326
  "audio"
7321
- ]);
7327
+ ];
7328
+ /**
7329
+ * The same list as a Zod enum, for the cap inputs that must NAME the table
7330
+ * (D482: `getEventMedia` / `listEventMedia` take an owner, and an owner is
7331
+ * `(table, id)`).
7332
+ *
7333
+ * Built FROM {@link EVENT_OWNER_TYPES} rather than re-spelled: a fourth event
7334
+ * table would otherwise be accepted by the codec and refused at the door, with
7335
+ * nothing failing until a caller asked.
7336
+ */
7337
+ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
7338
+ new Set(EVENT_OWNER_TYPES);
7322
7339
  var EncodeProfileSchema = object({
7323
7340
  video: object({
7324
7341
  codec: _enum([
@@ -7357,7 +7374,23 @@ var EncodeProfileSchema = object({
7357
7374
  "zerolatency",
7358
7375
  "film",
7359
7376
  "animation"
7360
- ]).optional()
7377
+ ]).optional(),
7378
+ /**
7379
+ * ONE slice per access unit.
7380
+ *
7381
+ * `-tune zerolatency` turns on x264's sliced threads, and a frame then leaves
7382
+ * the encoder as five NAL slices that share one RTP timestamp and carry one
7383
+ * marker bit. A libwebrtc depacketiser sees five frame-starts and one
7384
+ * frame-end per frame: the first pictures render and the video then freezes
7385
+ * for good while the audio, on its own plane, plays on. Measured on this hub
7386
+ * 2026-09-13 against the Echo, and reduced to one slice by this flag alone.
7387
+ *
7388
+ * A NAMED field and not a raw flag, because {@link EgressEncodeSchema} omits
7389
+ * `outputArgs` on purpose: an opaque array is part of the sharing key, so two
7390
+ * consumers meaning the same thing spelled differently would stop sharing one
7391
+ * child. Absent means "whatever the encoder does" — today's behaviour.
7392
+ */
7393
+ singleSlicePerFrame: boolean().optional()
7361
7394
  }),
7362
7395
  audio: union([literal("passthrough"), object({
7363
7396
  codec: _enum([
@@ -7407,7 +7440,7 @@ var BASE_LIVE_EGRESS_PROFILE = {
7407
7440
  audio: "passthrough"
7408
7441
  };
7409
7442
  ({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
7410
- ({ ...BASE_LIVE_EGRESS_PROFILE });
7443
+ ({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
7411
7444
  /**
7412
7445
  * Deep wiring healthcheck — snapshot of active reachability probes across
7413
7446
  * every declared capability + widget of every installed plugin, on every
@@ -12415,6 +12448,16 @@ method(object({
12415
12448
  filter: QueryFilterSchema.optional(),
12416
12449
  columns: array(string()).readonly().optional()
12417
12450
  }), array(SettingsRecordSchema).readonly()), method(object({
12451
+ namespace: string().optional(),
12452
+ collection: string(),
12453
+ /** Declared columns identifying the slot; must be covered by a UNIQUE
12454
+ * index on the collection. Never empty. */
12455
+ conflict: array(string()).readonly(),
12456
+ record: BulkRecordSchema
12457
+ }), object({
12458
+ /** The id the row HAS: assigned by SQLite on an insert, or the existing
12459
+ * row's own id on an update. */
12460
+ id: union([string(), number()]) }), { kind: "mutation" }), method(object({
12418
12461
  namespace: string().optional(),
12419
12462
  collection: string(),
12420
12463
  record: object({
@@ -12549,6 +12592,14 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
12549
12592
  id: union([string(), number()]) }), {
12550
12593
  kind: "mutation",
12551
12594
  auth: "admin"
12595
+ }), method(object({
12596
+ namespace: string().optional(),
12597
+ collection: string(),
12598
+ conflict: array(string()).readonly(),
12599
+ record: BulkRecordSchema
12600
+ }), object({ id: union([string(), number()]) }), {
12601
+ kind: "mutation",
12602
+ auth: "admin"
12552
12603
  }), method(object({
12553
12604
  namespace: string().optional(),
12554
12605
  collection: string(),
@@ -18846,8 +18897,8 @@ var TrackPositionSchema = object({
18846
18897
  var TrackSnapshotSchema = object({
18847
18898
  timestamp: number(),
18848
18899
  position: TrackPositionSchema,
18849
- /** MediaStore key; resolve via `getTrackMedia({ trackId })`. */
18850
- mediaKey: string()
18900
+ /** The snapshot's media row id (D482); resolve via `listTrackMedia({ trackId })`. */
18901
+ mediaId: number().int()
18851
18902
  });
18852
18903
  /**
18853
18904
  * Normalized 0..1 trajectory envelope (min/max over every position bbox,
@@ -19451,14 +19502,14 @@ var ObjectEventSchema = object({
19451
19502
  * pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
19452
19503
  frameWidth: number().optional(),
19453
19504
  frameHeight: number().optional(),
19454
- /** MediaStore key for the crop attached to this event (if any). */
19455
- mediaKey: string().optional(),
19456
- /** Design B: MediaStore key of the track's native-resolution key frame (the
19505
+ /** Media row id of the crop attached to this event (if any) — D482. */
19506
+ mediaId: number().int().optional(),
19507
+ /** Design B: media row id of the track's native-resolution key frame (the
19457
19508
  * best-detection full frame). Resolve via the event-media data-plane
19458
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
19509
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`) for a detail view that
19459
19510
  * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
19460
- * sources — consumers fall back to `mediaKey` (the tight crop). */
19461
- keyFrameMediaKey: string().optional(),
19511
+ * sources — consumers fall back to `mediaId` (the tight crop). */
19512
+ keyFrameMediaId: number().int().optional(),
19462
19513
  /** Populated by B5 (recording playback URL for this event). */
19463
19514
  mediaUrl: string().optional(),
19464
19515
  /** The parent track's key-event importance [0,1], propagated to every object
@@ -19508,7 +19559,7 @@ var MediaFileKindEnum = _enum([
19508
19559
  * hub-main's heap on the way past — for an `<img>` that would have cached it.
19509
19560
  *
19510
19561
  * `url` points at the `event-media` data plane
19511
- * (`/addon/<addonId>/event-media/<storedKey>`), which serves the same blob
19562
+ * (`/addon/<addonId>/event-media/m/<mediaId>` — D482), which serves the same blob
19512
19563
  * with an ETag and `Cache-Control: immutable`, honours conditional GETs, can
19513
19564
  * render a `?variant=thumb`, and streams. The hub gate in front of it requires
19514
19565
  * a bearer or the session cookie (`access: 'authenticated'`), so the bytes are
@@ -19516,10 +19567,13 @@ var MediaFileKindEnum = _enum([
19516
19567
  * `data-plane-access.ts` for the rule and the one gap it does not close
19517
19568
  * (per-device scoping).
19518
19569
  *
19519
- * The URL is built from the row's **stored** key, which is not always its
19520
- * published `kind`: a track's face/plate crop is stored as `crop` under
19570
+ * The URL is built from the row's own id, which since D482 says nothing about
19571
+ * the row's owner or kind and that is the point. The published `kind` is not
19572
+ * the stored one (a track's face/plate crop is stored as `crop` under
19521
19573
  * `('face'|'plate', '<prefix>-<trackId>')` and published as
19522
- * `faceCrop`/`plateCrop`. `MediaStore.getByKey` knows only the stored key.
19574
+ * `faceCrop`/`plateCrop`), and under the old composite key the URL had to be
19575
+ * taken from `row.key` verbatim or it 404'd exactly those two rows. An id
19576
+ * cannot be mis-reconstructed, because there is nothing in it to reconstruct.
19523
19577
  *
19524
19578
  * ## `base64` is TRANSITIONAL and is going away
19525
19579
  *
@@ -19532,7 +19586,19 @@ var MediaFileKindEnum = _enum([
19532
19586
  * `analytics-query-facade.ts`; nothing else reads it.
19533
19587
  */
19534
19588
  var MediaFileSchema = object({
19535
- key: string(),
19589
+ /**
19590
+ * The media row's OWN id — the rowid SQLite assigned it (D482).
19591
+ *
19592
+ * It used to be the row's composite key, `<ownerType>:<ownerId>:<fileKind>
19593
+ * [:<timestampMs>]`, which embedded a FOREIGN id. D474 made event ids
19594
+ * per-table rowid aliases, so `object:101314` and `motion:101314` are two
19595
+ * different rows that spell the same number, and a track whose
19596
+ * `bestEventId` was an object event was served a motion event's snapshot —
19597
+ * a night-time thumbnail on an afternoon track, with no error anywhere. A
19598
+ * surrogate id cannot name the wrong row's owner, because it names no owner
19599
+ * at all.
19600
+ */
19601
+ mediaId: number().int(),
19536
19602
  kind: MediaFileKindEnum,
19537
19603
  sizeBytes: number(),
19538
19604
  timestamp: number()
@@ -19640,7 +19706,7 @@ var RetrainTrackSchema = object({
19640
19706
  });
19641
19707
  /** A frame the picker may offer — an index row, no blob was read to produce it. */
19642
19708
  var RetrainFrameCandidateSchema = object({
19643
- mediaKey: string(),
19709
+ mediaId: number().int(),
19644
19710
  kind: MediaFileKindEnum,
19645
19711
  timestamp: number(),
19646
19712
  sizeBytes: number().int(),
@@ -19654,7 +19720,7 @@ var RetrainFrameSchema = object({
19654
19720
  deviceId: number(),
19655
19721
  trackId: string(),
19656
19722
  /** Provenance only. It may already point at nothing — that is expected. */
19657
- sourceMediaKey: string(),
19723
+ sourceMediaId: number().int(),
19658
19724
  sourceKind: MediaFileKindEnum,
19659
19725
  sizeBytes: number().int(),
19660
19726
  width: number().int(),
@@ -19670,7 +19736,7 @@ var RetrainCopyRefusalSchema = _enum([
19670
19736
  var RetrainFrameSelectionSchema = object({
19671
19737
  copied: array(RetrainFrameSchema).readonly(),
19672
19738
  refused: array(object({
19673
- sourceMediaKey: string(),
19739
+ sourceMediaId: number().int(),
19674
19740
  reason: RetrainCopyRefusalSchema
19675
19741
  })).readonly()
19676
19742
  });
@@ -19678,7 +19744,7 @@ var RetrainFrameListSchema = object({
19678
19744
  candidates: array(RetrainFrameCandidateSchema).readonly(),
19679
19745
  copies: array(RetrainFrameSchema).readonly(),
19680
19746
  /** What the page pre-selects — the native key frame when one survives. */
19681
- autoPickMediaKey: string().optional()
19747
+ autoPickMediaId: number().int().optional()
19682
19748
  });
19683
19749
  /** What the operator asked the assist to look for. */
19684
19750
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
@@ -19773,9 +19839,11 @@ var RecentTracksQueryInput = object({
19773
19839
  });
19774
19840
  /**
19775
19841
  * A Summary (D359): the per-camera session envelope that references tracks.
19776
- * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
19777
- * served by the event-media plane by key), null until the first frame with a
19778
- * member visible has been materialised.
19842
+ * `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
19843
+ * 'summary'`, served by the event-media plane at `/m/<id>`), null until the
19844
+ * first frame with a member visible has been materialised (D482 — it was the
19845
+ * row's composite key, which embedded the owner and could name another table's
19846
+ * row once event ids became per-table rowids).
19779
19847
  */
19780
19848
  var SummarySchema = object({
19781
19849
  id: string(),
@@ -19784,19 +19852,115 @@ var SummarySchema = object({
19784
19852
  lastActiveAt: number(),
19785
19853
  sealedAt: number().nullable(),
19786
19854
  memberCount: number().int().nonnegative(),
19787
- groupShotKey: string().nullable()
19855
+ groupShotMediaId: number().int().nullable()
19788
19856
  });
19789
19857
  var SummariesQueryInput = object({
19790
19858
  deviceIds: array(number()).min(1),
19791
19859
  since: number().optional(),
19792
19860
  until: number().optional(),
19793
- limit: number().int().min(1).max(200).default(50)
19861
+ limit: number().int().min(1).max(200).default(50),
19862
+ /** The same member-wise filter {@link listRecentSummaries} takes — one
19863
+ * meaning of "dog" on every summary surface. */
19864
+ classes: array(string().min(1).max(60)).max(40).optional()
19794
19865
  });
19795
- var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
19796
19866
  var SummaryDetailSchema = object({
19797
19867
  summary: SummarySchema,
19798
- /** Member track ids, in absorption order. */
19799
- trackIds: array(string()).readonly()
19868
+ /** Members in absorption order, oldest join first. */
19869
+ members: array(object({
19870
+ trackId: string(),
19871
+ /**
19872
+ * The track's class at the time it JOINED, or `null` when it was unresolved
19873
+ * and the track no longer exists to fill it.
19874
+ *
19875
+ * The join, not the latest opinion: class voting can re-decide a track's
19876
+ * class afterwards, and a group's composition is the history of who came
19877
+ * together. A consumer counts these to badge a thumbnail — "two people and a
19878
+ * dog" — rather than being handed a second, denormalised tally that would
19879
+ * drift from the members it claims to describe.
19880
+ */
19881
+ className: string().nullable(),
19882
+ /** `primary` is the one member that carries the group's identity. */
19883
+ role: _enum([
19884
+ "primary",
19885
+ "sibling",
19886
+ "child"
19887
+ ]).nullable(),
19888
+ joinedAt: number(),
19889
+ /** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
19890
+ * at read time. Absent when nothing resolved, never an empty string. */
19891
+ label: string().optional(),
19892
+ /** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
19893
+ * recognised nobody, and absent for a member whose track has been pruned —
19894
+ * a thumbnail that names the wrong person is worse than one naming nobody. */
19895
+ subLabel: string().optional()
19896
+ })).readonly()
19897
+ });
19898
+ /**
19899
+ * What a LIST of groups carries: the envelope plus what it is MADE OF.
19900
+ *
19901
+ * Coarse on purpose — the operator's rule is "only the rough data on the list,
19902
+ * we extend when we notice we need more". Enough to draw the card ("two people
19903
+ * and a dog") and no more. The MEMBERS, their names and the per-member links
19904
+ * are on {@link getSummary}: shipping every member of every group so a client
19905
+ * can count them turns a page of two hundred groups into a thousand records to
19906
+ * draw two hundred badges.
19907
+ */
19908
+ var SummaryListItemSchema = object({
19909
+ summary: SummarySchema,
19910
+ /** Class counts, most numerous first; `className: null` is a member whose
19911
+ * class never resolved, counted so the counts add up to `memberCount`. */
19912
+ classes: array(object({
19913
+ className: string().nullable(),
19914
+ count: number().int().positive()
19915
+ })).readonly()
19916
+ });
19917
+ var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
19918
+ /**
19919
+ * The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
19920
+ *
19921
+ * The reel on the cameras page and the Events gallery both ride a cursor, so a
19922
+ * summaries feed that could only answer "the last N for these cameras"
19923
+ * (`listSummaries`) would make groups available in the timeline and nowhere
19924
+ * else. Two feeds with different ordering contracts would be two ideas of what
19925
+ * "newest" means, on one screen.
19926
+ */
19927
+ var RecentSummariesQueryInput = object({
19928
+ /** Devices to merge. An empty array yields an empty page. */
19929
+ deviceIds: array(number()),
19930
+ /** Window lower bound on `lastActiveAt` (inclusive). */
19931
+ since: number().optional(),
19932
+ /** Window upper bound on `lastActiveAt` (inclusive). */
19933
+ until: number().optional(),
19934
+ limit: number().int().min(1).max(500).default(100),
19935
+ /** Opaque continuation cursor from a previous page's `nextCursor`. */
19936
+ cursor: string().optional(),
19937
+ /**
19938
+ * Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
19939
+ * deliberately the same name: the events filter tree emits one list of ticked
19940
+ * taxonomy nodes, and a summaries feed that called it something else would
19941
+ * make the operator's one filter component produce two shapes.
19942
+ *
19943
+ * A question about the MEMBERS: a group matches when ANY of them does. "Show
19944
+ * me the arrivals with a dog" has to return the group of four people who had
19945
+ * one with them; a filter on the group's own fields could only ever answer
19946
+ * about its primary.
19947
+ *
19948
+ * Matched against all THREE tiers of a member — the class (`animal`), the
19949
+ * sub-class (`dog`) and the instance (a name, a plate) — because which tier a
19950
+ * ticked node lives on is the taxonomy's business, not the caller's. `dog` is
19951
+ * an event kind in the tree and a tier-1 label on an `animal` track; a filter
19952
+ * that read only the class would answer "animal" and never "dog".
19953
+ *
19954
+ * ABSENT or EMPTY means no filter — absent is not a selection of none.
19955
+ */
19956
+ classes: array(string().min(1).max(60)).max(40).optional()
19957
+ });
19958
+ var RecentSummariesPageSchema = object({
19959
+ /** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
19960
+ * {@link listSummaries} — one list shape, so a card renders the same
19961
+ * whichever feed drew it. */
19962
+ summaries: array(SummaryListItemSchema).readonly(),
19963
+ nextCursor: string().nullable()
19800
19964
  });
19801
19965
  var RecentTracksPageSchema = object({
19802
19966
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -20210,7 +20374,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20210
20374
  classes: array(string()).optional(),
20211
20375
  /** See {@link ExcludeSourcesDoc}. */
20212
20376
  excludeSources: array(TrackSourceSchema).optional()
20213
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
20377
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(RecentSummariesQueryInput, RecentSummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
20214
20378
  kind: "mutation",
20215
20379
  auth: "admin"
20216
20380
  }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
@@ -20338,7 +20502,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20338
20502
  }), method(object({
20339
20503
  deviceId: number(),
20340
20504
  trackId: string(),
20341
- mediaKeys: array(string()).min(1)
20505
+ mediaIds: array(number().int()).min(1)
20342
20506
  }), RetrainFrameSelectionSchema, {
20343
20507
  kind: "mutation",
20344
20508
  auth: "admin"
@@ -20406,7 +20570,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20406
20570
  kind: "query",
20407
20571
  auth: "admin"
20408
20572
  }), method(object({
20409
- eventId: string(),
20573
+ /** Which of the three event tables owns the row. */
20574
+ ownerType: EventOwnerTypeSchema,
20575
+ /** The event's rowid in that table (D474: an event id is a number). */
20576
+ eventId: number().int(),
20410
20577
  kind: MediaFileKindEnum.optional(),
20411
20578
  deviceId: number()
20412
20579
  }), array(MediaFileSchema).readonly()), method(object({
@@ -20417,7 +20584,8 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20417
20584
  trackId: string(),
20418
20585
  deviceId: number()
20419
20586
  }), array(MediaFileInfoSchema).readonly()), method(object({
20420
- eventId: string(),
20587
+ ownerType: EventOwnerTypeSchema,
20588
+ eventId: number().int(),
20421
20589
  deviceId: number()
20422
20590
  }), array(MediaFileInfoSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
20423
20591
  kind: "mutation",
@@ -24984,8 +25152,8 @@ var IdentitySchema = object({
24984
25152
  id: string(),
24985
25153
  name: string(),
24986
25154
  sampleCount: number().int().nonnegative(),
24987
- coverMediaKey: string().optional(),
24988
- /** Inline base64 of the cover sample's crop, resolved from `coverMediaKey`.
25155
+ coverMediaId: number().int().optional(),
25156
+ /** Inline base64 of the cover sample's crop, resolved from `coverMediaId`.
24989
25157
  * Lets the UI render the person's face avatar instead of a placeholder icon. */
24990
25158
  coverBase64: string().optional()
24991
25159
  });
@@ -25011,8 +25179,8 @@ var IdentitySampleAuditRowSchema = object({
25011
25179
  enrolledAt: number().int(),
25012
25180
  deviceId: number().int().optional(),
25013
25181
  source: _enum(["detected", "photo"]),
25014
- /** The enrolled crop's media key, so the panel can show the evidence. */
25015
- mediaKey: string().optional(),
25182
+ /** The enrolled crop's media row id, so the panel can show the evidence. */
25183
+ mediaId: number().int().optional(),
25016
25184
  /**
25017
25185
  * False = the sample is stamped with a DIFFERENT face model, and a cosine
25018
25186
  * across feature spaces is a well-formed float with no meaning. Every number
@@ -25081,15 +25249,15 @@ var FaceInfoSchema = object({
25081
25249
  */
25082
25250
  cropUrl: string().optional(),
25083
25251
  /** Design B: the face bbox (pixel space) on the key frame — lets a detail
25084
- * view draw the box over the native `keyFrameMediaKey` frame. Absent on
25252
+ * view draw the box over the native `keyFrameMediaId` frame. Absent on
25085
25253
  * legacy rows written before design B. */
25086
25254
  faceBbox: BoundingBoxSchema.optional(),
25087
25255
  /** Design B: MediaStore key of the track's native-resolution key frame.
25088
25256
  * Fetch the native JPEG via the event-media data-plane
25089
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
25257
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`). Absent when the
25090
25258
  * track produced no key frame (e.g. native/onboard source) — the UI falls
25091
25259
  * back to the inline `base64` face crop. */
25092
- keyFrameMediaKey: string().optional(),
25260
+ keyFrameMediaId: number().int().optional(),
25093
25261
  /** Winning identity-match cosine (0..1) for this face's track, when an
25094
25262
  * identity was auto-confirmed. Lets the UI surface WHY a face was assigned
25095
25263
  * (confidence badge / low-confidence audit). Absent on legacy rows and on
@@ -25158,11 +25326,14 @@ var FaceClusterSchema = object({
25158
25326
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
25159
25327
  * dialog already rendering its key FRAME from the `event-media` plane.
25160
25328
  *
25161
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
25162
- * media key directly, so this needed no new plane and no new access decision.
25329
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
25330
+ * resolves a media row by its own id, so this needed no new plane and no new
25331
+ * access decision.
25163
25332
  */
25164
25333
  var MediaFileLiteSchema$1 = object({
25165
- key: string(),
25334
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
25335
+ * (D482). It was the row's composite key, which embedded the owner. */
25336
+ mediaId: number().int(),
25166
25337
  kind: string(),
25167
25338
  url: string(),
25168
25339
  sizeBytes: number(),
@@ -25179,7 +25350,7 @@ method(object({
25179
25350
  * covers inline, ~10 KB of base64 per row, on a query this UI mounts
25180
25351
  * four times and the viewer holds at `staleTime: 30_000`.
25181
25352
  *
25182
- * Nothing loses its avatar: `coverMediaKey` is already on every row and
25353
+ * Nothing loses its avatar: `coverMediaId` is already on every row and
25183
25354
  * the `event-media` plane serves that key `immutable` with an ETag.
25184
25355
  *
25185
25356
  * **This is an INPUT field, so it does not reach the addon until the
@@ -27647,8 +27818,8 @@ var VehicleSchema = object({
27647
27818
  id: string(),
27648
27819
  name: string(),
27649
27820
  sampleCount: number().int().nonnegative(),
27650
- coverMediaKey: string().optional(),
27651
- /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaKey`. */
27821
+ coverMediaId: number().int().optional(),
27822
+ /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaId`. */
27652
27823
  coverBase64: string().optional()
27653
27824
  });
27654
27825
  var VehicleSampleInfoSchema = object({
@@ -27681,7 +27852,7 @@ var PlateInfoSchema = object({
27681
27852
  /** keyFrame parity: the plate bbox (pixel space) on the native key frame. */
27682
27853
  plateBbox: BoundingBoxSchema.optional(),
27683
27854
  /** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
27684
- keyFrameMediaKey: string().optional(),
27855
+ keyFrameMediaId: number().int().optional(),
27685
27856
  base64: string().optional(),
27686
27857
  /**
27687
27858
  * Same crop as a data-plane URL, always present when the plate has a stored
@@ -27702,11 +27873,14 @@ var PlateInfoSchema = object({
27702
27873
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
27703
27874
  * dialog already rendering its key FRAME from the `event-media` plane.
27704
27875
  *
27705
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
27706
- * media key directly, so this needed no new plane and no new access decision.
27876
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
27877
+ * resolves a media row by its own id, so this needed no new plane and no new
27878
+ * access decision.
27707
27879
  */
27708
27880
  var MediaFileLiteSchema = object({
27709
- key: string(),
27881
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
27882
+ * (D482). It was the row's composite key, which embedded the owner. */
27883
+ mediaId: number().int(),
27710
27884
  kind: string(),
27711
27885
  url: string(),
27712
27886
  sizeBytes: number(),
@@ -27765,7 +27939,7 @@ method(object({
27765
27939
  }), method(object({
27766
27940
  /** Inline {@link VehicleSchema.coverBase64} on every row. Default
27767
27941
  * `false` — the vehicle twin of `faceGallery.listIdentities`'s
27768
- * option; `coverMediaKey` + the `event-media` plane carry the picture.
27942
+ * option; `coverMediaId` + the `event-media` plane carry the picture.
27769
27943
  * INPUT field: stripped by the hub router until the train ships, which
27770
27944
  * resolves to `false` and is exactly the intended default. */
27771
27945
  includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
@@ -29131,7 +29305,14 @@ var SceneReferenceSchema = object({
29131
29305
  modelId: string(),
29132
29306
  condition: SceneConditionSchema,
29133
29307
  capturedAt: number(),
29134
- thumbnailMediaId: string().optional(),
29308
+ /**
29309
+ * The reference thumbnail's media ROW id (D482).
29310
+ *
29311
+ * The name already said `mediaId` while the value was the row's composite
29312
+ * key — a leftover that read as done and was not. It is the row's own id
29313
+ * now, addressed at `/addon/<addonId>/event-media/m/<id>`.
29314
+ */
29315
+ thumbnailMediaId: number().int().optional(),
29135
29316
  /** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
29136
29317
  * anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
29137
29318
  * normalized rect frame a different piece of world, and the scene would
@@ -29945,7 +30126,29 @@ var LoggingSettingsPatchSchema = object({
29945
30126
  * disarmed the channels it did not mention would make the Levels page and
29946
30127
  * the Diagnostics page fight over the same value.
29947
30128
  */
29948
- channels: array(LogChannelWindowPatchSchema).readonly().optional()
30129
+ channels: array(LogChannelWindowPatchSchema).readonly().optional(),
30130
+ /**
30131
+ * How many days the analytics OPS LOG is kept — the audit trail of what
30132
+ * retention actually deleted.
30133
+ *
30134
+ * It lives HERE, on the logging document, and not on the analytics addon's
30135
+ * settings form, on the operator's instruction: every other log-ish window in
30136
+ * this system is configured through this one document, and a retention audit
30137
+ * configured somewhere else is a second place to look when the question is
30138
+ * "what happened to my data".
30139
+ *
30140
+ * That placement has a cost worth stating: this document ships in the
30141
+ * framework closure, so this knob needs a published `@camstack/server` while
30142
+ * the four windows beside it (D485) reach a node on `camstack deploy`.
30143
+ *
30144
+ * `retention-model.ts` argued this one must NOT follow a device window,
30145
+ * because the audit trail is the history of the SWEEP and not of the camera.
30146
+ * That argument stands and is untouched — what changes is that 30 days stops
30147
+ * being a constant nobody can reach. `0` keeps it forever. The floor is 1 day
30148
+ * rather than 0-as-delete: an audit log truncated to nothing is precisely the
30149
+ * state in which the next 9.5 GiB leak cannot be explained.
30150
+ */
30151
+ opsLogRetentionDays: number().int().min(0).max(3650).optional()
29949
30152
  });
29950
30153
  /**
29951
30154
  * Which LAYER of the hierarchy is addressed. Absent = the cluster layer.
@@ -30018,6 +30221,14 @@ var LoggingSettingsStateSchema = object({
30018
30221
  channels: array(LogChannelDescriptorSchema).readonly(),
30019
30222
  /** The channels ARMED right now, each with its deadline. */
30020
30223
  activeChannels: array(LogChannelWindowStateSchema).readonly(),
30224
+ /**
30225
+ * The ops-log window in days, as it is in force. `0` = kept forever.
30226
+ *
30227
+ * Reported rather than left to the caller's memory of what it wrote: this is
30228
+ * the value the analytics sweep will actually use, and an operator asking how
30229
+ * long their audit trail lives should not have to infer it from a default.
30230
+ */
30231
+ opsLogRetentionDays: number().int().min(0),
30021
30232
  persisted: boolean()
30022
30233
  });
30023
30234
  method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
@@ -30579,7 +30790,7 @@ var StationaryObjectSchema = object({
30579
30790
  /** Enrichment label carried from the source track (identity / plate). */
30580
30791
  label: string().optional(),
30581
30792
  /** Native-resolution key-frame media key for the parked object's best image. */
30582
- keyFrameMediaKey: string().optional()
30793
+ keyFrameMediaId: number().int().optional()
30583
30794
  });
30584
30795
  var CameraOccupancySnapshotSchema = object({
30585
30796
  /** Frame timestamp of the inference result that produced this snapshot. */
@@ -32561,6 +32772,12 @@ Object.freeze({
32561
32772
  addonId: null,
32562
32773
  access: "create"
32563
32774
  },
32775
+ "dataStoreProvider.upsert": {
32776
+ capName: "data-store-provider",
32777
+ capScope: "system",
32778
+ addonId: null,
32779
+ access: "create"
32780
+ },
32564
32781
  "dayNight.getOptions": {
32565
32782
  capName: "day-night",
32566
32783
  capScope: "device",
@@ -34997,6 +35214,12 @@ Object.freeze({
34997
35214
  addonId: null,
34998
35215
  access: "view"
34999
35216
  },
35217
+ "pipelineAnalytics.listRecentSummaries": {
35218
+ capName: "pipeline-analytics",
35219
+ capScope: "device",
35220
+ addonId: null,
35221
+ access: "view"
35222
+ },
35000
35223
  "pipelineAnalytics.listRecentTracks": {
35001
35224
  capName: "pipeline-analytics",
35002
35225
  capScope: "device",
@@ -36425,6 +36648,12 @@ Object.freeze({
36425
36648
  addonId: null,
36426
36649
  access: "create"
36427
36650
  },
36651
+ "settingsStore.upsert": {
36652
+ capName: "settings-store",
36653
+ capScope: "system",
36654
+ addonId: null,
36655
+ access: "create"
36656
+ },
36428
36657
  "smtpProvider.getStatus": {
36429
36658
  capName: "smtp-provider",
36430
36659
  capScope: "system",
@@ -38818,6 +39047,11 @@ Object.freeze({
38818
39047
  form: "single",
38819
39048
  optional: true
38820
39049
  }],
39050
+ "pipelineAnalytics.listRecentSummaries": [{
39051
+ name: "deviceIds",
39052
+ form: "array",
39053
+ optional: false
39054
+ }],
38821
39055
  "pipelineAnalytics.listRecentTracks": [{
38822
39056
  name: "deviceIds",
38823
39057
  form: "array",
package/dist/addon.mjs CHANGED
@@ -3,7 +3,7 @@ import { createRequire } from "node:module";
3
3
  var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
4
4
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
5
5
  //#endregion
6
- //#region ../types/dist/event-category-DAXzJeTX.mjs
6
+ //#region ../types/dist/event-category-ZyX6jcse.mjs
7
7
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
8
8
  EventCategory["SystemBoot"] = "system.boot";
9
9
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -564,7 +564,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
564
564
  * a package zone — a newly-appeared stationary object of a package class
565
565
  * that cleared the class / zone / dwell / size gates. Payload:
566
566
  * `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
567
- * entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
567
+ * entryId, className, zoneIds, keyFrameMediaId?, bbox, timestamp }`.
568
568
  * Telemetry (D8): the durable record is the `package-events` store row;
569
569
  * this bus topic drives notifier rules + live UI. See
570
570
  * docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
@@ -5350,7 +5350,7 @@ var ZodIssueCode = {
5350
5350
  var ZodFirstPartyTypeKind;
5351
5351
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5352
5352
  //#endregion
5353
- //#region ../types/dist/sleep-BnujYGPe.mjs
5353
+ //#region ../types/dist/sleep-DBKu2-U5.mjs
5354
5354
  /**
5355
5355
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5356
5356
  * window to float samples (D455).
@@ -7313,13 +7313,30 @@ new Set([
7313
7313
  "scene",
7314
7314
  "motion",
7315
7315
  "object",
7316
- "audio"
7316
+ "audio",
7317
+ "mosaic"
7317
7318
  ]);
7318
- new Set([
7319
+ /**
7320
+ * The owner types that are event tables, in the order the event-media resolver
7321
+ * should consider them. Exported so a consumer asking "is this key an event?"
7322
+ * does not re-spell the list and drift from it.
7323
+ */
7324
+ var EVENT_OWNER_TYPES = [
7319
7325
  "motion",
7320
7326
  "object",
7321
7327
  "audio"
7322
- ]);
7328
+ ];
7329
+ /**
7330
+ * The same list as a Zod enum, for the cap inputs that must NAME the table
7331
+ * (D482: `getEventMedia` / `listEventMedia` take an owner, and an owner is
7332
+ * `(table, id)`).
7333
+ *
7334
+ * Built FROM {@link EVENT_OWNER_TYPES} rather than re-spelled: a fourth event
7335
+ * table would otherwise be accepted by the codec and refused at the door, with
7336
+ * nothing failing until a caller asked.
7337
+ */
7338
+ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
7339
+ new Set(EVENT_OWNER_TYPES);
7323
7340
  var EncodeProfileSchema = object({
7324
7341
  video: object({
7325
7342
  codec: _enum([
@@ -7358,7 +7375,23 @@ var EncodeProfileSchema = object({
7358
7375
  "zerolatency",
7359
7376
  "film",
7360
7377
  "animation"
7361
- ]).optional()
7378
+ ]).optional(),
7379
+ /**
7380
+ * ONE slice per access unit.
7381
+ *
7382
+ * `-tune zerolatency` turns on x264's sliced threads, and a frame then leaves
7383
+ * the encoder as five NAL slices that share one RTP timestamp and carry one
7384
+ * marker bit. A libwebrtc depacketiser sees five frame-starts and one
7385
+ * frame-end per frame: the first pictures render and the video then freezes
7386
+ * for good while the audio, on its own plane, plays on. Measured on this hub
7387
+ * 2026-09-13 against the Echo, and reduced to one slice by this flag alone.
7388
+ *
7389
+ * A NAMED field and not a raw flag, because {@link EgressEncodeSchema} omits
7390
+ * `outputArgs` on purpose: an opaque array is part of the sharing key, so two
7391
+ * consumers meaning the same thing spelled differently would stop sharing one
7392
+ * child. Absent means "whatever the encoder does" — today's behaviour.
7393
+ */
7394
+ singleSlicePerFrame: boolean().optional()
7362
7395
  }),
7363
7396
  audio: union([literal("passthrough"), object({
7364
7397
  codec: _enum([
@@ -7408,7 +7441,7 @@ var BASE_LIVE_EGRESS_PROFILE = {
7408
7441
  audio: "passthrough"
7409
7442
  };
7410
7443
  ({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
7411
- ({ ...BASE_LIVE_EGRESS_PROFILE });
7444
+ ({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
7412
7445
  /**
7413
7446
  * Deep wiring healthcheck — snapshot of active reachability probes across
7414
7447
  * every declared capability + widget of every installed plugin, on every
@@ -12416,6 +12449,16 @@ method(object({
12416
12449
  filter: QueryFilterSchema.optional(),
12417
12450
  columns: array(string()).readonly().optional()
12418
12451
  }), array(SettingsRecordSchema).readonly()), method(object({
12452
+ namespace: string().optional(),
12453
+ collection: string(),
12454
+ /** Declared columns identifying the slot; must be covered by a UNIQUE
12455
+ * index on the collection. Never empty. */
12456
+ conflict: array(string()).readonly(),
12457
+ record: BulkRecordSchema
12458
+ }), object({
12459
+ /** The id the row HAS: assigned by SQLite on an insert, or the existing
12460
+ * row's own id on an update. */
12461
+ id: union([string(), number()]) }), { kind: "mutation" }), method(object({
12419
12462
  namespace: string().optional(),
12420
12463
  collection: string(),
12421
12464
  record: object({
@@ -12550,6 +12593,14 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
12550
12593
  id: union([string(), number()]) }), {
12551
12594
  kind: "mutation",
12552
12595
  auth: "admin"
12596
+ }), method(object({
12597
+ namespace: string().optional(),
12598
+ collection: string(),
12599
+ conflict: array(string()).readonly(),
12600
+ record: BulkRecordSchema
12601
+ }), object({ id: union([string(), number()]) }), {
12602
+ kind: "mutation",
12603
+ auth: "admin"
12553
12604
  }), method(object({
12554
12605
  namespace: string().optional(),
12555
12606
  collection: string(),
@@ -18847,8 +18898,8 @@ var TrackPositionSchema = object({
18847
18898
  var TrackSnapshotSchema = object({
18848
18899
  timestamp: number(),
18849
18900
  position: TrackPositionSchema,
18850
- /** MediaStore key; resolve via `getTrackMedia({ trackId })`. */
18851
- mediaKey: string()
18901
+ /** The snapshot's media row id (D482); resolve via `listTrackMedia({ trackId })`. */
18902
+ mediaId: number().int()
18852
18903
  });
18853
18904
  /**
18854
18905
  * Normalized 0..1 trajectory envelope (min/max over every position bbox,
@@ -19452,14 +19503,14 @@ var ObjectEventSchema = object({
19452
19503
  * pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
19453
19504
  frameWidth: number().optional(),
19454
19505
  frameHeight: number().optional(),
19455
- /** MediaStore key for the crop attached to this event (if any). */
19456
- mediaKey: string().optional(),
19457
- /** Design B: MediaStore key of the track's native-resolution key frame (the
19506
+ /** Media row id of the crop attached to this event (if any) — D482. */
19507
+ mediaId: number().int().optional(),
19508
+ /** Design B: media row id of the track's native-resolution key frame (the
19458
19509
  * best-detection full frame). Resolve via the event-media data-plane
19459
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
19510
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`) for a detail view that
19460
19511
  * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
19461
- * sources — consumers fall back to `mediaKey` (the tight crop). */
19462
- keyFrameMediaKey: string().optional(),
19512
+ * sources — consumers fall back to `mediaId` (the tight crop). */
19513
+ keyFrameMediaId: number().int().optional(),
19463
19514
  /** Populated by B5 (recording playback URL for this event). */
19464
19515
  mediaUrl: string().optional(),
19465
19516
  /** The parent track's key-event importance [0,1], propagated to every object
@@ -19509,7 +19560,7 @@ var MediaFileKindEnum = _enum([
19509
19560
  * hub-main's heap on the way past — for an `<img>` that would have cached it.
19510
19561
  *
19511
19562
  * `url` points at the `event-media` data plane
19512
- * (`/addon/<addonId>/event-media/<storedKey>`), which serves the same blob
19563
+ * (`/addon/<addonId>/event-media/m/<mediaId>` — D482), which serves the same blob
19513
19564
  * with an ETag and `Cache-Control: immutable`, honours conditional GETs, can
19514
19565
  * render a `?variant=thumb`, and streams. The hub gate in front of it requires
19515
19566
  * a bearer or the session cookie (`access: 'authenticated'`), so the bytes are
@@ -19517,10 +19568,13 @@ var MediaFileKindEnum = _enum([
19517
19568
  * `data-plane-access.ts` for the rule and the one gap it does not close
19518
19569
  * (per-device scoping).
19519
19570
  *
19520
- * The URL is built from the row's **stored** key, which is not always its
19521
- * published `kind`: a track's face/plate crop is stored as `crop` under
19571
+ * The URL is built from the row's own id, which since D482 says nothing about
19572
+ * the row's owner or kind and that is the point. The published `kind` is not
19573
+ * the stored one (a track's face/plate crop is stored as `crop` under
19522
19574
  * `('face'|'plate', '<prefix>-<trackId>')` and published as
19523
- * `faceCrop`/`plateCrop`. `MediaStore.getByKey` knows only the stored key.
19575
+ * `faceCrop`/`plateCrop`), and under the old composite key the URL had to be
19576
+ * taken from `row.key` verbatim or it 404'd exactly those two rows. An id
19577
+ * cannot be mis-reconstructed, because there is nothing in it to reconstruct.
19524
19578
  *
19525
19579
  * ## `base64` is TRANSITIONAL and is going away
19526
19580
  *
@@ -19533,7 +19587,19 @@ var MediaFileKindEnum = _enum([
19533
19587
  * `analytics-query-facade.ts`; nothing else reads it.
19534
19588
  */
19535
19589
  var MediaFileSchema = object({
19536
- key: string(),
19590
+ /**
19591
+ * The media row's OWN id — the rowid SQLite assigned it (D482).
19592
+ *
19593
+ * It used to be the row's composite key, `<ownerType>:<ownerId>:<fileKind>
19594
+ * [:<timestampMs>]`, which embedded a FOREIGN id. D474 made event ids
19595
+ * per-table rowid aliases, so `object:101314` and `motion:101314` are two
19596
+ * different rows that spell the same number, and a track whose
19597
+ * `bestEventId` was an object event was served a motion event's snapshot —
19598
+ * a night-time thumbnail on an afternoon track, with no error anywhere. A
19599
+ * surrogate id cannot name the wrong row's owner, because it names no owner
19600
+ * at all.
19601
+ */
19602
+ mediaId: number().int(),
19537
19603
  kind: MediaFileKindEnum,
19538
19604
  sizeBytes: number(),
19539
19605
  timestamp: number()
@@ -19641,7 +19707,7 @@ var RetrainTrackSchema = object({
19641
19707
  });
19642
19708
  /** A frame the picker may offer — an index row, no blob was read to produce it. */
19643
19709
  var RetrainFrameCandidateSchema = object({
19644
- mediaKey: string(),
19710
+ mediaId: number().int(),
19645
19711
  kind: MediaFileKindEnum,
19646
19712
  timestamp: number(),
19647
19713
  sizeBytes: number().int(),
@@ -19655,7 +19721,7 @@ var RetrainFrameSchema = object({
19655
19721
  deviceId: number(),
19656
19722
  trackId: string(),
19657
19723
  /** Provenance only. It may already point at nothing — that is expected. */
19658
- sourceMediaKey: string(),
19724
+ sourceMediaId: number().int(),
19659
19725
  sourceKind: MediaFileKindEnum,
19660
19726
  sizeBytes: number().int(),
19661
19727
  width: number().int(),
@@ -19671,7 +19737,7 @@ var RetrainCopyRefusalSchema = _enum([
19671
19737
  var RetrainFrameSelectionSchema = object({
19672
19738
  copied: array(RetrainFrameSchema).readonly(),
19673
19739
  refused: array(object({
19674
- sourceMediaKey: string(),
19740
+ sourceMediaId: number().int(),
19675
19741
  reason: RetrainCopyRefusalSchema
19676
19742
  })).readonly()
19677
19743
  });
@@ -19679,7 +19745,7 @@ var RetrainFrameListSchema = object({
19679
19745
  candidates: array(RetrainFrameCandidateSchema).readonly(),
19680
19746
  copies: array(RetrainFrameSchema).readonly(),
19681
19747
  /** What the page pre-selects — the native key frame when one survives. */
19682
- autoPickMediaKey: string().optional()
19748
+ autoPickMediaId: number().int().optional()
19683
19749
  });
19684
19750
  /** What the operator asked the assist to look for. */
19685
19751
  var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
@@ -19774,9 +19840,11 @@ var RecentTracksQueryInput = object({
19774
19840
  });
19775
19841
  /**
19776
19842
  * A Summary (D359): the per-camera session envelope that references tracks.
19777
- * `groupShotKey` is the media key of its group shot (`ownerKind: 'summary'`,
19778
- * served by the event-media plane by key), null until the first frame with a
19779
- * member visible has been materialised.
19843
+ * `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
19844
+ * 'summary'`, served by the event-media plane at `/m/<id>`), null until the
19845
+ * first frame with a member visible has been materialised (D482 — it was the
19846
+ * row's composite key, which embedded the owner and could name another table's
19847
+ * row once event ids became per-table rowids).
19780
19848
  */
19781
19849
  var SummarySchema = object({
19782
19850
  id: string(),
@@ -19785,19 +19853,115 @@ var SummarySchema = object({
19785
19853
  lastActiveAt: number(),
19786
19854
  sealedAt: number().nullable(),
19787
19855
  memberCount: number().int().nonnegative(),
19788
- groupShotKey: string().nullable()
19856
+ groupShotMediaId: number().int().nullable()
19789
19857
  });
19790
19858
  var SummariesQueryInput = object({
19791
19859
  deviceIds: array(number()).min(1),
19792
19860
  since: number().optional(),
19793
19861
  until: number().optional(),
19794
- limit: number().int().min(1).max(200).default(50)
19862
+ limit: number().int().min(1).max(200).default(50),
19863
+ /** The same member-wise filter {@link listRecentSummaries} takes — one
19864
+ * meaning of "dog" on every summary surface. */
19865
+ classes: array(string().min(1).max(60)).max(40).optional()
19795
19866
  });
19796
- var SummariesPageSchema = object({ summaries: array(SummarySchema).readonly() });
19797
19867
  var SummaryDetailSchema = object({
19798
19868
  summary: SummarySchema,
19799
- /** Member track ids, in absorption order. */
19800
- trackIds: array(string()).readonly()
19869
+ /** Members in absorption order, oldest join first. */
19870
+ members: array(object({
19871
+ trackId: string(),
19872
+ /**
19873
+ * The track's class at the time it JOINED, or `null` when it was unresolved
19874
+ * and the track no longer exists to fill it.
19875
+ *
19876
+ * The join, not the latest opinion: class voting can re-decide a track's
19877
+ * class afterwards, and a group's composition is the history of who came
19878
+ * together. A consumer counts these to badge a thumbnail — "two people and a
19879
+ * dog" — rather than being handed a second, denormalised tally that would
19880
+ * drift from the members it claims to describe.
19881
+ */
19882
+ className: string().nullable(),
19883
+ /** `primary` is the one member that carries the group's identity. */
19884
+ role: _enum([
19885
+ "primary",
19886
+ "sibling",
19887
+ "child"
19888
+ ]).nullable(),
19889
+ joinedAt: number(),
19890
+ /** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
19891
+ * at read time. Absent when nothing resolved, never an empty string. */
19892
+ label: string().optional(),
19893
+ /** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
19894
+ * recognised nobody, and absent for a member whose track has been pruned —
19895
+ * a thumbnail that names the wrong person is worse than one naming nobody. */
19896
+ subLabel: string().optional()
19897
+ })).readonly()
19898
+ });
19899
+ /**
19900
+ * What a LIST of groups carries: the envelope plus what it is MADE OF.
19901
+ *
19902
+ * Coarse on purpose — the operator's rule is "only the rough data on the list,
19903
+ * we extend when we notice we need more". Enough to draw the card ("two people
19904
+ * and a dog") and no more. The MEMBERS, their names and the per-member links
19905
+ * are on {@link getSummary}: shipping every member of every group so a client
19906
+ * can count them turns a page of two hundred groups into a thousand records to
19907
+ * draw two hundred badges.
19908
+ */
19909
+ var SummaryListItemSchema = object({
19910
+ summary: SummarySchema,
19911
+ /** Class counts, most numerous first; `className: null` is a member whose
19912
+ * class never resolved, counted so the counts add up to `memberCount`. */
19913
+ classes: array(object({
19914
+ className: string().nullable(),
19915
+ count: number().int().positive()
19916
+ })).readonly()
19917
+ });
19918
+ var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
19919
+ /**
19920
+ * The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
19921
+ *
19922
+ * The reel on the cameras page and the Events gallery both ride a cursor, so a
19923
+ * summaries feed that could only answer "the last N for these cameras"
19924
+ * (`listSummaries`) would make groups available in the timeline and nowhere
19925
+ * else. Two feeds with different ordering contracts would be two ideas of what
19926
+ * "newest" means, on one screen.
19927
+ */
19928
+ var RecentSummariesQueryInput = object({
19929
+ /** Devices to merge. An empty array yields an empty page. */
19930
+ deviceIds: array(number()),
19931
+ /** Window lower bound on `lastActiveAt` (inclusive). */
19932
+ since: number().optional(),
19933
+ /** Window upper bound on `lastActiveAt` (inclusive). */
19934
+ until: number().optional(),
19935
+ limit: number().int().min(1).max(500).default(100),
19936
+ /** Opaque continuation cursor from a previous page's `nextCursor`. */
19937
+ cursor: string().optional(),
19938
+ /**
19939
+ * Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
19940
+ * deliberately the same name: the events filter tree emits one list of ticked
19941
+ * taxonomy nodes, and a summaries feed that called it something else would
19942
+ * make the operator's one filter component produce two shapes.
19943
+ *
19944
+ * A question about the MEMBERS: a group matches when ANY of them does. "Show
19945
+ * me the arrivals with a dog" has to return the group of four people who had
19946
+ * one with them; a filter on the group's own fields could only ever answer
19947
+ * about its primary.
19948
+ *
19949
+ * Matched against all THREE tiers of a member — the class (`animal`), the
19950
+ * sub-class (`dog`) and the instance (a name, a plate) — because which tier a
19951
+ * ticked node lives on is the taxonomy's business, not the caller's. `dog` is
19952
+ * an event kind in the tree and a tier-1 label on an `animal` track; a filter
19953
+ * that read only the class would answer "animal" and never "dog".
19954
+ *
19955
+ * ABSENT or EMPTY means no filter — absent is not a selection of none.
19956
+ */
19957
+ classes: array(string().min(1).max(60)).max(40).optional()
19958
+ });
19959
+ var RecentSummariesPageSchema = object({
19960
+ /** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
19961
+ * {@link listSummaries} — one list shape, so a card renders the same
19962
+ * whichever feed drew it. */
19963
+ summaries: array(SummaryListItemSchema).readonly(),
19964
+ nextCursor: string().nullable()
19801
19965
  });
19802
19966
  var RecentTracksPageSchema = object({
19803
19967
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -20211,7 +20375,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20211
20375
  classes: array(string()).optional(),
20212
20376
  /** See {@link ExcludeSourcesDoc}. */
20213
20377
  excludeSources: array(TrackSourceSchema).optional()
20214
- }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
20378
+ }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(SummariesQueryInput, SummariesPageSchema), method(RecentSummariesQueryInput, RecentSummariesPageSchema), method(object({ id: string() }), SummaryDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
20215
20379
  kind: "mutation",
20216
20380
  auth: "admin"
20217
20381
  }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
@@ -20339,7 +20503,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20339
20503
  }), method(object({
20340
20504
  deviceId: number(),
20341
20505
  trackId: string(),
20342
- mediaKeys: array(string()).min(1)
20506
+ mediaIds: array(number().int()).min(1)
20343
20507
  }), RetrainFrameSelectionSchema, {
20344
20508
  kind: "mutation",
20345
20509
  auth: "admin"
@@ -20407,7 +20571,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20407
20571
  kind: "query",
20408
20572
  auth: "admin"
20409
20573
  }), method(object({
20410
- eventId: string(),
20574
+ /** Which of the three event tables owns the row. */
20575
+ ownerType: EventOwnerTypeSchema,
20576
+ /** The event's rowid in that table (D474: an event id is a number). */
20577
+ eventId: number().int(),
20411
20578
  kind: MediaFileKindEnum.optional(),
20412
20579
  deviceId: number()
20413
20580
  }), array(MediaFileSchema).readonly()), method(object({
@@ -20418,7 +20585,8 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
20418
20585
  trackId: string(),
20419
20586
  deviceId: number()
20420
20587
  }), array(MediaFileInfoSchema).readonly()), method(object({
20421
- eventId: string(),
20588
+ ownerType: EventOwnerTypeSchema,
20589
+ eventId: number().int(),
20422
20590
  deviceId: number()
20423
20591
  }), array(MediaFileInfoSchema).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
20424
20592
  kind: "mutation",
@@ -24985,8 +25153,8 @@ var IdentitySchema = object({
24985
25153
  id: string(),
24986
25154
  name: string(),
24987
25155
  sampleCount: number().int().nonnegative(),
24988
- coverMediaKey: string().optional(),
24989
- /** Inline base64 of the cover sample's crop, resolved from `coverMediaKey`.
25156
+ coverMediaId: number().int().optional(),
25157
+ /** Inline base64 of the cover sample's crop, resolved from `coverMediaId`.
24990
25158
  * Lets the UI render the person's face avatar instead of a placeholder icon. */
24991
25159
  coverBase64: string().optional()
24992
25160
  });
@@ -25012,8 +25180,8 @@ var IdentitySampleAuditRowSchema = object({
25012
25180
  enrolledAt: number().int(),
25013
25181
  deviceId: number().int().optional(),
25014
25182
  source: _enum(["detected", "photo"]),
25015
- /** The enrolled crop's media key, so the panel can show the evidence. */
25016
- mediaKey: string().optional(),
25183
+ /** The enrolled crop's media row id, so the panel can show the evidence. */
25184
+ mediaId: number().int().optional(),
25017
25185
  /**
25018
25186
  * False = the sample is stamped with a DIFFERENT face model, and a cosine
25019
25187
  * across feature spaces is a well-formed float with no meaning. Every number
@@ -25082,15 +25250,15 @@ var FaceInfoSchema = object({
25082
25250
  */
25083
25251
  cropUrl: string().optional(),
25084
25252
  /** Design B: the face bbox (pixel space) on the key frame — lets a detail
25085
- * view draw the box over the native `keyFrameMediaKey` frame. Absent on
25253
+ * view draw the box over the native `keyFrameMediaId` frame. Absent on
25086
25254
  * legacy rows written before design B. */
25087
25255
  faceBbox: BoundingBoxSchema.optional(),
25088
25256
  /** Design B: MediaStore key of the track's native-resolution key frame.
25089
25257
  * Fetch the native JPEG via the event-media data-plane
25090
- * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
25258
+ * (`/addon/<addonId>/event-media/m/<keyFrameMediaId>`). Absent when the
25091
25259
  * track produced no key frame (e.g. native/onboard source) — the UI falls
25092
25260
  * back to the inline `base64` face crop. */
25093
- keyFrameMediaKey: string().optional(),
25261
+ keyFrameMediaId: number().int().optional(),
25094
25262
  /** Winning identity-match cosine (0..1) for this face's track, when an
25095
25263
  * identity was auto-confirmed. Lets the UI surface WHY a face was assigned
25096
25264
  * (confidence badge / low-confidence audit). Absent on legacy rows and on
@@ -25159,11 +25327,14 @@ var FaceClusterSchema = object({
25159
25327
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
25160
25328
  * dialog already rendering its key FRAME from the `event-media` plane.
25161
25329
  *
25162
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
25163
- * media key directly, so this needed no new plane and no new access decision.
25330
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
25331
+ * resolves a media row by its own id, so this needed no new plane and no new
25332
+ * access decision.
25164
25333
  */
25165
25334
  var MediaFileLiteSchema$1 = object({
25166
- key: string(),
25335
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
25336
+ * (D482). It was the row's composite key, which embedded the owner. */
25337
+ mediaId: number().int(),
25167
25338
  kind: string(),
25168
25339
  url: string(),
25169
25340
  sizeBytes: number(),
@@ -25180,7 +25351,7 @@ method(object({
25180
25351
  * covers inline, ~10 KB of base64 per row, on a query this UI mounts
25181
25352
  * four times and the viewer holds at `staleTime: 30_000`.
25182
25353
  *
25183
- * Nothing loses its avatar: `coverMediaKey` is already on every row and
25354
+ * Nothing loses its avatar: `coverMediaId` is already on every row and
25184
25355
  * the `event-media` plane serves that key `immutable` with an ETag.
25185
25356
  *
25186
25357
  * **This is an INPUT field, so it does not reach the addon until the
@@ -27648,8 +27819,8 @@ var VehicleSchema = object({
27648
27819
  id: string(),
27649
27820
  name: string(),
27650
27821
  sampleCount: number().int().nonnegative(),
27651
- coverMediaKey: string().optional(),
27652
- /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaKey`. */
27822
+ coverMediaId: number().int().optional(),
27823
+ /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaId`. */
27653
27824
  coverBase64: string().optional()
27654
27825
  });
27655
27826
  var VehicleSampleInfoSchema = object({
@@ -27682,7 +27853,7 @@ var PlateInfoSchema = object({
27682
27853
  /** keyFrame parity: the plate bbox (pixel space) on the native key frame. */
27683
27854
  plateBbox: BoundingBoxSchema.optional(),
27684
27855
  /** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
27685
- keyFrameMediaKey: string().optional(),
27856
+ keyFrameMediaId: number().int().optional(),
27686
27857
  base64: string().optional(),
27687
27858
  /**
27688
27859
  * Same crop as a data-plane URL, always present when the plate has a stored
@@ -27703,11 +27874,14 @@ var PlateInfoSchema = object({
27703
27874
  * `data:image/jpeg;base64,…` from a row whose `key` sat right beside it, in a
27704
27875
  * dialog already rendering its key FRAME from the `event-media` plane.
27705
27876
  *
27706
- * `url` is `/addon/<addonId>/event-media/<encoded key>`. The plane resolves a
27707
- * media key directly, so this needed no new plane and no new access decision.
27877
+ * `url` is `/addon/<addonId>/event-media/m/<mediaId>` (D482). The plane
27878
+ * resolves a media row by its own id, so this needed no new plane and no new
27879
+ * access decision.
27708
27880
  */
27709
27881
  var MediaFileLiteSchema = object({
27710
- key: string(),
27882
+ /** The media row's own id — the same address `MediaFileRef.mediaId` carries
27883
+ * (D482). It was the row's composite key, which embedded the owner. */
27884
+ mediaId: number().int(),
27711
27885
  kind: string(),
27712
27886
  url: string(),
27713
27887
  sizeBytes: number(),
@@ -27766,7 +27940,7 @@ method(object({
27766
27940
  }), method(object({
27767
27941
  /** Inline {@link VehicleSchema.coverBase64} on every row. Default
27768
27942
  * `false` — the vehicle twin of `faceGallery.listIdentities`'s
27769
- * option; `coverMediaKey` + the `event-media` plane carry the picture.
27943
+ * option; `coverMediaId` + the `event-media` plane carry the picture.
27770
27944
  * INPUT field: stripped by the hub router until the train ships, which
27771
27945
  * resolves to `false` and is exactly the intended default. */
27772
27946
  includeCrops: boolean().optional() }).optional(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
@@ -29132,7 +29306,14 @@ var SceneReferenceSchema = object({
29132
29306
  modelId: string(),
29133
29307
  condition: SceneConditionSchema,
29134
29308
  capturedAt: number(),
29135
- thumbnailMediaId: string().optional(),
29309
+ /**
29310
+ * The reference thumbnail's media ROW id (D482).
29311
+ *
29312
+ * The name already said `mediaId` while the value was the row's composite
29313
+ * key — a leftover that read as done and was not. It is the row's own id
29314
+ * now, addressed at `/addon/<addonId>/event-media/m/<id>`.
29315
+ */
29316
+ thumbnailMediaId: number().int().optional(),
29136
29317
  /** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
29137
29318
  * anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
29138
29319
  * normalized rect frame a different piece of world, and the scene would
@@ -29946,7 +30127,29 @@ var LoggingSettingsPatchSchema = object({
29946
30127
  * disarmed the channels it did not mention would make the Levels page and
29947
30128
  * the Diagnostics page fight over the same value.
29948
30129
  */
29949
- channels: array(LogChannelWindowPatchSchema).readonly().optional()
30130
+ channels: array(LogChannelWindowPatchSchema).readonly().optional(),
30131
+ /**
30132
+ * How many days the analytics OPS LOG is kept — the audit trail of what
30133
+ * retention actually deleted.
30134
+ *
30135
+ * It lives HERE, on the logging document, and not on the analytics addon's
30136
+ * settings form, on the operator's instruction: every other log-ish window in
30137
+ * this system is configured through this one document, and a retention audit
30138
+ * configured somewhere else is a second place to look when the question is
30139
+ * "what happened to my data".
30140
+ *
30141
+ * That placement has a cost worth stating: this document ships in the
30142
+ * framework closure, so this knob needs a published `@camstack/server` while
30143
+ * the four windows beside it (D485) reach a node on `camstack deploy`.
30144
+ *
30145
+ * `retention-model.ts` argued this one must NOT follow a device window,
30146
+ * because the audit trail is the history of the SWEEP and not of the camera.
30147
+ * That argument stands and is untouched — what changes is that 30 days stops
30148
+ * being a constant nobody can reach. `0` keeps it forever. The floor is 1 day
30149
+ * rather than 0-as-delete: an audit log truncated to nothing is precisely the
30150
+ * state in which the next 9.5 GiB leak cannot be explained.
30151
+ */
30152
+ opsLogRetentionDays: number().int().min(0).max(3650).optional()
29950
30153
  });
29951
30154
  /**
29952
30155
  * Which LAYER of the hierarchy is addressed. Absent = the cluster layer.
@@ -30019,6 +30222,14 @@ var LoggingSettingsStateSchema = object({
30019
30222
  channels: array(LogChannelDescriptorSchema).readonly(),
30020
30223
  /** The channels ARMED right now, each with its deadline. */
30021
30224
  activeChannels: array(LogChannelWindowStateSchema).readonly(),
30225
+ /**
30226
+ * The ops-log window in days, as it is in force. `0` = kept forever.
30227
+ *
30228
+ * Reported rather than left to the caller's memory of what it wrote: this is
30229
+ * the value the analytics sweep will actually use, and an operator asking how
30230
+ * long their audit trail lives should not have to infer it from a default.
30231
+ */
30232
+ opsLogRetentionDays: number().int().min(0),
30022
30233
  persisted: boolean()
30023
30234
  });
30024
30235
  method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
@@ -30580,7 +30791,7 @@ var StationaryObjectSchema = object({
30580
30791
  /** Enrichment label carried from the source track (identity / plate). */
30581
30792
  label: string().optional(),
30582
30793
  /** Native-resolution key-frame media key for the parked object's best image. */
30583
- keyFrameMediaKey: string().optional()
30794
+ keyFrameMediaId: number().int().optional()
30584
30795
  });
30585
30796
  var CameraOccupancySnapshotSchema = object({
30586
30797
  /** Frame timestamp of the inference result that produced this snapshot. */
@@ -32562,6 +32773,12 @@ Object.freeze({
32562
32773
  addonId: null,
32563
32774
  access: "create"
32564
32775
  },
32776
+ "dataStoreProvider.upsert": {
32777
+ capName: "data-store-provider",
32778
+ capScope: "system",
32779
+ addonId: null,
32780
+ access: "create"
32781
+ },
32565
32782
  "dayNight.getOptions": {
32566
32783
  capName: "day-night",
32567
32784
  capScope: "device",
@@ -34998,6 +35215,12 @@ Object.freeze({
34998
35215
  addonId: null,
34999
35216
  access: "view"
35000
35217
  },
35218
+ "pipelineAnalytics.listRecentSummaries": {
35219
+ capName: "pipeline-analytics",
35220
+ capScope: "device",
35221
+ addonId: null,
35222
+ access: "view"
35223
+ },
35001
35224
  "pipelineAnalytics.listRecentTracks": {
35002
35225
  capName: "pipeline-analytics",
35003
35226
  capScope: "device",
@@ -36426,6 +36649,12 @@ Object.freeze({
36426
36649
  addonId: null,
36427
36650
  access: "create"
36428
36651
  },
36652
+ "settingsStore.upsert": {
36653
+ capName: "settings-store",
36654
+ capScope: "system",
36655
+ addonId: null,
36656
+ access: "create"
36657
+ },
36429
36658
  "smtpProvider.getStatus": {
36430
36659
  capName: "smtp-provider",
36431
36660
  capScope: "system",
@@ -38819,6 +39048,11 @@ Object.freeze({
38819
39048
  form: "single",
38820
39049
  optional: true
38821
39050
  }],
39051
+ "pipelineAnalytics.listRecentSummaries": [{
39052
+ name: "deviceIds",
39053
+ form: "array",
39054
+ optional: false
39055
+ }],
38822
39056
  "pipelineAnalytics.listRecentTracks": [{
38823
39057
  name: "deviceIds",
38824
39058
  form: "array",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-onvif",
3
- "version": "1.2.98",
3
+ "version": "1.2.100",
4
4
  "description": "ONVIF camera device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",