@camstack/addon-provider-tuya 0.2.30 → 0.2.31

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
@@ -16619,7 +16619,23 @@ var NcHistoryEntrySchema = object({
16619
16619
  updatedAt: number(),
16620
16620
  /** Failure detail — present on a `dead` row. */
16621
16621
  error: string().optional(),
16622
- subject: NcHistorySubjectSchema
16622
+ subject: NcHistorySubjectSchema,
16623
+ /**
16624
+ * Ids of the artefacts (still, then gif, then clip) this row's successful
16625
+ * delivery indexed in the artefact library — a REFERENCE, never the bytes
16626
+ * (an artefact is often megabytes; this row is durable JSON rewritten on
16627
+ * every delivery attempt). Absent on a row still pending/dead, a row
16628
+ * delivered before this field shipped, or a wiring with no artefact index.
16629
+ *
16630
+ * Resolve one to a fetchable URL with `resolveArtifactUrl` — an id
16631
+ * outlives any one URL's TTL, so a caller mints a fresh link on demand
16632
+ * rather than trusting one frozen at delivery time. `resolveArtifactUrl`
16633
+ * also answers `null` for an id whose artefact has since expired past the
16634
+ * retained shelf's own age bound — the degrade a caller (the Home
16635
+ * Assistant export) must render as "no image right now", never as a
16636
+ * broken link.
16637
+ */
16638
+ artifactIds: array(string().min(1)).optional()
16623
16639
  });
16624
16640
  /**
16625
16641
  * Query filter for `getHistory` (spec §4.2). Every field is a narrowing
@@ -16846,7 +16862,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
16846
16862
  }), method(object({}), object({
16847
16863
  catalog: array(NcConditionDescriptorSchema),
16848
16864
  taxonomy: NcTaxonomySchema.optional()
16849
- })), 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 }), {
16865
+ })), 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 }), {
16850
16866
  kind: "mutation",
16851
16867
  caller: "required"
16852
16868
  }), method(object({ snoozeId: string() }), object({ success: literal(true) }), {
@@ -27874,6 +27890,39 @@ var ReadGopBytesResultSchema = object({
27874
27890
  /** Media ms the returned fragment covers. */
27875
27891
  gopDurMs: number()
27876
27892
  });
