@camstack/addon-provider-onvif 1.1.22 → 1.1.24

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/addon.js CHANGED
@@ -4631,7 +4631,7 @@ function _instanceof(cls, params = {}) {
4631
4631
  return inst;
4632
4632
  }
4633
4633
  //#endregion
4634
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4634
+ //#region ../types/dist/sleep-Baang_XW.mjs
4635
4635
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4636
4636
  EventCategory["SystemBoot"] = "system.boot";
4637
4637
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6735,6 +6735,18 @@ function method(input, output, options) {
6735
6735
  timeoutMs: options?.timeoutMs
6736
6736
  };
6737
6737
  }
6738
+ /**
6739
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6740
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6741
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6742
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6743
+ */
6744
+ function systemMethod(input, output, options) {
6745
+ return {
6746
+ ...method(input, output, options),
6747
+ systemOnly: true
6748
+ };
6749
+ }
6738
6750
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
6739
6751
  var VersionOutputSchema$1 = object({ version: string() });
6740
6752
  method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
@@ -10655,6 +10667,7 @@ var PipelineAddonSchemaSchema = object({
10655
10667
  defaultModelId: string(),
10656
10668
  defaultModelIdByFormat: record(string(), string()).optional(),
10657
10669
  enabledByDefault: boolean().optional(),
10670
+ backfillIntoExistingOverrides: boolean().optional(),
10658
10671
  defaultConfidence: number(),
10659
10672
  group: string().optional(),
10660
10673
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -10836,7 +10849,15 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10836
10849
  image: _instanceof(Uint8Array).optional(),
10837
10850
  referenceImage: string().optional(),
10838
10851
  deviceId: number().optional(),
10839
- sessionId: string().optional()
10852
+ sessionId: string().optional(),
10853
+ /**
10854
+ * Execution plane. 'full' (default) runs the whole tree — benchmark,
10855
+ * reference-image, and detail-subtree calls. 'frame' is the live
10856
+ * per-frame dispatch: ONLY root-plane steps run; crop children
10857
+ * (inputClasses ≠ null) are skipped and served per-track via
10858
+ * pipelineRunner.runDetailSubtree (two-plane design).
10859
+ */
10860
+ plane: _enum(["full", "frame"]).optional()
10840
10861
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
10841
10862
  engine: PipelineEngineChoiceSchema.optional(),
10842
10863
  steps: array(PipelineStepInputSchema).min(1),
@@ -10961,6 +10982,47 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).read
10961
10982
  auth: "admin"
10962
10983
  }), object({ zones: array(ZoneSchema).readonly() });
10963
10984
  /**
10985
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
10986
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
10987
+ * so the caller supplies only the detection-res bbox divided by the detection
10988
+ * dims — no native resolution to plumb.
10989
+ */
10990
+ var NativeCropBboxSchema = object({
10991
+ x: number(),
10992
+ y: number(),
10993
+ w: number(),
10994
+ h: number()
10995
+ });
10996
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
10997
+ var NativeCropResultSchema = object({
10998
+ /** Packed rgb (24-bit) pixels of the crop. */
10999
+ bytes: _instanceof(Uint8Array),
11000
+ width: number().int().positive(),
11001
+ height: number().int().positive()
11002
+ });
11003
+ /** Parent detection context passed to `runDetailSubtree` — the crop's
11004
+ * originating detection, in FRAME-space coordinates. Reuses
11005
+ * `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
11006
+ * the coordinates are frame-space rather than getNativeCrop's
11007
+ * normalized [0,1] convention). */
11008
+ var DetailParentSchema = object({
11009
+ bbox: NativeCropBboxSchema,
11010
+ className: string()
11011
+ });
11012
+ /** One child-step result from `runDetailSubtree` — an embedding, label,
11013
+ * or refined detection produced by running the crop-subtree on a
11014
+ * single tracked detection. */
11015
+ var DetailResultSchema = object({
11016
+ stepId: string(),
11017
+ className: string(),
11018
+ score: number(),
11019
+ /** FRAME-space bbox (already mapped back from crop space). */
11020
+ bbox: NativeCropBboxSchema.optional(),
11021
+ embedding: string().optional(),
11022
+ label: string().optional(),
11023
+ alignedCropJpeg: string().optional()
11024
+ });
11025
+ /**
10964
11026
  * Per-camera tunable ranges + defaults. Single source of truth used
10965
11027
  * by both the Zod data schema (validation + default fallback) and
10966
11028
  * the device settings UI (slider min/max/step). Touch one place and
@@ -11216,7 +11278,17 @@ var RunnerLocalMetricsSchema = object({
11216
11278
  avgInferenceTimeMs: number(),
11217
11279
  queueDepth: number()
11218
11280
  });
11219
- method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly());
11281
+ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
11282
+ handle: FrameHandleSchema,
11283
+ bbox: NativeCropBboxSchema,
11284
+ maxWidth: number().int().positive().optional()
11285
+ }), NativeCropResultSchema.nullable()), method(object({
11286
+ deviceId: number(),
11287
+ frameHandle: FrameHandleSchema.optional(),
11288
+ cropJpeg: string().optional(),
11289
+ parent: DetailParentSchema,
11290
+ steps: array(string()).optional()
11291
+ }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" });
11220
11292
  object({
11221
11293
  detected: boolean(),
11222
11294
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -15548,7 +15620,17 @@ var TrackSchema = object({
15548
15620
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
15549
15621
  totalDistance: number(),
15550
15622
  state: TrackStateSchema,
15551
- active: boolean()
15623
+ active: boolean(),
15624
+ /** Deterministic key-event importance score in [0,1] (server-computed at
15625
+ * track expiry, recomputed on late label). Absent on legacy rows written
15626
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
15627
+ importance: number().optional(),
15628
+ /** Id of the track's highest-confidence ObjectEvent (its representative
15629
+ * "best" frame). Absent when the track produced no object events. */
15630
+ bestEventId: string().optional(),
15631
+ /** Tag of the importance sub-signal that dominated the score
15632
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
15633
+ importanceReason: string().optional()
15552
15634
  });
15553
15635
  var BaseEventFields = {
15554
15636
  id: string(),
@@ -15613,8 +15695,18 @@ var ObjectEventSchema = object({
15613
15695
  frameHeight: number().optional(),
15614
15696
  /** MediaStore key for the crop attached to this event (if any). */
