@camstack/types 1.2.380 → 1.2.382

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 (51) hide show
  1. package/dist/addon.d.ts +2 -0
  2. package/dist/addon.js +88 -2
  3. package/dist/addon.mjs +79 -3
  4. package/dist/capabilities/alerts.cap.d.ts +25 -0
  5. package/dist/capabilities/battery.cap.d.ts +1 -1
  6. package/dist/capabilities/caller-stamp.d.ts +4 -3
  7. package/dist/capabilities/dishwasher.cap.d.ts +178 -0
  8. package/dist/capabilities/heating-valve.cap.d.ts +39 -0
  9. package/dist/capabilities/index.d.ts +5 -1
  10. package/dist/capabilities/storage-admin.cap.d.ts +22 -0
  11. package/dist/client.js +71 -32
  12. package/dist/client.mjs +71 -32
  13. package/dist/{composition-DOwQB_Ua.mjs → composition-CB6PMT9p.mjs} +1 -1
  14. package/dist/{composition-CUAOHZ38.js → composition-eoYYVfOp.js} +1 -1
  15. package/dist/device/base-device-provider.d.ts +4 -2
  16. package/dist/device/device-context.d.ts +2 -0
  17. package/dist/device/device-control-resolution.d.ts +1 -1
  18. package/dist/device/device-type.d.ts +5 -1
  19. package/dist/{err-msg--2RrYiLO.mjs → err-msg-BXKzRBwg.mjs} +4 -0
  20. package/dist/{err-msg-Bb-s4Xuj.js → err-msg-BhVbr0NX.js} +4 -0
  21. package/dist/ffmpeg/fmp4-fragment-child.d.ts +2 -2
  22. package/dist/ffmpeg/process.d.ts +21 -0
  23. package/dist/generated/addon-api.d.ts +329 -230
  24. package/dist/generated/addon-cap-facts.d.ts +1 -1
  25. package/dist/generated/cap-status-types.d.ts +5 -1
  26. package/dist/generated/capability-router-map.d.ts +8 -2
  27. package/dist/generated/device-local-state.d.ts +6 -0
  28. package/dist/generated/device-proxy.d.ts +6 -0
  29. package/dist/generated/device-scoped-caps.d.ts +1 -1
  30. package/dist/generated/history-catalog.d.ts +1 -1
  31. package/dist/generated/method-access-map.d.ts +1 -1
  32. package/dist/generated/method-device-selectors.d.ts +1 -1
  33. package/dist/generated/runtime-state-durability.d.ts +1 -1
  34. package/dist/helpers/addon-slice-handle.d.ts +4 -0
  35. package/dist/helpers/trpc-leaf.d.ts +17 -0
  36. package/dist/index.d.ts +3 -2
  37. package/dist/index.js +431 -68
  38. package/dist/index.mjs +413 -67
  39. package/dist/interfaces/addon-peer-bytes.d.ts +19 -2
  40. package/dist/interfaces/config-ui-secrets.d.ts +2 -0
  41. package/dist/interfaces/config-ui.d.ts +14 -0
  42. package/dist/node.d.ts +2 -2
  43. package/dist/node.js +6 -2
  44. package/dist/node.mjs +6 -3
  45. package/dist/records/in-memory-records.d.ts +21 -0
  46. package/dist/records/index.d.ts +3 -0
  47. package/dist/records/settings-array-adopts-from.d.ts +12 -0
  48. package/dist/records/settings-brokers-adopts-from.d.ts +10 -0
  49. package/dist/{sleep-CIGOw58l.js → sleep--L6qY125.js} +572 -47
  50. package/dist/{sleep-WsrozGDL.mjs → sleep-BOjuyoPC.mjs} +489 -48
  51. package/package.json +1 -1
