Browse Source

Add observability to node resolution

master
buttercat1791 10 months ago
parent
commit
d3ec3ad3e2
  1. 32
      src/lib/data_structures/publication_tree.ts

32
src/lib/data_structures/publication_tree.ts

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
import type NDK from "@nostr-dev-kit/ndk";
import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { Lazy } from "./lazy.ts";
import { findIndexAsync as _findIndexAsync } from '../utils.ts';
import type NDK from '@nostr-dev-kit/ndk';
import type { NDKEvent } from '@nostr-dev-kit/ndk';
import { Lazy } from './lazy.ts';
import { SvelteSet } from "svelte/reactivity";
enum PublicationTreeNodeType {
Branch,
@ -22,6 +22,14 @@ interface PublicationTreeNode { @@ -22,6 +22,14 @@ interface PublicationTreeNode {
}
export class PublicationTree implements AsyncIterable<NDKEvent | null> {
// TODO: Abstract this into a `SveltePublicationTree` wrapper class.
/**
* A reactive set of addresses of the events that have been resolved (loaded) into the tree.
* Svelte components can use this set in reactive code blocks to trigger updates when new nodes
* are added to the tree.
*/
resolvedAddresses: SvelteSet<string> = new SvelteSet();
/**
* The root node of the tree.
*/
@ -52,6 +60,8 @@ export class PublicationTree implements AsyncIterable<NDKEvent | null> { @@ -52,6 +60,8 @@ export class PublicationTree implements AsyncIterable<NDKEvent | null> {
*/
#ndk: NDK;
#onNodeResolvedCallbacks: Array<(address: string) => void> = [];
constructor(rootEvent: NDKEvent, ndk: NDK) {
const rootAddress = rootEvent.tagAddress();
this.#root = {
@ -185,6 +195,16 @@ export class PublicationTree implements AsyncIterable<NDKEvent | null> { @@ -185,6 +195,16 @@ export class PublicationTree implements AsyncIterable<NDKEvent | null> {
this.#cursor.tryMoveTo(address);
}
/**
* Registers an observer function that is invoked whenever a new node is resolved. Nodes are
* added lazily.
*
* @param observer The observer function.
*/
onNodeResolved(observer: (address: string) => void) {
this.#onNodeResolvedCallbacks.push(observer);
}
// #region Iteration Cursor
#cursor = new class {
@ -504,6 +524,7 @@ export class PublicationTree implements AsyncIterable<NDKEvent | null> { @@ -504,6 +524,7 @@ export class PublicationTree implements AsyncIterable<NDKEvent | null> {
}
this.#events.set(address, event);
this.resolvedAddresses.add(address);
const childAddresses = event.tags.filter(tag => tag[0] === 'a').map(tag => tag[1]);
@ -519,6 +540,9 @@ export class PublicationTree implements AsyncIterable<NDKEvent | null> { @@ -519,6 +540,9 @@ export class PublicationTree implements AsyncIterable<NDKEvent | null> {
this.addEventByAddress(address, event);
}
// TODO: We may need to move this to `#addNode`, so the observer is notified more eagerly.
this.#onNodeResolvedCallbacks.forEach(observer => observer(address));
return node;
}

Loading…
Cancel
Save