@camstack/addon-export-hap 1.2.41 → 1.2.42

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.
@@ -16281,7 +16281,23 @@ var NcHistoryEntrySchema = object({
16281
16281
  updatedAt: number(),
16282
16282
  /** Failure detail — present on a `dead` row. */
16283
16283
  error: string().optional(),
16284
- subject: NcHistorySubjectSchema
16284
+ subject: NcHistorySubjectSchema,
16285
+ /**
16286
+ * Ids of the artefacts (still, then gif, then clip) this row's successful
16287
+ * delivery indexed in the artefact library — a REFERENCE, never the bytes
16288
+ * (an artefact is often megabytes; this row is durable JSON rewritten on
16289
+ * every delivery attempt). Absent on a row still pending/dead, a row
16290
+ * delivered before this field shipped, or a wiring with no artefact index.
16291
+ *
16292
+ * Resolve one to a fetchable URL with `resolveArtifactUrl` — an id
16293
+ * outlives any one URL's TTL, so a caller mints a fresh link on demand
16294
+ * rather than trusting one frozen at delivery time. `resolveArtifactUrl`
16295
+ * also answers `null` for an id whose artefact has since expired past the
16296
+ * retained shelf's own age bound — the degrade a caller (the Home
16297
+ * Assistant export) must render as "no image right now", never as a
16298
+ * broken link.
16299
+ */
16300
+ artifactIds: array(string().min(1)).optional()
16285
16301
  });
16286
16302
  /**
16287
16303
  * Query filter for `getHistory` (spec §4.2). Every field is a narrowing
@@ -16508,7 +16524,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
16508
16524
  }), method(object({}), object({
16509
16525
  catalog: array(NcConditionDescriptorSchema),
16510
16526
  taxonomy: NcTaxonomySchema.optional()
16511
- })), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }), method(object({}), object({ snoozes: array(NcSnoozeSchema) }), { caller: "required" }), method(object({ snooze: NcSnoozeInputSchema }), object({ snooze: NcSnoozeSchema }), {
16527
+ })), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }), method(object({ artifactId: string().min(1) }), object({ url: string().nullable() }), { auth: "admin" }), method(object({}), object({ snoozes: array(NcSnoozeSchema) }), { caller: "required" }), method(object({ snooze: NcSnoozeInputSchema }), object({ snooze: NcSnoozeSchema }), {
16512
16528
  kind: "mutation",
16513
16529
  caller: "required"
16514
16530
  }), method(object({ snoozeId: string() }), object({ success: literal(true) }), {
@@ -25848,6 +25864,39 @@ var ReadGopBytesResultSchema = object({
25848
25864
  /** Media ms the returned fragment covers. */
25849
25865
  gopDurMs: number()
25850
25866
  });