15615
15697
  mediaKey: string().optional(),
15698
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
15699
+ * best-detection full frame). Resolve via the event-media data-plane
15700
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
15701
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
15702
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
15703
+ keyFrameMediaKey: string().optional(),
15616
15704
  /** Populated by B5 (recording playback URL for this event). */
15617
- mediaUrl: string().optional()
15705
+ mediaUrl: string().optional(),
15706
+ /** The parent track's key-event importance [0,1], propagated to every object
15707
+ * event of the track (so an event row can be sorted by importance without a
15708
+ * track join). Absent on legacy rows / before the track was scored. */
15709
+ importance: number().optional()
15618
15710
  });
15619
15711
  var AudioEventSchema = object({
15620
15712
  ...BaseEventFields,
@@ -15638,7 +15730,8 @@ var MediaFileKindEnum = _enum([
15638
15730
  "fullFrame",
15639
15731
  "fullFrameBoxed",
15640
15732
  "faceCrop",
15641
- "plateCrop"
15733
+ "plateCrop",
15734
+ "keyFrame"
15642
15735
  ]);
15643
15736
  var MediaFileSchema = object({
15644
15737
  key: string(),
@@ -15659,6 +15752,32 @@ var DeviceEventQueryInput = object({
15659
15752
  projection: _enum(["full", "slim"]).optional()
15660
15753
  });
15661
15754
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
15755
+ var KeyEventQueryInput = object({
15756
+ deviceId: number(),
15757
+ /** Window lower bound (track firstSeen ≥ since). */
15758
+ since: number(),
15759
+ /** Window upper bound (track firstSeen ≤ until). */
15760
+ until: number(),
15761
+ limit: number().int().min(1).max(200).default(50),
15762
+ /** Drop tracks scoring below this importance. */
15763
+ minImportance: number().min(0).max(1).optional(),
15764
+ /** Restrict to a single class (e.g. 'person'). */
15765
+ classFilter: string().optional()
15766
+ });
15767
+ var KeyEventSchema = object({
15768
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
15769
+ id: string(),
15770
+ trackId: string(),
15771
+ /** Track start time (firstSeen). */
15772
+ timestamp: number(),
15773
+ className: string(),
15774
+ label: string().optional(),
15775
+ importance: number(),
15776
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
15777
+ bestEventId: string(),
15778
+ /** Track lifetime in ms (lastSeen - firstSeen). */
15779
+ windowMs: number().optional()
15780
+ });
15662
15781
  var TrackedDetectionSchema = object({
15663
15782
  trackId: string(),
15664
15783
  className: string(),
@@ -15688,7 +15807,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15688
15807
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
15689
15808
  kind: "mutation",
15690
15809
  auth: "admin"
15691
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
15810
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
15692
15811
  deviceId: number(),
15693
15812
  since: number(),
15694
15813
  until: number(),
@@ -16492,7 +16611,20 @@ var snapshotCapability = {
16492
16611
  invalidateCache: method(object({ deviceId: number() }), _void(), {
16493
16612
  kind: "mutation",
16494
16613
  auth: "admin"
16495
- })
16614
+ }),
16615
+ /**
16616
+ * Cache-only batch overview — answers from the wrapper's in-memory cache in
16617
+ * O(n) and NEVER triggers a capture. Lets a grid skip requesting images for
16618
+ * devices that never produced a frame, and gives it an ETag per device for
16619
+ * conditional (304-able) image fetches. `lastCapturedAt`/`cacheAgeMs`/`etag`
16620
+ * are null for a device with no cached frame.
16621
+ */
16622
+ getSnapshotOverview: systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
16623
+ deviceId: number(),
16624
+ lastCapturedAt: number().nullable(),
16625
+ cacheAgeMs: number().nullable(),
16626
+ etag: string().nullable()
16627
+ })))
16496
16628
  },
