import type { ReactiveController, ReactiveControllerHost } from 'lit';
import type { SyncedState } from '@u-devtools/core';
/**
* Lit adapter for SyncedState.
* Works as a Reactive Controller.
* Automatically calls requestUpdate() on component when state changes.
*
* @template T - State value type
*
* @example
* ```typescript
* import { useBridgeState } from '@u-devtools/kit/lit';
* import { useDevTools } from './context';
*
* class MyElement extends LitElement {
* private bridge = useDevTools().bridge;
* private isOpen = useBridgeState(this, this.bridge.state('isOpen', false));
*
* render() {
* return html`
*
* `;
* }
* }
* ```
*/
export class BridgeStateController implements ReactiveController {
private _cleanup?: () => void;
constructor(
protected host: ReactiveControllerHost,
protected syncedState: SyncedState
) {
host.addController(this);
}
hostConnected() {
this._cleanup = this.syncedState.subscribe(() => {
this.host.requestUpdate();
});
}
hostDisconnected() {
if (this._cleanup) {
this._cleanup();
this._cleanup = undefined;
}
}
get value(): T {
return this.syncedState.value;
}
set value(v: T) {
this.syncedState.value = v;
}
}
/**
* Helper for creating controller (for convenience)
*
* @template T - State value type
* @param host - ReactiveControllerHost (usually LitElement)
* @param syncedState - SyncedState instance to synchronize
* @returns BridgeStateController instance
*
* @example
* ```typescript
* class MyElement extends LitElement {
* private isOpen = useBridgeState(this, bridge.state('isOpen', false));
* }
* ```
*/
export function useBridgeState(
host: ReactiveControllerHost,
syncedState: SyncedState
): BridgeStateController {
return new BridgeStateController(host, syncedState);
}