@glasshome/sync-layer 0.7.1 → 0.8.0

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 (58) hide show
  1. package/dist/index.d.ts +1291 -54
  2. package/dist/index.js +215 -308
  3. package/dist/service-C8H42I-Q.d.ts +459 -0
  4. package/dist/solid/index.d.ts +119 -6
  5. package/dist/solid/index.js +20 -15
  6. package/dist/{statistics-CtRfIF6D.js → statistics-DyCCTwv2.js} +83 -95
  7. package/dist/worker/worker-main.d.ts +11 -8
  8. package/dist/worker/worker-main.js +2 -3
  9. package/dist/{worker-main-C-3QM4di.js → worker-main-D_wyGAIG.js} +47 -157
  10. package/package.json +3 -3
  11. package/dist/calendar/track.d.ts +0 -19
  12. package/dist/calendar/types.d.ts +0 -32
  13. package/dist/camera/fetch.d.ts +0 -16
  14. package/dist/camera/query.d.ts +0 -15
  15. package/dist/camera/types.d.ts +0 -85
  16. package/dist/camera/webrtc.d.ts +0 -31
  17. package/dist/commands/service.d.ts +0 -53
  18. package/dist/commands/types.d.ts +0 -113
  19. package/dist/connection/adapter.d.ts +0 -48
  20. package/dist/connection/auth.d.ts +0 -126
  21. package/dist/connection/bridged.d.ts +0 -16
  22. package/dist/connection/manager.d.ts +0 -51
  23. package/dist/connection/subscription-manager.d.ts +0 -48
  24. package/dist/connection/subscriptions.d.ts +0 -31
  25. package/dist/connection/types.d.ts +0 -151
  26. package/dist/core/privileged-conn.d.ts +0 -29
  27. package/dist/core/reducers.d.ts +0 -99
  28. package/dist/core/store.d.ts +0 -100
  29. package/dist/core/types.d.ts +0 -339
  30. package/dist/demo/demo-data.d.ts +0 -24
  31. package/dist/demo/demo-provider.d.ts +0 -40
  32. package/dist/demo/energy-sim.d.ts +0 -112
  33. package/dist/energy/prefs.d.ts +0 -56
  34. package/dist/entities/area-views.d.ts +0 -32
  35. package/dist/entities/index.d.ts +0 -54
  36. package/dist/entities/views.d.ts +0 -35
  37. package/dist/history/constants.d.ts +0 -16
  38. package/dist/history/fetch.d.ts +0 -19
  39. package/dist/history/query.d.ts +0 -27
  40. package/dist/history/statistics.d.ts +0 -55
  41. package/dist/history/types.d.ts +0 -146
  42. package/dist/host-api.d.ts +0 -50
  43. package/dist/media/url.d.ts +0 -14
  44. package/dist/query/area-builder.d.ts +0 -25
  45. package/dist/query/builder.d.ts +0 -18
  46. package/dist/query/helpers.d.ts +0 -21
  47. package/dist/query/memoization.d.ts +0 -18
  48. package/dist/query/projections.d.ts +0 -74
  49. package/dist/query/types.d.ts +0 -260
  50. package/dist/solid/hooks.d.ts +0 -119
  51. package/dist/solid/indices.d.ts +0 -15
  52. package/dist/weather/fetch.d.ts +0 -19
  53. package/dist/weather/query.d.ts +0 -23
  54. package/dist/weather/types.d.ts +0 -126
  55. package/dist/worker/bridge-client.d.ts +0 -47
  56. package/dist/worker/enforcement.d.ts +0 -53
  57. package/dist/worker/protocol.d.ts +0 -129
  58. package/dist/worker/token-store.d.ts +0 -3