16497
16629
  status: {
16498
16630
  schema: SnapshotStatusSchema,
@@ -16749,10 +16881,32 @@ method(_void(), array(TurnServerSchema).readonly());
16749
16881
  * b. `finishAuthentication({userId, response})` → server verifies
16750
16882
  * the assertion, bumps the credential counter, returns ok.
16751
16883
  *
16884
+ * 2b. Usernameless (discoverable-credential) authentication — the
16885
+ * passkey IS the primary factor, no password leg:
16886
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
16887
+ * EMPTY `allowCredentials` (the browser offers every resident
16888
+ * passkey it holds for this RP) + `userVerification: 'required'`
16889
+ * (the passkey replaces both factors, so UV is mandatory).
16890
+ * The challenge is stored server-side, NOT bound to any user.
16891
+ * b. `finishDiscoverableAuthentication({response})` → the provider
16892
+ * resolves the credential by the response's credential id,
16893
+ * verifies the assertion against the stored challenge + that
16894
+ * credential's public key/counter, and returns the OWNING
16895
+ * `userId` — the caller (core auth router) mints the session.
16896
+ *
16752
16897
  * 3. Management:
16753
16898
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
16754
16899
  * - `removePasskey({userId, credentialId})` — revoke one credential.
16755
16900
  *
16901
+ * 4. Second-factor preference (opt-in, default OFF):
16902
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
16903
+ * demanded as a second factor after a password login ONLY when the
16904
+ * user explicitly opts in via `setSecondFactorPreference`.
16905
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
16906
+ * row ⇒ `enabled: false`).
16907
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
16908
+ * the providing addon beside its credentials.
16909
+ *
16756
16910
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
16757
16911
  * the admin-ui composes the begin/finish round-trip and never exposes
16758
16912
  * the cap to non-admins.
@@ -16795,6 +16949,17 @@ method(object({
16795
16949
  }), object({ verified: boolean() }), {
16796
16950
  kind: "mutation",
16797
16951
  access: "view"
16952
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
16953
+ kind: "mutation",
16954
+ access: "view"
16955
+ }), method(object({
16956
+ /** AuthenticationResponseJSON from the browser. */
16957
+ response: record(string(), unknown()) }), object({
16958
+ verified: boolean(),
16959
+ userId: string().nullable()
16960
+ }), {
16961
+ kind: "mutation",
16962
+ access: "view"
16798
16963
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
16799
16964
  userId: string(),
16800
16965
  credentialId: string()
@@ -16802,6 +16967,13 @@ method(object({
16802
16967
  kind: "mutation",
16803
16968
  auth: "admin",
16804
16969
  access: "delete"
16970
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
16971
+ userId: string(),
16972
+ enabled: boolean()
16973
+ }), object({ success: literal(true) }), {
16974
+ kind: "mutation",
16975
+ auth: "admin",
16976
+ access: "create"
16805
16977
  });
16806
16978
  /**
16807
16979
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -17603,7 +17775,17 @@ var FaceInfoSchema = object({
17603
17775
  recognizedIdentityId: string().optional(),
17604
17776
  identityName: string().optional(),
17605
17777
  assigned: boolean(),
17606
- base64: string().optional()
17778
+ base64: string().optional(),
17779
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
17780
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
17781
+ * legacy rows written before design B. */
17782
+ faceBbox: BoundingBoxSchema.optional(),
17783
+ /** Design B: MediaStore key of the track's native-resolution key frame.
17784
+ * Fetch the native JPEG via the event-media data-plane
17785
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
17786
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
17787
+ * back to the inline `base64` face crop. */
17788
+ keyFrameMediaKey: string().optional()
17607
17789
  });
