67 lines
No EOL
1.9 KiB
TypeScript
67 lines
No EOL
1.9 KiB
TypeScript
import {
|
|
implicit$FirstArg,
|
|
noSerialize,
|
|
NoSerialize,
|
|
QRL,
|
|
Signal,
|
|
useSignal,
|
|
useTask$,
|
|
useVisibleTask$,
|
|
} from "@builder.io/qwik";
|
|
import { Atom, WritableAtom } from "nanostores";
|
|
|
|
function writeable<T>(store: Atom<T> | WritableAtom<T>): store is WritableAtom<T> {
|
|
return typeof (store as WritableAtom<T>).set === 'function';
|
|
}
|
|
|
|
export function useNanostoreQrl<T>(qrl: QRL<WritableAtom<T> | Atom<T>>, defaultValue?: T): Signal<T> {
|
|
const signal = useSignal<T | undefined>(defaultValue);
|
|
const storeSignal = useSignal<NoSerialize<WritableAtom<T> | Atom<T>> | undefined>(undefined);
|
|
|
|
useTask$(async ({ track }) => {
|
|
let store: WritableAtom<T> | Atom<T> | undefined = storeSignal.value;
|
|
|
|
if (!store) {
|
|
const modified = await qrl.resolve();
|
|
storeSignal.value = noSerialize(modified);
|
|
store = modified;
|
|
}
|
|
|
|
if (signal.value === undefined && store.value !== undefined) {
|
|
signal.value = store.value;
|
|
}
|
|
|
|
const v = track(signal);
|
|
|
|
if (writeable(store) && v !== undefined && store.value !== v) {
|
|
store.set(v);
|
|
}
|
|
});
|
|
|
|
// eslint-disable-next-line qwik/no-use-visible-task
|
|
useVisibleTask$(async ({ cleanup }) => {
|
|
let store: WritableAtom<T> | Atom<T> | undefined = storeSignal.value;
|
|
|
|
if (!store) {
|
|
const modified = await qrl.resolve();
|
|
storeSignal.value = noSerialize(modified);
|
|
store = modified;
|
|
}
|
|
|
|
if (store.value !== undefined && signal.value !== store.value) {
|
|
signal.value = store.value;
|
|
}
|
|
|
|
const unsub = store.subscribe((value) => {
|
|
if (signal.value !== value) {
|
|
signal.value = value;
|
|
}
|
|
});
|
|
|
|
cleanup(unsub);
|
|
});
|
|
|
|
return signal as Signal<T>;
|
|
}
|
|
|
|
export const useNanostore$ = implicit$FirstArg(useNanostoreQrl); |