@@ -174,6 +174,7 @@ export { type DayNightMode, DayNightModeSchema, type DayNightOptions, DayNightOp
174
174
  export { type DeviceDiscoveryStatus, DeviceDiscoveryStatusSchema, type DiscoveredChildDevice, DiscoveredChildDeviceSchema, type DiscoveredChildStatus, DiscoveredChildStatusSchema, deviceDiscoveryCapability, type IDeviceDiscoveryNativeProvider, type IDeviceDiscoveryProvider, } from './device-discovery.cap.js';
175
175
  export { deviceOpsCapability, type IDeviceOpsProvider, type RawStateResult, RawStateResultSchema, } from './device-ops.cap.js';
176
176
  export { type DeviceStatus, DeviceStatusSchema, deviceStatusCapability, type IDeviceStatusProvider, } from './device-status.cap.js';
177
+ export { type DishwasherConsumableLevel, DishwasherConsumableLevelSchema, type DishwasherState, DishwasherStateSchema, type DishwasherStatus, DishwasherStatusSchema, dishwasherCapability, type IDishwasherProvider, } from './dishwasher.cap.js';
177
178
  export { type DoorbellPressEvent, DoorbellPressEventSchema, type DoorbellStatus, DoorbellStatusSchema, doorbellCapability, type IDoorbellProvider, } from './doorbell.cap.js';
178
179
  export { type EnumSensorDateTimeFormat, EnumSensorDateTimeFormatSchema, type EnumSensorStatus, EnumSensorStatusSchema, enumSensorCapability, type IEnumSensorProvider, } from './enum-sensor.cap.js';
179
180
  export { type EventEmitterStatus, EventEmitterStatusSchema, type EventFire, EventFireSchema, eventEmitterCapability, type IEventEmitterProvider, } from './event-emitter.cap.js';
@@ -182,6 +183,7 @@ export { type FanControlStatus, FanControlStatusSchema, type FanDirection, FanDi
182
183
  export { type FeatureProbeStatus, FeatureProbeStatusSchema, featureProbeCapability, type IFeatureProbeProvider, } from './feature-probe.cap.js';
183
184
  export { type FloodStatus, FloodStatusSchema, floodCapability, type IFloodProvider, } from './flood.cap.js';
184
185
  export { type GasStatus, GasStatusSchema, gasCapability, type IGasProvider } from './gas.cap.js';
186
+ export { type HeatingValveStatus, HeatingValveStatusSchema, heatingValveCapability, type IHeatingValveProvider, } from './heating-valve.cap.js';
185
187
  export { type HumidifierStatus, HumidifierStatusSchema, humidifierCapability, type IHumidifierProvider, } from './humidifier.cap.js';
186
188
  export { type HumiditySensorStatus, HumiditySensorStatusSchema, humiditySensorCapability, type IHumiditySensorProvider, } from './humidity-sensor.cap.js';
187
189
  export { type IImageProvider, type ImageStatus, ImageStatusSchema, imageCapability, } from './image.cap.js';
@@ -317,6 +319,7 @@ import type { deviceProviderCapability } from './device-provider.cap.js';
317
319
  import type { deviceStateCapability } from './device-state.cap.js';
318
320
  import type { deviceStatusCapability } from './device-status.cap.js';
319
321
  import type { deviceRemovalHookCapability } from './device-removal-hook.cap.js';
322
+ import type { dishwasherCapability } from './dishwasher.cap.js';
320
323
  import type { doorbellCapability } from './doorbell.cap.js';
321
324
  import type { embeddingEncoderCapability } from './embedding-encoder.cap.js';
322
325
  import type { enumSensorCapability } from './enum-sensor.cap.js';
@@ -328,6 +331,7 @@ import type { featureProbeCapability } from './feature-probe.cap.js';
328
331
  import type { filesystemBrowseCapability } from './filesystem-browse.cap.js';
329
332
  import type { floodCapability } from './flood.cap.js';
330
333
  import type { gasCapability } from './gas.cap.js';
334
+ import type { heatingValveCapability } from './heating-valve.cap.js';
331
335
  import type { humidifierCapability } from './humidifier.cap.js';
332
336
  import type { humiditySensorCapability } from './humidity-sensor.cap.js';
333
337
  import type { imageCapability } from './image.cap.js';
@@ -427,6 +431,6 @@ import type { trainingProviderCapability } from './training-provider.cap.js';
427
431
  import type { zoneAnalyticsCapability } from './zone-analytics.cap.js';
428
432
  import type { zoneRulesCapability } from './zone-rules.cap.js';
429
433
  import type { zonesCapability } from './zones.cap.js';
430
- type AnyCapability = typeof streamSignalsCapability | typeof addonSettingsCapability | typeof alertsCapability | typeof storageCapability | typeof storageMigrationCapability | typeof storageProviderCapability | typeof storageEvictableCapability | typeof storageOccupancyCapability | typeof filesystemBrowseCapability | typeof backupCapability | typeof terminalSessionCapability | typeof settingsStoreCapability | typeof dataStoreProviderCapability | typeof databaseSnapshotCapability | typeof storageAdminCapability | typeof recordsCapability | typeof recordEntriesCapability | typeof deviceHistoryCapability | typeof keychainCapability | typeof keychainAdminCapability | typeof deviceCredentialsCapability | typeof nodeCertificatesCapability | typeof logChannelsCapability | typeof logDestinationCapability | typeof loadContributionCapability | typeof failureContributionCapability | typeof deviceRemovalHookCapability | typeof adminUiCapability | typeof viewerUiCapability | typeof ssoBridgeCapability | typeof userPasskeysCapability | typeof smtpProviderCapability | typeof mqttBrokerCapability | typeof brokerCapability | typeof deviceAdoptionCapability | typeof deviceAdminLinkCapability | typeof deviceExportCapability | typeof addonPagesCapability | typeof addonPagesSourceCapability | typeof addonWidgetsCapability | typeof addonWidgetsSourceCapability | typeof customModelRegistryCapability | typeof modelDistributorCapability | typeof modelConvertCapability | typeof addonRoutesCapability | typeof streamBrokerCapability | typeof decoderCapability | typeof webrtcSessionCapability | typeof cameraStreamsCapability | typeof calendarSourceCapability | typeof calendarsCapability | typeof motionDetectionCapability | typeof pipelineExecutorCapability | typeof detectionPipelineCapability | typeof cameraPipelineConfigCapability | typeof pipelineRunnerCapability | typeof pipelineOrchestratorCapability | typeof audioAnalyzerCapability | typeof audioAnalysisCapability | typeof audioCodecCapability | typeof embeddingEncoderCapability | typeof vectorStoreCapability | typeof deviceProviderCapability | typeof deviceManagerCapability | typeof deviceStateCapability | typeof authProviderCapability | typeof loginMethodCapability | typeof networkAccessCapability | typeof turnProviderCapability | typeof snapshotCapability | typeof llmCapability | typeof llmRuntimeCapability | typeof notificationOutputCapability | typeof composerCapability | typeof coreBlocksCapability | typeof notificationRulesCapability | typeof pipelineAnalyticsCapability | typeof metricsProviderCapability | typeof ptzCapability | typeof ptzAutotrackCapability | typeof navigationCapability | typeof consumablesCapability | typeof connectionTestCapability | typeof rebootCapability | typeof deviceDiscoveryCapability | typeof brightnessCapability | typeof colorCapability | typeof climateControlCapability | typeof coverCapability | typeof valveCapability | typeof humidifierCapability | typeof waterHeaterCapability | typeof weatherCapability | typeof imageCapability | typeof lockControlCapability | typeof vacuumControlCapability | typeof petFeederCapability | typeof lawnMowerControlCapability | typeof fanControlCapability | typeof controlCapability | typeof notifierCapability | typeof mediaPlayerCapability | typeof alarmPanelCapability | typeof presenceCapability | typeof scriptRunnerCapability | typeof automationControlCapability | typeof motionTriggerCapability | typeof zonesCapability | typeof zoneRulesCapability | typeof trainingCapability | typeof trainingProviderCapability | typeof zoneAnalyticsCapability | typeof audioMetricsCapability | typeof motionCapability | typeof contactCapability | typeof floodCapability | typeof smokeCapability | typeof carbonMonoxideCapability | typeof gasCapability | typeof tamperCapability | typeof vibrationCapability | typeof connectivityCapability | typeof binaryCapability | typeof temperatureSensorCapability | typeof humiditySensorCapability | typeof ambientLightSensorCapability | typeof pressureSensorCapability | typeof powerMeterCapability | typeof airQualitySensorCapability | typeof numericSensorCapability | typeof enumSensorCapability | typeof recordingCapability | typeof recordingArchiveCapability | typeof recordingExportCapability | typeof recordingSignalCapability | typeof deviceOpsCapability | typeof platformProbeCapability | typeof localNetworkCapability | typeof meshNetworkCapability | typeof userManagementCapability | typeof systemCapability | typeof networkQualityCapability | typeof toastCapability | typeof nodesCapability | typeof serverManagementCapability | typeof integrationsCapability | typeof addonsCapability | typeof oauthIntegrationCapability | typeof oidcConnectionsCapability | typeof streamParamsCapability | typeof streamCatalogCapability | typeof motionZonesCapability | typeof cameraGridLayoutCapability | typeof sceneMonitorCapability | typeof privacyMaskCapability | typeof dayNightCapability | typeof recordingOnboardCapability | typeof imageSettingsCapability | typeof osdCapability | typeof osdManagerCapability | typeof accessoriesCapability | typeof batteryCapability | typeof networkLinkCapability | typeof buttonCapability | typeof cameraCredentialsCapability | typeof deviceStatusCapability | typeof doorbellCapability | typeof eventEmitterCapability | typeof faceGalleryCapability | typeof featureProbeCapability | typeof intercomCapability | typeof nativeObjectDetectionCapability | typeof plateGalleryCapability | typeof switchCapability | typeof updateCapability | typeof videoclipsCapability | typeof deviceExtensionCapability;
434
+ type AnyCapability = typeof streamSignalsCapability | typeof addonSettingsCapability | typeof alertsCapability | typeof storageCapability | typeof storageMigrationCapability | typeof storageProviderCapability | typeof storageEvictableCapability | typeof storageOccupancyCapability | typeof filesystemBrowseCapability | typeof backupCapability | typeof terminalSessionCapability | typeof settingsStoreCapability | typeof dataStoreProviderCapability | typeof databaseSnapshotCapability | typeof storageAdminCapability | typeof recordsCapability | typeof recordEntriesCapability | typeof deviceHistoryCapability | typeof keychainCapability | typeof keychainAdminCapability | typeof deviceCredentialsCapability | typeof nodeCertificatesCapability | typeof logChannelsCapability | typeof logDestinationCapability | typeof loadContributionCapability | typeof failureContributionCapability | typeof deviceRemovalHookCapability | typeof adminUiCapability | typeof viewerUiCapability | typeof ssoBridgeCapability | typeof userPasskeysCapability | typeof smtpProviderCapability | typeof mqttBrokerCapability | typeof brokerCapability | typeof deviceAdoptionCapability | typeof deviceAdminLinkCapability | typeof deviceExportCapability | typeof addonPagesCapability | typeof addonPagesSourceCapability | typeof addonWidgetsCapability | typeof addonWidgetsSourceCapability | typeof customModelRegistryCapability | typeof modelDistributorCapability | typeof modelConvertCapability | typeof addonRoutesCapability | typeof streamBrokerCapability | typeof decoderCapability | typeof webrtcSessionCapability | typeof cameraStreamsCapability | typeof calendarSourceCapability | typeof calendarsCapability | typeof motionDetectionCapability | typeof pipelineExecutorCapability | typeof detectionPipelineCapability | typeof cameraPipelineConfigCapability | typeof pipelineRunnerCapability | typeof pipelineOrchestratorCapability | typeof audioAnalyzerCapability | typeof audioAnalysisCapability | typeof audioCodecCapability | typeof embeddingEncoderCapability | typeof vectorStoreCapability | typeof deviceProviderCapability | typeof deviceManagerCapability | typeof deviceStateCapability | typeof authProviderCapability | typeof loginMethodCapability | typeof networkAccessCapability | typeof turnProviderCapability | typeof snapshotCapability | typeof llmCapability | typeof llmRuntimeCapability | typeof notificationOutputCapability | typeof composerCapability | typeof coreBlocksCapability | typeof notificationRulesCapability | typeof pipelineAnalyticsCapability | typeof metricsProviderCapability | typeof ptzCapability | typeof ptzAutotrackCapability | typeof navigationCapability | typeof consumablesCapability | typeof connectionTestCapability | typeof rebootCapability | typeof deviceDiscoveryCapability | typeof brightnessCapability | typeof colorCapability | typeof climateControlCapability | typeof coverCapability | typeof valveCapability | typeof humidifierCapability | typeof waterHeaterCapability | typeof weatherCapability | typeof imageCapability | typeof lockControlCapability | typeof vacuumControlCapability | typeof petFeederCapability | typeof lawnMowerControlCapability | typeof fanControlCapability | typeof controlCapability | typeof notifierCapability | typeof mediaPlayerCapability | typeof alarmPanelCapability | typeof presenceCapability | typeof scriptRunnerCapability | typeof automationControlCapability | typeof motionTriggerCapability | typeof zonesCapability | typeof zoneRulesCapability | typeof trainingCapability | typeof trainingProviderCapability | typeof zoneAnalyticsCapability | typeof audioMetricsCapability | typeof motionCapability | typeof contactCapability | typeof floodCapability | typeof smokeCapability | typeof carbonMonoxideCapability | typeof gasCapability | typeof tamperCapability | typeof vibrationCapability | typeof connectivityCapability | typeof binaryCapability | typeof temperatureSensorCapability | typeof heatingValveCapability | typeof humiditySensorCapability | typeof ambientLightSensorCapability | typeof pressureSensorCapability | typeof powerMeterCapability | typeof airQualitySensorCapability | typeof numericSensorCapability | typeof enumSensorCapability | typeof recordingCapability | typeof recordingArchiveCapability | typeof recordingExportCapability | typeof recordingSignalCapability | typeof deviceOpsCapability | typeof platformProbeCapability | typeof localNetworkCapability | typeof meshNetworkCapability | typeof userManagementCapability | typeof systemCapability | typeof networkQualityCapability | typeof toastCapability | typeof nodesCapability | typeof serverManagementCapability | typeof integrationsCapability | typeof addonsCapability | typeof oauthIntegrationCapability | typeof oidcConnectionsCapability | typeof streamParamsCapability | typeof streamCatalogCapability | typeof motionZonesCapability | typeof cameraGridLayoutCapability | typeof sceneMonitorCapability | typeof privacyMaskCapability | typeof dayNightCapability | typeof recordingOnboardCapability | typeof imageSettingsCapability | typeof osdCapability | typeof osdManagerCapability | typeof accessoriesCapability | typeof batteryCapability | typeof networkLinkCapability | typeof buttonCapability | typeof cameraCredentialsCapability | typeof deviceStatusCapability | typeof doorbellCapability | typeof eventEmitterCapability | typeof faceGalleryCapability | typeof featureProbeCapability | typeof intercomCapability | typeof nativeObjectDetectionCapability | typeof plateGalleryCapability | typeof switchCapability | typeof updateCapability | typeof videoclipsCapability | typeof deviceExtensionCapability | typeof dishwasherCapability;
431
435
  export type CapabilityName = AnyCapability['name'];
432
436
  export type ITypedReadinessRegistry = IReadinessRegistry<CapabilityName>;
@@ -317,6 +317,28 @@ export declare const storageAdminCapability: {
317
317
  }, z.core.$strip>, z.ZodObject<{
318
318
  adopted: z.ZodNumber;
319
319
  }, z.core.$strip>, "mutation">;
320
+ /**
321
+ * Read rows from a legacy KV table by physical name, without a running
322
+ * `declareCollection`. Used by `records-adopt.ts` when the owner already
323
+ * moved to records and the collection door refuses the name.
324
+ */
325
+ readonly readLegacyCollection: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
326
+ collection: z.ZodString;
327
+ cursor: z.ZodOptional<z.ZodString>;
328
+ limit: z.ZodOptional<z.ZodNumber>;
329
+ }, z.core.$strip>, z.ZodObject<{
330
+ rows: z.ZodArray<z.ZodObject<{
331
+ id: z.ZodString;
332
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
333
+ }, z.core.$strip>>;
334
+ nextCursor: z.ZodNullable<z.ZodString>;
335
+ }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
336
+ /** True when a declared kind lists `collection` as `adoptsFrom` and adoption finished. */
337
+ readonly isAdoptedLegacyTable: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
338
+ collection: z.ZodString;
339
+ }, z.core.$strip>, z.ZodObject<{
340
+ adopted: z.ZodBoolean;
341
+ }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
320
342
  };