package/dist/index.d.ts CHANGED
@@ -1,60 +1,1297 @@
1
+ import { A as HassEntity, C as DeviceRegistryEntry, D as EntityView, E as EntityId, F as StatisticData, I as StatisticMetadata, L as UnsubscribeFunc, M as LabelRegistryEntry, N as MapFunc, O as FloorId, P as PredicateFunc, R as extractDomain, S as DeviceId, T as EntityDomain, _ as AreaId, a as toggle, b as Callback, c as updateEntity, d as EntityUpdateFields, f as ServiceCallContext, g as CalendarWindowOptions, h as CalendarEventsData, i as sendCommand, j as LabelId, k as FloorRegistryEntry, l as CommandOptions, m as CalendarEvent, n as batchServiceCalls, o as turnOff, p as ServiceTarget, r as callService, s as turnOn, t as batchEntityUpdates, u as CommandResult, v as AreaRegistryEntry, w as DeviceView, x as ConnectionState, y as AreaView } from "./service-C8H42I-Q.js";
2
+ import { WorkerScope, runHaBridgeWorker } from "./worker/worker-main.js";
3
+ import { Auth, ConnectionOptions as ConnectionOptions$1 } from "home-assistant-js-websocket";
4
+ import { Store } from "solid-js/store";
5
+ import { CapabilityGrant } from "@glasshome/widget-contract";
6
+ import { CallServiceRequest, CoreEventType, Domain, EntityCategory, EntityRegistryEntry, EntityRegistryEntry as EntityRegistryEntry$1, EventStateChangedData, HAEvent, HAEvent as HAEvent$1, HassConfig, HassUnitSystem, RegistryEntryDisabler, RegistryEntryHider, ServiceCall, ServiceName, WsCommandType, WsResult } from "@glasshome/ha-types";
7
+ //#region src/camera/types.d.ts
1
8
  /**
2
- * @glasshome/sync-layer
9
+ * Stream format
10
+ * Supported stream formats from Home Assistant Camera API
11
+ */
12
+ type StreamFormat = "hls" | "webrtc" | "mjpeg";
13
+ /**
14
+ * Camera stream data
15
+ */
16
+ interface CameraStream {
17
+ /** Stream URL */
18
+ url: string | null;
19
+ /** Loading state */
20
+ loading: boolean;
21
+ /** Error if any */
22
+ error: Error | null;
23
+ /** Last fetched timestamp */
24
+ lastFetched: number | null;
25
+ /** Stream format */
26
+ format: StreamFormat;
27
+ /** Stream expiration time (if available) */
28
+ expiresAt?: number | null;
29
+ }
30
+ /**
31
+ * Camera stream data for an entity
32
+ */
33
+ interface CameraStreamData {
34
+ /** Entity ID */
35
+ entityId: EntityId;
36
+ /** Stream data */
37
+ stream: CameraStream;
38
+ /** Loading state */
39
+ loading: boolean;
40
+ /** Error if any */
41
+ error: Error | null;
42
+ /** Last fetched timestamp */
43
+ lastFetched: number | null;
44
+ }
45
+ /**
46
+ * Camera stream data for multiple entities
47
+ */
48
+ interface CameraStreams {
49
+ /** Entity ID -> Stream data */
50
+ [entityId: EntityId]: CameraStreamData;
51
+ }
52
+ /**
53
+ * Options for stream queries
54
+ */
55
+ interface StreamQueryOptions {
56
+ /** Stream format (default: "hls") */
57
+ format?: StreamFormat;
58
+ /** Auto-refresh stream before expiration */
59
+ autoRefresh?: boolean;
60
+ /** Stream refresh interval in milliseconds (default: 5 minutes) */
61
+ refreshInterval?: number;
62
+ }
63
+ /**
64
+ * Single entity stream query options
65
+ */
66
+ interface EntityStreamQueryOptions {
67
+ /** Stream format (default: "hls") */
68
+ format?: StreamFormat;
69
+ /** Auto-refresh stream before expiration */
70
+ autoRefresh?: boolean;
71
+ /** Stream refresh interval in milliseconds (default: 5 minutes) */
72
+ refreshInterval?: number;
73
+ }
74
+ /**
75
+ * Stream query result
76
+ */
77
+ interface StreamResult {
78
+ /** Stream data */
79
+ data: CameraStreamData | null;
80
+ /** Loading state */
81
+ loading: boolean;
82
+ /** Error if any */
83
+ error: Error | null;
84
+ }
85
+ //#endregion
86
+ //#region src/history/types.d.ts
87
+ /**
88
+ * History states record
89
+ * Maps entity IDs to their history state arrays
90
+ *
91
+ * Based on HA frontend: HistoryStates
92
+ */
93
+ type HistoryStates = Record<string, EntityHistoryState[]>;
94
+ /**
95
+ * Entity history state point
96
+ * Represents a single point in entity history from Home Assistant
97
+ *
98
+ * Based on HA frontend: EntityHistoryState
99
+ */
100
+ interface EntityHistoryState {
101
+ /** State value (compressed format from HA) */
102
+ s: string;
103
+ /** Attributes */
104
+ a: Record<string, any>;
105
+ /** Last changed timestamp (Unix timestamp in seconds, optional; if set, also applies to lu) */
106
+ lc?: number;
107
+ /** Last updated timestamp (Unix timestamp in seconds) */
108
+ lu: number;
109
+ }
110
+ /**
111
+ * Timeline state point
112
+ * Represents a point in the timeline with full data
113
+ */
114
+ interface TimelineState {
115
+ /** Timestamp (Unix timestamp in seconds) */
116
+ timestamp: number;
117
+ /** State value */
118
+ state: string;
119
+ /** Attributes */
120
+ attributes?: Record<string, any>;
121
+ /** Last changed timestamp */
122
+ lastChanged?: number;
123
+ /** Last updated timestamp */
124
+ lastUpdated: number;
125
+ }
126
+ /**
127
+ * History data for a single entity
128
+ */
129
+ interface EntityHistoryData {
130
+ /** Entity ID */
131
+ entityId: EntityId;
132
+ /** Timeline data points */
133
+ timeline: TimelineState[];
134
+ /** Compressed history states (from HA API) */
135
+ entityHistory: EntityHistoryState[];
136
+ /** Loading state */
137
+ loading: boolean;
138
+ /** Error if any */
139
+ error: Error | null;
140
+ /** Last fetched timestamp */
141
+ lastFetched: number | null;
142
+ }
143
+ /**
144
+ * History data for multiple entities
145
+ */
146
+ interface HistoryData {
147
+ /** Entity ID -> History data */
148
+ [entityId: EntityId]: EntityHistoryData;
149
+ }
150
+ /**
151
+ * Options for history queries
152
+ *
153
+ * Based on HA frontend fetchDateWS parameters
154
+ */
155
+ interface HistoryQueryOptions {
156
+ /** Start time (required) */
157
+ startTime: Date;
158
+ /** End time (optional, defaults to now) */
159
+ endTime?: Date;
160
+ /** Entity IDs to query (optional, defaults to all) */
161
+ entityIds?: EntityId[];
162
+ /** Include start time state */
163
+ includeStartTimeState?: boolean;
164
+ /** Only significant changes */
165
+ significantChangesOnly?: boolean;
166
+ /** Minimal response (defaults to true, matching HA frontend) */
167
+ minimalResponse?: boolean;
168
+ /** No attributes (if not provided, automatically determined based on entity domains) */
169
+ noAttributes?: boolean;
170
+ }
171
+ /**
172
+ * Single entity history query options
173
+ */
174
+ interface EntityHistoryQueryOptions {
175
+ /** Start time (required) */
176
+ startTime: Date;
177
+ /** End time (optional, defaults to now) */
178
+ endTime?: Date;
179
+ /** Include start time state */
180
+ includeStartTimeState?: boolean;
181
+ /** Only significant changes */
182
+ significantChangesOnly?: boolean;
183
+ /** Minimal response (no attributes) */
184
+ minimalResponse?: boolean;
185
+ /** No attributes */
186
+ noAttributes?: boolean;
187
+ }
188
+ /**
189
+ * History query result
190
+ */
191
+ interface HistoryResult {
192
+ /** History data for each entity */
193
+ data: HistoryData;
194
+ /** Loading state */
195
+ loading: boolean;
196
+ /** Error if any */
197
+ error: Error | null;
198
+ }
199
+ /**
200
+ * Single entity history result
201
+ */
202
+ interface EntityHistoryResult {
203
+ /** History data */
204
+ data: EntityHistoryData | null;
205
+ /** Loading state */
206
+ loading: boolean;
207
+ /** Error if any */
208
+ error: Error | null;
209
+ }
210
+ //#endregion
211
+ //#region src/weather/types.d.ts
212
+ /**
213
+ * Forecast type
214
+ * Supported forecast types from Home Assistant Weather API
215
+ */
216
+ type ForecastType = "hourly" | "daily" | "twice_daily";
217
+ /**
218
+ * Weather forecast entry
219
+ * Represents a single forecast point from Home Assistant
220
+ */
221
+ interface WeatherForecast {
222
+ /** Forecast datetime (ISO 8601) */
223
+ datetime: string;
224
+ /** Temperature (in unit system) */
225
+ temperature?: number;
226
+ /** Temperature low (for daily forecasts) */
227
+ temp_low?: number;
228
+ /** Temperature high (for daily forecasts) */
229
+ temp_high?: number;
230
+ /** Humidity percentage */
231
+ humidity?: number;
232
+ /** Wind bearing (degrees) */
233
+ wind_bearing?: number;
234
+ /** Wind speed (in unit system) */
235
+ wind_speed?: number;
236
+ /** Precipitation probability (0-100) */
237
+ precipitation?: number;
238
+ /** Precipitation amount (in unit system) */
239
+ precipitation_probability?: number;
240
+ /** Condition (e.g., "sunny", "cloudy", "rainy") */
241
+ condition?: string;
242
+ /** Pressure (in unit system) */
243
+ pressure?: number;
244
+ /** Cloud coverage (0-100) */
245
+ cloud_coverage?: number;
246
+ /** UV index */
247
+ uv_index?: number;
248
+ /** Additional forecast data */
249
+ [key: string]: any;
250
+ }
251
+ /**
252
+ * Weather forecast data for a single type
253
+ */
254
+ interface WeatherForecastData {
255
+ /** Entity ID */
256
+ entityId: EntityId;
257
+ /** Forecast type */
258
+ type: ForecastType;
259
+ /** Forecast entries */
260
+ forecast: WeatherForecast[];
261
+ /** Loading state */
262
+ loading: boolean;
263
+ /** Error if any */
264
+ error: Error | null;
265
+ /** Last fetched timestamp */
266
+ lastFetched: number | null;
267
+ }
268
+ /**
269
+ * Weather forecast data for multiple types
270
+ */
271
+ interface WeatherForecastsData {
272
+ /** Entity ID */
273
+ entityId: EntityId;
274
+ /** Forecast data by type */
275
+ forecasts: Partial<Record<ForecastType, WeatherForecast[]>>;
276
+ /** Loading states by type */
277
+ loading: Partial<Record<ForecastType, boolean>>;
278
+ /** Errors by type */
279
+ errors: Partial<Record<ForecastType, Error | null>>;
280
+ /** Last fetched timestamps by type */
281
+ lastFetched: Partial<Record<ForecastType, number | null>>;
282
+ }
283
+ /**
284
+ * Weather forecast data for multiple entities
285
+ */
286
+ interface WeatherForecasts {
287
+ /** Entity ID -> Forecast data */
288
+ [entityId: EntityId]: WeatherForecastsData;
289
+ }
290
+ /**
291
+ * Options for forecast queries
292
+ */
293
+ interface ForecastQueryOptions {
294
+ /** Forecast type(s) to fetch */
295
+ type?: ForecastType;
296
+ /** Multiple forecast types to fetch */
297
+ types?: ForecastType[];
298
+ }
299
+ /**
300
+ * Single entity forecast query options
301
+ */
302
+ interface EntityForecastQueryOptions {
303
+ /** Forecast type(s) to fetch */
304
+ type?: ForecastType;
305
+ /** Multiple forecast types to fetch */
306
+ types?: ForecastType[];
307
+ }
308
+ /**
309
+ * Forecast query result for a single type
310
+ */
311
+ interface ForecastResult {
312
+ /** Forecast data */
313
+ data: WeatherForecastData | null;
314
+ /** Loading state */
315
+ loading: boolean;
316
+ /** Error if any */
317
+ error: Error | null;
318
+ }
319
+ /**
320
+ * Forecast query result for multiple types
321
+ */
322
+ interface ForecastsResult {
323
+ /** Forecast data */
324
+ data: WeatherForecastsData | null;
325
+ /** Loading states by type */
326
+ loading: Partial<Record<ForecastType, boolean>>;
327
+ /** Errors by type */
328
+ errors: Partial<Record<ForecastType, Error | null>>;
329
+ }
330
+ //#endregion
331
+ //#region src/core/store.d.ts
332
+ interface GlassHomeState {
333
+ /** Current connection state */
334
+ connectionState: ConnectionState;
335
+ /** Connection error (if any) */
336
+ connectionError: Error | null;
337
+ /** Home Assistant base URL */
338
+ hassUrl: string | null;
339
+ /** Same-origin prefix for the HA media proxy (e.g. "/ha-proxy/media"), or null
340
+ * to resolve media directly against hassUrl. Set by the host at connect. */
341
+ mediaProxyBase: string | null;
342
+ /** Home Assistant core config (unit system, locale, currency); null until loaded */
343
+ config: import("@glasshome/ha-types").HassConfig | null;
344
+ /** Live entity state (keyed by entity_id) */
345
+ entities: Record<EntityId, HassEntity>;
346
+ /** Entity registry entries (keyed by entity_id) */
347
+ entityRegistry: Record<EntityId, import("@glasshome/ha-types").EntityRegistryEntry>;
348
+ /** Device registry entries (keyed by device ID) */
349
+ devices: Record<DeviceId, DeviceRegistryEntry>;
350
+ /** Area registry entries (keyed by area ID) */
351
+ areas: Record<AreaId, AreaRegistryEntry>;
352
+ /** Floor registry entries (keyed by floor ID) */
353
+ floors: Record<FloorId, FloorRegistryEntry>;
354
+ /** Label registry entries (keyed by label ID) */
355
+ labels: Record<LabelId, LabelRegistryEntry>;
356
+ /** Statistics data (keyed by statistic_id) */
357
+ statistics: Record<string, StatisticData[]>;
358
+ /** Statistics metadata (keyed by statistic_id) */
359
+ statisticsMetadata: Record<string, StatisticMetadata>;
360
+ /** Entity history data (keyed by entity ID) */
361
+ history: Record<EntityId, EntityHistoryData>;
362
+ /** Weather forecasts data (keyed by entity ID) */
363
+ forecasts: Record<EntityId, WeatherForecastsData>;
364
+ /** Live calendar events (keyed by entity ID), maintained by calendar/track */
365
+ calendars: Record<EntityId, CalendarEventsData>;
366
+ /** Camera stream data (keyed by entity ID) */
367
+ streams: Record<EntityId, CameraStreamData>;
368
+ }
369
+ /**
370
+ * Module-level SolidJS createStore singleton
371
+ *
372
+ * `state` is a read-only reactive proxy.
373
+ * `setState` is used for mutations via produce() or direct path setting.
374
+ *
375
+ * @example
376
+ * ```typescript
377
+ * import { state, setState } from '@glasshome/sync-layer/core/store';
378
+ *
379
+ * // Read state (auto-tracked in SolidJS reactive contexts)
380
+ * const entities = state.entities;
381
+ *
382
+ * // Mutate via produce
383
+ * setState(produce((s) => {
384
+ * s.entities['light.living_room'] = newEntity;
385
+ * }));
386
+ *
387
+ * // Bulk replace
388
+ * setState("entities", reconcile(newEntities));
389
+ * ```
390
+ */
391
+ declare global {
392
+ var __GH_SYNC_LAYER_STORE__: boolean | undefined;
393
+ }
394
+ declare const state: Store<GlassHomeState>;
395
+ //#endregion
396
+ //#region src/connection/auth.d.ts
397
+ /**
398
+ * Options for OAuth authentication flow
399
+ */
400
+ interface OAuthOptions {
401
+ /**
402
+ * Home Assistant instance URL
403
+ * (e.g., "https://homeassistant.local:8123")
404
+ */
405
+ url: string;
406
+ /**
407
+ * Client ID for OAuth
408
+ * Typically the same as the Home Assistant URL
409
+ */
410
+ clientId: string;
411
+ /**
412
+ * Redirect URI after OAuth authorization
413
+ * (e.g., "https://myapp.com/auth/callback")
414
+ */
415
+ redirectUri?: string;
416
+ /**
417
+ * Optional authorization code if already obtained
418
+ * If provided, will be used directly instead of starting OAuth flow
419
+ */
420
+ authCode?: string;
421
+ /**
422
+ * Optional function to get authorization code
423
+ * If provided, will be called to get the code before token exchange
424
+ */
425
+ getAuthCode?: () => Promise<string>;
426
+ /**
427
+ * Optional function to save auth data
428
+ * Useful for persisting auth tokens
429
+ */
430
+ saveAuth?: (auth: Auth) => void | Promise<void>;
431
+ /**
432
+ * Optional function to load saved auth data
433
+ */
434
+ loadAuth?: () => Promise<Auth | null>;
435
+ /**
436
+ * Optional flag to limit to specific Home Assistant instance
437
+ */
438
+ limitHassInstance?: boolean;
439
+ }
440
+ //#endregion
441
+ //#region src/connection/manager.d.ts
442
+ /**
443
+ * Options for initializing a connection
444
+ */
445
+ interface ConnectionOptions {
446
+ url: string;
447
+ auth: Auth | string | OAuthOptions;
448
+ createSocket?: ConnectionOptions$1["createSocket"];
449
+ onConnect?: () => void;
450
+ onDisconnect?: () => void;
451
+ onReconnect?: () => void;
452
+ onError?: (error: Error) => void;
453
+ }
454
+ /**
455
+ * Disconnect from Home Assistant
456
+ */
457
+ declare function disconnect(): void;
458
+ /**
459
+ * Check if currently connected
460
+ */
461
+ declare function isConnected(): boolean;
462
+ /**
463
+ * Get the underlying socket's connected flag.
464
+ *
465
+ * Exposed so apps can render a connection indicator in the UI. Distinct from
466
+ * `isConnected()` which reflects the manager's internal lifecycle state.
467
+ */
468
+ declare function getConnectionState(): boolean;
469
+ //#endregion
470
+ //#region src/connection/types.d.ts
471
+ /**
472
+ * Unified connection interface for Home Assistant connections
3
473
  *
4
- * Type-safe, reactive state synchronization layer for Home Assistant
5
- * Uses SolidJS createStore for reactive state management.
474
+ * This interface is implemented by both:
475
+ * - MockConnection (for testing)
476
+ * - Wrapped HA Connection (for production)
6
477
  *
7
- * THIS ENTRY IS AN ACCESS-CONTROL SURFACE, not an ordinary barrel. The host
8
- * import map serves it to every untrusted widget bundle, so anything exported
9
- * here is callable by widget code. Before adding an export, ask who outside
10
- * this package needs it: in-package callers use relative imports and need
11
- * nothing here, host-only lifecycle belongs on claimHostApi(), and widget
12
- * hooks belong on the ./solid subpath. Types are always safe; they carry no
13
- * authority. scripts/check-widget-reachable-surface.ts guards this, but it is
14
- * a DENYLIST of known-dangerous names and is blind to any handle invented
15
- * after it was written — it cannot be relied on to catch a new mistake.
478
+ * @example
479
+ * ```typescript
480
+ * // In tests
481
+ * const mockConn: SyncLayerConnection = new MockConnection(fixtures);
482
+ * await syncLayer.connect({ connection: mockConn });
483
+ *
484
+ * // In production
485
+ * const haConn = await createConnection({ auth });
486
+ * const wrappedConn: SyncLayerConnection = wrapHAConnection(haConn);
487
+ * await syncLayer.connect({ connection: wrappedConn });
488
+ * ```
489
+ */
490
+ interface SyncLayerConnection {
491
+ /**
492
+ * Connect to Home Assistant (or mock)
493
+ *
494
+ * Establishes the WebSocket connection. For real HA connections,
495
+ * this is called automatically by createConnection. For mock connections,
496
+ * this simulates the connection process.
497
+ *
498
+ * @returns Promise that resolves when connection is established
499
+ */
500
+ connect(): Promise<void>;
501
+ /**
502
+ * Disconnect from Home Assistant
503
+ *
504
+ * Closes the WebSocket connection and cleans up resources.
505
+ */
506
+ disconnect(): void;
507
+ /**
508
+ * Check if connection is currently active
509
+ *
510
+ * @returns true if connected, false otherwise
511
+ */
512
+ get connected$(): boolean;
513
+ /**
514
+ * Authenticate with Home Assistant
515
+ *
516
+ * Sends authentication credentials. For real HA connections,
517
+ * authentication is handled during connection creation. For mock connections,
518
+ * this simulates the authentication process.
519
+ *
520
+ * @param accessToken - Access token for authentication
521
+ * @returns Promise that resolves when authentication completes
522
+ */
523
+ authenticate(accessToken: string): Promise<void>;
524
+ /**
525
+ * Get current authentication state
526
+ *
527
+ * @returns Authentication state: "pending", "authenticated", or "failed"
528
+ */
529
+ get authState(): "pending" | "authenticated" | "failed";
530
+ /**
531
+ * Subscribe to Home Assistant events
532
+ *
533
+ * Registers a callback to receive events of a specific type (or all events).
534
+ *
535
+ * @param callback - Function called when events are received
536
+ * @param eventType - Optional event type filter (e.g., "entity_registry_updated")
537
+ * @returns Promise resolving to unsubscribe function
538
+ *
539
+ * @example
540
+ * ```typescript
541
+ * const unsubscribe = await connection.subscribeEvents((event) => {
542
+ * console.log("Event received:", event);
543
+ * }, "entity_registry_updated");
544
+ *
545
+ * // Later, unsubscribe
546
+ * await unsubscribe();
547
+ * ```
548
+ */
549
+ subscribeEvents(callback: (event: HAEvent$1<any>) => void, eventType?: string): Promise<() => void>;
550
+ /**
551
+ * Subscribe to message stream
552
+ *
553
+ * Used for streaming subscriptions like history/stream.
554
+ * Sends a subscription message and receives streaming responses.
555
+ *
556
+ * @param callback - Function called when messages are received
557
+ * @param message - Subscription message (e.g., { type: "history/stream", ... })
558
+ * @returns Promise resolving to unsubscribe function
559
+ *
560
+ * @example
561
+ * ```typescript
562
+ * const unsubscribe = await connection.subscribeMessage((message) => {
563
+ * console.log("Stream message:", message);
564
+ * }, {
565
+ * type: "history/stream",
566
+ * entity_ids: ["sensor.temperature"],
567
+ * start_time: startTime.toISOString(),
568
+ * });
569
+ *
570
+ * // Later, unsubscribe
571
+ * await unsubscribe();
572
+ * ```
573
+ */
574
+ subscribeMessage<T>(callback: (message: T) => void, message: any): Promise<() => Promise<void>>;
575
+ /**
576
+ * Send a message and wait for response
577
+ *
578
+ * Sends a WebSocket message and returns a promise that resolves
579
+ * with the response.
580
+ *
581
+ * @param message - Message to send
582
+ * @returns Promise resolving to the response data
583
+ *
584
+ * @example
585
+ * ```typescript
586
+ * const states = await connection.sendMessagePromise({
587
+ * type: "get_states",
588
+ * });
589
+ * ```
590
+ */
591
+ sendMessagePromise<T>(message: any): Promise<T>;
592
+ /**
593
+ * Add event listener for WebSocket messages
594
+ *
595
+ * Registers a handler for all WebSocket messages (not just events).
596
+ * Useful for listening to auth messages, connection status, etc.
597
+ *
598
+ * @param handler - Function called when any message is received
599
+ * @returns Unsubscribe function
600
+ *
601
+ * @example
602
+ * ```typescript
603
+ * const unsubscribe = connection.addEventListener((message) => {
604
+ * console.log("Any message:", message);
605
+ * });
606
+ *
607
+ * // Later, unsubscribe
608
+ * unsubscribe();
609
+ * ```
610
+ */
611
+ addEventListener(handler: (message: any) => void): () => void;
612
+ }
613
+ //#endregion
614
+ //#region src/connection/subscription-manager.d.ts
615
+ declare global {
616
+ var __GH_SYNC_LAYER_SUB_MGR__: boolean | undefined;
617
+ }
618
+ /**
619
+ * Register an entity for live updates. Returns an unregister function.
620
+ * Call from useEntity/useEntities hooks via onCleanup.
621
+ */
622
+ declare function registerEntity(entityId: EntityId): () => void;
623
+ //#endregion
624
+ //#region src/query/area-builder.d.ts
625
+ interface AreaQueryBuilder$1 {
626
+ byFloor(floorId: FloorId): AreaQueryBuilder$1;
627
+ byLabel(labelId: LabelId): AreaQueryBuilder$1;
628
+ where(predicate: PredicateFunc<AreaView>): AreaQueryBuilder$1;
629
+ orderBy(key: keyof AreaView | string, direction?: "asc" | "desc"): AreaQueryBuilder$1;
630
+ get(): AreaView[];
631
+ first(): AreaView | undefined;
632
+ subscribe(callback: Callback<AreaView[]>): UnsubscribeFunc;
633
+ }
634
+ /**
635
+ * Create a query builder for areas
636
+ */
637
+ declare function areas(): AreaQueryBuilder$1;
638
+ /**
639
+ * Create a query for a single area
640
+ */
641
+ declare function area(areaId: AreaId): AreaView | undefined;
642
+ //#endregion
643
+ //#region src/query/types.d.ts
644
+ /**
645
+ * Main query builder interface for multiple entities
646
+ *
647
+ * Provides a fluent API for filtering, sorting, projecting, and subscribing.
648
+ *
649
+ * @template T - The result type (defaults to EntityView)
650
+ */
651
+ interface EntitiesQueryBuilder<T = EntityView> {
652
+ /**
653
+ * Filter by area
654
+ *
655
+ * @param areaId - Area ID to filter by
656
+ * @returns Query builder for chaining
657
+ */
658
+ byArea(areaId: AreaId): EntitiesQueryBuilder<T>;
659
+ /**
660
+ * Filter by domain
661
+ *
662
+ * @param domain - Domain to filter by (e.g., "light", "sensor")
663
+ * @returns Query builder for chaining
664
+ */
665
+ byDomain(domain: EntityDomain): EntitiesQueryBuilder<T>;
666
+ /**
667
+ * Filter by device
668
+ *
669
+ * @param deviceId - Device ID to filter by
670
+ * @returns Query builder for chaining
671
+ */
672
+ byDevice(deviceId: DeviceId): EntitiesQueryBuilder<T>;
673
+ /**
674
+ * Filter by floor
675
+ *
676
+ * @param floorId - Floor ID to filter by
677
+ * @returns Query builder for chaining
678
+ */
679
+ byFloor(floorId: FloorId): EntitiesQueryBuilder<T>;
680
+ /**
681
+ * Filter by label
682
+ *
683
+ * @param labelId - Label ID to filter by
684
+ * @returns Query builder for chaining
685
+ */
686
+ byLabel(labelId: LabelId): EntitiesQueryBuilder<T>;
687
+ /**
688
+ * Filter with custom predicate
689
+ *
690
+ * @param predicate - Function to test each entity
691
+ * @returns Query builder for chaining
692
+ */
693
+ where(predicate: PredicateFunc<EntityView>): EntitiesQueryBuilder<T>;
694
+ /**
695
+ * Search entities by text (searches id, name, friendlyName)
696
+ *
697
+ * @param searchText - Text to search for
698
+ * @returns Query builder for chaining
699
+ */
700
+ search(searchText: string): EntitiesQueryBuilder<T>;
701
+ /**
702
+ * Sort results
703
+ *
704
+ * @param key - Property key or dot-path (e.g., "name", "attributes.brightness")
705
+ * @param direction - Sort direction ("asc" or "desc")
706
+ * @returns Query builder for chaining
707
+ */
708
+ orderBy(key: string, direction?: "asc" | "desc"): EntitiesQueryBuilder<T>;
709
+ /**
710
+ * Project to entity IDs only
711
+ *
712
+ * @returns Query builder for entity IDs
713
+ */
714
+ ids(): EntitiesQueryBuilder<EntityId>;
715
+ /**
716
+ * Pick specific fields
717
+ *
718
+ * @param keys - Array of field names to include
719
+ * @returns Query builder with picked fields
720
+ */
721
+ pick<K extends keyof EntityView>(keys: K[]): EntitiesQueryBuilder<Pick<EntityView, K>>;
722
+ /**
723
+ * Extract a single field from each entity
724
+ *
725
+ * @param key - Field name to extract
726
+ * @returns Query builder for field values
727
+ */
728
+ pluck<K extends keyof EntityView>(key: K): EntitiesQueryBuilder<EntityView[K]>;
729
+ /**
730
+ * Map entities to new values
731
+ *
732
+ * @param mapper - Function to transform each entity
733
+ * @returns Query builder for mapped values
734
+ */
735
+ map<R>(mapper: MapFunc<EntityView, R>): EntitiesQueryBuilder<R>;
736
+ /**
737
+ * Limit the number of results
738
+ *
739
+ * @param limit - Maximum number of results to return
740
+ * @returns Query builder for chaining
741
+ */
742
+ take(limit: number): EntitiesQueryBuilder<T>;
743
+ /**
744
+ * Skip a number of results (for pagination)
745
+ *
746
+ * @param count - Number of results to skip
747
+ * @returns Query builder for chaining
748
+ */
749
+ skip(count: number): EntitiesQueryBuilder<T>;
750
+ /**
751
+ * Get distinct values by a key
752
+ *
753
+ * @param key - Field name or dot-path to get distinct values for
754
+ * @returns Query builder for distinct values
755
+ */
756
+ distinct(key: string): EntitiesQueryBuilder<T>;
757
+ /**
758
+ * Execute query and return results
759
+ *
760
+ * @returns Array of results
761
+ */
762
+ get(): T[];
763
+ /**
764
+ * Get first result
765
+ *
766
+ * @returns First result or undefined
767
+ */
768
+ first(): T | undefined;
769
+ /**
770
+ * Subscribe to query results
771
+ *
772
+ * Receives updates when entities matching the query change.
773
+ *
774
+ * @param callback - Function called with results
775
+ * @returns Unsubscribe function
776
+ */
777
+ subscribe(callback: Callback<T[]>): UnsubscribeFunc;
778
+ }
779
+ /**
780
+ * Query builder interface for areas
781
+ */
782
+ interface AreaQueryBuilder {
783
+ /**
784
+ * Filter areas by floor
785
+ */
786
+ byFloor(floorId: FloorId): AreaQueryBuilder;
787
+ /**
788
+ * Filter areas by label
789
+ */
790
+ byLabel(labelId: LabelId): AreaQueryBuilder;
791
+ /**
792
+ * Filter areas using a predicate
793
+ */
794
+ where(predicate: PredicateFunc<AreaView>): AreaQueryBuilder;
795
+ /**
796
+ * Order results by a key
797
+ */
798
+ orderBy(key: keyof AreaView | string, direction?: "asc" | "desc"): AreaQueryBuilder;
799
+ /**
800
+ * Execute query and get results
801
+ */
802
+ get(): AreaView[];
803
+ /**
804
+ * Get first result
805
+ */
806
+ first(): AreaView | undefined;
807
+ /**
808
+ * Subscribe to query results
809
+ */
810
+ subscribe(callback: Callback<AreaView[]>): UnsubscribeFunc;
811
+ }
812
+ /**
813
+ * Query builder interface for a single entity
814
+ */
815
+ interface EntityQueryBuilder {
816
+ /**
817
+ * Get entity view
818
+ *
819
+ * @returns Entity view or undefined
820
+ */
821
+ get(): EntityView | undefined;
822
+ /**
823
+ * Extract a single field
824
+ *
825
+ * @param key - Field name to extract
826
+ * @returns Field value or undefined
827
+ */
828
+ pluck<K extends keyof EntityView>(key: K): EntityView[K] | undefined;
829
+ /**
830
+ * Subscribe to entity changes
831
+ *
832
+ * @param callback - Function called with entity view
833
+ * @returns Unsubscribe function
834
+ */
835
+ subscribe(callback: Callback<EntityView | undefined>): UnsubscribeFunc;
836
+ }
837
+ //#endregion
838
+ //#region src/query/builder.d.ts
839
+ /**
840
+ * Create a query builder for multiple entities
841
+ */
842
+ declare function entities(): EntitiesQueryBuilder<EntityView>;
843
+ /**
844
+ * Create a query builder for a single entity
845
+ */
846
+ declare function entity(entityId: EntityId): EntityQueryBuilder;
847
+ //#endregion
848
+ //#region src/query/helpers.d.ts
849
+ /**
850
+ * Create a search query builder
851
+ */
852
+ declare function searchEntities(searchText: string): EntitiesQueryBuilder<EntityView>;
853
+ /**
854
+ * Create a query for entities in an area by domain
855
+ */
856
+ declare function entitiesByAreaAndDomain(areaId: AreaId, domain: EntityDomain): EntitiesQueryBuilder<EntityView>;
857
+ /**
858
+ * Create a query for entities matching a predicate
859
+ */
860
+ declare function entitiesWhere(predicate: (entity: EntityView) => boolean): EntitiesQueryBuilder<EntityView>;
861
+ //#endregion
862
+ //#region src/camera/fetch.d.ts
863
+ /**
864
+ * Fetch stream for a camera entity.
865
+ * Returns a public demo HLS stream when not connected.
866
+ */
867
+ declare function fetchStream(entityId: EntityId, format?: StreamFormat): Promise<string | null>;
868
+ /**
869
+ * Fetch stream data for a camera entity
870
+ */
871
+ declare function fetchStreamData(entityId: EntityId, options?: StreamQueryOptions): Promise<CameraStreamData>;
872
+ //#endregion
873
+ //#region src/camera/query.d.ts
874
+ /**
875
+ * Get stream for a camera entity
876
+ */
877
+ declare function getStream(entityId: EntityId, options?: EntityStreamQueryOptions): Promise<CameraStreamData>;
878
+ /**
879
+ * Refresh stream for a camera entity
880
+ */
881
+ declare function refreshStream(entityId: EntityId, format?: StreamFormat): Promise<CameraStreamData>;
882
+ //#endregion
883
+ //#region src/energy/prefs.d.ts
884
+ /**
885
+ * An energy source entry. Only the fields the widgets read are typed; the
886
+ * rest is passthrough. HA emits one of several shapes keyed by `type`:
887
+ * - grid: `flow_from[].stat_energy_from`, `flow_to[].stat_energy_to`
888
+ * - solar: `stat_energy_from`
889
+ * - battery: `stat_energy_from`, `stat_energy_to`
890
+ */
891
+ interface EnergySource {
892
+ type: "grid" | "solar" | "battery" | "gas" | "water" | string;
893
+ stat_energy_from?: string;
894
+ stat_energy_to?: string;
895
+ flow_from?: Array<{
896
+ stat_energy_from: string;
897
+ [key: string]: unknown;
898
+ }>;
899
+ flow_to?: Array<{
900
+ stat_energy_to: string;
901
+ [key: string]: unknown;
902
+ }>;
903
+ [key: string]: unknown;
904
+ }
905
+ /** A device tracked on the energy dashboard. */
906
+ interface EnergyDeviceConsumption {
907
+ stat_consumption: string;
908
+ name?: string;
909
+ [key: string]: unknown;
910
+ }
911
+ /**
912
+ * HA energy dashboard preferences.
913
+ *
914
+ * Based on HA frontend: EnergyPreferences.
915
+ */
916
+ interface EnergyPreferences {
917
+ energy_sources: EnergySource[];
918
+ device_consumption: EnergyDeviceConsumption[];
919
+ [key: string]: unknown;
920
+ }
921
+ /** Connection surface used by energy prefs fetching. */
922
+ type EnergyConnection = Pick<SyncLayerConnection, "sendMessagePromise">;
923
+ /**
924
+ * Fetch the HA energy dashboard preferences.
925
+ *
926
+ * Returns `null` when no energy dashboard is configured (HA raises an error
927
+ * for `energy/get_prefs` in that case); callers treat `null` as "not
928
+ * configured".
929
+ */
930
+ declare function fetchEnergyPreferences(connection: EnergyConnection): Promise<EnergyPreferences | null>;
931
+ //#endregion
932
+ //#region src/media/url.d.ts
933
+ /**
934
+ * Resolve an HA media reference (e.g. an entity's `entity_picture`, a camera
935
+ * proxy path) to a URL the page can actually load.
936
+ *
937
+ * HA gives these as origin-relative paths (`/api/media_player_proxy/...?token=`)
938
+ * carrying their own signed token. A bare `<img src>` would resolve them against
939
+ * the dash origin and 404. When the host set `mediaProxyBase`, route through the
940
+ * same-origin media proxy so the page CSP (`img-src 'self'`) covers it in every
941
+ * mode, LAN and remote. Otherwise fall back to prefixing `hassUrl` directly
942
+ * (the LAN-only path, used until a transport sets the proxy base).
943
+ *
944
+ * Absolute URLs and non-path values pass through untouched.
945
+ */
946
+ declare function hassMediaUrl(path: string | null | undefined): string | undefined;
947
+ //#endregion
948
+ //#region src/camera/webrtc.d.ts
949
+ /** Minimal RTC types for sync-layer (no DOM lib dependency) */
950
+ type RtcConfiguration = Record<string, unknown>;
951
+ type RtcIceCandidateInit = Record<string, unknown>;
952
+ interface WebRtcClientConfig {
953
+ configuration: RtcConfiguration;
954
+ dataChannel?: string;
955
+ }
956
+ interface WebRtcSession {
957
+ sessionId: string | null;
958
+ unsubscribe: (() => Promise<void>) | null;
959
+ }
960
+ /**
961
+ * Get WebRTC client configuration (STUN/TURN servers) from HA
962
+ */
963
+ declare function getWebRtcClientConfig(entityId: EntityId): Promise<WebRtcClientConfig>;
964
+ /**
965
+ * Start WebRTC session with HA.
966
+ * Returns a promise that resolves when the answer SDP is received.
967
+ * ICE candidates from HA are forwarded to the provided callback.
968
+ * Local ICE candidates should be sent via sendWebRtcCandidate().
969
+ */
970
+ declare function startWebRtcSession(entityId: EntityId, sdpOffer: string, onCandidate: (candidate: RtcIceCandidateInit) => void): Promise<{
971
+ answer: string;
972
+ session: WebRtcSession;
973
+ }>;
974
+ /**
975
+ * Send a local ICE candidate to HA
976
+ */
977
+ declare function sendWebRtcCandidate(entityId: EntityId, sessionId: string, candidate: RtcIceCandidateInit): Promise<void>;
978
+ //#endregion
979
+ //#region src/entities/area-views.d.ts
980
+ /**
981
+ * Build a DeviceView from registry data
982
+ */
983
+ declare function buildDeviceView(device: DeviceRegistryEntry): DeviceView;
984
+ /**
985
+ * Build an AreaView for a single area from registry data.
986
+ */
987
+ declare function buildAreaView(areaId: AreaId): AreaView;
988
+ /**
989
+ * Get all area views. Membership is resolved in a single registry pass; entity
990
+ * views stay lazy per area (see `assembleAreaView`).
991
+ */
992
+ declare function getAreaViews(): AreaView[];
993
+ /**
994
+ * Get area view
995
+ */
996
+ declare function getAreaView(areaId: AreaId): AreaView | undefined;
997
+ //#endregion
998
+ //#region src/entities/views.d.ts
999
+ /**
1000
+ * Build an EntityView from runtime state and registry metadata
1001
+ */
1002
+ declare function buildEntityView(entity: HassEntity, registry: EntityRegistryEntry$1 | undefined): EntityView;
1003
+ /**
1004
+ * Get or build an EntityView
1005
+ */
1006
+ declare function getEntityView(entityId: EntityId): EntityView | undefined;
1007
+ /**
1008
+ * Get multiple entity views
1009
+ */
1010
+ declare function getEntityViews(entityIds: EntityId[]): EntityView[];
1011
+ /**
1012
+ * Get all entity views
1013
+ */
1014
+ declare function getAllEntityViews(): EntityView[];
1015
+ /**
1016
+ * Shallow equality check for EntityView.
1017
+ * Compares fields that affect rendering; skips lastUpdated (heartbeat noise).
1018
+ */
1019
+ declare function entityViewEquals(a: EntityView | undefined, b: EntityView | undefined): boolean;
1020
+ //#endregion
1021
+ //#region src/history/constants.d.ts
1022
+ declare const DOMAINS_USE_LAST_UPDATED: readonly ["climate", "humidifier", "water_heater"];
1023
+ declare const NEED_ATTRIBUTE_DOMAINS: readonly ["climate", "humidifier", "input_datetime", "water_heater", "person", "device_tracker"];
1024
+ declare const LINE_ATTRIBUTES_TO_KEEP: readonly ["temperature", "current_temperature", "target_temp_low", "target_temp_high", "hvac_action", "humidity", "mode", "action", "current_humidity"];
1025
+ /**
1026
+ * Check if an entity needs attributes in history response
1027
+ */
1028
+ declare function entityIdHistoryNeedsAttributes(entityId: EntityId): boolean;
1029
+ //#endregion
1030
+ //#region src/history/fetch.d.ts
1031
+ /**
1032
+ * Fetch history for entities during a time period
1033
+ */
1034
+ declare function fetchHistory(options: HistoryQueryOptions): Promise<Record<EntityId, EntityHistoryState[]>>;
1035
+ /**
1036
+ * Fetch history for a single entity
1037
+ */
1038
+ declare function fetchEntityHistory(entityId: EntityId, options: EntityHistoryQueryOptions): Promise<EntityHistoryData>;
1039
+ /**
1040
+ * Convert compressed history state to timeline state
1041
+ */
1042
+ declare function historyStateToTimeline(s: EntityHistoryState): TimelineState;
1043
+ //#endregion
1044
+ //#region src/history/query.d.ts
1045
+ interface HistoryPoint {
1046
+ entityId: EntityId;
1047
+ stateValue: string;
1048
+ attributes: Record<string, unknown>;
1049
+ lastUpdated: number;
1050
+ lastChanged?: number;
1051
+ }
1052
+ /** Hard cap on retained points per entity timeline. */
1053
+ declare const MAX_HISTORY_POINTS = 5760;
1054
+ /** Check if an entity has active history tracking. */
1055
+ declare function isHistoryTracked(entityId: EntityId): boolean;
1056
+ /** Start tracking history for an entity. Fetches initial backfill. */
1057
+ declare function trackEntityHistory(entityId: EntityId, options: EntityHistoryQueryOptions): Promise<EntityHistoryData>;
1058
+ /** Release one tracker. The entity's data is cleared only when the last one goes. */
1059
+ declare function untrackEntityHistory(entityId: EntityId): void;
1060
+ /**
1061
+ * Append a state change to an entity's history.
1062
+ * Called by the entity subscription handler when a tracked entity changes.
1063
+ */
1064
+ declare function appendHistoryPoint(entityId: EntityId, stateValue: string, attributes: Record<string, unknown>, lastUpdated: number, lastChanged?: number): void;
1065
+ /**
1066
+ * Append multiple history points in a single setState(produce(...)).
1067
+ * Called by the rAF-batched subscription flush.
1068
+ */
1069
+ declare function bulkAppendHistoryPoints(points: HistoryPoint[]): void;
1070
+ //#endregion
1071
+ //#region src/history/statistics.d.ts
1072
+ /**
1073
+ * A single statistics bucket for one statistic id.
1074
+ *
1075
+ * HA 2023.6+ omits columns that were not requested and may omit null
1076
+ * columns, so every value field is optional. `start`/`end` are normalized
1077
+ * to ms epoch numbers regardless of the version's wire format.
1078
+ */
1079
+ interface StatisticValue {
1080
+ /** Bucket start (ms epoch) */
1081
+ start: number;
1082
+ /** Bucket end (ms epoch) */
1083
+ end: number;
1084
+ mean?: number;
1085
+ sum?: number;
1086
+ min?: number;
1087
+ max?: number;
1088
+ state?: number;
1089
+ change?: number;
1090
+ }
1091
+ /** Aggregation period for statistics buckets. */
1092
+ type StatisticsPeriod = "5minute" | "hour" | "day" | "week" | "month";
1093
+ /**
1094
+ * Options for {@link fetchStatisticsDuringPeriod}.
1095
+ */
1096
+ interface StatisticsQueryOptions {
1097
+ /** Start time (required) */
1098
+ startTime: Date;
1099
+ /** End time (optional, defaults to now on the HA side) */
1100
+ endTime?: Date;
1101
+ /** Aggregation period */
1102
+ period: StatisticsPeriod;
1103
+ }
1104
+ /** Connection surface used by statistics fetching. */
1105
+ type StatisticsConnection = Pick<SyncLayerConnection, "sendMessagePromise">;
1106
+ /**
1107
+ * HA returns start/end as ISO strings or ms numbers depending on version.
1108
+ * Normalize both shapes to ms epoch numbers; unparseable values become NaN.
1109
+ */
1110
+ declare function normalizeStatisticTime(value: unknown): number;
1111
+ /**
1112
+ * Fetch long-term statistics for one or more statistic ids during a period.
1113
+ *
1114
+ * Statistic ids with no data are returned as empty arrays so callers never
1115
+ * hit `undefined`.
1116
+ */
1117
+ declare function fetchStatisticsDuringPeriod(connection: StatisticsConnection, statisticIds: string[], options: StatisticsQueryOptions): Promise<Record<string, StatisticValue[]>>;
1118
+ //#endregion
1119
+ //#region src/weather/fetch.d.ts
1120
+ /**
1121
+ * Fetch forecast for a single entity and type
1122
+ */
1123
+ declare function fetchForecast(entityId: EntityId, type: ForecastType): Promise<WeatherForecast[]>;
1124
+ /**
1125
+ * Fetch forecasts for a single entity and multiple types
1126
+ */
1127
+ declare function fetchForecasts(entityId: EntityId, types: ForecastType[]): Promise<WeatherForecastsData>;
1128
+ /**
1129
+ * Fetch forecast data with error handling
1130
+ */
1131
+ declare function fetchForecastData(entityId: EntityId, type: ForecastType): Promise<WeatherForecastData>;
1132
+ //#endregion
1133
+ //#region src/weather/query.d.ts
1134
+ /**
1135
+ * Get forecast for a single entity and type
1136
+ */
1137
+ declare function getForecast(entityId: EntityId, type: ForecastType): Promise<WeatherForecastData>;
1138
+ /**
1139
+ * Get forecasts for a single entity and multiple types
1140
+ */
1141
+ declare function getForecasts(entityId: EntityId, types: ForecastType[]): Promise<WeatherForecastsData>;
1142
+ /**
1143
+ * Refresh forecast
1144
+ */
1145
+ declare function refreshForecast(entityId: EntityId, type: ForecastType): Promise<WeatherForecastData>;
1146
+ /**
1147
+ * Refresh forecasts
1148
+ */
1149
+ declare function refreshForecasts(entityId: EntityId, types: ForecastType[]): Promise<WeatherForecastsData>;
1150
+ //#endregion
1151
+ //#region src/demo/demo-data.d.ts
1152
+ interface DemoFixtures {
1153
+ entities: Record<string, HassEntity>;
1154
+ entityRegistry: Record<string, EntityRegistryEntry$1>;
1155
+ areas: Record<string, AreaRegistryEntry>;
1156
+ devices: Record<string, DeviceRegistryEntry>;
1157
+ }
1158
+ /**
1159
+ * Create ~30 curated apartment entity fixtures.
1160
+ *
1161
+ * Entities span lights, sensors, binary sensors, climate, covers,
1162
+ * locks, switches, media player, weather, camera, scenes, and buttons
1163
+ * across 6 areas: living_room, bedroom, kitchen, entry, utility, garage.
1164
+ */
1165
+ declare function createDemoFixtures(): DemoFixtures;
1166
+ //#endregion
1167
+ //#region src/demo/demo-provider.d.ts
1168
+ /**
1169
+ * Demo Mode Provider
1170
+ *
1171
+ * Loads demo fixtures into the SolidJS store and provides
1172
+ * optimistic local state updates for service calls (toggle, turnOn, turnOff).
16
1173
  *
17
1174
  * @packageDocumentation
18
1175
  */
