refactor: RequestBuilder
This commit is contained in:
50
packages/app/src/Hooks/useRequestBuilder.tsx
Normal file
50
packages/app/src/Hooks/useRequestBuilder.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
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;
|
Reference in New Issue
Block a user