321
343
  };
322
344
  export type IStorageAdminProvider = InferProvider<typeof storageAdminCapability>;
package/dist/client.js CHANGED
@@ -1003,6 +1003,10 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
1003
1003
  * native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
1004
1004
  * integrations sharing the same food/desiccant/hopper surface. */
1005
1005
  DeviceType["PetFeeder"] = "pet-feeder";
1006
+ /** Built-in dishwasher — program lifecycle, door / remote-start gates,
1007
+ * salt and rinse-aid levels. Installed with the `dishwasher` cap.
1008
+ * Sources: native Bosch Home Connect, reusable by similar integrations. */
1009
+ DeviceType["Dishwasher"] = "dishwasher";
1006
1010
  return DeviceType;
1007
1011
  }({});
1008
1012
  //#endregion
@@ -25895,6 +25899,50 @@ function isSource(x) {
25895
25899
  return typeof x.read === "function" && typeof x.watch === "function";
25896
25900
  }
25897
25901
  //#endregion
25902
+ //#region src/helpers/addon-slice-handle.ts
25903
+ /** Structural bridge: every `AddonApi` client carries `deviceState` (+ optional `live`). */
25904
+ function addonSliceHandleApi(api) {
25905
+ return api;
25906
+ }
25907
+ //#endregion
25908
+ //#region src/helpers/trpc-leaf.ts
25909
+ function isTrpcProcedureLeaf(value) {
25910
+ if (typeof value !== "object" || value === null) return false;
25911
+ const record = value;
25912
+ return (typeof record.query === "function" || typeof record.mutate === "function" || typeof record.subscribe === "function") && !Array.isArray(value);
25913
+ }
25914
+ function readCapRecord(api, capProp) {
25915
+ const cap = Reflect.get(api, capProp);
25916
+ if (typeof cap !== "object" || cap === null || Array.isArray(cap)) return void 0;
25917
+ return cap;
25918
+ }
25919
+ function readTrpcLeaf(api, capProp, method) {
25920
+ const capRecord = readCapRecord(api, capProp);
25921
+ if (!capRecord) throw new Error(`tRPC client has no router '${capProp}'`);
25922
+ const leaf = capRecord[method];
25923
+ if (!isTrpcProcedureLeaf(leaf)) throw new Error(`tRPC client has no '${capProp}.${method}'`);
25924
+ return leaf;
25925
+ }
25926
+ /**
25927
+ * Invoke `api.<capProp>.<method>.{query|mutate|subscribe}(input)`.
25928
+ * `Result` is the generated proxy method's return. The leaf itself is only
25929
+ * `unknown` (the client is a structural bag), so the assertion is the one
25930
+ * boundary between that bag and the typed proxy.
25931
+ */
25932
+ function invokeTrpcLeaf(api, capProp, method, kind, input, push) {
25933
+ const fn = readTrpcLeaf(api, capProp, method);
25934
+ if (kind === "mutation") {
25935
+ if (typeof fn.mutate !== "function") throw new Error(`tRPC '${capProp}.${method}' has no mutate()`);
25936
+ return fn.mutate(input);
25937
+ }
25938
+ if (kind === "subscription") {
25939
+ if (typeof fn.subscribe !== "function") throw new Error(`tRPC '${capProp}.${method}' has no subscribe()`);
25940
+ return fn.subscribe(input, push);
25941
+ }
25942
+ if (typeof fn.query !== "function") throw new Error(`tRPC '${capProp}.${method}' has no query()`);
25943
+ return fn.query(input);
25944
+ }
25945
+ //#endregion
25898
25946
  //#region src/generated/device-proxy.ts