19
- export type { ConnectionOptions } from "./connection/manager";
20
- export { getConnectionState, isConnected } from "./connection/manager";
21
- export { registerEntity } from "./connection/subscription-manager";
22
- export type { SyncLayerConnection } from "./connection/types";
23
- export type { OAuthOptions } from "./connection/auth";
24
- export { area, areas } from "./query/area-builder";
25
- export { entities, entity } from "./query/builder";
26
- export { entitiesByAreaAndDomain, entitiesWhere, searchEntities, } from "./query/helpers";
27
- export type { AreaQueryBuilder, EntitiesQueryBuilder, EntityQueryBuilder, UnsubscribeFunc, } from "./query/types";
28
- export { batchEntityUpdates, batchServiceCalls, callService, sendCommand, toggle, turnOff, turnOn, updateEntity, } from "./commands/service";
29
- export type { CommandOptions, CommandResult, EntityUpdateFields, ServiceCallContext, ServiceTarget, } from "./commands/types";
30
- export type { GlassHomeState } from "./core/store";
31
- export type { AreaId, AreaView, ConnectionState, DeviceId, DeviceView, EntityDomain, EntityId, EntityView, HassEntity, } from "./core/types";
32
- export { extractDomain } from "./core/types";
33
- export { state } from "./core/store";
34
- export type { CallServiceRequest, CoreEventType, Domain, EntityCategory, EntityRegistryEntry, EventStateChangedData, HAEvent, HassConfig, HassUnitSystem, RegistryEntryDisabler, RegistryEntryHider, ServiceCall, ServiceName, WsCommandType, WsResult, } from "@glasshome/ha-types";
35
- export { fetchStream, fetchStreamData } from "./camera/fetch";
36
- export { getStream, refreshStream } from "./camera/query";
37
- export { fetchEnergyPreferences } from "./energy/prefs";
38
- export { hassMediaUrl } from "./media/url";
39
- export type { EnergyDeviceConsumption, EnergyPreferences, EnergySource, } from "./energy/prefs";
40
- export type { CameraStream, CameraStreamData, CameraStreams, EntityStreamQueryOptions, StreamFormat, StreamQueryOptions, StreamResult, } from "./camera/types";
41
- export { getWebRtcClientConfig, sendWebRtcCandidate, startWebRtcSession, } from "./camera/webrtc";
42
- export { buildAreaView, buildDeviceView, getAreaView, getAreaViews, } from "./entities/area-views";
43
- export { buildEntityView, entityViewEquals, getAllEntityViews, getEntityView, getEntityViews, } from "./entities/views";
44
- export { DOMAINS_USE_LAST_UPDATED, entityIdHistoryNeedsAttributes, LINE_ATTRIBUTES_TO_KEEP, NEED_ATTRIBUTE_DOMAINS, } from "./history/constants";
45
- export { fetchEntityHistory, fetchHistory, historyStateToTimeline } from "./history/fetch";
46
- export { appendHistoryPoint, bulkAppendHistoryPoints, isHistoryTracked, MAX_HISTORY_POINTS, trackEntityHistory, untrackEntityHistory, } from "./history/query";
47
- export type { HistoryPoint } from "./history/query";
48
- export { fetchStatisticsDuringPeriod, normalizeStatisticTime, } from "./history/statistics";
49
- export type { StatisticsPeriod, StatisticsQueryOptions, StatisticValue, } from "./history/statistics";
50
- export type { EntityHistoryData, EntityHistoryQueryOptions, EntityHistoryResult, EntityHistoryState, HistoryData, HistoryQueryOptions, HistoryResult, HistoryStates, TimelineState, } from "./history/types";
51
- export { fetchForecast, fetchForecastData, fetchForecasts } from "./weather/fetch";
52
- export type { CalendarEvent, CalendarEventsData, CalendarWindowOptions } from "./calendar/types";
53
- export { getForecast, getForecasts, refreshForecast, refreshForecasts } from "./weather/query";
54
- export type { EntityForecastQueryOptions, ForecastQueryOptions, ForecastResult, ForecastsResult, ForecastType, WeatherForecast, WeatherForecastData, WeatherForecasts, WeatherForecastsData, } from "./weather/types";
55
- export { applyDemoServiceCall, createDemoFixtures, isDemoMode, startDemoEnergyTicker, stopDemoEnergyTicker, } from "./demo/demo-provider";
56
- export declare const VERSION = "0.2.1";
57
- export { BridgeNeedsAuthError, type BridgeConnectOptions, type BridgeEvents, type HaBridge, } from "./worker/bridge-client";
58
- export { claimHostApi, type HostApi } from "./host-api";
59
- export type { AuthMode, ConnState, OAuthTokenData } from "./worker/protocol";
60
- export { runHaBridgeWorker, type WorkerScope } from "./worker/worker-main";
1176
+ /**
1177
+ * Whether demo mode is currently active.
1178
+ */
1179
+ declare function isDemoMode(): boolean;
1180
+ /**
1181
+ * Load demo fixtures into the SolidJS store.
1182
+ *
1183
+ * Populates entities, entity registry, areas, and devices.
1184
+ * Sets connection state to "connected" (pretend connected).
1185
+ */
1186
+ declare function loadDemoData(): Promise<void>;
1187
+ /**
1188
+ * Unload demo data and reset to disconnected state.
1189
+ */
1190
+ declare function unloadDemoData(): void;
1191
+ /**
1192
+ * Start the demo energy ticker. Updates the energy sensors and `sun.sun`
1193
+ * every 5 seconds. Idempotent: clears any prior interval first. SSR-safe.
1194
+ */
1195
+ declare function startDemoEnergyTicker(): void;
1196
+ /** Stop the demo energy ticker if running. */
1197
+ declare function stopDemoEnergyTicker(): void;
1198
+ /**
1199
+ * Apply an optimistic state update for demo mode.
1200
+ *
1201
+ * When a service call is made in demo mode, this updates the entity
1202
+ * state locally (no WebSocket message sent). State resets on page refresh.
1203
+ */
1204
+ declare function applyDemoServiceCall(_domain: string, service: string, _serviceData?: Record<string, any>, target?: {
1205
+ entity_id?: string | string[];
1206
+ }): void;
1207
+ //#endregion
1208
+ //#region src/worker/protocol.d.ts
1209
+ type ConnState = "connected" | "disconnected" | "reconnecting";
1210
+ //#endregion
1211
+ //#region src/worker/bridge-client.d.ts
1212
+ /**
1213
+ * Main-thread side of the HA bridge. Wraps the Worker and exposes:
1214
+ * - a SyncLayerConnection facade so the existing store/subscription/command
1215
+ * code runs unchanged, with all HA traffic tunneled through the worker
1216
+ * - registerWidget(), which mints the per-widget MessagePort the SDK's
1217
+ * service hooks call through (capability-checked in the worker)
1218
+ *
1219
+ * The Worker reference and its privileged channel live in this module's
1220
+ * closures only.
1221
+ */
1222
+ interface BridgeConnectOptions {
1223
+ url: string;
1224
+ proxyWsPath: string;
1225
+ proxyTicket?: string;
1226
+ }
1227
+ interface BridgeEvents {
1228
+ onConnState?: (state: ConnState) => void;
1229
+ onReadyAfterReconnect?: () => void;
1230
+ onInvalidAuth?: () => void;
1231
+ onDenial?: (denial: {
1232
+ widgetId: string;
1233
+ domain: string;
1234
+ service: string;
1235
+ entityIds: string[];
1236
+ message: string;
1237
+ }) => void;
1238
+ }
1239
+ interface HaBridge {
1240
+ /** Resolves on socket-up; rejects with BridgeInvalidAuthError when the relay or HA refused the handshake. */
1241
+ connect(opts: BridgeConnectOptions): Promise<void>;
1242
+ disconnect(): void;
1243
+ reconnect(): void;
1244
+ conn: SyncLayerConnection;
1245
+ registerWidget(widgetId: string, caps: CapabilityGrant[]): MessagePort;
1246
+ unregisterWidget(widgetId: string): void;
1247
+ /** Forward visibility/pageshow so the worker can drive suspend/reconnect. Returns teardown. */
1248
+ forwardLifecycle(): () => void;
1249
+ terminate(): void;
1250
+ }
1251
+ declare class BridgeInvalidAuthError extends Error {
1252
+ constructor();
1253
+ }
1254
+ declare function createHaBridge(worker: Worker, events?: BridgeEvents): HaBridge;
1255
+ //#endregion
1256
+ //#region src/connection/bridged.d.ts
1257
+ /**
1258
+ * Wire an HA bridge (worker-backed connection) into the store. The bridge's
1259
+ * facade rides the same load/subscribe pipeline as a direct socket; only the
1260
+ * lifecycle signals differ — they arrive as worker messages instead of
1261
+ * Connection events.
1262
+ *
1263
+ * Call after bridge.connect() resolved. Returns when initial data is loaded.
1264
+ */
1265
+ declare function attachBridgeToStore(bridge: HaBridge, hassUrl: string, mediaProxyBase?: string): Promise<void>;
1266
+ /** Map worker connection-state messages onto the store. */
1267
+ declare function applyBridgeConnState(state: "connected" | "disconnected" | "reconnecting"): void;
1268
+ /** Re-sync after the worker reports a completed reconnect. */
1269
+ declare function reloadAfterBridgeReconnect(bridge: HaBridge): Promise<void>;
1270
+ /** Detach on shutdown; the caller terminates the worker itself. */
1271
+ declare function detachBridgeFromStore(): void;
1272
+ //#endregion
1273
+ //#region src/host-api.d.ts
1274
+ interface HostApi {
1275
+ attachBridgeToStore: typeof attachBridgeToStore;
1276
+ detachBridgeFromStore: typeof detachBridgeFromStore;
1277
+ applyBridgeConnState: typeof applyBridgeConnState;
1278
+ reloadAfterBridgeReconnect: typeof reloadAfterBridgeReconnect;
1279
+ createHaBridge: typeof createHaBridge;
1280
+ disconnect: typeof disconnect;
1281
+ loadDemoData: typeof loadDemoData;
1282
+ unloadDemoData: typeof unloadDemoData;
1283
+ }
1284
+ /**
1285
+ * Take the host-only surface. Returns it once; null on every later call.
1286
+ *
1287
+ * Call it exactly once, during host boot, and keep the result in a module the
1288
+ * import map does not serve. Calling it from anywhere else is what this guards
1289
+ * against, so a null return means something already claimed it — treat that as
1290
+ * a fatal misconfiguration, not a retry.
1291
+ */
1292
+ declare function claimHostApi(): HostApi | null;
1293
+ //#endregion
1294
+ //#region src/index.d.ts
1295
+ declare const VERSION = "0.2.1";
1296
+ //#endregion
1297
+ export { type AreaId, type AreaQueryBuilder, type AreaView, type BridgeConnectOptions, type BridgeEvents, BridgeInvalidAuthError, type CalendarEvent, type CalendarEventsData, type CalendarWindowOptions, type CallServiceRequest, type CameraStream, type CameraStreamData, type CameraStreams, type CommandOptions, type CommandResult, type ConnState, type ConnectionOptions, type ConnectionState, type CoreEventType, DOMAINS_USE_LAST_UPDATED, type DeviceId, type DeviceView, type Domain, type EnergyDeviceConsumption, type EnergyPreferences, type EnergySource, type EntitiesQueryBuilder, type EntityCategory, type EntityDomain, type EntityForecastQueryOptions, type EntityHistoryData, type EntityHistoryQueryOptions, type EntityHistoryResult, type EntityHistoryState, type EntityId, type EntityQueryBuilder, type EntityRegistryEntry, type EntityStreamQueryOptions, type EntityUpdateFields, type EntityView, type EventStateChangedData, type ForecastQueryOptions, type ForecastResult, type ForecastType, type ForecastsResult, type GlassHomeState, type HAEvent, type HaBridge, type HassConfig, type HassEntity, type HassUnitSystem, type HistoryData, type HistoryPoint, type HistoryQueryOptions, type HistoryResult, type HistoryStates, type HostApi, LINE_ATTRIBUTES_TO_KEEP, MAX_HISTORY_POINTS, NEED_ATTRIBUTE_DOMAINS, type RegistryEntryDisabler, type RegistryEntryHider, type ServiceCall, type ServiceCallContext, type ServiceName, type ServiceTarget, type StatisticValue, type StatisticsPeriod, type StatisticsQueryOptions, type StreamFormat, type StreamQueryOptions, type StreamResult, type SyncLayerConnection, type TimelineState, type UnsubscribeFunc, VERSION, type WeatherForecast, type WeatherForecastData, type WeatherForecasts, type WeatherForecastsData, type WorkerScope, type WsCommandType, type WsResult, appendHistoryPoint, applyDemoServiceCall, area, areas, batchEntityUpdates, batchServiceCalls, buildAreaView, buildDeviceView, buildEntityView, bulkAppendHistoryPoints, callService, claimHostApi, createDemoFixtures, entities, entitiesByAreaAndDomain, entitiesWhere, entity, entityIdHistoryNeedsAttributes, entityViewEquals, extractDomain, fetchEnergyPreferences, fetchEntityHistory, fetchForecast, fetchForecastData, fetchForecasts, fetchHistory, fetchStatisticsDuringPeriod, fetchStream, fetchStreamData, getAllEntityViews, getAreaView, getAreaViews, getConnectionState, getEntityView, getEntityViews, getForecast, getForecasts, getStream, getWebRtcClientConfig, hassMediaUrl, historyStateToTimeline, isConnected, isDemoMode, isHistoryTracked, normalizeStatisticTime, refreshForecast, refreshForecasts, refreshStream, registerEntity, runHaBridgeWorker, searchEntities, sendCommand, sendWebRtcCandidate, startDemoEnergyTicker, startWebRtcSession, state, stopDemoEnergyTicker, toggle, trackEntityHistory, turnOff, turnOn, untrackEntityHistory, updateEntity };