import type { ConnectedLdoDataset, ConnectedPlugin, GetResourceReturnType, } from "@ldo/connected"; import { writable, type Readable } from "svelte/store"; export interface UseResourceOptions { pluginName?: Name; suppressInitialRead?: boolean; reloadOnMount?: boolean; subscribe?: boolean; } export type useResourceType = { < Name extends Plugins[number]["name"], Plugin extends Extract, UriType extends string, >( uri: UriType, options?: UseResourceOptions, ): Readable>; < Name extends Plugins[number]["name"], Plugin extends Extract, UriType extends string, >( uri?: UriType, options?: UseResourceOptions, ): Readable | undefined>; }; /** * @internal * * Creates a useResource function. */ export function createUseResource( dataset: ConnectedLdoDataset, ): useResourceType { /** * Returns a resource and triggers a rerender if that resource is updated. */ return function useResource< Name extends Plugins[number]["name"], Plugin extends Extract, UriType extends string, >( uri?: UriType, options?: UseResourceOptions, ): Readable | undefined> { let resource: GetResourceReturnType | undefined; // Get the resource based on incoming data if (uri) { // eslint-disable-next-line @typescript-eslint/no-explicit-any resource = dataset.getResource(uri) as any; // Run read operations if necissary if (!options?.suppressInitialRead) { if (options?.reloadOnMount) { resource!.read(); } else { resource!.readIfUnfetched(); } } } else { resource = undefined; } // The Svelte store const store = writable | undefined>( resource, (set) => { const onResourceUpdate = () => { set(resource); }; if (resource) { resource.on("update", onResourceUpdate); // TODO: handle subscriptions return () => { resource.off("update", onResourceUpdate); }; } }, ); return { subscribe: store.subscribe, }; }; }