import { AsyncMutableRefObject, createAsyncRef } from "async-ref"; import { GetValueFromKeyPath, KeyPath, Subscriber, Unsubscribe, ExternalStore, Notifier } from "../types"; import { Backend } from "./types"; export abstract class AbstractBackend implements Backend { public abstract getSnapshot, T extends GetValueFromKeyPath>(keyPath: KP, defaultValue: T): T; public getServerSnapshot, T extends GetValueFromKeyPath>(keyPath: KP, defaultValue: T): T { return this.getSnapshot(keyPath, defaultValue); } public notify: Notifier = () => this.#listeners.forEach((sub) => sub()); public get name() { return this.constructor.name; } public toExternalStore, T extends GetValueFromKeyPath>(keyPath: KP, defaultValue: T): ExternalStore { const subscribe = this.#subscribe; const getSnapshot = () => this.getSnapshot(keyPath, defaultValue); const getServerSnapshot = () => this.getServerSnapshot(keyPath, defaultValue); return { subscribe, getSnapshot, getServerSnapshot, }; } #listeners = new Set(); #subscribe = (sub: Subscriber): Unsubscribe => { this.#listeners.add(sub); return () => this.#listeners.delete(sub); }; protected createAsyncRef(): AsyncMutableRefObject { return createAsyncRef(this.notify); } }