@glasshome/sync-layer 0.1.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 (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/area-views-B-m8vwce.js +321 -0
  4. package/dist/camera/fetch.d.ts +15 -0
  5. package/dist/camera/query.d.ts +15 -0
  6. package/dist/camera/types.d.ts +85 -0
  7. package/dist/camera/webrtc.d.ts +31 -0
  8. package/dist/commands/service.d.ts +53 -0
  9. package/dist/commands/types.d.ts +113 -0
  10. package/dist/connection/adapter.d.ts +48 -0
  11. package/dist/connection/auth.d.ts +126 -0
  12. package/dist/connection/manager.d.ts +42 -0
  13. package/dist/connection/subscriptions.d.ts +25 -0
  14. package/dist/connection/types.d.ts +161 -0
  15. package/dist/core/reducers.d.ts +99 -0
  16. package/dist/core/store.d.ts +64 -0
  17. package/dist/core/types.d.ts +336 -0
  18. package/dist/demo/demo-data.d.ts +24 -0
  19. package/dist/demo/demo-provider.d.ts +33 -0
  20. package/dist/demo/demo-provider.js +103 -0
  21. package/dist/demo-data-D8JXWRpw.js +419 -0
  22. package/dist/entities/area-views.d.ts +25 -0
  23. package/dist/entities/index.d.ts +54 -0
  24. package/dist/entities/views.d.ts +30 -0
  25. package/dist/history/constants.d.ts +16 -0
  26. package/dist/history/fetch.d.ts +19 -0
  27. package/dist/history/query.d.ts +13 -0
  28. package/dist/history/types.d.ts +146 -0
  29. package/dist/index.d.ts +38 -0
  30. package/dist/index.js +1747 -0
  31. package/dist/query/area-builder.d.ts +25 -0
  32. package/dist/query/builder.d.ts +18 -0
  33. package/dist/query/helpers.d.ts +21 -0
  34. package/dist/query/memoization.d.ts +18 -0
  35. package/dist/query/projections.d.ts +74 -0
  36. package/dist/query/types.d.ts +260 -0
  37. package/dist/solid/hooks.d.ts +88 -0
  38. package/dist/solid/index.d.ts +10 -0
  39. package/dist/solid/index.js +176 -0
  40. package/dist/solid/indices.d.ts +14 -0
  41. package/dist/store-B1sbyexX.js +54 -0
  42. package/dist/testing/fixtures.d.ts +161 -0
  43. package/dist/testing/helpers.d.ts +160 -0
  44. package/dist/testing/index.d.ts +13 -0
  45. package/dist/testing/index.js +2047 -0
  46. package/dist/testing/mock-behaviors/base.d.ts +73 -0
  47. package/dist/testing/mock-behaviors/climate.d.ts +22 -0
  48. package/dist/testing/mock-behaviors/cover.d.ts +22 -0
  49. package/dist/testing/mock-behaviors/index.d.ts +11 -0
  50. package/dist/testing/mock-behaviors/light.d.ts +20 -0
  51. package/dist/testing/mock-behaviors/lock.d.ts +20 -0
  52. package/dist/testing/mock-behaviors/media_player.d.ts +42 -0
  53. package/dist/testing/mock-behaviors/registry.d.ts +55 -0
  54. package/dist/testing/mock-behaviors/switch.d.ts +17 -0
  55. package/dist/testing/mock.d.ts +191 -0
  56. package/dist/testing/types.d.ts +87 -0
  57. package/dist/types-Csog0nqk.js +10 -0
  58. package/dist/weather/fetch.d.ts +19 -0
  59. package/dist/weather/query.d.ts +23 -0
  60. package/dist/weather/types.d.ts +126 -0
  61. package/package.json +85 -0
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Base types and interfaces for mock behavior handlers
3
+ *
4
+ * This file defines the contract that all domain behavior handlers must implement.
5
+ * Each domain handler simulates how Home Assistant would change entity states
6
+ * in response to service calls.
7
+ */
8
+ import type { Domain, ServiceCall, ServiceName } from "@glasshome/ha-types";
9
+ import type { HassEntity } from "../../core/types";
10
+ /**
11
+ * Context from a service call or state change
12
+ * Matches HA's context structure
13
+ */
14
+ export interface ServiceContext {
15
+ id: string;
16
+ parent_id: string | null;
17
+ user_id: string | null;
18
+ }
19
+ /**
20
+ * Result of a behavior handler processing a service call
21
+ */
22
+ export interface BehaviorResult {
23
+ /** Updated entity state (null if no change) */
24
+ stateUpdate: Partial<HassEntity> | null;
25
+ /** Optional error to throw */
26
+ error?: {
27
+ code: string;
28
+ message: string;
29
+ };
30
+ /** Optional additional actions (for multi-step behaviors) */
31
+ additionalActions?: Array<{
32
+ delay: number;
33
+ update: Partial<HassEntity>;
34
+ }>;
35
+ }
36
+ /**
37
+ * Domain behavior handler interface
38
+ *
39
+ * Each domain (light, switch, cover, etc.) implements this interface
40
+ * to define how it reacts to service calls.
41
+ *
42
+ * Uses strongly-typed Domain and ServiceName from @glasshome/ha-types.
43
+ */
44
+ export interface DomainBehavior<D extends Domain = Domain> {
45
+ /** Domain this handler manages (e.g., "light", "switch") */
46
+ readonly domain: D;
47
+ /**
48
+ * Handle a service call for an entity in this domain
49
+ *
50
+ * @param entity - Current entity state
51
+ * @param service - Service name (e.g., "turn_on", "set_temperature")
52
+ * @param serviceData - Service call data/parameters
53
+ * @param context - Service call context
54
+ * @returns Behavior result with state updates
55
+ */
56
+ handleService(entity: HassEntity, service: ServiceName<D>, serviceData: ServiceCall<D, ServiceName<D>> | undefined, context: ServiceContext): BehaviorResult;
57
+ }
58
+ /**
59
+ * Helper to create a simple state update result
60
+ */
61
+ export declare function simpleStateUpdate(update: Partial<HassEntity>): BehaviorResult;
62
+ /**
63
+ * Helper to create a no-change result
64
+ */
65
+ export declare function noChange(): BehaviorResult;
66
+ /**
67
+ * Helper to create an error result
68
+ */
69
+ export declare function behaviorError(code: string, message: string): BehaviorResult;
70
+ /**
71
+ * Helper to merge attributes safely
72
+ */
73
+ export declare function mergeAttributes(current: Record<string, unknown>, updates: Record<string, unknown>): Record<string, unknown>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Climate domain behavior handler
3
+ *
4
+ * Simulates Home Assistant's climate entity behavior for:
5
+ * - set_temperature: Set target temperature
6
+ * - set_hvac_mode: Change HVAC mode (heat, cool, auto, etc.)
7
+ * - set_preset_mode: Change preset (eco, comfort, etc.)
8
+ * - set_fan_mode: Change fan mode
9
+ * - set_humidity: Set target humidity
10
+ * - turn_on: Turn on to last mode (or heat)
11
+ * - turn_off: Turn off
12
+ *
13
+ * Uses strongly-typed ClimateService from @glasshome/ha-types.
14
+ */
15
+ import type { ServiceCall, ServiceName } from "@glasshome/ha-types";
16
+ import type { HassEntity } from "../../core/types";
17
+ import type { BehaviorResult, DomainBehavior, ServiceContext } from "./base";
18
+ export declare class ClimateBehavior implements DomainBehavior<"climate"> {
19
+ readonly domain: "climate";
20
+ handleService(entity: HassEntity, service: ServiceName<"climate">, serviceData: ServiceCall<"climate", ServiceName<"climate">> | undefined, _context: ServiceContext): BehaviorResult;
21
+ private handleSetTemperature;
22
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Cover domain behavior handler
3
+ *
4
+ * Simulates Home Assistant's cover entity behavior for:
5
+ * - open_cover: Open cover fully
6
+ * - close_cover: Close cover fully
7
+ * - stop_cover: Stop cover movement
8
+ * - set_cover_position: Set to specific position
9
+ * - open_cover_tilt: Open tilt fully
10
+ * - close_cover_tilt: Close tilt fully
11
+ * - set_cover_tilt_position: Set tilt to specific position
12
+ * - toggle: Toggle open/closed
13
+ *
14
+ * Uses strongly-typed CoverService from @glasshome/ha-types.
15
+ */
16
+ import type { ServiceCall, ServiceName } from "@glasshome/ha-types";
17
+ import type { HassEntity } from "../../core/types";
18
+ import type { BehaviorResult, DomainBehavior, ServiceContext } from "./base";
19
+ export declare class CoverBehavior implements DomainBehavior<"cover"> {
20
+ readonly domain: "cover";
21
+ handleService(entity: HassEntity, service: ServiceName<"cover">, serviceData: ServiceCall<"cover", ServiceName<"cover">> | undefined, _context: ServiceContext): BehaviorResult;
22
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Mock Behaviors - Export all behavior handlers and utilities
3
+ */
4
+ export * from "./base";
5
+ export { ClimateBehavior } from "./climate";
6
+ export { CoverBehavior } from "./cover";
7
+ export { LightBehavior } from "./light";
8
+ export { LockBehavior } from "./lock";
9
+ export { MediaPlayerBehavior } from "./media_player";
10
+ export * from "./registry";
11
+ export { SwitchBehavior } from "./switch";
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Light domain behavior handler
3
+ *
4
+ * Simulates Home Assistant's light entity behavior for:
5
+ * - turn_on: Turn on with optional brightness, color, etc.
6
+ * - turn_off: Turn off with optional transition
7
+ * - toggle: Toggle state
8
+ *
9
+ * Uses strongly-typed LightService and ServiceCall from @glasshome/ha-types.
10
+ */
11
+ import type { ServiceCall, ServiceName } from "@glasshome/ha-types";
12
+ import type { HassEntity } from "../../core/types";
13
+ import type { BehaviorResult, DomainBehavior, ServiceContext } from "./base";
14
+ export declare class LightBehavior implements DomainBehavior<"light"> {
15
+ readonly domain: "light";
16
+ handleService(entity: HassEntity, service: ServiceName<"light">, serviceData: ServiceCall<"light", ServiceName<"light">> | undefined, _context: ServiceContext): BehaviorResult;
17
+ private handleTurnOn;
18
+ private handleTurnOff;
19
+ private handleToggle;
20
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Lock domain behavior handler
3
+ *
4
+ * Simulates Home Assistant's lock entity behavior for:
5
+ * - lock: Lock the lock
6
+ * - unlock: Unlock the lock
7
+ * - open: Open the lock (unlocks and opens door)
8
+ *
9
+ * Uses strongly-typed LockService from @glasshome/ha-types.
10
+ */
11
+ import type { ServiceCall, ServiceName } from "@glasshome/ha-types";
12
+ import type { HassEntity } from "../../core/types";
13
+ import type { BehaviorResult, DomainBehavior, ServiceContext } from "./base";
14
+ export declare class LockBehavior implements DomainBehavior<"lock"> {
15
+ readonly domain: "lock";
16
+ handleService(entity: HassEntity, service: ServiceName<"lock">, _serviceData: ServiceCall<"lock", ServiceName<"lock">> | undefined, _context: ServiceContext): BehaviorResult;
17
+ private handleLock;
18
+ private handleUnlock;
19
+ private handleOpen;
20
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Media Player domain behavior handler
3
+ *
4
+ * Simulates Home Assistant's media player entity behavior for:
5
+ * - media_play: Start playback
6
+ * - media_pause: Pause playback
7
+ * - media_play_pause: Toggle play/pause
8
+ * - media_stop: Stop playback
9
+ * - media_next_track: Skip to next track
10
+ * - media_previous_track: Skip to previous track
11
+ * - media_seek: Seek to position
12
+ * - volume_up: Increase volume
13
+ * - volume_down: Decrease volume
14
+ * - set_volume_level: Set volume level
15
+ * - mute_volume: Mute/unmute
16
+ * - turn_on: Turn on media player
17
+ * - turn_off: Turn off media player
18
+ * - toggle: Toggle power
19
+ *
20
+ * Uses strongly-typed MediaPlayerService from @glasshome/ha-types.
21
+ */
22
+ import type { ServiceCall, ServiceName } from "@glasshome/ha-types";
23
+ import type { HassEntity } from "../../core/types";
24
+ import type { BehaviorResult, DomainBehavior, ServiceContext } from "./base";
25
+ export declare class MediaPlayerBehavior implements DomainBehavior<"media_player"> {
26
+ readonly domain: "media_player";
27
+ handleService(entity: HassEntity, service: ServiceName<"media_player">, serviceData: ServiceCall<"media_player", ServiceName<"media_player">> | undefined, _context: ServiceContext): BehaviorResult;
28
+ private handlePlay;
29
+ private handlePause;
30
+ private handlePlayPause;
31
+ private handleStop;
32
+ private handleNextTrack;
33
+ private handlePreviousTrack;
34
+ private handleSeek;
35
+ private handleVolumeUp;
36
+ private handleVolumeDown;
37
+ private handleSetVolumeLevel;
38
+ private handleMuteVolume;
39
+ private handleTurnOn;
40
+ private handleTurnOff;
41
+ private handleToggle;
42
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Behavior Registry
3
+ *
4
+ * Manages and provides access to all domain behavior handlers.
5
+ * Automatically discovers and registers handlers.
6
+ */
7
+ import type { DomainBehavior } from "./base";
8
+ /**
9
+ * Central registry of all domain behavior handlers
10
+ */
11
+ export declare class BehaviorRegistry {
12
+ private handlers;
13
+ constructor();
14
+ /**
15
+ * Register all built-in domain handlers
16
+ */
17
+ private registerDefaultHandlers;
18
+ /**
19
+ * Register a domain behavior handler
20
+ */
21
+ register(handler: DomainBehavior): void;
22
+ /**
23
+ * Get handler for a specific domain
24
+ */
25
+ getHandler(domain: string): DomainBehavior | undefined;
26
+ /**
27
+ * Check if a domain has a registered handler
28
+ */
29
+ hasHandler(domain: string): boolean;
30
+ /**
31
+ * Get all registered domains
32
+ */
33
+ getRegisteredDomains(): string[];
34
+ /**
35
+ * Clear all handlers (useful for testing)
36
+ */
37
+ clear(): void;
38
+ /**
39
+ * Reset to default handlers
40
+ */
41
+ reset(): void;
42
+ }
43
+ /**
44
+ * Global behavior registry instance
45
+ */
46
+ export declare const behaviorRegistry: BehaviorRegistry;
47
+ /**
48
+ * Get behavior handler for a domain
49
+ */
50
+ export declare function getBehaviorHandler(domain: string): DomainBehavior | undefined;
51
+ /**
52
+ * Register a custom behavior handler
53
+ * Useful for tests or custom mock scenarios
54
+ */
55
+ export declare function registerBehaviorHandler(handler: DomainBehavior): void;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Switch domain behavior handler
3
+ *
4
+ * Simulates Home Assistant's switch entity behavior for:
5
+ * - turn_on: Turn on switch
6
+ * - turn_off: Turn off switch
7
+ * - toggle: Toggle state
8
+ *
9
+ * Uses strongly-typed SwitchService from @glasshome/ha-types.
10
+ */
11
+ import type { ServiceCall, ServiceName } from "@glasshome/ha-types";
12
+ import type { HassEntity } from "../../core/types";
13
+ import type { BehaviorResult, DomainBehavior, ServiceContext } from "./base";
14
+ export declare class SwitchBehavior implements DomainBehavior<"switch"> {
15
+ readonly domain: "switch";
16
+ handleService(entity: HassEntity, service: ServiceName<"switch">, _serviceData: ServiceCall<"switch", ServiceName<"switch">> | undefined, _context: ServiceContext): BehaviorResult;
17
+ }
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Mock Home Assistant connection
3
+ *
4
+ * Provides a mock implementation for testing without a real HA instance.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import type { EntityRegistryEntry, HAEvent } from "@glasshome/ha-types";
9
+ import type { SyncLayerConnection } from "../connection/types";
10
+ import type { HassEntity } from "../core/types";
11
+ import type { AreaRegistryEntry, DeviceRegistryEntry, Fixtures } from "./types";
12
+ /**
13
+ * Mock WebSocket connection for testing
14
+ *
15
+ * Simulates a Home Assistant WebSocket connection without requiring
16
+ * a real backend.
17
+ *
18
+ * MockConnection does NOT manipulate the store directly.
19
+ * SyncLayer loads fixtures via `getFixtures()` and manages state itself.
20
+ */
21
+ export declare class MockConnection implements SyncLayerConnection {
22
+ private connected;
23
+ authState: "pending" | "authenticated" | "failed";
24
+ private messageHandlers;
25
+ private eventSubscriptions;
26
+ private subscriptions;
27
+ private latency;
28
+ private fixtures;
29
+ private mockVersion;
30
+ private messageIdCounter;
31
+ private autoReact;
32
+ private reactionDelay;
33
+ serviceCalls: Array<{
34
+ domain: string;
35
+ service: string;
36
+ serviceData?: Record<string, any>;
37
+ target?: any;
38
+ timestamp: number;
39
+ }>;
40
+ sentCommands: Array<{
41
+ type: string;
42
+ data?: any;
43
+ timestamp: number;
44
+ }>;
45
+ constructor(fixtures: Fixtures, latency?: number, options?: {
46
+ /** Enable automatic state reactions to service calls (default: true) */
47
+ autoReact?: boolean;
48
+ /** Delay before emitting entity update events after service calls in ms (default: 0) */
49
+ reactionDelay?: number;
50
+ });
51
+ /**
52
+ * Get connected state
53
+ */
54
+ get connected$(): boolean;
55
+ /**
56
+ * Simulate connection - sends auth_required per WebSocket spec
57
+ */
58
+ connect(): Promise<void>;
59
+ /**
60
+ * Register message handler for auth and other server messages
61
+ */
62
+ addEventListener(handler: (message: any) => void): () => void;
63
+ /**
64
+ * Handle authentication message (from client)
65
+ */
66
+ authenticate(_accessToken: string): Promise<void>;
67
+ /**
68
+ * Send auth_required message (server-initiated)
69
+ */
70
+ private sendAuthRequired;
71
+ /**
72
+ * Simulate disconnection
73
+ */
74
+ disconnect(): void;
75
+ /**
76
+ * Close connection (alias for disconnect for compatibility)
77
+ */
78
+ close(): void;
79
+ /**
80
+ * Send a message (mock implementation)
81
+ */
82
+ sendMessage(message: any): Promise<void>;
83
+ /**
84
+ * Call a service (mock implementation)
85
+ */
86
+ callService(domain: string, service: string, serviceData?: Record<string, any>, target?: any): Promise<any>;
87
+ /**
88
+ * Send a message and wait for response - returns proper WebSocket result format
89
+ */
90
+ sendMessagePromise<T>(message: any): Promise<T>;
91
+ /**
92
+ * Handle different message types and return appropriate data
93
+ */
94
+ private handleMessage;
95
+ /**
96
+ * Subscribe to events
97
+ */
98
+ subscribeEvents(callback: (event: any) => void, eventType?: string): Promise<() => void>;
99
+ /**
100
+ * Subscribe to WebSocket messages
101
+ *
102
+ * Used for subscribing to command responses like history/stream
103
+ *
104
+ * @param callback - Callback function for messages
105
+ * @param message - Message to subscribe to
106
+ * @returns Promise resolving to unsubscribe function
107
+ */
108
+ subscribeMessage<T>(callback: (message: T) => void, message: {
109
+ type: string;
110
+ [key: string]: unknown;
111
+ }): Promise<() => Promise<void>>;
112
+ /**
113
+ * Simulate state change
114
+ */
115
+ setState(entityId: string, updates: Partial<HassEntity>): void;
116
+ /**
117
+ * Simulate entity registry update
118
+ */
119
+ updateEntityRegistry(entityId: string, updates: Partial<EntityRegistryEntry>): void;
120
+ /**
121
+ * Simulate area registry update
122
+ */
123
+ updateAreaRegistry(areaId: string, updates: Partial<AreaRegistryEntry>): void;
124
+ /**
125
+ * Simulate device registry update
126
+ */
127
+ updateDeviceRegistry(deviceId: string, updates: Partial<DeviceRegistryEntry>): void;
128
+ /**
129
+ * Emit custom event - sends proper WebSocket event messages to subscriptions
130
+ */
131
+ emitEvent(event: HAEvent<any>): void;
132
+ /**
133
+ * Handle subscribe_events command
134
+ */
135
+ private handleSubscribeEvents;
136
+ /**
137
+ * Handle unsubscribe_events command
138
+ */
139
+ private handleUnsubscribeEvents;
140
+ /**
141
+ * Get current fixtures
142
+ *
143
+ * SyncLayer calls this to load fixtures into its store.
144
+ */
145
+ getFixtures(): Fixtures;
146
+ /**
147
+ * Load new fixtures
148
+ */
149
+ loadFixtures(fixtures: Partial<Fixtures>): void;
150
+ /**
151
+ * Clear tracking data
152
+ */
153
+ clearTracking(): void;
154
+ /**
155
+ * Get last service call
156
+ */
157
+ getLastServiceCall(): (typeof this.serviceCalls)[number] | undefined;
158
+ /**
159
+ * Get last command
160
+ */
161
+ getLastCommand(): (typeof this.sentCommands)[number] | undefined;
162
+ private delay;
163
+ private sendResponse;
164
+ private handleEntityUpdate;
165
+ private handleServiceCall;
166
+ /**
167
+ * Handle automatic reactions to service calls using behavior handlers
168
+ */
169
+ private handleServiceReaction;
170
+ /**
171
+ * Resolve target entities from service call target
172
+ */
173
+ private resolveTargetEntities;
174
+ /**
175
+ * Set state with custom context (internal use)
176
+ */
177
+ private setStateWithContext;
178
+ /**
179
+ * Enable/disable automatic reactions
180
+ */
181
+ setAutoReact(enabled: boolean): void;
182
+ /**
183
+ * Set reaction delay (useful for testing timing)
184
+ */
185
+ setReactionDelay(delay: number): void;
186
+ private generateId;
187
+ }
188
+ /**
189
+ * Export types
190
+ */
191
+ export type { Fixtures };
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Testing types
3
+ *
4
+ * Type definitions for testing utilities and mocks.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import type { AreaEntry, DeviceEntry, EntityRegistryEntry } from "@glasshome/ha-types";
9
+ import type { HassEntity } from "../core/types";
10
+ import type { EntityHistoryState } from "../history/types";
11
+ import type { WeatherForecast } from "../weather/types";
12
+ /**
13
+ * Area registry entry
14
+ *
15
+ * @alias AreaEntry
16
+ * @note AreaEntry uses 'id' field, not 'area_id'
17
+ */
18
+ export type AreaRegistryEntry = AreaEntry;
19
+ /**
20
+ * Device registry entry
21
+ *
22
+ * @alias DeviceEntry
23
+ */
24
+ export type DeviceRegistryEntry = DeviceEntry;
25
+ /**
26
+ * Floor registry entry
27
+ */
28
+ export interface FloorRegistryEntry {
29
+ floor_id: string;
30
+ name: string;
31
+ level: number;
32
+ icon: string | null;
33
+ aliases: string[];
34
+ created_at: string;
35
+ modified_at: string;
36
+ }
37
+ /**
38
+ * Label registry entry
39
+ */
40
+ export interface LabelRegistryEntry {
41
+ label_id: string;
42
+ name: string;
43
+ color: string | null;
44
+ icon: string | null;
45
+ description: string | null;
46
+ created_at: string;
47
+ modified_at: string;
48
+ }
49
+ /**
50
+ * Fixture data for testing
51
+ */
52
+ export interface Fixtures {
53
+ /** Entity states */
54
+ entities: Record<string, HassEntity>;
55
+ /** Entity registry */
56
+ entityRegistry: EntityRegistryEntry[];
57
+ /** Device registry */
58
+ deviceRegistry: DeviceRegistryEntry[];
59
+ /** Area registry */
60
+ areaRegistry: AreaRegistryEntry[];
61
+ /** Floor registry */
62
+ floorRegistry: FloorRegistryEntry[];
63
+ /** Label registry */
64
+ labelRegistry: LabelRegistryEntry[];
65
+ /** History data for entities (entityId -> history states array) */
66
+ history?: Record<string, EntityHistoryState[]>;
67
+ /** Weather forecasts data (entityId -> forecastType -> forecast array) */
68
+ forecasts?: Record<string, Record<string, WeatherForecast[]>>;
69
+ }
70
+ /**
71
+ * Options for simulating state changes
72
+ */
73
+ export interface StateChangeOptions {
74
+ /** Delay before emitting (ms) */
75
+ delay?: number;
76
+ /** Only update specific attributes */
77
+ attributesOnly?: boolean;
78
+ }
79
+ /**
80
+ * Options for simulating registry updates
81
+ */
82
+ export interface RegistryUpdateOptions {
83
+ /** Delay before emitting (ms) */
84
+ delay?: number;
85
+ /** Emit event immediately */
86
+ immediate?: boolean;
87
+ }
@@ -0,0 +1,10 @@
1
+ //#region src/core/types.ts
2
+ /**
3
+ * Extract domain from entity ID
4
+ */
5
+ function extractDomain(entityId) {
6
+ return entityId.split(".")[0] ?? "";
7
+ }
8
+
9
+ //#endregion
10
+ export { extractDomain };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Weather Forecast Fetching
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ import type { EntityId } from "../core/types";
7
+ import type { ForecastType, WeatherForecast, WeatherForecastData, WeatherForecastsData } from "./types";
8
+ /**
9
+ * Fetch forecast for a single entity and type
10
+ */
11
+ export declare function fetchForecast(entityId: EntityId, type: ForecastType): Promise<WeatherForecast[]>;
12
+ /**
13
+ * Fetch forecasts for a single entity and multiple types
14
+ */
15
+ export declare function fetchForecasts(entityId: EntityId, types: ForecastType[]): Promise<WeatherForecastsData>;
16
+ /**
17
+ * Fetch forecast data with error handling
18
+ */
19
+ export declare function fetchForecastData(entityId: EntityId, type: ForecastType): Promise<WeatherForecastData>;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Weather Forecast Query Builder
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ import type { EntityId } from "../core/types";
7
+ import type { ForecastType, WeatherForecastData, WeatherForecastsData } from "./types";
8
+ /**
9
+ * Get forecast for a single entity and type
10
+ */
11
+ export declare function getForecast(entityId: EntityId, type: ForecastType): Promise<WeatherForecastData>;
12
+ /**
13
+ * Get forecasts for a single entity and multiple types
14
+ */
15
+ export declare function getForecasts(entityId: EntityId, types: ForecastType[]): Promise<WeatherForecastsData>;
16
+ /**
17
+ * Refresh forecast
18
+ */
19
+ export declare function refreshForecast(entityId: EntityId, type: ForecastType): Promise<WeatherForecastData>;
20
+ /**
21
+ * Refresh forecasts
22
+ */
23
+ export declare function refreshForecasts(entityId: EntityId, types: ForecastType[]): Promise<WeatherForecastsData>;