27893
+ /**
27894
+ * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
27895
+ * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
27896
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
27897
+ * a replay needs several seconds of native pixels, not one frame.
27898
+ *
27899
+ * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
27900
+ * is `false` when the returned bytes were cut short by the read's own safety
27901
+ * byte cap before covering `[fromMs, toMs)` — a truncation, reported, not a
27902
+ * silently shorter answer. `spans-multiple-segments` is a REFUSAL, not a
27903
+ * degradation: a window whose end falls past the covering segment would need
27904
+ * bytes stitched from a second segment file (its own `ftyp`+`moov`), which is
27905
+ * not one standalone-demuxable stream — the caller's answer is to request a
27906
+ * shorter window or one aligned to a single segment, not to receive spliced
27907
+ * bytes nothing has proven decodable.
27908
+ */
27909
+ var ReadWindowBytesResultSchema = discriminatedUnion("kind", [object({
27910
+ kind: literal("ok"),
27911
+ data: _instanceof(Uint8Array),
27912
+ /** Absolute epoch ms of the returned bytes' first sample — at or before
27913
+ * the requested `fromMs` (anchored on the nearest keyframe). */
27914
+ gopStartMs: number(),
27915
+ /** Media ms the returned bytes cover, from `gopStartMs`. */
27916
+ gopDurMs: number(),
27917
+ /** `false` ⇒ the safety byte cap cut the read short before it reached
27918
+ * the requested `toMs`; the caller got fewer frames than asked for. */
27919
+ reachesRequestedEnd: boolean()
27920
+ }), object({
27921
+ kind: literal("spans-multiple-segments"),
27922
+ /** Where the covering segment's own footage runs out — informational,
27923
+ * not a retry hint (retrying the same window would refuse again). */
27924
+ segmentEndMs: number()
27925
+ })]);
27877
27926
  method(object({
27878
27927
  deviceId: number(),
27879
27928
  fromMs: number(),
@@ -27924,6 +27973,15 @@ method(object({
27924
27973
  }), ReadGopBytesResultSchema, {
27925
27974
  kind: "query",
27926
27975
  auth: "admin"
27976
+ }), method(object({
27977
+ deviceId: number(),
27978
+ profile: string(),
27979
+ startMs: number(),
27980
+ fromMs: number(),
27981
+ toMs: number()
27982
+ }), ReadWindowBytesResultSchema, {
27983
+ kind: "query",
27984
+ auth: "admin"
27927
27985
  }), method(object({
27928
27986
  deviceId: number(),
27929
27987
  config: RecordingConfigSchema
@@ -34011,6 +34069,12 @@ Object.freeze({
34011
34069
  addonId: null,
34012
34070
  access: "view"
34013
34071
  },
34072
+ "notificationRules.resolveArtifactUrl": {
34073
+ capName: "notification-rules",
34074
+ capScope: "system",
34075
+ addonId: null,
34076
+ access: "view"
34077
+ },
34014
34078
  "notificationRules.setAlarmConfig": {
34015
34079
  capName: "notification-rules",
34016
34080
  capScope: "system",
@@ -35415,6 +35479,12 @@ Object.freeze({
35415
35479
  addonId: null,
35416
35480
  access: "view"
35417
35481
  },
35482
+ "recording.readWindowBytes": {
35483
+ capName: "recording",
35484
+ capScope: "system",
35485
+ addonId: null,
35486
+ access: "view"
35487
+ },
35418
35488
  "recording.refreshStorageLocationsForMigration": {
35419
35489
  capName: "recording",
35420
35490
  capScope: "system",
@@ -38245,6 +38315,11 @@ Object.freeze({
38245
38315
  form: "single",
38246
38316
  optional: false
38247
38317
  }],
38318
+ "recording.readWindowBytes": [{
38319
+ name: "deviceId",
38320
+ form: "single",
38321
+ optional: false
38322
+ }],
38248
38323
  "recording.relocateFootage": [{
38249
38324
  name: "deviceId",
38250
38325
  form: "single",
package/dist/addon.mjs CHANGED
@@ -16618,7 +16618,23 @@ var NcHistoryEntrySchema = object({
16618
16618
  updatedAt: number(),
16619
16619
  /** Failure detail — present on a `dead` row. */
16620
16620
  error: string().optional(),
16621
- subject: NcHistorySubjectSchema
16621
+ subject: NcHistorySubjectSchema,
16622
+ /**
16623
+ * Ids of the artefacts (still, then gif, then clip) this row's successful
16624
+ * delivery indexed in the artefact library — a REFERENCE, never the bytes
16625
+ * (an artefact is often megabytes; this row is durable JSON rewritten on
16626
+ * every delivery attempt). Absent on a row still pending/dead, a row
16627
+ * delivered before this field shipped, or a wiring with no artefact index.
16628
+ *
16629
+ * Resolve one to a fetchable URL with `resolveArtifactUrl` — an id
16630
+ * outlives any one URL's TTL, so a caller mints a fresh link on demand
16631
+ * rather than trusting one frozen at delivery time. `resolveArtifactUrl`
16632
+ * also answers `null` for an id whose artefact has since expired past the
16633
+ * retained shelf's own age bound — the degrade a caller (the Home
16634
+ * Assistant export) must render as "no image right now", never as a
16635
+ * broken link.
16636
+ */
16637
+ artifactIds: array(string().min(1)).optional()
16622
16638
  });
16623
16639
  /**
16624
16640
  * Query filter for `getHistory` (spec §4.2). Every field is a narrowing
@@ -16845,7 +16861,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
16845
16861
  }), method(object({}), object({
16846
16862
  catalog: array(NcConditionDescriptorSchema),
16847
16863
  taxonomy: NcTaxonomySchema.optional()
16848
- })), 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 }), {
16864
+ })), 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 }), {
16849
16865
  kind: "mutation",
16850
16866
  caller: "required"
16851
16867
  }), method(object({ snoozeId: string() }), object({ success: literal(true) }), {
@@ -27873,6 +27889,39 @@ var ReadGopBytesResultSchema = object({
27873
27889
  /** Media ms the returned fragment covers. */
27874
27890
  gopDurMs: number()
27875
27891
  });
27892
+ /**
27893
+ * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
27894
+ * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
27895
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
27896
+ * a replay needs several seconds of native pixels, not one frame.
27897
+ *
27898
+ * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
27899
+ * is `false` when the returned bytes were cut short by the read's own safety
27900
+ * byte cap before covering `[fromMs, toMs)` — a truncation, reported, not a
27901
+ * silently shorter answer. `spans-multiple-segments` is a REFUSAL, not a
27902
+ * degradation: a window whose end falls past the covering segment would need
27903
+ * bytes stitched from a second segment file (its own `ftyp`+`moov`), which is
27904
+ * not one standalone-demuxable stream — the caller's answer is to request a
27905
+ * shorter window or one aligned to a single segment, not to receive spliced
27906
+ * bytes nothing has proven decodable.
27907
+ */
27908
+ var ReadWindowBytesResultSchema = discriminatedUnion("kind", [object({
27909
+ kind: literal("ok"),
27910
+ data: _instanceof(Uint8Array),
27911
+ /** Absolute epoch ms of the returned bytes' first sample — at or before
27912
+ * the requested `fromMs` (anchored on the nearest keyframe). */
27913
+ gopStartMs: number(),
27914
+ /** Media ms the returned bytes cover, from `gopStartMs`. */
27915
+ gopDurMs: number(),
27916
+ /** `false` ⇒ the safety byte cap cut the read short before it reached
27917
+ * the requested `toMs`; the caller got fewer frames than asked for. */
27918
+ reachesRequestedEnd: boolean()
27919
+ }), object({
27920
+ kind: literal("spans-multiple-segments"),
27921
+ /** Where the covering segment's own footage runs out — informational,
27922
+ * not a retry hint (retrying the same window would refuse again). */
27923
+ segmentEndMs: number()
27924
+ })]);
27876
27925
  method(object({
27877
27926
  deviceId: number(),
27878
27927
  fromMs: number(),
@@ -27923,6 +27972,15 @@ method(object({
27923
27972
  }), ReadGopBytesResultSchema, {
27924
27973
  kind: "query",
27925
27974
  auth: "admin"
27975
+ }), method(object({
27976
+ deviceId: number(),
27977
+ profile: string(),
27978
+ startMs: number(),
27979
+ fromMs: number(),
27980
+ toMs: number()
27981
+ }), ReadWindowBytesResultSchema, {
27982
+ kind: "query",
27983
+ auth: "admin"
27926
27984
  }), method(object({
27927
27985
  deviceId: number(),
27928
27986
  config: RecordingConfigSchema
@@ -34010,6 +34068,12 @@ Object.freeze({
34010
34068
  addonId: null,
34011
34069
  access: "view"
34012
34070
  },
34071
+ "notificationRules.resolveArtifactUrl": {
34072
+ capName: "notification-rules",
34073
+ capScope: "system",
34074
+ addonId: null,
34075
+ access: "view"
34076
+ },
34013
34077
  "notificationRules.setAlarmConfig": {
34014
34078
  capName: "notification-rules",
34015
34079
  capScope: "system",
@@ -35414,6 +35478,12 @@ Object.freeze({
35414
35478
  addonId: null,
35415
35479
  access: "view"
35416
35480
  },
35481
+ "recording.readWindowBytes": {
35482
+ capName: "recording",
35483
+ capScope: "system",
35484
+ addonId: null,
35485
+ access: "view"
35486
+ },
35417
35487
  "recording.refreshStorageLocationsForMigration": {
35418
35488
  capName: "recording",
35419
35489
  capScope: "system",
@@ -38244,6 +38314,11 @@ Object.freeze({
38244
38314
  form: "single",
38245
38315
  optional: false
38246
38316
  }],
38317
+ "recording.readWindowBytes": [{
38318
+ name: "deviceId",
38319
+ form: "single",
38320
+ optional: false
38321
+ }],
38247
38322
  "recording.relocateFootage": [{
38248
38323
  name: "deviceId",
38249
38324
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-tuya",
3
- "version": "0.2.30",
3
+ "version": "0.2.31",
4
4
  "description": "Tuya / Smart Life device-provider addon for CamStack — account-onboarded (Tuya IoT cloud fetch of device localKeys) + LOCAL DP control via the @apocaliss92/nodetuya encrypted-LAN client, exposing switch / water-heater-family kettle entities",
5
5
  "keywords": [
6
6
  "camstack",