bug: load more fix
This commit is contained in:
@ -3,9 +3,22 @@ import { findTag } from "Util";
|
||||
|
||||
export interface StoreSnapshot<TSnapshot> {
|
||||
data: TSnapshot | undefined;
|
||||
store: NoteStore;
|
||||
clear: () => void;
|
||||
loading: () => boolean;
|
||||
add: (ev: Readonly<TaggedRawEvent> | Readonly<Array<TaggedRawEvent>>) => void;
|
||||
}
|
||||
|
||||
export const EmptySnapshot = {
|
||||
data: undefined,
|
||||
clear: () => {
|
||||
// empty
|
||||
},
|
||||
loading: () => true,
|
||||
add: (ev: Readonly<TaggedRawEvent> | Readonly<Array<TaggedRawEvent>>) => {
|
||||
// empty
|
||||
},
|
||||
} as StoreSnapshot<FlatNoteStore>;
|
||||
|
||||
export type NoteStoreSnapshotData = Readonly<Array<TaggedRawEvent>> | Readonly<TaggedRawEvent>;
|
||||
export type NoteStoreHook = () => void;
|
||||
export type NoteStoreHookRelease = () => void;
|
||||
@ -20,7 +33,6 @@ export type OnEoseCallbackRelease = () => void;
|
||||
export abstract class NoteStore {
|
||||
abstract add(ev: Readonly<TaggedRawEvent> | Readonly<Array<TaggedRawEvent>>): void;
|
||||
abstract clear(): void;
|
||||
abstract eose(c: string): void;
|
||||
|
||||
// react hooks
|
||||
abstract hook(cb: NoteStoreHook): NoteStoreHookRelease;
|
||||
@ -28,7 +40,6 @@ export abstract class NoteStore {
|
||||
|
||||
// events
|
||||
abstract onEvent(cb: OnEventCallback): OnEventCallbackRelease;
|
||||
abstract onEose(cb: OnEoseCallback): OnEoseCallback;
|
||||
|
||||
abstract get snapshot(): StoreSnapshot<NoteStoreSnapshotData>;
|
||||
abstract get loading(): boolean;
|
||||
@ -38,10 +49,11 @@ export abstract class NoteStore {
|
||||
export abstract class HookedNoteStore<TSnapshot extends NoteStoreSnapshotData> implements NoteStore {
|
||||
#hooks: Array<NoteStoreHook> = [];
|
||||
#eventHooks: Array<OnEventCallback> = [];
|
||||
#eoseHooks: Array<OnEoseCallback> = [];
|
||||
#loading = true;
|
||||
#storeSnapshot: StoreSnapshot<TSnapshot> = {
|
||||
store: this,
|
||||
clear: () => this.clear(),
|
||||
loading: () => this.loading,
|
||||
add: ev => this.add(ev),
|
||||
data: undefined,
|
||||
};
|
||||
#needsSnapshot = true;
|
||||
@ -60,15 +72,9 @@ export abstract class HookedNoteStore<TSnapshot extends NoteStoreSnapshotData> i
|
||||
this.onChange([]);
|
||||
}
|
||||
|
||||
abstract add(ev: TaggedRawEvent | Array<TaggedRawEvent>): void;
|
||||
abstract add(ev: Readonly<TaggedRawEvent> | Readonly<Array<TaggedRawEvent>>): void;
|
||||
abstract clear(): void;
|
||||
|
||||
eose(c: string): void {
|
||||
for (const hkE of this.#eoseHooks) {
|
||||
hkE(c);
|
||||
}
|
||||
}
|
||||
|
||||
hook(cb: NoteStoreHook): NoteStoreHookRelease {
|
||||
this.#hooks.push(cb);
|
||||
return () => {
|
||||
@ -90,14 +96,6 @@ export abstract class HookedNoteStore<TSnapshot extends NoteStoreSnapshotData> i
|
||||
};
|
||||
}
|
||||
|
||||
onEose(cb: OnEoseCallback): OnEoseCallback {
|
||||
this.#eoseHooks.push(cb);
|
||||
return () => {
|
||||
const idx = this.#eoseHooks.findIndex(a => a === cb);
|
||||
this.#eoseHooks.splice(idx, 1);
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract takeSnapshot(): TSnapshot | undefined;
|
||||
|
||||
protected onChange(changes: Readonly<Array<TaggedRawEvent>>): void {
|
||||
@ -115,8 +113,8 @@ export abstract class HookedNoteStore<TSnapshot extends NoteStoreSnapshotData> i
|
||||
#updateSnapshot() {
|
||||
if (this.#needsSnapshot) {
|
||||
this.#storeSnapshot = {
|
||||
...this.#storeSnapshot,
|
||||
data: this.takeSnapshot(),
|
||||
store: this,
|
||||
};
|
||||
this.#needsSnapshot = false;
|
||||
}
|
||||
|
@ -31,6 +31,11 @@ export class Query {
|
||||
*/
|
||||
#sentToRelays: Array<Readonly<Connection>> = [];
|
||||
|
||||
/**
|
||||
* When each relay returned EOSE
|
||||
*/
|
||||
#eoseRelays: Map<string, number> = new Map();
|
||||
|
||||
/**
|
||||
* Leave the query open until its removed
|
||||
*/
|
||||
@ -88,4 +93,32 @@ export class Query {
|
||||
c.CloseReq(this.id);
|
||||
}
|
||||
}
|
||||
|
||||
eose(sub: string, relay: string) {
|
||||
if (sub === this.id) {
|
||||
console.debug(`[EOSE][${sub}] ${relay}`);
|
||||
this.#eoseRelays.set(relay, unixNowMs());
|
||||
} else {
|
||||
const subQ = this.subQueries.find(a => a.id === sub);
|
||||
if (subQ) {
|
||||
subQ.eose(sub, relay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the progress to EOSE, can be used to determine when we should load more content
|
||||
*/
|
||||
get progress() {
|
||||
const thisProgress = this.#eoseRelays.size / this.#sentToRelays.reduce((acc, v) => (acc += v.Down ? 0 : 1), 0);
|
||||
if (this.subQueries.length === 0) {
|
||||
return thisProgress;
|
||||
}
|
||||
|
||||
let totalProgress = thisProgress;
|
||||
for (const sq of this.subQueries) {
|
||||
totalProgress += sq.progress;
|
||||
}
|
||||
return totalProgress / (this.subQueries.length + 1);
|
||||
}
|
||||
}
|
||||
|
@ -112,11 +112,11 @@ export class NostrSystem {
|
||||
OnEndOfStoredEvents(c: Connection, sub: string) {
|
||||
const q = this.GetQuery(sub);
|
||||
if (q) {
|
||||
q.request.finished = unixNowMs();
|
||||
const f = this.Feeds.get(sub);
|
||||
q.eose(sub, c.Address);
|
||||
const f = this.Feeds.get(q.id);
|
||||
if (f) {
|
||||
f.eose(c.Address);
|
||||
f.loading = false;
|
||||
f.loading = q.progress <= 0.5;
|
||||
console.debug(`${sub} loading=${f.loading}, progress=${q.progress}`);
|
||||
}
|
||||
if (!q.leaveOpen) {
|
||||
c.CloseReq(sub);
|
||||
@ -255,8 +255,6 @@ export class NostrSystem {
|
||||
this.Queries.set(rb.id, q);
|
||||
const store = new type();
|
||||
this.Feeds.set(rb.id, store);
|
||||
store.onEose(c => console.debug(`[EOSE][${rb.id}]: ${c}`));
|
||||
|
||||
this.SendQuery(q);
|
||||
this.#changed();
|
||||
return store;
|
||||
|
Reference in New Issue
Block a user