25867
+ /**
25868
+ * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
25869
+ * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
25870
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
25871
+ * a replay needs several seconds of native pixels, not one frame.
25872
+ *
25873
+ * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
25874
+ * is `false` when the returned bytes were cut short by the read's own safety
25875
+ * byte cap before covering `[fromMs, toMs)` — a truncation, reported, not a
25876
+ * silently shorter answer. `spans-multiple-segments` is a REFUSAL, not a
25877
+ * degradation: a window whose end falls past the covering segment would need
25878
+ * bytes stitched from a second segment file (its own `ftyp`+`moov`), which is
25879
+ * not one standalone-demuxable stream — the caller's answer is to request a
25880
+ * shorter window or one aligned to a single segment, not to receive spliced
25881
+ * bytes nothing has proven decodable.
25882
+ */
25883
+ var ReadWindowBytesResultSchema = discriminatedUnion("kind", [object({
25884
+ kind: literal("ok"),
25885
+ data: _instanceof(Uint8Array),
25886
+ /** Absolute epoch ms of the returned bytes' first sample — at or before
25887
+ * the requested `fromMs` (anchored on the nearest keyframe). */
25888
+ gopStartMs: number(),
25889
+ /** Media ms the returned bytes cover, from `gopStartMs`. */
25890
+ gopDurMs: number(),
25891
+ /** `false` ⇒ the safety byte cap cut the read short before it reached
25892
+ * the requested `toMs`; the caller got fewer frames than asked for. */
25893
+ reachesRequestedEnd: boolean()
25894
+ }), object({
25895
+ kind: literal("spans-multiple-segments"),
25896
+ /** Where the covering segment's own footage runs out — informational,
25897
+ * not a retry hint (retrying the same window would refuse again). */
25898
+ segmentEndMs: number()
25899
+ })]);
25851
25900
  method(object({
25852
25901
  deviceId: number(),
25853
25902
  fromMs: number(),
@@ -25898,6 +25947,15 @@ method(object({
25898
25947
  }), ReadGopBytesResultSchema, {
25899
25948
  kind: "query",
25900
25949
  auth: "admin"
25950
+ }), method(object({
25951
+ deviceId: number(),
25952
+ profile: string(),
25953
+ startMs: number(),
25954
+ fromMs: number(),
25955
+ toMs: number()
25956
+ }), ReadWindowBytesResultSchema, {
25957
+ kind: "query",
25958
+ auth: "admin"
25901
25959
  }), method(object({
25902
25960
  deviceId: number(),
25903
25961
  config: RecordingConfigSchema
@@ -30341,6 +30399,12 @@ Object.freeze({
30341
30399
  addonId: null,
30342
30400
  access: "view"
30343
30401
  },
30402
+ "notificationRules.resolveArtifactUrl": {
30403
+ capName: "notification-rules",
30404
+ capScope: "system",
30405
+ addonId: null,
30406
+ access: "view"
30407
+ },
30344
30408
  "notificationRules.setAlarmConfig": {
30345
30409
  capName: "notification-rules",
30346
30410
  capScope: "system",
@@ -31745,6 +31809,12 @@ Object.freeze({
31745
31809
  addonId: null,
31746
31810
  access: "view"
31747
31811
  },
31812
+ "recording.readWindowBytes": {
31813
+ capName: "recording",
31814
+ capScope: "system",
31815
+ addonId: null,
31816
+ access: "view"
31817
+ },
31748
31818
  "recording.refreshStorageLocationsForMigration": {
31749
31819
  capName: "recording",
31750
31820
  capScope: "system",
@@ -34575,6 +34645,11 @@ Object.freeze({
34575
34645
  form: "single",
34576
34646
  optional: false
34577
34647
  }],
34648
+ "recording.readWindowBytes": [{
34649
+ name: "deviceId",
34650
+ form: "single",
34651
+ optional: false
34652
+ }],
34578
34653
  "recording.relocateFootage": [{
34579
34654
  name: "deviceId",
34580
34655
  form: "single",
@@ -16269,7 +16269,23 @@ var NcHistoryEntrySchema = object({
16269
16269
  updatedAt: number(),
16270
16270
  /** Failure detail — present on a `dead` row. */
16271
16271
  error: string().optional(),
16272
- subject: NcHistorySubjectSchema
16272
+ subject: NcHistorySubjectSchema,
16273
+ /**
16274
+ * Ids of the artefacts (still, then gif, then clip) this row's successful
16275
+ * delivery indexed in the artefact library — a REFERENCE, never the bytes
16276
+ * (an artefact is often megabytes; this row is durable JSON rewritten on
16277
+ * every delivery attempt). Absent on a row still pending/dead, a row
16278
+ * delivered before this field shipped, or a wiring with no artefact index.
16279
+ *
16280
+ * Resolve one to a fetchable URL with `resolveArtifactUrl` — an id
16281
+ * outlives any one URL's TTL, so a caller mints a fresh link on demand
16282
+ * rather than trusting one frozen at delivery time. `resolveArtifactUrl`
16283
+ * also answers `null` for an id whose artefact has since expired past the
16284
+ * retained shelf's own age bound — the degrade a caller (the Home
16285
+ * Assistant export) must render as "no image right now", never as a
16286
+ * broken link.
16287
+ */
16288
+ artifactIds: array(string().min(1)).optional()
16273
16289
  });
16274
16290
  /**
16275
16291
  * Query filter for `getHistory` (spec §4.2). Every field is a narrowing
@@ -16496,7 +16512,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
16496
16512
  }), method(object({}), object({
16497
16513
  catalog: array(NcConditionDescriptorSchema),
16498
16514
  taxonomy: NcTaxonomySchema.optional()
16499
- })), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }), method(object({}), object({ snoozes: array(NcSnoozeSchema) }), { caller: "required" }), method(object({ snooze: NcSnoozeInputSchema }), object({ snooze: NcSnoozeSchema }), {
16515
+ })), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }), method(object({ artifactId: string().min(1) }), object({ url: string().nullable() }), { auth: "admin" }), method(object({}), object({ snoozes: array(NcSnoozeSchema) }), { caller: "required" }), method(object({ snooze: NcSnoozeInputSchema }), object({ snooze: NcSnoozeSchema }), {
16500
16516
  kind: "mutation",
16501
16517
  caller: "required"
16502
16518
  }), method(object({ snoozeId: string() }), object({ success: literal(true) }), {
@@ -25836,6 +25852,39 @@ var ReadGopBytesResultSchema = object({
25836
25852
  /** Media ms the returned fragment covers. */
25837
25853
  gopDurMs: number()
25838
25854
  });
25855
+ /**
25856
+ * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
25857
+ * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
25858
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
25859
+ * a replay needs several seconds of native pixels, not one frame.
25860
+ *
25861
+ * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
25862
+ * is `false` when the returned bytes were cut short by the read's own safety
25863
+ * byte cap before covering `[fromMs, toMs)` — a truncation, reported, not a
25864
+ * silently shorter answer. `spans-multiple-segments` is a REFUSAL, not a
25865
+ * degradation: a window whose end falls past the covering segment would need
25866
+ * bytes stitched from a second segment file (its own `ftyp`+`moov`), which is
25867
+ * not one standalone-demuxable stream — the caller's answer is to request a
25868
+ * shorter window or one aligned to a single segment, not to receive spliced
25869
+ * bytes nothing has proven decodable.
25870
+ */
25871
+ var ReadWindowBytesResultSchema = discriminatedUnion("kind", [object({
25872
+ kind: literal("ok"),
25873
+ data: _instanceof(Uint8Array),
25874
+ /** Absolute epoch ms of the returned bytes' first sample — at or before
25875
+ * the requested `fromMs` (anchored on the nearest keyframe). */
25876
+ gopStartMs: number(),
25877
+ /** Media ms the returned bytes cover, from `gopStartMs`. */
25878
+ gopDurMs: number(),
25879
+ /** `false` ⇒ the safety byte cap cut the read short before it reached
25880
+ * the requested `toMs`; the caller got fewer frames than asked for. */
25881
+ reachesRequestedEnd: boolean()
25882
+ }), object({
25883
+ kind: literal("spans-multiple-segments"),
25884
+ /** Where the covering segment's own footage runs out — informational,
25885
+ * not a retry hint (retrying the same window would refuse again). */
25886
+ segmentEndMs: number()
25887
+ })]);
25839
25888
  method(object({
25840
25889
  deviceId: number(),
25841
25890
  fromMs: number(),
@@ -25886,6 +25935,15 @@ method(object({
25886
25935
  }), ReadGopBytesResultSchema, {
25887
25936
  kind: "query",
25888
25937
  auth: "admin"
25938
+ }), method(object({
25939
+ deviceId: number(),
25940
+ profile: string(),
25941
+ startMs: number(),
25942
+ fromMs: number(),
25943
+ toMs: number()
25944
+ }), ReadWindowBytesResultSchema, {
25945
+ kind: "query",
25946
+ auth: "admin"
25889
25947
  }), method(object({
25890
25948
  deviceId: number(),
25891
25949
  config: RecordingConfigSchema
@@ -30329,6 +30387,12 @@ Object.freeze({
30329
30387
  addonId: null,
30330
30388
  access: "view"
30331
30389
  },
30390
+ "notificationRules.resolveArtifactUrl": {
30391
+ capName: "notification-rules",
30392
+ capScope: "system",
30393
+ addonId: null,
30394
+ access: "view"
30395
+ },
30332
30396
  "notificationRules.setAlarmConfig": {
30333
30397
  capName: "notification-rules",
30334
30398
  capScope: "system",
@@ -31733,6 +31797,12 @@ Object.freeze({
31733
31797
  addonId: null,
31734
31798
  access: "view"
31735
31799
  },
31800
+ "recording.readWindowBytes": {
31801
+ capName: "recording",
31802
+ capScope: "system",
31803
+ addonId: null,
31804
+ access: "view"
31805
+ },
31736
31806
  "recording.refreshStorageLocationsForMigration": {
31737
31807
  capName: "recording",
31738
31808
  capScope: "system",
@@ -34563,6 +34633,11 @@ Object.freeze({
34563
34633
  form: "single",
34564
34634
  optional: false
34565
34635
  }],
34636
+ "recording.readWindowBytes": [{
34637
+ name: "deviceId",
34638
+ form: "single",
34639
+ optional: false
34640
+ }],
34566
34641
  "recording.relocateFootage": [{
34567
34642
  name: "deviceId",
34568
34643
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-export-hap",
3
- "version": "1.2.41",
3
+ "version": "1.2.42",
4
4
  "description": "HomeKit (HAP) exporter for CamStack devices. Publishes each exposed device as its own HomeKit accessory: cameras and doorbells with SRTP streaming, HomeKit Secure Video, motion, two-way audio, PTZ and battery; switches, lights, locks and sensors through a capability→service table.",
5
5
  "keywords": [
6
6
  "camstack",