@camstack/addon-notifiers 1.2.34 → 1.2.35

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
@@ -15668,7 +15668,23 @@ var NcHistoryEntrySchema = object({
15668
15668
  updatedAt: number(),
15669
15669
  /** Failure detail — present on a `dead` row. */
15670
15670
  error: string().optional(),
15671
- subject: NcHistorySubjectSchema
15671
+ subject: NcHistorySubjectSchema,
15672
+ /**
15673
+ * Ids of the artefacts (still, then gif, then clip) this row's successful
15674
+ * delivery indexed in the artefact library — a REFERENCE, never the bytes
15675
+ * (an artefact is often megabytes; this row is durable JSON rewritten on
15676
+ * every delivery attempt). Absent on a row still pending/dead, a row
15677
+ * delivered before this field shipped, or a wiring with no artefact index.
15678
+ *
15679
+ * Resolve one to a fetchable URL with `resolveArtifactUrl` — an id
15680
+ * outlives any one URL's TTL, so a caller mints a fresh link on demand
15681
+ * rather than trusting one frozen at delivery time. `resolveArtifactUrl`
15682
+ * also answers `null` for an id whose artefact has since expired past the
15683
+ * retained shelf's own age bound — the degrade a caller (the Home
15684
+ * Assistant export) must render as "no image right now", never as a
15685
+ * broken link.
15686
+ */
15687
+ artifactIds: array(string().min(1)).optional()
15672
15688
  });
15673
15689
  /**
15674
15690
  * Query filter for `getHistory` (spec §4.2). Every field is a narrowing
@@ -15895,7 +15911,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
15895
15911
  }), method(object({}), object({
15896
15912
  catalog: array(NcConditionDescriptorSchema),
15897
15913
  taxonomy: NcTaxonomySchema.optional()
15898
- })), 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 }), {
15914
+ })), 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 }), {
15899
15915
  kind: "mutation",
15900
15916
  caller: "required"
15901
15917
  }), method(object({ snoozeId: string() }), object({ success: literal(true) }), {
@@ -25187,6 +25203,39 @@ var ReadGopBytesResultSchema = object({
25187
25203
  /** Media ms the returned fragment covers. */
25188
25204
  gopDurMs: number()
25189
25205
  });
