snort/packages/app/src/Hooks/useRequestBuilder.tsx

47 lines
1.3 KiB
TypeScript
Raw Normal View History

2023-03-28 14:34:01 +00:00
import { useSyncExternalStore } from "react";
import { RequestBuilder, System } from "System";
2023-03-28 15:41:57 +00:00
import { EmptySnapshot, NoteStore, StoreSnapshot } from "System/NoteCollection";
2023-03-28 14:34:01 +00:00
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 getState = (): StoreSnapshot<TSnapshot> => {
if (rb?.id) {
2023-04-06 21:37:40 +00:00
const q = System.GetQuery(rb.id);
if (q) {
return unwrap(q).feed?.snapshot as StoreSnapshot<TSnapshot>;
2023-03-28 14:34:01 +00:00
}
}
2023-03-28 15:41:57 +00:00
return EmptySnapshot as StoreSnapshot<TSnapshot>;
2023-03-28 14:34:01 +00:00
};
return useSyncExternalStore<StoreSnapshot<TSnapshot>>(
v => subscribe(v),
() => getState()
);
};
export default useRequestBuilder;