Browse Source

Enable parser to fetch publications from relays

master
buttercat1791 1 year ago
parent
commit
fdefbcb1f9
  1. 79
      src/lib/parser.ts

79
src/lib/parser.ts

@ -12,6 +12,7 @@ import asciidoctor, {
} from 'asciidoctor'; } from 'asciidoctor';
import he from 'he'; import he from 'he';
import { writable, type Writable } from 'svelte/store'; import { writable, type Writable } from 'svelte/store';
import { indexKind, zettelKinds } from './consts';
interface IndexMetadata { interface IndexMetadata {
authors?: string[]; authors?: string[];
@ -154,6 +155,28 @@ export default class Pharos {
} }
} }
/**
* Fetches and parses the event tree for a publication given the event or event ID of the
* publication's root index.
* @param event The event or event ID of the publication's root index.
*/
async fetch(event: NDKEvent | string): Promise<void> {
let content: string;
if (typeof event === 'string') {
const index = await this.ndk.fetchEvent({ ids: [event] });
if (!index) {
throw new Error('Failed to fetch publication.');
}
content = await this.getPublicationContent(index);
} else {
content = await this.getPublicationContent(event);
}
this.parse(content);
}
/** /**
* Generates and stores Nostr events from the parsed AsciiDoc document. The events can be * Generates and stores Nostr events from the parsed AsciiDoc document. The events can be
* modified via the parser's API and retrieved via the `getEvents()` method. * modified via the parser's API and retrieved via the `getEvents()` method.
@ -558,6 +581,62 @@ export default class Pharos {
} }
} }
/**
* Uses the NDK to crawl the event tree of a publication and return its content as a string.
* @param event The root index event of the publication.
* @returns The content of the publication as a string.
* @remarks This function does a depth-first crawl of the event tree using the relays specified
* on the NDK instance.
*/
private async getPublicationContent(event: NDKEvent, depth: number = 0): Promise<string> {
let content: string = '';
// Format title into AsciiDoc header.
const title = event.getMatchingTags('title')[0][1];
let titleLevel = '';
for (let i = 0; i <= depth; i++) {
titleLevel += '=';
}
content += `${titleLevel} ${title}\n\n`;
// TODO: Deprecate `e` tags in favor of `a` tags required by NIP-62.
let tags = event.getMatchingTags('a');
if (tags.length === 0) {
tags = event.getMatchingTags('e');
}
// Base case: The event is a zettel.
if (zettelKinds.includes(event.kind ?? -1)) {
content += event.content;
return content;
}
// Recursive case: The event is an index.
const childEvents = await Promise.all(
tags.map(tag => this.ndk.fetchEventFromTag(tag, event))
);
// Michael J - 15 December 2024 - This could be further parallelized by recursively fetching
// children of index events before processing them for content. We won't make that change now,
// as it would increase complexity, but if performance suffers, we can revisit this option.
const childContentPromises: Promise<string>[] = [];
for (let i = 0; i < childEvents.length; i++) {
const childEvent = childEvents[i];
if (!childEvent) {
console.warn(`NDK could not find event ${tags[i][1]}.`);
continue;
}
childContentPromises.push(this.getPublicationContent(childEvent, depth + 1));
}
const childContents = await Promise.all(childContentPromises);
content += childContents.join('\n\n');
return content;
}
// #endregion // #endregion
// #region NDKEvent Generation // #region NDKEvent Generation

Loading…
Cancel
Save