Files
snort/packages/app/src/Hooks/useRequestBuilder.tsx
2023-03-28 15:34:01 +01:00

51 lines
1.3 KiB
TypeScript

import { useSyncExternalStore } from "react";
import { RequestBuilder, System } from "System";
import { FlatNoteStore, NoteStore, StoreSnapshot } from "System/NoteCollection";
import { unwrap } from "Util";
const useRequestBuilder = <TStore extends NoteStore, TSnapshot = ReturnType<TStore["getSnapshotData"]>>(
type: { new (): TStore },
rb: RequestBuilder | null,
debounced?: number
) => {
const subscribe = (onChanged: () => void) => {
const store = System.Query<TStore>(type, rb);
let t: ReturnType<typeof setTimeout> | undefined;
const release = store.hook(() => {
if (!t) {
t = setTimeout(() => {
clearTimeout(t);
t = undefined;
onChanged();
}, debounced ?? 500);
}
});
return () => {
if (rb?.id) {
System.CancelQuery(rb.id);
}
release();
};
};
const emptyStore = {
data: undefined,
store: new FlatNoteStore(),
} as StoreSnapshot<TSnapshot>;
const getState = (): StoreSnapshot<TSnapshot> => {
if (rb?.id) {
const feed = System.GetFeed(rb.id);
if (feed) {
return unwrap(feed).snapshot as StoreSnapshot<TSnapshot>;
}
}
return emptyStore;
};
return useSyncExternalStore<StoreSnapshot<TSnapshot>>(
v => subscribe(v),
() => getState()
);
};
export default useRequestBuilder;