refactor: move directory

This commit is contained in:
Shusui MOYATANI
2023-03-08 13:33:55 +09:00
parent 3228f401ae
commit adbee3e174
24 changed files with 137 additions and 43 deletions

View File

@@ -0,0 +1,95 @@
import { createSignal, createMemo, type Signal, type Accessor } from 'solid-js';
import { type Event as NostrEvent, type Filter } from 'nostr-tools';
import useConfig from '@/nostr/useConfig';
import useBatch, { type Task } from '@/nostr/useBatch';
import useSubscription from '@/nostr/useSubscription';
export type UseBatchedEventsProps<TaskArgs> = {
interval?: number;
generateKey: (args: TaskArgs) => string | number;
mergeFilters: (args: TaskArgs[]) => Filter[];
extractKey: (event: NostrEvent) => string | number | undefined;
};
export type BatchedEvents = {
events: NostrEvent[];
completed: boolean;
};
const emptyBatchedEvents = () => ({ completed: true, events: [] });
const completeBatchedEvents = (current: BatchedEvents): BatchedEvents => ({
...current,
completed: true,
});
const addEvent =
(event: NostrEvent) =>
(current: BatchedEvents): BatchedEvents => ({
...current,
events: [...current.events, event],
});
const useBatchedEvents = <TaskArgs>(propsProvider: () => UseBatchedEventsProps<TaskArgs>) => {
const props = createMemo(propsProvider);
return useBatch<TaskArgs, Accessor<BatchedEvents>>(() => ({
interval: props().interval,
executor: (tasks) => {
const { generateKey, mergeFilters, extractKey } = props();
// TODO relayUrlsを考慮する
const [config] = useConfig();
const keyTaskMap = new Map<string | number, Task<TaskArgs, Accessor<BatchedEvents>>>(
tasks.map((task) => [generateKey(task.args), task]),
);
const filters = mergeFilters(tasks.map((task) => task.args));
const keyEventSignalsMap = new Map<string | number, Signal<BatchedEvents>>();
const getSignalForKey = (key: string | number): Signal<BatchedEvents> => {
const eventsSignal =
keyEventSignalsMap.get(key) ??
createSignal<BatchedEvents>({
events: [],
completed: false,
});
keyEventSignalsMap.set(key, eventsSignal);
return eventsSignal;
};
const didReceivedEventsForKey = (key: string | number): boolean =>
keyEventSignalsMap.has(key);
useSubscription(() => ({
relayUrls: config().relayUrls,
filters,
continuous: false,
onEvent: (event: NostrEvent) => {
const key = extractKey(event);
if (key == null) return;
const task = keyTaskMap.get(key);
if (task == null) return;
const [events, setEvents] = getSignalForKey(key);
setEvents(addEvent(event));
task.resolve(events);
},
onEOSE: () => {
tasks.forEach((task) => {
const key = generateKey(task.args);
if (didReceivedEventsForKey(key)) {
const [, setEvents] = getSignalForKey(key);
setEvents(completeBatchedEvents);
} else {
task.resolve(emptyBatchedEvents);
}
});
},
}));
},
}));
};
export default useBatchedEvents;