25206
+ /**
25207
+ * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
25208
+ * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
25209
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
25210
+ * a replay needs several seconds of native pixels, not one frame.
25211
+ *
25212
+ * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
25213
+ * is `false` when the returned bytes were cut short by the read's own safety
25214
+ * byte cap before covering `[fromMs, toMs)` — a truncation, reported, not a
25215
+ * silently shorter answer. `spans-multiple-segments` is a REFUSAL, not a
25216
+ * degradation: a window whose end falls past the covering segment would need
25217
+ * bytes stitched from a second segment file (its own `ftyp`+`moov`), which is
25218
+ * not one standalone-demuxable stream — the caller's answer is to request a
25219
+ * shorter window or one aligned to a single segment, not to receive spliced
25220
+ * bytes nothing has proven decodable.
25221
+ */
25222
+ var ReadWindowBytesResultSchema = discriminatedUnion("kind", [object({
25223
+ kind: literal("ok"),
25224
+ data: _instanceof(Uint8Array),
25225
+ /** Absolute epoch ms of the returned bytes' first sample — at or before
25226
+ * the requested `fromMs` (anchored on the nearest keyframe). */
25227
+ gopStartMs: number(),
25228
+ /** Media ms the returned bytes cover, from `gopStartMs`. */
25229
+ gopDurMs: number(),
25230
+ /** `false` ⇒ the safety byte cap cut the read short before it reached
25231
+ * the requested `toMs`; the caller got fewer frames than asked for. */
25232
+ reachesRequestedEnd: boolean()
25233
+ }), object({
25234
+ kind: literal("spans-multiple-segments"),
25235
+ /** Where the covering segment's own footage runs out — informational,
25236
+ * not a retry hint (retrying the same window would refuse again). */
25237
+ segmentEndMs: number()
25238
+ })]);
25190
25239
  method(object({
25191
25240
  deviceId: number(),
25192
25241
  fromMs: number(),
@@ -25237,6 +25286,15 @@ method(object({
25237
25286
  }), ReadGopBytesResultSchema, {
25238
25287
  kind: "query",
25239
25288
  auth: "admin"
25289
+ }), method(object({
25290
+ deviceId: number(),
25291
+ profile: string(),
25292
+ startMs: number(),
25293
+ fromMs: number(),
25294
+ toMs: number()
25295
+ }), ReadWindowBytesResultSchema, {
25296
+ kind: "query",
25297
+ auth: "admin"
25240
25298
  }), method(object({
25241
25299
  deviceId: number(),
25242
25300
  config: RecordingConfigSchema
@@ -29655,6 +29713,12 @@ Object.freeze({
29655
29713
  addonId: null,
29656
29714
  access: "view"
29657
29715
  },
29716
+ "notificationRules.resolveArtifactUrl": {
29717
+ capName: "notification-rules",
29718
+ capScope: "system",
29719
+ addonId: null,
29720
+ access: "view"
29721
+ },
29658
29722
  "notificationRules.setAlarmConfig": {
29659
29723
  capName: "notification-rules",
29660
29724
  capScope: "system",
@@ -31059,6 +31123,12 @@ Object.freeze({
31059
31123
  addonId: null,
31060
31124
  access: "view"
31061
31125
  },
31126
+ "recording.readWindowBytes": {
31127
+ capName: "recording",
31128
+ capScope: "system",
31129
+ addonId: null,
31130
+ access: "view"
31131
+ },
31062
31132
  "recording.refreshStorageLocationsForMigration": {
31063
31133
  capName: "recording",
31064
31134
  capScope: "system",
@@ -33889,6 +33959,11 @@ Object.freeze({
33889
33959
  form: "single",
33890
33960
  optional: false
33891
33961
  }],
33962
+ "recording.readWindowBytes": [{
33963
+ name: "deviceId",
33964
+ form: "single",
33965
+ optional: false
33966
+ }],
33892
33967
  "recording.relocateFootage": [{
33893
33968
  name: "deviceId",
33894
33969
  form: "single",
package/dist/addon.mjs CHANGED
@@ -15641,7 +15641,23 @@ var NcHistoryEntrySchema = object({
15641
15641
  updatedAt: number(),
15642
15642
  /** Failure detail — present on a `dead` row. */
15643
15643
  error: string().optional(),
15644
- subject: NcHistorySubjectSchema
15644
+ subject: NcHistorySubjectSchema,
15645
+ /**
15646
+ * Ids of the artefacts (still, then gif, then clip) this row's successful
15647
+ * delivery indexed in the artefact library — a REFERENCE, never the bytes
15648
+ * (an artefact is often megabytes; this row is durable JSON rewritten on
15649
+ * every delivery attempt). Absent on a row still pending/dead, a row
15650
+ * delivered before this field shipped, or a wiring with no artefact index.
15651
+ *
15652
+ * Resolve one to a fetchable URL with `resolveArtifactUrl` — an id
15653
+ * outlives any one URL's TTL, so a caller mints a fresh link on demand
15654
+ * rather than trusting one frozen at delivery time. `resolveArtifactUrl`
15655
+ * also answers `null` for an id whose artefact has since expired past the
15656
+ * retained shelf's own age bound — the degrade a caller (the Home
15657
+ * Assistant export) must render as "no image right now", never as a
15658
+ * broken link.
15659
+ */
15660
+ artifactIds: array(string().min(1)).optional()
15645
15661
  });
15646
15662
  /**
15647
15663
  * Query filter for `getHistory` (spec §4.2). Every field is a narrowing
@@ -15868,7 +15884,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
15868
15884
  }), method(object({}), object({
15869
15885
  catalog: array(NcConditionDescriptorSchema),
15870
15886
  taxonomy: NcTaxonomySchema.optional()
15871
- })), 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 }), {
15887
+ })), 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 }), {
15872
15888
  kind: "mutation",
15873
15889
  caller: "required"
15874
15890
  }), method(object({ snoozeId: string() }), object({ success: literal(true) }), {
@@ -25160,6 +25176,39 @@ var ReadGopBytesResultSchema = object({
25160
25176
  /** Media ms the returned fragment covers. */
25161
25177
  gopDurMs: number()
25162
25178
  });
25179
+ /**
25180
+ * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
25181
+ * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
25182
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
25183
+ * a replay needs several seconds of native pixels, not one frame.
25184
+ *
25185
+ * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
25186
+ * is `false` when the returned bytes were cut short by the read's own safety
25187
+ * byte cap before covering `[fromMs, toMs)` — a truncation, reported, not a
25188
+ * silently shorter answer. `spans-multiple-segments` is a REFUSAL, not a
25189
+ * degradation: a window whose end falls past the covering segment would need
25190
+ * bytes stitched from a second segment file (its own `ftyp`+`moov`), which is
25191
+ * not one standalone-demuxable stream — the caller's answer is to request a
25192
+ * shorter window or one aligned to a single segment, not to receive spliced
25193
+ * bytes nothing has proven decodable.
25194
+ */
25195
+ var ReadWindowBytesResultSchema = discriminatedUnion("kind", [object({
25196
+ kind: literal("ok"),
25197
+ data: _instanceof(Uint8Array),
25198
+ /** Absolute epoch ms of the returned bytes' first sample — at or before
25199
+ * the requested `fromMs` (anchored on the nearest keyframe). */
25200
+ gopStartMs: number(),
25201
+ /** Media ms the returned bytes cover, from `gopStartMs`. */
25202
+ gopDurMs: number(),
25203
+ /** `false` ⇒ the safety byte cap cut the read short before it reached
25204
+ * the requested `toMs`; the caller got fewer frames than asked for. */
25205
+ reachesRequestedEnd: boolean()
25206
+ }), object({
25207
+ kind: literal("spans-multiple-segments"),
25208
+ /** Where the covering segment's own footage runs out — informational,
25209
+ * not a retry hint (retrying the same window would refuse again). */
25210
+ segmentEndMs: number()
25211
+ })]);
25163
25212
  method(object({
25164
25213
  deviceId: number(),
25165
25214
  fromMs: number(),
@@ -25210,6 +25259,15 @@ method(object({
25210
25259
  }), ReadGopBytesResultSchema, {
25211
25260
  kind: "query",
25212
25261
  auth: "admin"
25262
+ }), method(object({
25263
+ deviceId: number(),
25264
+ profile: string(),
25265
+ startMs: number(),
25266
+ fromMs: number(),
25267
+ toMs: number()
25268
+ }), ReadWindowBytesResultSchema, {
25269
+ kind: "query",
25270
+ auth: "admin"
25213
25271
  }), method(object({
25214
25272
  deviceId: number(),
25215
25273
  config: RecordingConfigSchema
@@ -29628,6 +29686,12 @@ Object.freeze({
29628
29686
  addonId: null,
29629
29687
  access: "view"
29630
29688
  },
29689
+ "notificationRules.resolveArtifactUrl": {
29690
+ capName: "notification-rules",
29691
+ capScope: "system",
29692
+ addonId: null,
29693
+ access: "view"
29694
+ },
29631
29695
  "notificationRules.setAlarmConfig": {
29632
29696
  capName: "notification-rules",
29633
29697
  capScope: "system",
@@ -31032,6 +31096,12 @@ Object.freeze({
31032
31096
  addonId: null,
31033
31097
  access: "view"
31034
31098
  },
31099
+ "recording.readWindowBytes": {
31100
+ capName: "recording",
31101
+ capScope: "system",
31102
+ addonId: null,
31103
+ access: "view"
31104
+ },
31035
31105
  "recording.refreshStorageLocationsForMigration": {
31036
31106
  capName: "recording",
31037
31107
  capScope: "system",
@@ -33862,6 +33932,11 @@ Object.freeze({
33862
33932
  form: "single",
33863
33933
  optional: false
33864
33934
  }],
33935
+ "recording.readWindowBytes": [{
33936
+ name: "deviceId",
33937
+ form: "single",
33938
+ optional: false
33939
+ }],
33865
33940
  "recording.relocateFootage": [{
33866
33941
  name: "deviceId",
33867
33942
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-notifiers",
3
- "version": "1.2.34",
3
+ "version": "1.2.35",
4
4
  "description": "System notifiers addon for CamStack — a `notification-output` collection provider hosting per-kind notifier adapters (ntfy, pushover, gotify, telegram, discord, webhook, zentik).",
5
5
  "keywords": [
6
6
  "camstack",