2023-03-28 14:34:01 +00:00
|
|
|
import { useSyncExternalStore } from "react";
|
2023-05-30 13:48:38 +00:00
|
|
|
import { RequestBuilder } from "System";
|
2023-03-28 15:41:57 +00:00
|
|
|
import { EmptySnapshot, NoteStore, StoreSnapshot } from "System/NoteCollection";
|
2023-05-24 10:12:23 +00:00
|
|
|
import { unwrap } from "SnortUtils";
|
2023-05-30 13:48:38 +00:00
|
|
|
import { System } from "index";
|
2023-03-28 14:34:01 +00:00
|
|
|
|
|
|
|
const useRequestBuilder = <TStore extends NoteStore, TSnapshot = ReturnType<TStore["getSnapshotData"]>>(
|
|
|
|
type: { new (): TStore },
|
|
|
|
rb: RequestBuilder | null,
|
|
|
|
debounced?: number
|
|
|
|
) => {
|
|
|
|
const subscribe = (onChanged: () => void) => {
|
2023-06-01 08:54:25 +00:00
|
|
|
const store = (System.Query<TStore>(type, rb)?.feed as TStore) ?? new type();
|
2023-03-28 14:34:01 +00:00
|
|
|
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) {
|
2023-06-01 08:54:25 +00:00
|
|
|
System.GetQuery(rb.id)?.cancel();
|
2023-03-28 14:34:01 +00:00
|
|
|
}
|
|
|
|
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;
|