preact-homeassistant 0.2.2 → 0.3.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.
- package/dist/index.d.ts +104 -20
- package/dist/index.js +222 -158
- package/dist/index.js.map +1 -1
- package/package.json +32 -15
- package/src/HAContext.tsx +162 -120
- package/src/__tests__/cacheUtils.test.ts +23 -48
- package/src/__tests__/registerPreactCard.test.tsx +75 -0
- package/src/__tests__/testHelpers.tsx +11 -1
- package/src/__tests__/useCachedFetch.test.tsx +57 -33
- package/src/__tests__/{useMultiCalendarEvents.test.tsx → useCalendarEvents.test.tsx} +3 -4
- package/src/__tests__/useEntity.test.tsx +11 -17
- package/src/__tests__/useHassValue.test.tsx +99 -0
- package/src/cacheUtils.ts +12 -24
- package/src/index.ts +3 -2
- package/src/registerPreactCard.tsx +101 -32
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,13 @@ import { HassEntityAttributeBase } from 'home-assistant-js-websocket';
|
|
|
8
8
|
import { HassEntityBase } from 'home-assistant-js-websocket';
|
|
9
9
|
import { HassServices } from 'home-assistant-js-websocket';
|
|
10
10
|
import { JSX } from 'preact';
|
|
11
|
+
import { RefObject } from 'preact';
|
|
12
|
+
|
|
13
|
+
declare type Cache_2 = Map<string, CacheEntry<unknown>>;
|
|
14
|
+
|
|
15
|
+
declare interface CacheEntry<T> {
|
|
16
|
+
data: T;
|
|
17
|
+
}
|
|
11
18
|
|
|
12
19
|
/**
|
|
13
20
|
* Calendar entity - only exposes the current/next event.
|
|
@@ -74,6 +81,11 @@ export declare interface DomainServiceMap {
|
|
|
74
81
|
fan: FanServices;
|
|
75
82
|
}
|
|
76
83
|
|
|
84
|
+
export declare interface ElementSize {
|
|
85
|
+
width: number;
|
|
86
|
+
height: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
77
89
|
/**
|
|
78
90
|
* Infers the strict entity type from an entity ID literal type.
|
|
79
91
|
*
|
|
@@ -141,11 +153,13 @@ export declare type ForecastType = 'daily' | 'hourly' | 'twice_daily';
|
|
|
141
153
|
*/
|
|
142
154
|
export declare function getAllStyles(): string;
|
|
143
155
|
|
|
144
|
-
export declare function HAProvider({ hass, subscribeToEntity, children }: HAProviderProps): JSX.Element;
|
|
156
|
+
export declare function HAProvider({ hass, subscribeToEntity, subscribeToHass, cache, children, }: HAProviderProps): JSX.Element;
|
|
145
157
|
|
|
146
158
|
declare interface HAProviderProps {
|
|
147
159
|
hass: HomeAssistant | undefined;
|
|
148
160
|
subscribeToEntity: (entityId: string, callback: (entity: any) => void) => () => void;
|
|
161
|
+
subscribeToHass?: SubscribeToHass;
|
|
162
|
+
cache?: Cache_2;
|
|
149
163
|
children: ComponentChildren;
|
|
150
164
|
}
|
|
151
165
|
|
|
@@ -168,8 +182,6 @@ declare type KnownDomain = keyof DomainEntityMap;
|
|
|
168
182
|
|
|
169
183
|
declare type KnownServiceDomain = keyof DomainServiceMap;
|
|
170
184
|
|
|
171
|
-
export declare function loadFromCache<T>(key: string): T | undefined;
|
|
172
|
-
|
|
173
185
|
export declare function registerPreactCard<TConfig>(options: RegisterPreactCardOptions<TConfig>): void;
|
|
174
186
|
|
|
175
187
|
declare interface RegisterPreactCardOptions<TConfig> {
|
|
@@ -194,7 +206,7 @@ declare interface RegisterPreactCardOptions<TConfig> {
|
|
|
194
206
|
*/
|
|
195
207
|
export declare function registerRawStyles(styles: string): void;
|
|
196
208
|
|
|
197
|
-
export declare
|
|
209
|
+
export declare type ResizeCallback = (size: ElementSize) => void;
|
|
198
210
|
|
|
199
211
|
declare type ServiceCaller<T extends string> = <S extends keyof ServicesForId<T> & string>(service: S, ...args: ServicesForId<T>[S] extends undefined ? [] : Record<string, never> extends Exclude<ServicesForId<T>[S], undefined> ? [data?: ServicesForId<T>[S]] : [data: ServicesForId<T>[S]]) => Promise<void>;
|
|
200
212
|
|
|
@@ -206,6 +218,8 @@ declare type ServiceCaller<T extends string> = <S extends keyof ServicesForId<T>
|
|
|
206
218
|
*/
|
|
207
219
|
export declare type ServicesForId<T extends string> = T extends `${infer D}.${string}` ? D extends KnownServiceDomain ? DomainServiceMap[D] : Record<string, Record<string, unknown> | undefined> : Record<string, Record<string, unknown> | undefined>;
|
|
208
220
|
|
|
221
|
+
declare type SubscribeToHass = (callback: () => void) => () => void;
|
|
222
|
+
|
|
209
223
|
/**
|
|
210
224
|
* Sun entity - provides sunrise/sunset and elevation information.
|
|
211
225
|
*/
|
|
@@ -239,18 +253,29 @@ declare interface UseCachedFetchResult<T> {
|
|
|
239
253
|
}
|
|
240
254
|
|
|
241
255
|
/**
|
|
242
|
-
* Fetch
|
|
256
|
+
* Fetch events from one or more calendars for a date range, with in-memory
|
|
257
|
+
* (per-card) caching and stale-while-revalidate behavior. Events are tagged
|
|
258
|
+
* with their source calendar ID. Returns `prefetch` to warm adjacent ranges.
|
|
243
259
|
*/
|
|
244
|
-
export declare function useCalendarEvents(
|
|
260
|
+
export declare function useCalendarEvents(entityIds: `calendar.${string}`[], options: {
|
|
245
261
|
start: Date;
|
|
246
262
|
end: Date;
|
|
247
263
|
}): UseCalendarEventsResult;
|
|
248
264
|
|
|
249
265
|
declare interface UseCalendarEventsResult {
|
|
250
|
-
events:
|
|
251
|
-
|
|
266
|
+
events: CalendarEventWithSource[] | undefined;
|
|
267
|
+
status: FetchStatus;
|
|
252
268
|
error: Error | undefined;
|
|
253
269
|
refetch: () => void;
|
|
270
|
+
/**
|
|
271
|
+
* Warm the cache for an arbitrary range (e.g. adjacent months) without
|
|
272
|
+
* touching component state. Best-effort: skips ranges already cached and
|
|
273
|
+
* swallows failures.
|
|
274
|
+
*/
|
|
275
|
+
prefetch: (range: {
|
|
276
|
+
start: Date;
|
|
277
|
+
end: Date;
|
|
278
|
+
}) => void;
|
|
254
279
|
}
|
|
255
280
|
|
|
256
281
|
/**
|
|
@@ -262,6 +287,9 @@ declare interface UseCalendarEventsResult {
|
|
|
262
287
|
*/
|
|
263
288
|
export declare function useCallbackStable<T extends (...args: never[]) => unknown>(callback: T): T;
|
|
264
289
|
|
|
290
|
+
/** Re-renders when the active theme's dark mode flips. */
|
|
291
|
+
export declare function useDarkMode(): boolean;
|
|
292
|
+
|
|
265
293
|
/**
|
|
266
294
|
* Subscribe to a specific entity by ID. Re-renders only when that entity changes.
|
|
267
295
|
*
|
|
@@ -281,21 +309,50 @@ export declare function useHass(): {
|
|
|
281
309
|
getHass: () => HomeAssistant | undefined;
|
|
282
310
|
};
|
|
283
311
|
|
|
312
|
+
/** Re-renders when `hass.config` changes (units, latitude/longitude, etc.). */
|
|
313
|
+
export declare function useHassConfig(): HomeAssistant['config'] | undefined;
|
|
314
|
+
|
|
284
315
|
/**
|
|
285
|
-
*
|
|
286
|
-
*
|
|
316
|
+
* Subscribe to a derived slice of the `hass` object (e.g. config, themes) and
|
|
317
|
+
* re-render only when that slice changes. Use this for non-entity values —
|
|
318
|
+
* entity state goes through `useEntity`. The selector runs on every hass update
|
|
319
|
+
* but only re-renders the consumer when `isEqual` reports a change, so it's
|
|
320
|
+
* cheap for rarely-changing values like config/themes.
|
|
287
321
|
*/
|
|
288
|
-
export declare function
|
|
289
|
-
start: Date;
|
|
290
|
-
end: Date;
|
|
291
|
-
}): UseMultiCalendarEventsResult;
|
|
322
|
+
export declare function useHassValue<T>(selector: (hass: HomeAssistant | undefined) => T, isEqual?: (a: T, b: T) => boolean): T;
|
|
292
323
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
324
|
+
/**
|
|
325
|
+
* Observe an element's size via ResizeObserver. The callback fires:
|
|
326
|
+
*
|
|
327
|
+
* 1. Once after mount, with the element's current size.
|
|
328
|
+
* 2. Whenever the element's size changes.
|
|
329
|
+
* 3. Whenever `deps` change, re-firing with the current size — so callers
|
|
330
|
+
* can re-run draws when their inputs change without re-creating the
|
|
331
|
+
* observer.
|
|
332
|
+
*
|
|
333
|
+
* The callback is suppressed only while the element is detached from the
|
|
334
|
+
* document. Zero width/height is delivered to the callback as-is — consumers
|
|
335
|
+
* that need to skip degenerate sizes (e.g. canvas painters where a 0-sized
|
|
336
|
+
* drawImage throws InvalidStateError) should add their own early return.
|
|
337
|
+
*
|
|
338
|
+
* Sizes are read from `offsetWidth` / `offsetHeight` (CSS pixels, includes
|
|
339
|
+
* padding + border). The callback is held in a ref, so passing a fresh
|
|
340
|
+
* function each render is safe — it never re-creates the observer.
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* const containerRef = useRef<HTMLDivElement>(null);
|
|
344
|
+
* const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
345
|
+
*
|
|
346
|
+
* useResizeObserver(
|
|
347
|
+
* containerRef,
|
|
348
|
+
* ({ width, height }) => {
|
|
349
|
+
* if (width === 0 || height === 0) return; // optional, consumer's call
|
|
350
|
+
* drawChart(canvasRef.current, forecast, width, height);
|
|
351
|
+
* },
|
|
352
|
+
* [forecast],
|
|
353
|
+
* );
|
|
354
|
+
*/
|
|
355
|
+
export declare function useResizeObserver<T extends HTMLElement>(ref: RefObject<T>, callback: ResizeCallback, deps?: unknown[]): void;
|
|
299
356
|
|
|
300
357
|
/**
|
|
301
358
|
* Returns a stable function that calls services on a specific HA entity.
|
|
@@ -323,6 +380,33 @@ declare interface UseWeatherForecastResult {
|
|
|
323
380
|
refetch: () => void;
|
|
324
381
|
}
|
|
325
382
|
|
|
383
|
+
/**
|
|
384
|
+
* Track the current width of a referenced element in CSS pixels.
|
|
385
|
+
*
|
|
386
|
+
* Returns `undefined` until the first non-zero measurement is observed, then
|
|
387
|
+
* a positive number that updates as the element resizes. Once a real width
|
|
388
|
+
* is captured the hook will never report `undefined` or `0` again, even
|
|
389
|
+
* during HA layout transitions (dashboard switch, edit-mode toggle) — the
|
|
390
|
+
* underlying ResizeObserver firings are silently dropped while the element
|
|
391
|
+
* is detached or transiently zero-width, so the component renders with the
|
|
392
|
+
* last good value instead of flashing through a degenerate state.
|
|
393
|
+
*
|
|
394
|
+
* Use this when you need a width value in JSX (responsive layout, prop to a
|
|
395
|
+
* sized child). If you only need the value imperatively inside a draw
|
|
396
|
+
* callback, prefer `useResizeObserver` directly — it doesn't allocate
|
|
397
|
+
* component state or cause re-renders.
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* const ref = useRef<HTMLDivElement>(null);
|
|
401
|
+
* const width = useWidth(ref);
|
|
402
|
+
* return (
|
|
403
|
+
* <div ref={ref}>
|
|
404
|
+
* {width !== undefined && <Chart width={width} />}
|
|
405
|
+
* </div>
|
|
406
|
+
* );
|
|
407
|
+
*/
|
|
408
|
+
export declare function useWidth<T extends HTMLElement>(ref: RefObject<T>): number | undefined;
|
|
409
|
+
|
|
326
410
|
/**
|
|
327
411
|
* Weather entity - current conditions only.
|
|
328
412
|
* Use useWeatherForecast() to fetch forecast data.
|