mock dashboard + 2 way sync in nanostores (i hate ctx)
This commit is contained in:
parent
d792cec873
commit
31594891e5
5 changed files with 150 additions and 70 deletions
|
@ -1,17 +1,67 @@
|
|||
import { isServer, noSerialize, useSignal, type NoSerialize } from '@builder.io/qwik';
|
||||
import type { ReadableAtom } from 'nanostores';
|
||||
import {
|
||||
implicit$FirstArg,
|
||||
noSerialize,
|
||||
NoSerialize,
|
||||
QRL,
|
||||
Signal,
|
||||
useSignal,
|
||||
useTask$,
|
||||
useVisibleTask$,
|
||||
} from "@builder.io/qwik";
|
||||
import { Atom, WritableAtom } from "nanostores";
|
||||
|
||||
export function useNanostore<T>(atom: ReadableAtom<T>) {
|
||||
if (isServer) return
|
||||
function writeable<T = any>(store: Atom<T> | WritableAtom<T>): store is WritableAtom<T> {
|
||||
return typeof (store as WritableAtom<T>).set === 'function';
|
||||
}
|
||||
|
||||
const state = useSignal<T>(atom.get());
|
||||
const store = useSignal<NoSerialize<ReadableAtom<T>> | undefined>(undefined);
|
||||
export function useNanostoreQrl<T>(qrl: QRL<WritableAtom<T> | Atom<T>>): Signal<T> {
|
||||
const signal = useSignal<T | undefined>(undefined);
|
||||
const storeSignal = useSignal<NoSerialize<WritableAtom<T> | Atom<T>> | undefined>(undefined);
|
||||
|
||||
store.value = noSerialize(atom);
|
||||
const unsubscribe = atom.subscribe((value) => {
|
||||
state.value = value;
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('beforeunload', () => unsubscribe());
|
||||
return state;
|
||||
}
|
||||
// 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);
|
Loading…
Add table
Add a link
Reference in a new issue