import { AsyncDirective, PartInfo } from "lit/async-directive.js"; import { directive } from "lit/directive.js"; import { noChange } from "lit"; import { SearchableDomElement } from "../utils/HTML"; import { getObservables, get as pubGet, set as pubSet, dataProvider as pubDataProvider , dp as pubDp, DataProvider } from "../utils/PublisherProxy"; class ObserveDirective extends AsyncDirective { observables: Set> = new Set(); unsubscribe(): void { this.observables.forEach((publisher: DataProvider) => publisher.offAssign(this.onAssign) ); } observable?: string; node?: SearchableDomElement; /* eslint-disable @typescript-eslint/no-explicit-any*/ constructor(partInfo: any) { super(partInfo as PartInfo); this.node = partInfo.options?.host; } /* eslint-enable @typescript-eslint/no-explicit-any*/ render(observable: string) { if (this.observable !== observable) { this.observable = observable; if (this.isConnected) { this.subscribe(observable); } } return noChange; } onAssign = (v: unknown) => { this.setValue(v); }; // Subscribes to the observable, calling the directive's asynchronous // setValue API each time the value changes subscribe(observable: string) { this.unsubscribe(); this.onAssign = (v: unknown) => { this.setValue(v); }; this.observables = getObservables(observable); this.observables.forEach((publisher) => { publisher.onAssign(this.onAssign); }); } // When the directive is disconnected from the DOM, unsubscribe to ensure // the directive instance can be garbage collected disconnected() { this.unsubscribe(); } // If the subtree the directive is in was disconnected and subsequently // re-connected, re-subscribe to make the directive operable again reconnected() { if (!this.observable) return; this.subscribe(this.observable); } } const dir = directive(ObserveDirective); // //autoUpdate directive export const subscribe = dir; export const sub = dir; /** * @deprecated @see {@link "/src/core/utils/PublisherProxy.ts#get"} * @param id Observable * @returns value of the observable * */ export const get: (id: string) => T = pubGet; /** * @deprecated @see {@link "/src/core/utils/PublisherProxy.ts#dataProvider"} * @param id Observable * @param defaultValue Optional default value * @returns Observable */ export const dataProvider = pubDataProvider; /** * @deprecated @see {@link "/src/core/utils/PublisherProxy.ts#dp"} * @param id Observable * @param defaultValue Optional default value * @returns Observable */ export const dp = pubDp; /** * @deprecated @see {@link "/src/core/utils/PublisherProxy.ts#set"} * @param id Observable * @param value value to set * @returns void */ export const set: (id: string, value: T) => void = pubSet;