Refactor streaming to use async iterators

This commit is contained in:
Alex Gleason
2023-08-25 13:35:20 -05:00
parent 00c531bbff
commit baace5ea2d
4 changed files with 85 additions and 38 deletions

46
src/subscription.ts Normal file
View File

@@ -0,0 +1,46 @@
import { type Event } from '@/deps.ts';
import { matchDittoFilters } from '@/filter.ts';
import type { DittoFilter, EventData } from '@/types.ts';
class Subscription<K extends number = number> implements AsyncIterable<Event<K>> {
filters: DittoFilter<K>[];
#next?: (event: Event<K>) => void;
#closed = false;
constructor(filters: DittoFilter<K>[]) {
this.filters = filters;
}
stream(event: Event<K>): void {
if (this.#next) {
this.#next(event);
this.#next = undefined;
}
}
matches(event: Event, data: EventData): boolean {
return matchDittoFilters(this.filters, event, data);
}
close() {
this.#closed = true;
this.#next?.(undefined!);
}
async *[Symbol.asyncIterator]() {
while (true) {
const event = await new Promise<Event<K>>((resolve) => {
this.#next = resolve;
});
if (this.#closed) {
return;
}
yield event;
}
}
}
export { Subscription };