25899
25947
  /**
25900
25948
  * Build a DeviceProxy that pre-binds deviceId + nodeId on every method call
@@ -25912,8 +25960,7 @@ function isSource(x) {
25912
25960
  * field on the returned object.
25913
25961
  */
25914
25962
  function createDeviceProxy(api, binding, opts) {
25915
- const typedApi = api;
25916
- const stateSource = opts?.stateSource ?? createLazyTrpcSource(api);
25963
+ const stateSource = opts?.stateSource ?? createLazyTrpcSource(addonSliceHandleApi(api));
25917
25964
  /** Merge `{deviceId, nodeId?}` into the caller-supplied input. */
25918
25965
  function mergeInput(input, nodeId) {
25919
25966
  const base = typeof input === "object" && input !== null ? input : {};
@@ -25926,20 +25973,8 @@ function createDeviceProxy(api, binding, opts) {
25926
25973
  deviceId: binding.deviceId
25927
25974
  };
25928
25975
  }
25929
- /**
25930
- * Invoke `api.<capProp>.<method>.{query|mutate|subscribe}(merged)`.
25931
- * Returns `any` so the caller-side per-method declaration assigns
25932
- * cleanly into the strongly-typed `InferDeviceProxyCap<...>` shape on
25933
- * the `DeviceProxy` interface — the proxy's contract is enforced by
25934
- * the interface, not the dispatch helper.
25935
- */
25936
25976
  function callLeaf(capProp, method, kind, merged, push) {
25937
- const leaf = typedApi[capProp]?.[method];
25938
- if (!leaf) throw new Error(`DeviceProxy: api has no '${capProp}.${method}'`);
25939
- const fn = leaf;
25940
- if (kind === "mutation") return fn.mutate(merged);
25941
- if (kind === "subscription") return fn.subscribe(merged, push);
25942
- return fn.query(merged);
25977
+ return invokeTrpcLeaf(api, capProp, method, kind, merged, push);
25943
25978
  }
25944
25979
  /**
25945
25980
  * Device-scoped cap dispatch. Looks up the binding entry for `capName`
@@ -26094,6 +26129,17 @@ function createDeviceProxy(api, binding, opts) {
26094
26129
  getRawState: (input) => dispatch("device-ops", "deviceOps", "getRawState", "query", input)
26095
26130
  };
26096
26131
  const deviceStatusInterface = { getStatus: (input) => dispatch("device-status", "deviceStatus", "getStatus", "query", input) };
26132
+ const dishwasherInterface = {
26133
+ start: (input) => dispatch("dishwasher", "dishwasher", "start", "mutation", input),
26134
+ pause: (input) => dispatch("dishwasher", "dishwasher", "pause", "mutation", input),
26135
+ stop: (input) => dispatch("dishwasher", "dishwasher", "stop", "mutation", input),
26136
+ setProgram: (input) => dispatch("dishwasher", "dishwasher", "setProgram", "mutation", input),
26137
+ setPower: (input) => dispatch("dishwasher", "dishwasher", "setPower", "mutation", input),
26138
+ setHalfLoad: (input) => dispatch("dishwasher", "dishwasher", "setHalfLoad", "mutation", input),
26139
+ setHygienePlus: (input) => dispatch("dishwasher", "dishwasher", "setHygienePlus", "mutation", input),
26140
+ setOption: (input) => dispatch("dishwasher", "dishwasher", "setOption", "mutation", input),
26141
+ getStatus: (input) => dispatch("dishwasher", "dishwasher", "getStatus", "query", input)
26142
+ };
26097
26143
  const doorbellInterface = { getStatus: (input) => dispatch("doorbell", "doorbell", "getStatus", "query", input) };
26098
26144
  const enumSensorInterface = { getStatus: (input) => dispatch("enum-sensor", "enumSensor", "getStatus", "query", input) };
26099
26145
  const eventEmitterInterface = { getStatus: (input) => dispatch("event-emitter", "eventEmitter", "getStatus", "query", input) };
@@ -26107,6 +26153,7 @@ function createDeviceProxy(api, binding, opts) {
26107
26153
  const featureProbeInterface = { getStatus: (input) => dispatch("feature-probe", "featureProbe", "getStatus", "query", input) };
26108
26154
  const floodInterface = { getStatus: (input) => dispatch("flood", "flood", "getStatus", "query", input) };
26109
26155
  const gasInterface = { getStatus: (input) => dispatch("gas", "gas", "getStatus", "query", input) };
26156
+ const heatingValveInterface = { getStatus: (input) => dispatch("heating-valve", "heatingValve", "getStatus", "query", input) };
26110
26157
  const humidifierInterface = {
26111
26158
  setOn: (input) => dispatch("humidifier", "humidifier", "setOn", "mutation", input),
26112
26159
  setTargetHumidity: (input) => dispatch("humidifier", "humidifier", "setTargetHumidity", "mutation", input),
@@ -26654,6 +26701,7 @@ function createDeviceProxy(api, binding, opts) {
26654
26701
  dayNight: createSliceHandle(stateSource, binding.deviceId, "day-night"),
26655
26702
  deviceDiscovery: createSliceHandle(stateSource, binding.deviceId, "device-discovery"),
26656
26703
  deviceStatus: createSliceHandle(stateSource, binding.deviceId, "device-status"),
26704
+ dishwasher: createSliceHandle(stateSource, binding.deviceId, "dishwasher"),
26657
26705
  doorbell: createSliceHandle(stateSource, binding.deviceId, "doorbell"),
26658
26706
  enumSensor: createSliceHandle(stateSource, binding.deviceId, "enum-sensor"),
26659
26707
  eventEmitter: createSliceHandle(stateSource, binding.deviceId, "event-emitter"),
@@ -26661,6 +26709,7 @@ function createDeviceProxy(api, binding, opts) {
26661
26709
  featureProbe: createSliceHandle(stateSource, binding.deviceId, "feature-probe"),
26662
26710
  flood: createSliceHandle(stateSource, binding.deviceId, "flood"),
26663
26711
  gas: createSliceHandle(stateSource, binding.deviceId, "gas"),
26712
+ heatingValve: createSliceHandle(stateSource, binding.deviceId, "heating-valve"),
26664
26713
  humidifier: createSliceHandle(stateSource, binding.deviceId, "humidifier"),
26665
26714
  humiditySensor: createSliceHandle(stateSource, binding.deviceId, "humidity-sensor"),
26666
26715
  image: createSliceHandle(stateSource, binding.deviceId, "image"),
@@ -26734,6 +26783,7 @@ function createDeviceProxy(api, binding, opts) {
26734
26783
  ...bound("device-extension") ? { deviceExtension: deviceExtensionInterface } : {},
26735
26784
  ...bound("device-ops") ? { deviceOps: deviceOpsInterface } : {},
26736
26785
  ...bound("device-status") ? { deviceStatus: deviceStatusInterface } : {},
26786
+ ...bound("dishwasher") ? { dishwasher: dishwasherInterface } : {},
26737
26787
  ...bound("doorbell") ? { doorbell: doorbellInterface } : {},
26738
26788
  ...bound("enum-sensor") ? { enumSensor: enumSensorInterface } : {},
26739
26789
  ...bound("event-emitter") ? { eventEmitter: eventEmitterInterface } : {},
@@ -26741,6 +26791,7 @@ function createDeviceProxy(api, binding, opts) {
26741
26791
  ...bound("feature-probe") ? { featureProbe: featureProbeInterface } : {},
26742
26792
  ...bound("flood") ? { flood: floodInterface } : {},
26743
26793
  ...bound("gas") ? { gas: gasInterface } : {},
26794
+ ...bound("heating-valve") ? { heatingValve: heatingValveInterface } : {},
26744
26795
  ...bound("humidifier") ? { humidifier: humidifierInterface } : {},
26745
26796
  ...bound("humidity-sensor") ? { humiditySensor: humiditySensorInterface } : {},
26746
26797
  ...bound("image") ? { image: imageInterface } : {},
@@ -27252,9 +27303,10 @@ var SystemMirror = class {
27252
27303
  for (let i = 0; i < targets.length; i += parallelism) {
27253
27304
  const chunk = targets.slice(i, i + parallelism);
27254
27305
  const settled = await Promise.allSettled(chunk.map(async (proxy) => {
27255
- const cap = proxy[capName];
27256
- if (!cap || typeof cap[methodName] !== "function") throw new Error(`device '${proxy.deviceId}' does not expose '${capName}.${methodName}'`);
27257
- return await cap[methodName](args);
27306
+ const cap = Reflect.get(proxy, capName);
27307
+ const method = typeof cap === "object" && cap !== null ? Reflect.get(cap, methodName) : void 0;
27308
+ if (typeof method !== "function") throw new Error(`device '${proxy.deviceId}' does not expose '${capName}.${methodName}'`);
27309
+ return await Reflect.apply(method, cap, [args]);
27258
27310
  }));
27259
27311
  for (let j = 0; j < settled.length; j++) {
27260
27312
  const proxy = chunk[j];
@@ -27489,21 +27541,8 @@ function matchesString(haystack, match) {
27489
27541
  * dropping the reference.
27490
27542
  */
27491
27543
  function createSystemProxy(api) {
27492
- const typedApi = api;
27493
- /**
27494
- * Invoke `api.<capProp>.<method>.{query|mutate|subscribe}(input)`.
27495
- * Returns `any` so the caller-side per-method declaration assigns
27496
- * cleanly into the strongly-typed `Pick<InferProvider<...>, ...>`
27497
- * shape on the `SystemProxy` interface — the proxy's contract is
27498
- * enforced by the interface, not the dispatch helper.
27499
- */
27500
27544
  function dispatch(capProp, method, kind, input, push) {
27501
- const leaf = typedApi[capProp]?.[method];
27502
- if (!leaf) throw new Error(`SystemProxy: api has no '${capProp}.${method}'`);
27503
- const fn = leaf;
27504
- if (kind === "mutation") return fn.mutate(input);
27505
- if (kind === "subscription") return fn.subscribe(input, push);
27506
- return fn.query(input);
27545
+ return invokeTrpcLeaf(api, capProp, method, kind, input, push);
27507
27546
  }
27508
27547
  return {
27509
27548
  addonPages: { listPages: (input) => dispatch("addonPages", "listPages", "query", input) },
package/dist/client.mjs CHANGED
@@ -1002,6 +1002,10 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
1002
1002
  * native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
1003
1003
  * integrations sharing the same food/desiccant/hopper surface. */
1004
1004
  DeviceType["PetFeeder"] = "pet-feeder";
1005
+ /** Built-in dishwasher — program lifecycle, door / remote-start gates,
1006
+ * salt and rinse-aid levels. Installed with the `dishwasher` cap.
1007
+ * Sources: native Bosch Home Connect, reusable by similar integrations. */
1008
+ DeviceType["Dishwasher"] = "dishwasher";
1005
1009
  return DeviceType;
1006
1010
  }({});
1007
1011
  //#endregion
@@ -25894,6 +25898,50 @@ function isSource(x) {
25894
25898
  return typeof x.read === "function" && typeof x.watch === "function";
25895
25899
  }
25896
25900
  //#endregion
25901
+ //#region src/helpers/addon-slice-handle.ts
25902
+ /** Structural bridge: every `AddonApi` client carries `deviceState` (+ optional `live`). */
25903
+ function addonSliceHandleApi(api) {
25904
+ return api;
25905
+ }
25906
+ //#endregion
25907
+ //#region src/helpers/trpc-leaf.ts
25908
+ function isTrpcProcedureLeaf(value) {
25909
+ if (typeof value !== "object" || value === null) return false;
25910
+ const record = value;
25911
+ return (typeof record.query === "function" || typeof record.mutate === "function" || typeof record.subscribe === "function") && !Array.isArray(value);
25912
+ }
25913
+ function readCapRecord(api, capProp) {
25914
+ const cap = Reflect.get(api, capProp);
25915
+ if (typeof cap !== "object" || cap === null || Array.isArray(cap)) return void 0;
25916
+ return cap;
25917
+ }
25918
+ function readTrpcLeaf(api, capProp, method) {
25919
+ const capRecord = readCapRecord(api, capProp);
25920
+ if (!capRecord) throw new Error(`tRPC client has no router '${capProp}'`);
25921
+ const leaf = capRecord[method];
25922
+ if (!isTrpcProcedureLeaf(leaf)) throw new Error(`tRPC client has no '${capProp}.${method}'`);
25923
+ return leaf;
25924
+ }
25925
+ /**
25926
+ * Invoke `api.<capProp>.<method>.{query|mutate|subscribe}(input)`.
25927
+ * `Result` is the generated proxy method's return. The leaf itself is only
25928
+ * `unknown` (the client is a structural bag), so the assertion is the one
25929
+ * boundary between that bag and the typed proxy.
25930
+ */
25931
+ function invokeTrpcLeaf(api, capProp, method, kind, input, push) {
25932
+ const fn = readTrpcLeaf(api, capProp, method);
25933
+ if (kind === "mutation") {
25934
+ if (typeof fn.mutate !== "function") throw new Error(`tRPC '${capProp}.${method}' has no mutate()`);
25935
+ return fn.mutate(input);
25936
+ }
25937
+ if (kind === "subscription") {
25938
+ if (typeof fn.subscribe !== "function") throw new Error(`tRPC '${capProp}.${method}' has no subscribe()`);
25939
+ return fn.subscribe(input, push);
25940
+ }
25941
+ if (typeof fn.query !== "function") throw new Error(`tRPC '${capProp}.${method}' has no query()`);
25942
+ return fn.query(input);
25943
+ }
25944
+ //#endregion
25897
25945
  //#region src/generated/device-proxy.ts
25898
25946
  /**
25899
25947
  * Build a DeviceProxy that pre-binds deviceId + nodeId on every method call
@@ -25911,8 +25959,7 @@ function isSource(x) {
25911
25959
  * field on the returned object.
25912
25960
  */
25913
25961
  function createDeviceProxy(api, binding, opts) {
25914
- const typedApi = api;
25915
- const stateSource = opts?.stateSource ?? createLazyTrpcSource(api);
25962
+ const stateSource = opts?.stateSource ?? createLazyTrpcSource(addonSliceHandleApi(api));
25916
25963
  /** Merge `{deviceId, nodeId?}` into the caller-supplied input. */
25917
25964
  function mergeInput(input, nodeId) {
25918
25965
  const base = typeof input === "object" && input !== null ? input : {};
@@ -25925,20 +25972,8 @@ function createDeviceProxy(api, binding, opts) {
25925
25972
  deviceId: binding.deviceId
25926
25973
  };
25927
25974
  }
25928
- /**
25929
- * Invoke `api.<capProp>.<method>.{query|mutate|subscribe}(merged)`.
25930
- * Returns `any` so the caller-side per-method declaration assigns
25931
- * cleanly into the strongly-typed `InferDeviceProxyCap<...>` shape on
25932
- * the `DeviceProxy` interface — the proxy's contract is enforced by
25933
- * the interface, not the dispatch helper.
25934
- */
25935
25975
  function callLeaf(capProp, method, kind, merged, push) {
25936
- const leaf = typedApi[capProp]?.[method];
25937
- if (!leaf) throw new Error(`DeviceProxy: api has no '${capProp}.${method}'`);
25938
- const fn = leaf;
25939
- if (kind === "mutation") return fn.mutate(merged);
25940
- if (kind === "subscription") return fn.subscribe(merged, push);
25941
- return fn.query(merged);
25976
+ return invokeTrpcLeaf(api, capProp, method, kind, merged, push);
25942
25977
  }
25943
25978
  /**
25944
25979
  * Device-scoped cap dispatch. Looks up the binding entry for `capName`
@@ -26093,6 +26128,17 @@ function createDeviceProxy(api, binding, opts) {
26093
26128
  getRawState: (input) => dispatch("device-ops", "deviceOps", "getRawState", "query", input)
26094
26129
  };
26095
26130
  const deviceStatusInterface = { getStatus: (input) => dispatch("device-status", "deviceStatus", "getStatus", "query", input) };
26131
+ const dishwasherInterface = {
26132
+ start: (input) => dispatch("dishwasher", "dishwasher", "start", "mutation", input),
26133
+ pause: (input) => dispatch("dishwasher", "dishwasher", "pause", "mutation", input),
26134
+ stop: (input) => dispatch("dishwasher", "dishwasher", "stop", "mutation", input),
26135
+ setProgram: (input) => dispatch("dishwasher", "dishwasher", "setProgram", "mutation", input),
26136
+ setPower: (input) => dispatch("dishwasher", "dishwasher", "setPower", "mutation", input),
26137
+ setHalfLoad: (input) => dispatch("dishwasher", "dishwasher", "setHalfLoad", "mutation", input),
26138
+ setHygienePlus: (input) => dispatch("dishwasher", "dishwasher", "setHygienePlus", "mutation", input),
26139
+ setOption: (input) => dispatch("dishwasher", "dishwasher", "setOption", "mutation", input),
26140
+ getStatus: (input) => dispatch("dishwasher", "dishwasher", "getStatus", "query", input)
26141
+ };
26096
26142
  const doorbellInterface = { getStatus: (input) => dispatch("doorbell", "doorbell", "getStatus", "query", input) };
26097
26143
  const enumSensorInterface = { getStatus: (input) => dispatch("enum-sensor", "enumSensor", "getStatus", "query", input) };
26098
26144
  const eventEmitterInterface = { getStatus: (input) => dispatch("event-emitter", "eventEmitter", "getStatus", "query", input) };
@@ -26106,6 +26152,7 @@ function createDeviceProxy(api, binding, opts) {
26106
26152
  const featureProbeInterface = { getStatus: (input) => dispatch("feature-probe", "featureProbe", "getStatus", "query", input) };
26107
26153
  const floodInterface = { getStatus: (input) => dispatch("flood", "flood", "getStatus", "query", input) };
26108
26154
  const gasInterface = { getStatus: (input) => dispatch("gas", "gas", "getStatus", "query", input) };
26155
+ const heatingValveInterface = { getStatus: (input) => dispatch("heating-valve", "heatingValve", "getStatus", "query", input) };
26109
26156
  const humidifierInterface = {
26110
26157
  setOn: (input) => dispatch("humidifier", "humidifier", "setOn", "mutation", input),
26111
26158
  setTargetHumidity: (input) => dispatch("humidifier", "humidifier", "setTargetHumidity", "mutation", input),
@@ -26653,6 +26700,7 @@ function createDeviceProxy(api, binding, opts) {
26653
26700
  dayNight: createSliceHandle(stateSource, binding.deviceId, "day-night"),
26654
26701
  deviceDiscovery: createSliceHandle(stateSource, binding.deviceId, "device-discovery"),
26655
26702
  deviceStatus: createSliceHandle(stateSource, binding.deviceId, "device-status"),
26703
+ dishwasher: createSliceHandle(stateSource, binding.deviceId, "dishwasher"),
26656
26704
  doorbell: createSliceHandle(stateSource, binding.deviceId, "doorbell"),
26657
26705
  enumSensor: createSliceHandle(stateSource, binding.deviceId, "enum-sensor"),
26658
26706
  eventEmitter: createSliceHandle(stateSource, binding.deviceId, "event-emitter"),
@@ -26660,6 +26708,7 @@ function createDeviceProxy(api, binding, opts) {
26660
26708
  featureProbe: createSliceHandle(stateSource, binding.deviceId, "feature-probe"),
26661
26709
  flood: createSliceHandle(stateSource, binding.deviceId, "flood"),
26662
26710
  gas: createSliceHandle(stateSource, binding.deviceId, "gas"),
26711
+ heatingValve: createSliceHandle(stateSource, binding.deviceId, "heating-valve"),
26663
26712
  humidifier: createSliceHandle(stateSource, binding.deviceId, "humidifier"),
26664
26713
  humiditySensor: createSliceHandle(stateSource, binding.deviceId, "humidity-sensor"),
26665
26714
  image: createSliceHandle(stateSource, binding.deviceId, "image"),
@@ -26733,6 +26782,7 @@ function createDeviceProxy(api, binding, opts) {
26733
26782
  ...bound("device-extension") ? { deviceExtension: deviceExtensionInterface } : {},
26734
26783
  ...bound("device-ops") ? { deviceOps: deviceOpsInterface } : {},
26735
26784
  ...bound("device-status") ? { deviceStatus: deviceStatusInterface } : {},
26785
+ ...bound("dishwasher") ? { dishwasher: dishwasherInterface } : {},
26736
26786
  ...bound("doorbell") ? { doorbell: doorbellInterface } : {},
26737
26787
  ...bound("enum-sensor") ? { enumSensor: enumSensorInterface } : {},
26738
26788
  ...bound("event-emitter") ? { eventEmitter: eventEmitterInterface } : {},
@@ -26740,6 +26790,7 @@ function createDeviceProxy(api, binding, opts) {
26740
26790
  ...bound("feature-probe") ? { featureProbe: featureProbeInterface } : {},
26741
26791
  ...bound("flood") ? { flood: floodInterface } : {},
26742
26792
  ...bound("gas") ? { gas: gasInterface } : {},
26793
+ ...bound("heating-valve") ? { heatingValve: heatingValveInterface } : {},
26743
26794
  ...bound("humidifier") ? { humidifier: humidifierInterface } : {},
26744
26795
  ...bound("humidity-sensor") ? { humiditySensor: humiditySensorInterface } : {},
26745
26796
  ...bound("image") ? { image: imageInterface } : {},
@@ -27251,9 +27302,10 @@ var SystemMirror = class {
27251
27302
  for (let i = 0; i < targets.length; i += parallelism) {
27252
27303
  const chunk = targets.slice(i, i + parallelism);
27253
27304
  const settled = await Promise.allSettled(chunk.map(async (proxy) => {
27254
- const cap = proxy[capName];
27255
- if (!cap || typeof cap[methodName] !== "function") throw new Error(`device '${proxy.deviceId}' does not expose '${capName}.${methodName}'`);
27256
- return await cap[methodName](args);
27305
+ const cap = Reflect.get(proxy, capName);
27306
+ const method = typeof cap === "object" && cap !== null ? Reflect.get(cap, methodName) : void 0;
27307
+ if (typeof method !== "function") throw new Error(`device '${proxy.deviceId}' does not expose '${capName}.${methodName}'`);
27308
+ return await Reflect.apply(method, cap, [args]);
27257
27309
  }));
27258
27310
  for (let j = 0; j < settled.length; j++) {
27259
27311
  const proxy = chunk[j];
@@ -27488,21 +27540,8 @@ function matchesString(haystack, match) {
27488
27540
  * dropping the reference.
27489
27541
  */
27490
27542
  function createSystemProxy(api) {
27491
- const typedApi = api;
27492
- /**
27493
- * Invoke `api.<capProp>.<method>.{query|mutate|subscribe}(input)`.
27494
- * Returns `any` so the caller-side per-method declaration assigns
27495
- * cleanly into the strongly-typed `Pick<InferProvider<...>, ...>`
27496
- * shape on the `SystemProxy` interface — the proxy's contract is
27497
- * enforced by the interface, not the dispatch helper.
27498
- */
27499
27543
  function dispatch(capProp, method, kind, input, push) {
27500
- const leaf = typedApi[capProp]?.[method];
27501
- if (!leaf) throw new Error(`SystemProxy: api has no '${capProp}.${method}'`);
27502
- const fn = leaf;
27503
- if (kind === "mutation") return fn.mutate(input);
27504
- if (kind === "subscription") return fn.subscribe(input, push);
27505
- return fn.query(input);
27544
+ return invokeTrpcLeaf(api, capProp, method, kind, input, push);
27506
27545
  }
27507
27546
  return {
27508
27547
  addonPages: { listPages: (input) => dispatch("addonPages", "listPages", "query", input) },
@@ -1,4 +1,4 @@
1
- import { a as DeviceType, i as DeviceRole } from "./err-msg--2RrYiLO.mjs";
1
+ import { a as DeviceType, i as DeviceRole } from "./err-msg-BXKzRBwg.mjs";
2
2
  import { z } from "zod";
3
3
  import { createHash } from "node:crypto";
4
4
  //#region src/ffmpeg/invocation.ts
@@ -1,4 +1,4 @@
1
- const require_err_msg = require("./err-msg-Bb-s4Xuj.js");
1
+ const require_err_msg = require("./err-msg-BhVbr0NX.js");
2
2
  let zod = require("zod");
3
3
  let node_crypto = require("node:crypto");
4
4
  //#region src/ffmpeg/invocation.ts
@@ -1,5 +1,5 @@
1
1
  import { BaseAddon } from '../addon/base-addon.js';
2
- import type { ProviderRegistration } from '../interfaces/addon.js';
2
+ import type { AddonInitResult, ProviderRegistration } from '../interfaces/addon.js';
3
3
  import type { ConfigUISchema } from '../interfaces/config-ui.js';
4
4
  import type { IDevice } from './device.js';
5
5
  import type { DeviceConstructor } from './device-context.js';
@@ -107,7 +107,9 @@ export declare abstract class BaseDeviceProvider<TConfig extends object = Record
107
107
  protected abstract readonly addonId: string;
108
108
  /** Human-readable provider name for log messages. */
109
109
  protected abstract readonly providerName: string;
110
- protected onInitialize(): Promise<ProviderRegistration[]>;
110
+ protected onInitialize(): Promise<ProviderRegistration[] | AddonInitResult | void>;
111
+ /** Flatten `super.onInitialize()` whether it returned an array or an envelope. */
112
+ protected providerRegistrationsFromSuper(result: ProviderRegistration[] | AddonInitResult | void): ProviderRegistration[];
111
113
  protected onShutdown(): Promise<void>;
112
114
  start(): Promise<void>;
113
115
  stop(): Promise<void>;
@@ -137,6 +137,8 @@ export interface DeviceContext {
137
137
  * + persistInitialConfig + createContext + register` flow.
138
138
  */
139
139
  export type DeviceConstructor<T extends IDevice = IDevice> = new (ctx: DeviceContext) => T;
140
+ /** Map entry helper — concrete camera/hub classes widen to `DeviceConstructor<IDevice>`. */
141
+ export declare function widenDeviceConstructor<T extends IDevice>(ctor: DeviceConstructor<T>): DeviceConstructor<IDevice>;
140
142
  export interface DeviceManagerApi {
141
143
  /**
142
144
  * Create, register, and persist a device in one call.
@@ -37,7 +37,7 @@ import { DeviceType } from './device-type.js';
37
37
  * kind can back several device types (`'switch'` ← Switch + Siren, `'sensor'`
38
38
  * ← Sensor + Presence, `'dummy'` ← every placeholder/non-controllable type).
39
39
  */
40
- export type DeviceControlKind = 'cover' | 'valve' | 'humidifier' | 'water-heater' | 'switch' | 'light' | 'fan' | 'sensor' | 'thermostat' | 'climate' | 'button' | 'update' | 'lock' | 'media-player' | 'alarm' | 'control' | 'weather' | 'vacuum' | 'lawn-mower' | 'image' | 'pet-feeder' | 'script' | 'automation' | 'dummy';
40
+ export type DeviceControlKind = 'cover' | 'valve' | 'humidifier' | 'water-heater' | 'switch' | 'light' | 'fan' | 'sensor' | 'thermostat' | 'climate' | 'button' | 'update' | 'lock' | 'media-player' | 'alarm' | 'control' | 'weather' | 'vacuum' | 'lawn-mower' | 'image' | 'pet-feeder' | 'dishwasher' | 'script' | 'automation' | 'dummy';
41
41
  /**
42
42
  * Exhaustive `DeviceType` → `DeviceControlKind` map. Omitting a new enum member
43
43
  * fails the build here (the single place the type→kind decision is encoded).
@@ -88,7 +88,11 @@ export declare enum DeviceType {
88
88
  * dual-hopper models (D4S/D4SH) expose per-hopper portions. Sources:
89
89
  * native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
90
90
  * integrations sharing the same food/desiccant/hopper surface. */
91
- PetFeeder = "pet-feeder"
91
+ PetFeeder = "pet-feeder",
92
+ /** Built-in dishwasher — program lifecycle, door / remote-start gates,
93
+ * salt and rinse-aid levels. Installed with the `dishwasher` cap.
94
+ * Sources: native Bosch Home Connect, reusable by similar integrations. */
95
+ Dishwasher = "dishwasher"
92
96
  }
93
97
  export declare enum DeviceFeature {
94
98
  BatteryOperated = "battery-operated",
@@ -90,6 +90,10 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
90
90
  * native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
91
91
  * integrations sharing the same food/desiccant/hopper surface. */
92
92
  DeviceType["PetFeeder"] = "pet-feeder";
93
+ /** Built-in dishwasher — program lifecycle, door / remote-start gates,
94
+ * salt and rinse-aid levels. Installed with the `dishwasher` cap.
95
+ * Sources: native Bosch Home Connect, reusable by similar integrations. */
96
+ DeviceType["Dishwasher"] = "dishwasher";
93
97
  return DeviceType;
94
98
  }({});
95
99
  var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
@@ -90,6 +90,10 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
90
90
  * native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
91
91
  * integrations sharing the same food/desiccant/hopper surface. */
92
92
  DeviceType["PetFeeder"] = "pet-feeder";
93
+ /** Built-in dishwasher — program lifecycle, door / remote-start gates,
94
+ * salt and rinse-aid levels. Installed with the `dishwasher` cap.
95
+ * Sources: native Bosch Home Connect, reusable by similar integrations. */
96
+ DeviceType["Dishwasher"] = "dishwasher";
93
97
  return DeviceType;
94
98
  }({});
95
99
  var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
@@ -35,14 +35,14 @@
35
35
  * request schema on purpose (see `egressTransportFromRequest`): a plane is a
36
36
  * live object, so an off-node caller could not use one anyway.
37
37
  */
38
- import type { spawn as nodeSpawn } from 'node:child_process';
39
38
  import type { IScopedLogger } from '../interfaces/logging.js';
40
39
  import type { FfmpegInvocation } from './invocation.js';
40
+ import type { FfmpegSpawnFn } from './process.js';
41
41
  import type { Fmp4FragmentPlane } from './fmp4-fragment-plane.js';
42
42
  export interface Fmp4FragmentChildDeps {
43
43
  readonly logger: IScopedLogger;
44
44
  readonly ffmpegBinaryPath: string;
45
- readonly spawnFn: typeof nodeSpawn;
45
+ readonly spawnFn: FfmpegSpawnFn;
46
46
  /** How long the child may produce no UNIT before it is declared dead. */
47
47
  readonly firstUnitTimeoutMs?: number;
48
48
  /** The child exited, or its output stopped parsing, AFTER it went live. */
@@ -32,6 +32,27 @@
32
32
  */
33
33
  import { spawn, type ChildProcess, type SpawnOptions } from 'node:child_process';
34
34
  import type { IScopedLogger } from '../interfaces/logging.js';
35
+ /** Subset of {@link ChildProcess} every live-media ffmpeg site reads. */
36
+ export interface SpawnedFfmpegProcess {
37
+ readonly pid?: number;
38
+ readonly killed?: boolean;
39
+ readonly exitCode?: number | null;
40
+ readonly signalCode?: NodeJS.Signals | null;
41
+ readonly stdin?: {
42
+ on(event: string, listener: () => void): void;
43
+ end(): void;
44
+ } | null;
45
+ readonly stdout: NodeJS.ReadableStream | null;
46
+ readonly stderr: NodeJS.ReadableStream | null;
47
+ on(event: 'exit', listener: (code: number | null, signal: NodeJS.Signals | null) => void): this;
48
+ on(event: 'error', listener: (err: Error) => void): this;
49
+ once(event: 'exit', listener: (code: number | null, signal: NodeJS.Signals | null) => void): this;
50
+ once(event: 'error', listener: (err: Error) => void): this;
51
+ kill(signal?: NodeJS.Signals): boolean;
52
+ }
53
+ /** Injectable ffmpeg spawn — the three-arg shape live-media sites use. */
54
+ export type FfmpegSpawnFn = (command: string, args: readonly string[], options?: SpawnOptions) => SpawnedFfmpegProcess;
55
+ export declare function defaultFfmpegSpawn(command: string, args: readonly string[], options?: SpawnOptions): SpawnedFfmpegProcess;
35
56
  /** How a child ended. */
36
57
  export type FfmpegExitClass =
37
58
  /** Exited 0. */