17608
17790
  var FaceFilterEnum = _enum([
17609
17791
  "unassigned",
@@ -21764,6 +21946,12 @@ Object.freeze({
21764
21946
  addonId: null,
21765
21947
  access: "view"
21766
21948
  },
21949
+ "pipelineAnalytics.getKeyEvents": {
21950
+ capName: "pipeline-analytics",
21951
+ capScope: "device",
21952
+ addonId: null,
21953
+ access: "view"
21954
+ },
21767
21955
  "pipelineAnalytics.getMotionEvents": {
21768
21956
  capName: "pipeline-analytics",
21769
21957
  capScope: "device",
@@ -22292,12 +22480,24 @@ Object.freeze({
22292
22480
  addonId: null,
22293
22481
  access: "view"
22294
22482
  },
22483
+ "pipelineRunner.getNativeCrop": {
22484
+ capName: "pipeline-runner",
22485
+ capScope: "system",
22486
+ addonId: null,
22487
+ access: "view"
22488
+ },
22295
22489
  "pipelineRunner.reportMotion": {
22296
22490
  capName: "pipeline-runner",
22297
22491
  capScope: "system",
22298
22492
  addonId: null,
22299
22493
  access: "create"
22300
22494
  },
22495
+ "pipelineRunner.runDetailSubtree": {
22496
+ capName: "pipeline-runner",
22497
+ capScope: "system",
22498
+ addonId: null,
22499
+ access: "create"
22500
+ },
22301
22501
  "plateGallery.correctPlateText": {
22302
22502
  capName: "plate-gallery",
22303
22503
  capScope: "system",
@@ -22658,6 +22858,12 @@ Object.freeze({
22658
22858
  addonId: null,
22659
22859
  access: "view"
22660
22860
  },
22861
+ "snapshot.getSnapshotOverview": {
22862
+ capName: "snapshot",
22863
+ capScope: "device",
22864
+ addonId: null,
22865
+ access: "view"
22866
+ },
22661
22867
  "snapshot.invalidateCache": {
22662
22868
  capName: "snapshot",
22663
22869
  capScope: "device",
@@ -23336,6 +23542,12 @@ Object.freeze({
23336
23542
  addonId: null,
23337
23543
  access: "view"
23338
23544
  },
23545
+ "userPasskeys.beginDiscoverableAuthentication": {
23546
+ capName: "user-passkeys",
23547
+ capScope: "system",
23548
+ addonId: null,
23549
+ access: "view"
23550
+ },
23339
23551
  "userPasskeys.beginRegistration": {
23340
23552
  capName: "user-passkeys",
23341
23553
  capScope: "system",
@@ -23348,12 +23560,24 @@ Object.freeze({
23348
23560
  addonId: null,
23349
23561
  access: "view"
23350
23562
  },
23563
+ "userPasskeys.finishDiscoverableAuthentication": {
23564
+ capName: "user-passkeys",
23565
+ capScope: "system",
23566
+ addonId: null,
23567
+ access: "view"
23568
+ },
23351
23569
  "userPasskeys.finishRegistration": {
23352
23570
  capName: "user-passkeys",
23353
23571
  capScope: "system",
23354
23572
  addonId: null,
23355
23573
  access: "create"
23356
23574
  },
23575
+ "userPasskeys.getSecondFactorPreference": {
23576
+ capName: "user-passkeys",
23577
+ capScope: "system",
23578
+ addonId: null,
23579
+ access: "view"
23580
+ },
23357
23581
  "userPasskeys.listPasskeys": {
23358
23582
  capName: "user-passkeys",
23359
23583
  capScope: "system",
@@ -23366,6 +23590,12 @@ Object.freeze({
23366
23590
  addonId: null,
23367
23591
  access: "delete"
23368
23592
  },
23593
+ "userPasskeys.setSecondFactorPreference": {
23594
+ capName: "user-passkeys",
23595
+ capScope: "system",
23596
+ addonId: null,
23597
+ access: "create"
23598
+ },
23369
23599
  "vacuumControl.locate": {
23370
23600
  capName: "vacuum-control",
23371
23601
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -4632,7 +4632,7 @@ function _instanceof(cls, params = {}) {
4632
4632
  return inst;
4633
4633
  }
4634
4634
  //#endregion
4635
- //#region ../types/dist/sleep-DJaTV2D7.mjs
4635
+ //#region ../types/dist/sleep-Baang_XW.mjs
4636
4636
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4637
4637
  EventCategory["SystemBoot"] = "system.boot";
4638
4638
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -6736,6 +6736,18 @@ function method(input, output, options) {
6736
6736
  timeoutMs: options?.timeoutMs
6737
6737
  };
6738
6738
  }
6739
+ /**
6740
+ * A wrapper/system-only method: served exclusively by the cap's system-level
6741
+ * provider (`InferProvider`), and OPTIONAL on `InferNativeProvider` so per-device
6742
+ * driver natives don't stub out a wrapper concern (e.g. a cross-device cache
6743
+ * overview). The `systemOnly: true` literal is what `InferNativeProvider` keys on.
6744
+ */
6745
+ function systemMethod(input, output, options) {
6746
+ return {
6747
+ ...method(input, output, options),
6748
+ systemOnly: true
6749
+ };
6750
+ }
6739
6751
  var StaticDirOutputSchema$1 = object({ staticDir: string() });
6740
6752
  var VersionOutputSchema$1 = object({ version: string() });
6741
6753
  method(_void(), StaticDirOutputSchema$1), method(_void(), VersionOutputSchema$1);
@@ -10656,6 +10668,7 @@ var PipelineAddonSchemaSchema = object({
10656
10668
  defaultModelId: string(),
10657
10669
  defaultModelIdByFormat: record(string(), string()).optional(),
10658
10670
  enabledByDefault: boolean().optional(),
10671
+ backfillIntoExistingOverrides: boolean().optional(),
10659
10672
  defaultConfidence: number(),
10660
10673
  group: string().optional(),
10661
10674
  configSchema: array(ConfigFieldBridge).readonly().optional()
@@ -10837,7 +10850,15 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10837
10850
  image: _instanceof(Uint8Array).optional(),
10838
10851
  referenceImage: string().optional(),
10839
10852
  deviceId: number().optional(),
10840
- sessionId: string().optional()
10853
+ sessionId: string().optional(),
10854
+ /**
10855
+ * Execution plane. 'full' (default) runs the whole tree — benchmark,
10856
+ * reference-image, and detail-subtree calls. 'frame' is the live
10857
+ * per-frame dispatch: ONLY root-plane steps run; crop children
10858
+ * (inputClasses ≠ null) are skipped and served per-track via
10859
+ * pipelineRunner.runDetailSubtree (two-plane design).
10860
+ */
10861
+ plane: _enum(["full", "frame"]).optional()
10841
10862
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
10842
10863
  engine: PipelineEngineChoiceSchema.optional(),
10843
10864
  steps: array(PipelineStepInputSchema).min(1),
@@ -10962,6 +10983,47 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).read
10962
10983
  auth: "admin"
10963
10984
  }), object({ zones: array(ZoneSchema).readonly() });
10964
10985
  /**
10986
+ * A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
10987
+ * decode worker resolves it against the RETAINED native frame's real pixel dims,
10988
+ * so the caller supplies only the detection-res bbox divided by the detection
10989
+ * dims — no native resolution to plumb.
10990
+ */
10991
+ var NativeCropBboxSchema = object({
10992
+ x: number(),
10993
+ y: number(),
10994
+ w: number(),
10995
+ h: number()
10996
+ });
10997
+ /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
10998
+ var NativeCropResultSchema = object({
10999
+ /** Packed rgb (24-bit) pixels of the crop. */
11000
+ bytes: _instanceof(Uint8Array),
11001
+ width: number().int().positive(),
11002
+ height: number().int().positive()
11003
+ });
11004
+ /** Parent detection context passed to `runDetailSubtree` — the crop's
11005
+ * originating detection, in FRAME-space coordinates. Reuses
11006
+ * `NativeCropBboxSchema`'s `{x,y,w,h}` shape (same numeric fields; here
11007
+ * the coordinates are frame-space rather than getNativeCrop's
11008
+ * normalized [0,1] convention). */
11009
+ var DetailParentSchema = object({
11010
+ bbox: NativeCropBboxSchema,
11011
+ className: string()
11012
+ });
11013
+ /** One child-step result from `runDetailSubtree` — an embedding, label,
11014
+ * or refined detection produced by running the crop-subtree on a
11015
+ * single tracked detection. */
11016
+ var DetailResultSchema = object({
11017
+ stepId: string(),
11018
+ className: string(),
11019
+ score: number(),
11020
+ /** FRAME-space bbox (already mapped back from crop space). */
11021
+ bbox: NativeCropBboxSchema.optional(),
11022
+ embedding: string().optional(),
11023
+ label: string().optional(),
11024
+ alignedCropJpeg: string().optional()
11025
+ });
11026
+ /**
10965
11027
  * Per-camera tunable ranges + defaults. Single source of truth used
10966
11028
  * by both the Zod data schema (validation + default fallback) and
10967
11029
  * the device settings UI (slider min/max/step). Touch one place and
@@ -11217,7 +11279,17 @@ var RunnerLocalMetricsSchema = object({
11217
11279
  avgInferenceTimeMs: number(),
11218
11280
  queueDepth: number()
11219
11281
  });
11220
- method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly());
11282
+ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
11283
+ handle: FrameHandleSchema,
11284
+ bbox: NativeCropBboxSchema,
11285
+ maxWidth: number().int().positive().optional()
11286
+ }), NativeCropResultSchema.nullable()), method(object({
11287
+ deviceId: number(),
11288
+ frameHandle: FrameHandleSchema.optional(),
11289
+ cropJpeg: string().optional(),
11290
+ parent: DetailParentSchema,
11291
+ steps: array(string()).optional()
11292
+ }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" });
11221
11293
  object({
11222
11294
  detected: boolean(),
11223
11295
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -15549,7 +15621,17 @@ var TrackSchema = object({
15549
15621
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
15550
15622
  totalDistance: number(),
15551
15623
  state: TrackStateSchema,
15552
- active: boolean()
15624
+ active: boolean(),
15625
+ /** Deterministic key-event importance score in [0,1] (server-computed at
15626
+ * track expiry, recomputed on late label). Absent on legacy rows written
15627
+ * before scoring shipped — consumers degrade to absence / compute-on-read. */
15628
+ importance: number().optional(),
15629
+ /** Id of the track's highest-confidence ObjectEvent (its representative
15630
+ * "best" frame). Absent when the track produced no object events. */
15631
+ bestEventId: string().optional(),
15632
+ /** Tag of the importance sub-signal that dominated the score
15633
+ * (identity|dwell|proximity|class|confidence|travel|zone). */
15634
+ importanceReason: string().optional()
15553
15635
  });
15554
15636
  var BaseEventFields = {
15555
15637
  id: string(),
@@ -15614,8 +15696,18 @@ var ObjectEventSchema = object({
15614
15696
  frameHeight: number().optional(),
15615
15697
  /** MediaStore key for the crop attached to this event (if any). */
15616
15698
  mediaKey: string().optional(),
15699
+ /** Design B: MediaStore key of the track's native-resolution key frame (the
15700
+ * best-detection full frame). Resolve via the event-media data-plane
15701
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`) for a detail view that
15702
+ * draws `bbox` over the native frame. Absent on legacy rows / non-decoded
15703
+ * sources — consumers fall back to `mediaKey` (the tight crop). */
15704
+ keyFrameMediaKey: string().optional(),
15617
15705
  /** Populated by B5 (recording playback URL for this event). */
15618
- mediaUrl: string().optional()
15706
+ mediaUrl: string().optional(),
15707
+ /** The parent track's key-event importance [0,1], propagated to every object
15708
+ * event of the track (so an event row can be sorted by importance without a
15709
+ * track join). Absent on legacy rows / before the track was scored. */
15710
+ importance: number().optional()
15619
15711
  });
15620
15712
  var AudioEventSchema = object({
15621
15713
  ...BaseEventFields,
@@ -15639,7 +15731,8 @@ var MediaFileKindEnum = _enum([
15639
15731
  "fullFrame",
15640
15732
  "fullFrameBoxed",
15641
15733
  "faceCrop",
15642
- "plateCrop"
15734
+ "plateCrop",
15735
+ "keyFrame"
15643
15736
  ]);
15644
15737
  var MediaFileSchema = object({
15645
15738
  key: string(),
@@ -15660,6 +15753,32 @@ var DeviceEventQueryInput = object({
15660
15753
  projection: _enum(["full", "slim"]).optional()
15661
15754
  });
15662
15755
  var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
15756
+ var KeyEventQueryInput = object({
15757
+ deviceId: number(),
15758
+ /** Window lower bound (track firstSeen ≥ since). */
15759
+ since: number(),
15760
+ /** Window upper bound (track firstSeen ≤ until). */
15761
+ until: number(),
15762
+ limit: number().int().min(1).max(200).default(50),
15763
+ /** Drop tracks scoring below this importance. */
15764
+ minImportance: number().min(0).max(1).optional(),
15765
+ /** Restrict to a single class (e.g. 'person'). */
15766
+ classFilter: string().optional()
15767
+ });
15768
+ var KeyEventSchema = object({
15769
+ /** The representative event id (the track's best ObjectEvent, else its trackId). */
15770
+ id: string(),
15771
+ trackId: string(),
15772
+ /** Track start time (firstSeen). */
15773
+ timestamp: number(),
15774
+ className: string(),
15775
+ label: string().optional(),
15776
+ importance: number(),
15777
+ /** Highest-confidence ObjectEvent id for the track (empty when none). */
15778
+ bestEventId: string(),
15779
+ /** Track lifetime in ms (lastSeen - firstSeen). */
15780
+ windowMs: number().optional()
15781
+ });
15663
15782
  var TrackedDetectionSchema = object({
15664
15783
  trackId: string(),
15665
15784
  className: string(),
@@ -15689,7 +15808,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15689
15808
  }), array(TrackSchema).readonly()), method(object({ deviceId: number() }), _void(), {
15690
15809
  kind: "mutation",
15691
15810
  auth: "admin"
15692
- }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({
15811
+ }), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
15693
15812
  deviceId: number(),
15694
15813
  since: number(),
15695
15814
  until: number(),
@@ -16493,7 +16612,20 @@ var snapshotCapability = {
16493
16612
  invalidateCache: method(object({ deviceId: number() }), _void(), {
16494
16613
  kind: "mutation",
16495
16614
  auth: "admin"
16496
- })
16615
+ }),
16616
+ /**
16617
+ * Cache-only batch overview — answers from the wrapper's in-memory cache in
16618
+ * O(n) and NEVER triggers a capture. Lets a grid skip requesting images for
16619
+ * devices that never produced a frame, and gives it an ETag per device for
16620
+ * conditional (304-able) image fetches. `lastCapturedAt`/`cacheAgeMs`/`etag`
16621
+ * are null for a device with no cached frame.
16622
+ */
16623
+ getSnapshotOverview: systemMethod(object({ deviceIds: array(number()).min(1).max(200) }), array(object({
16624
+ deviceId: number(),
16625
+ lastCapturedAt: number().nullable(),
16626
+ cacheAgeMs: number().nullable(),
16627
+ etag: string().nullable()
16628
+ })))
16497
16629
  },
16498
16630
  status: {
16499
16631
  schema: SnapshotStatusSchema,
@@ -16750,10 +16882,32 @@ method(_void(), array(TurnServerSchema).readonly());
16750
16882
  * b. `finishAuthentication({userId, response})` → server verifies
16751
16883
  * the assertion, bumps the credential counter, returns ok.
16752
16884
  *
16885
+ * 2b. Usernameless (discoverable-credential) authentication — the
16886
+ * passkey IS the primary factor, no password leg:
16887
+ * a. `beginDiscoverableAuthentication({})` → assertion options with
16888
+ * EMPTY `allowCredentials` (the browser offers every resident
16889
+ * passkey it holds for this RP) + `userVerification: 'required'`
16890
+ * (the passkey replaces both factors, so UV is mandatory).
16891
+ * The challenge is stored server-side, NOT bound to any user.
16892
+ * b. `finishDiscoverableAuthentication({response})` → the provider
16893
+ * resolves the credential by the response's credential id,
16894
+ * verifies the assertion against the stored challenge + that
16895
+ * credential's public key/counter, and returns the OWNING
16896
+ * `userId` — the caller (core auth router) mints the session.
16897
+ *
16753
16898
  * 3. Management:
16754
16899
  * - `listPasskeys({userId})` — enumerate user's enrolled credentials.
16755
16900
  * - `removePasskey({userId, credentialId})` — revoke one credential.
16756
16901
  *
16902
+ * 4. Second-factor preference (opt-in, default OFF):
16903
+ * Enrolling a passkey only enables passkey-FIRST sign-in. It is
16904
+ * demanded as a second factor after a password login ONLY when the
16905
+ * user explicitly opts in via `setSecondFactorPreference`.
16906
+ * - `getSecondFactorPreference({userId})` → `{ enabled }` (missing
16907
+ * row ⇒ `enabled: false`).
16908
+ * - `setSecondFactorPreference({userId, enabled})` — persisted by
16909
+ * the providing addon beside its credentials.
16910
+ *
16757
16911
  * Challenges are short-lived (5 min, in-memory). The cap is internal —
16758
16912
  * the admin-ui composes the begin/finish round-trip and never exposes
16759
16913
  * the cap to non-admins.
@@ -16796,6 +16950,17 @@ method(object({
16796
16950
  }), object({ verified: boolean() }), {
16797
16951
  kind: "mutation",
16798
16952
  access: "view"
16953
+ }), method(object({}), object({ optionsJSON: record(string(), unknown()) }), {
16954
+ kind: "mutation",
16955
+ access: "view"
16956
+ }), method(object({
16957
+ /** AuthenticationResponseJSON from the browser. */
16958
+ response: record(string(), unknown()) }), object({
16959
+ verified: boolean(),
16960
+ userId: string().nullable()
16961
+ }), {
16962
+ kind: "mutation",
16963
+ access: "view"
16799
16964
  }), method(object({ userId: string() }), array(PasskeySummarySchema), { auth: "admin" }), method(object({
16800
16965
  userId: string(),
16801
16966
  credentialId: string()
@@ -16803,6 +16968,13 @@ method(object({
16803
16968
  kind: "mutation",
16804
16969
  auth: "admin",
16805
16970
  access: "delete"
16971
+ }), method(object({ userId: string() }), object({ enabled: boolean() }), { auth: "admin" }), method(object({
16972
+ userId: string(),
16973
+ enabled: boolean()
16974
+ }), object({ success: literal(true) }), {
16975
+ kind: "mutation",
16976
+ auth: "admin",
16977
+ access: "create"
16806
16978
  });
16807
16979
  /**
16808
16980
  * `videoclips` — the unified, navigable-clip surface for a camera.
@@ -17604,7 +17776,17 @@ var FaceInfoSchema = object({
17604
17776
  recognizedIdentityId: string().optional(),
17605
17777
  identityName: string().optional(),
17606
17778
  assigned: boolean(),
17607
- base64: string().optional()
17779
+ base64: string().optional(),
17780
+ /** Design B: the face bbox (pixel space) on the key frame — lets a detail
17781
+ * view draw the box over the native `keyFrameMediaKey` frame. Absent on
17782
+ * legacy rows written before design B. */
17783
+ faceBbox: BoundingBoxSchema.optional(),
17784
+ /** Design B: MediaStore key of the track's native-resolution key frame.
17785
+ * Fetch the native JPEG via the event-media data-plane
17786
+ * (`/addon/<addonId>/event-media/<keyFrameMediaKey>`). Absent when the
17787
+ * track produced no key frame (e.g. native/onboard source) — the UI falls
17788
+ * back to the inline `base64` face crop. */
17789
+ keyFrameMediaKey: string().optional()
17608
17790
  });
17609
17791
  var FaceFilterEnum = _enum([
17610
17792
  "unassigned",
@@ -21765,6 +21947,12 @@ Object.freeze({
21765
21947
  addonId: null,
21766
21948
  access: "view"
21767
21949
  },
21950
+ "pipelineAnalytics.getKeyEvents": {
21951
+ capName: "pipeline-analytics",
21952
+ capScope: "device",
21953
+ addonId: null,
21954
+ access: "view"
21955
+ },
21768
21956
  "pipelineAnalytics.getMotionEvents": {
21769
21957
  capName: "pipeline-analytics",
21770
21958
  capScope: "device",
@@ -22293,12 +22481,24 @@ Object.freeze({
22293
22481
  addonId: null,
22294
22482
  access: "view"
22295
22483
  },
22484
+ "pipelineRunner.getNativeCrop": {
22485
+ capName: "pipeline-runner",
22486
+ capScope: "system",
22487
+ addonId: null,
22488
+ access: "view"
22489
+ },
22296
22490
  "pipelineRunner.reportMotion": {
22297
22491
  capName: "pipeline-runner",
22298
22492
  capScope: "system",
22299
22493
  addonId: null,
22300
22494
  access: "create"
22301
22495
  },
22496
+ "pipelineRunner.runDetailSubtree": {
22497
+ capName: "pipeline-runner",
22498
+ capScope: "system",
22499
+ addonId: null,
22500
+ access: "create"
22501
+ },
22302
22502
  "plateGallery.correctPlateText": {
22303
22503
  capName: "plate-gallery",
22304
22504
  capScope: "system",
@@ -22659,6 +22859,12 @@ Object.freeze({
22659
22859
  addonId: null,
22660
22860
  access: "view"
22661
22861
  },
22862
+ "snapshot.getSnapshotOverview": {
22863
+ capName: "snapshot",
22864
+ capScope: "device",
22865
+ addonId: null,
22866
+ access: "view"
22867
+ },
22662
22868
  "snapshot.invalidateCache": {
22663
22869
  capName: "snapshot",
22664
22870
  capScope: "device",
@@ -23337,6 +23543,12 @@ Object.freeze({
23337
23543
  addonId: null,
23338
23544
  access: "view"
23339
23545
  },
23546
+ "userPasskeys.beginDiscoverableAuthentication": {
23547
+ capName: "user-passkeys",
23548
+ capScope: "system",
23549
+ addonId: null,
23550
+ access: "view"
23551
+ },
23340
23552
  "userPasskeys.beginRegistration": {
23341
23553
  capName: "user-passkeys",
23342
23554
  capScope: "system",
@@ -23349,12 +23561,24 @@ Object.freeze({
23349
23561
  addonId: null,
23350
23562
  access: "view"
23351
23563
  },
23564
+ "userPasskeys.finishDiscoverableAuthentication": {
23565
+ capName: "user-passkeys",
23566
+ capScope: "system",
23567
+ addonId: null,
23568
+ access: "view"
23569
+ },
23352
23570
  "userPasskeys.finishRegistration": {
23353
23571
  capName: "user-passkeys",
23354
23572
  capScope: "system",
23355
23573
  addonId: null,
23356
23574
  access: "create"
23357
23575
  },
23576
+ "userPasskeys.getSecondFactorPreference": {
23577
+ capName: "user-passkeys",
23578
+ capScope: "system",
23579
+ addonId: null,
23580
+ access: "view"
23581
+ },
23358
23582
  "userPasskeys.listPasskeys": {
23359
23583
  capName: "user-passkeys",
23360
23584
  capScope: "system",
@@ -23367,6 +23591,12 @@ Object.freeze({
23367
23591
  addonId: null,
23368
23592
  access: "delete"
23369
23593
  },
23594
+ "userPasskeys.setSecondFactorPreference": {
23595
+ capName: "user-passkeys",
23596
+ capScope: "system",
23597
+ addonId: null,
23598
+ access: "create"
23599
+ },
23370
23600
  "vacuumControl.locate": {
23371
23601
  capName: "vacuum-control",
23372
23602
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-onvif",
3
- "version": "1.1.22",
3
+ "version": "1.1.24",
4
4
  "description": "ONVIF camera device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",