mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 03:38:47 +00:00
73 lines
2.7 KiB
TypeScript
73 lines
2.7 KiB
TypeScript
import {
|
|
commitHouseplanViewport, disposeHouseplanViewport, scheduleHouseplanViewport,
|
|
} from './live-viewport';
|
|
import { resetHouseplanHover, syncHouseplanHover } from './live-hover';
|
|
import {
|
|
classifyHassRenderChange, type HassRenderDependencies, type HassRenderSnapshot,
|
|
} from './render-invalidation';
|
|
import type { RenderLifecycle } from './houseplan-render-lifecycle';
|
|
|
|
interface LiveRuntimeHost {
|
|
_renderLife: RenderLifecycle;
|
|
_pointers: { size: number };
|
|
_cameraTransition: { active: boolean };
|
|
_deviceDrag?: unknown;
|
|
_physicalDrag?: unknown;
|
|
_physicalRotate?: unknown;
|
|
_decorMove?: unknown;
|
|
_decorDraft?: unknown;
|
|
_dtDrag?: unknown;
|
|
_bdDrag?: unknown;
|
|
_opDrag?: unknown;
|
|
_resize?: { dragging: boolean };
|
|
}
|
|
|
|
/** Lazily loaded DOM-only fast paths; the card keeps a full-render fallback. */
|
|
export class LiveRuntime {
|
|
private deferredHass = false;
|
|
public constructor(private readonly host: object) {}
|
|
public hass(
|
|
before: HassRenderSnapshot | null | undefined,
|
|
after: HassRenderSnapshot | null | undefined,
|
|
dependencies: HassRenderDependencies | null,
|
|
intake: () => void,
|
|
): boolean {
|
|
const change = classifyHassRenderChange(before, after, dependencies);
|
|
const defer = change === 'state' && this.active();
|
|
if (defer) this.deferredHass = true;
|
|
const render = change !== 'none' && !defer;
|
|
// Preserve ReactiveElement's ordering for snapshots which are about to
|
|
// render: willUpdate owns their intake. Tests, config editors and HA can
|
|
// legitimately finish other same-turn mutations after assigning `hass`.
|
|
// Only a deliberately skipped update needs operational intake here.
|
|
if (!render) {
|
|
(this.host as LiveRuntimeHost)._renderLife.observe(before, after, dependencies, intake);
|
|
}
|
|
return render;
|
|
}
|
|
public clear(): void { this.deferredHass = false; }
|
|
public take(): boolean {
|
|
const pending = this.deferredHass;
|
|
this.deferredHass = false;
|
|
return pending;
|
|
}
|
|
public viewport(now = false): void { scheduleHouseplanViewport(this.host, now); }
|
|
public hover(): void { syncHouseplanHover(this.host); }
|
|
public active(): boolean {
|
|
const host = this.host as LiveRuntimeHost;
|
|
return host._pointers.size > 0 || host._cameraTransition.active || !!host._deviceDrag
|
|
|| !!host._physicalDrag || !!host._physicalRotate || !!host._decorMove
|
|
|| !!host._decorDraft || !!host._dtDrag || !!host._bdDrag || !!host._opDrag
|
|
|| !!host._resize?.dragging;
|
|
}
|
|
public commit(): void {
|
|
commitHouseplanViewport(this.host);
|
|
resetHouseplanHover(this.host);
|
|
syncHouseplanHover(this.host);
|
|
}
|
|
public dispose(): void {
|
|
disposeHouseplanViewport(this.host);
|
|
resetHouseplanHover(this.host);
|
|
}
|
|
}
|