Browse Source

Clean up and refactor based on AI code review

master
buttercat1791 8 months ago
parent
commit
2bb42d3ec4
  1. 8
      src/lib/components/publications/PublicationFeed.svelte
  2. 2
      src/lib/navigator/EventNetwork/NodeTooltip.svelte
  3. 63
      src/lib/utils.ts
  4. 3
      src/lib/utils/event_search.ts
  5. 6
      src/lib/utils/markup/advancedAsciidoctorPostProcessor.ts
  6. 5
      src/lib/utils/network_detection.ts
  7. 83
      src/lib/utils/nostrUtils.ts
  8. 2
      src/lib/utils/search_types.ts
  9. 23
      src/routes/+layout.ts
  10. 33
      src/routes/publication/+page.server.ts
  11. 89
      src/routes/publication/[type]/[identifier]/+layout.server.ts
  12. 89
      src/routes/publication/[type]/[identifier]/+page.server.ts

8
src/lib/components/publications/PublicationFeed.svelte

@ -290,9 +290,9 @@
}; };
// Debounced search function // Debounced search function
const debouncedSearch = debounce(async (query: string) => { const debouncedSearch = debounce((query: string | undefined) => {
console.debug("[PublicationFeed] Search query changed:", query); console.debug("[PublicationFeed] Search query changed:", query);
if (query.trim()) { if (query && query.trim()) {
const filtered = filterEventsBySearch(allIndexEvents); const filtered = filterEventsBySearch(allIndexEvents);
eventsInView = filtered.slice(0, 30); eventsInView = filtered.slice(0, 30);
endOfFeed = filtered.length <= 30; endOfFeed = filtered.length <= 30;
@ -303,10 +303,6 @@
}, 300); }, 300);
$effect(() => { $effect(() => {
console.debug(
"[PublicationFeed] Search query effect triggered:",
props.searchQuery,
);
debouncedSearch(props.searchQuery); debouncedSearch(props.searchQuery);
}); });

2
src/lib/navigator/EventNetwork/NodeTooltip.svelte

@ -145,7 +145,7 @@
<div class="tooltip-content"> <div class="tooltip-content">
<!-- Title with link --> <!-- Title with link -->
<div class="tooltip-title"> <div class="tooltip-title">
<a href="/publication/id/{node.id}" class="tooltip-title-link"> <a href={`/publication/id/${node.id}`} class="tooltip-title-link">
{node.title || "Untitled"} {node.title || "Untitled"}
</a> </a>
</div> </div>

63
src/lib/utils.ts

@ -1,7 +1,21 @@
import type { NDKEvent } from "@nostr-dev-kit/ndk"; import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { nip19 } from "nostr-tools"; import { nip19 } from "nostr-tools";
import { getMatchingTags } from "./utils/nostrUtils.ts"; import { getMatchingTags } from "./utils/nostrUtils.ts";
import { AddressPointer, EventPointer } from "nostr-tools/nip19"; import type { AddressPointer, EventPointer } from "nostr-tools/nip19";
export class DecodeError extends Error {
constructor(message: string) {
super(message);
this.name = "DecodeError";
}
}
export class InvalidKindError extends DecodeError {
constructor(message: string) {
super(message);
this.name = "InvalidKindError";
}
}
export function neventEncode(event: NDKEvent, relays: string[]) { export function neventEncode(event: NDKEvent, relays: string[]) {
return nip19.neventEncode({ return nip19.neventEncode({
@ -31,39 +45,41 @@ export function nprofileEncode(pubkey: string, relays: string[]) {
} }
/** /**
* Decodes an naddr identifier and returns the decoded data * Decodes a nostr identifier (naddr, nevent) and returns the decoded data.
* @param identifier The nostr identifier to decode.
* @param expectedType The expected type of the decoded data ('naddr' or 'nevent').
* @returns The decoded data.
*/ */
export function naddrDecode(naddr: string): AddressPointer { function decodeNostrIdentifier<T extends AddressPointer | EventPointer>(
identifier: string,
expectedType: "naddr" | "nevent",
): T {
try { try {
if (!naddr.startsWith('naddr')) { if (!identifier.startsWith(expectedType)) {
throw new Error('Invalid naddr format'); throw new InvalidKindError(`Invalid ${expectedType} format`);
} }
const decoded = nip19.decode(naddr); const decoded = nip19.decode(identifier);
if (decoded.type !== 'naddr') { if (decoded.type !== expectedType) {
throw new Error('Decoded result is not an naddr'); throw new InvalidKindError(`Decoded result is not an ${expectedType}`);
} }
return decoded.data; return decoded.data as T;
} catch (error) { } catch (error) {
throw new Error(`Failed to decode naddr: ${error}`); throw new DecodeError(`Failed to decode ${expectedType}: ${error}`);
} }
} }
/**
* Decodes an naddr identifier and returns the decoded data
*/
export function naddrDecode(naddr: string): AddressPointer {
return decodeNostrIdentifier<AddressPointer>(naddr, "naddr");
}
/** /**
* Decodes an nevent identifier and returns the decoded data * Decodes an nevent identifier and returns the decoded data
*/ */
export function neventDecode(nevent: string): EventPointer { export function neventDecode(nevent: string): EventPointer {
try { return decodeNostrIdentifier<EventPointer>(nevent, "nevent");
if (!nevent.startsWith('nevent')) {
throw new Error('Invalid nevent format');
}
const decoded = nip19.decode(nevent);
if (decoded.type !== 'nevent') {
throw new Error('Decoded result is not an nevent');
}
return decoded.data;
} catch (error) {
throw new Error(`Failed to decode nevent: ${error}`);
}
} }
export function formatDate(unixtimestamp: number) { export function formatDate(unixtimestamp: number) {
@ -206,7 +222,8 @@ Array.prototype.findIndexAsync = function <T>(
* @param wait The number of milliseconds to delay * @param wait The number of milliseconds to delay
* @returns A debounced version of the function * @returns A debounced version of the function
*/ */
export function debounce<T extends (...args: unknown[]) => unknown>( // deno-lint-ignore no-explicit-any
export function debounce<T extends (...args: any[]) => any>(
func: T, func: T,
wait: number, wait: number,
): (...args: Parameters<T>) => void { ): (...args: Parameters<T>) => void {

3
src/lib/utils/event_search.ts

@ -1,7 +1,8 @@
import { ndkInstance } from "../ndk.ts"; import { ndkInstance } from "../ndk.ts";
import { fetchEventWithFallback } from "./nostrUtils.ts"; import { fetchEventWithFallback } from "./nostrUtils.ts";
import { nip19 } from "nostr-tools"; import { nip19 } from "nostr-tools";
import { NDKEvent, NDKFilter } from "@nostr-dev-kit/ndk"; import type { NDKFilter } from "@nostr-dev-kit/ndk";
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { wellKnownUrl, isValidNip05Address } from "./search_utils.ts"; import { wellKnownUrl, isValidNip05Address } from "./search_utils.ts";
import { TIMEOUTS, VALIDATION } from "./search_constants.ts"; import { TIMEOUTS, VALIDATION } from "./search_constants.ts";

6
src/lib/utils/markup/advancedAsciidoctorPostProcessor.ts

@ -32,9 +32,11 @@ export async function postProcessAdvancedAsciidoctorHtml(
} }
if ( if (
typeof globalThis !== "undefined" && typeof globalThis !== "undefined" &&
typeof globalThis.MathJax?.typesetPromise === "function" // deno-lint-ignore no-explicit-any
typeof (globalThis as any).MathJax?.typesetPromise === "function"
) { ) {
setTimeout(() => globalThis.MathJax.typesetPromise(), 0); // deno-lint-ignore no-explicit-any
setTimeout(() => (globalThis as any).MathJax.typesetPromise(), 0);
} }
return processedHtml; return processedHtml;
} catch (error) { } catch (error) {

5
src/lib/utils/network_detection.ts

@ -153,10 +153,11 @@ export function getRelaySetForNetworkCondition(
*/ */
export function startNetworkMonitoring( export function startNetworkMonitoring(
onNetworkChange: (condition: NetworkCondition) => void, onNetworkChange: (condition: NetworkCondition) => void,
checkInterval: number = 60000 // Increased to 60 seconds to reduce spam checkInterval: number = 60000, // Increased to 60 seconds to reduce spam
): () => void { ): () => void {
let lastCondition: NetworkCondition | null = null; let lastCondition: NetworkCondition | null = null;
let intervalId: number | null = null; // deno-lint-ignore no-explicit-any
let intervalId: any = null;
const checkNetwork = async () => { const checkNetwork = async () => {
try { try {

83
src/lib/utils/nostrUtils.ts

@ -12,6 +12,8 @@ import { schnorr } from "@noble/curves/secp256k1";
import { bytesToHex } from "@noble/hashes/utils"; import { bytesToHex } from "@noble/hashes/utils";
import { wellKnownUrl } from "./search_utility.ts"; import { wellKnownUrl } from "./search_utility.ts";
import { VALIDATION } from "./search_constants.ts"; import { VALIDATION } from "./search_constants.ts";
import { error } from "@sveltejs/kit";
import { naddrDecode, neventDecode } from "../utils.ts";
const badgeCheckSvg = const badgeCheckSvg =
'<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M12 2c-.791 0-1.55.314-2.11.874l-.893.893a.985.985 0 0 1-.696.288H7.04A2.984 2.984 0 0 0 4.055 7.04v1.262a.986.986 0 0 1-.288.696l-.893.893a2.984 2.984 0 0 0 0 4.22l.893.893a.985.985 0 0 1 .288.696v1.262a2.984 2.984 0 0 0 2.984 2.984h1.262c.261 0 .512.104.696.288l.893.893a2.984 2.984 0 0 0 4.22 0l.893-.893a.985.985 0 0 1 .696-.288h1.262a2.984 2.984 0 0 0 2.984-2.984V15.7c0-.261.104-.512.288-.696l.893-.893a2.984 2.984 0 0 0 0-4.22l-.893-.893a.985.985 0 0 1-.288-.696V7.04a2.984 2.984 0 0 0-2.984-2.984h-1.262a.985.985 0 0 1-.696-.288l-.893-.893A2.984 2.984 0 0 0 12 2Zm3.683 7.73a1 1 0 1 0-1.414-1.413l-4.253 4.253-1.277-1.277a1 1 0 0 0-1.415 1.414l1.985 1.984a1 1 0 0 0 1.414 0l4.96-4.96Z" clip-rule="evenodd"/></svg>'; '<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M12 2c-.791 0-1.55.314-2.11.874l-.893.893a.985.985 0 0 1-.696.288H7.04A2.984 2.984 0 0 0 4.055 7.04v1.262a.986.986 0 0 1-.288.696l-.893.893a2.984 2.984 0 0 0 0 4.22l.893.893a.985.985 0 0 1 .288.696v1.262a2.984 2.984 0 0 0 2.984 2.984h1.262c.261 0 .512.104.696.288l.893.893a2.984 2.984 0 0 0 4.22 0l.893-.893a.985.985 0 0 1 .696-.288h1.262a2.984 2.984 0 0 0 2.984-2.984V15.7c0-.261.104-.512.288-.696l.893-.893a2.984 2.984 0 0 0 0-4.22l-.893-.893a.985.985 0 0 1-.288-.696V7.04a2.984 2.984 0 0 0-2.984-2.984h-1.262a.985.985 0 0 1-.696-.288l-.893-.893A2.984 2.984 0 0 0 12 2Zm3.683 7.73a1 1 0 1 0-1.414-1.413l-4.253 4.253-1.277-1.277a1 1 0 0 0-1.415 1.414l1.985 1.984a1 1 0 0 0 1.414 0l4.96-4.96Z" clip-rule="evenodd"/></svg>';
@ -668,3 +670,84 @@ export function prefixNostrAddresses(content: string): string {
return `nostr:${match}`; return `nostr:${match}`;
}); });
} }
// Added functions for fetching events by various identifiers
/**
* Fetches an event by hex ID, throwing a SvelteKit 404 error if not found.
*/
export async function fetchEventById(ndk: NDK, id: string): Promise<NDKEvent> {
try {
const event = await fetchEventWithFallback(ndk, id);
if (!event) {
throw error(404, `Event not found for ID: ${id}`);
}
return event;
} catch (err) {
if (err && typeof err === "object" && "status" in err) {
throw err;
}
throw error(404, `Failed to fetch event by ID: ${err}`);
}
}
/**
* Fetches an event by d tag, throwing a 404 if not found.
*/
export async function fetchEventByDTag(ndk: NDK, dTag: string): Promise<NDKEvent> {
try {
const event = await fetchEventWithFallback(ndk, { "#d": [dTag], limit: 1 });
if (!event) {
throw error(404, `Event not found for d-tag: ${dTag}`);
}
return event;
} catch (err) {
if (err && typeof err === "object" && "status" in err) {
throw err;
}
throw error(404, `Failed to fetch event by d-tag: ${err}`);
}
}
/**
* Fetches an event by naddr identifier.
*/
export async function fetchEventByNaddr(ndk: NDK, naddr: string): Promise<NDKEvent> {
try {
const decoded = naddrDecode(naddr);
const filter = {
kinds: [decoded.kind],
authors: [decoded.pubkey],
"#d": [decoded.identifier],
};
const event = await fetchEventWithFallback(ndk, filter);
if (!event) {
throw error(404, `Event not found for naddr: ${naddr}`);
}
return event;
} catch (err) {
if (err && typeof err === "object" && "status" in err) {
throw err;
}
throw error(404, `Failed to fetch event by naddr: ${err}`);
}
}
/**
* Fetches an event by nevent identifier.
*/
export async function fetchEventByNevent(ndk: NDK, nevent: string): Promise<NDKEvent> {
try {
const decoded = neventDecode(nevent);
const event = await fetchEventWithFallback(ndk, decoded.id);
if (!event) {
throw error(404, `Event not found for nevent: ${nevent}`);
}
return event;
} catch (err) {
if (err && typeof err === "object" && "status" in err) {
throw err;
}
throw error(404, `Failed to fetch event by nevent: ${err}`);
}
}

2
src/lib/utils/search_types.ts

@ -1,4 +1,4 @@
import { NDKEvent, NDKFilter, NDKSubscription } from "@nostr-dev-kit/ndk"; import type { NDKEvent, NDKFilter, NDKSubscription } from "@nostr-dev-kit/ndk";
/** /**
* Extended NostrProfile interface for search results * Extended NostrProfile interface for search results

23
src/routes/+layout.ts

@ -8,12 +8,13 @@ import { loginMethodStorageKey } from "../lib/stores/userStore.ts";
import Pharos, { pharosInstance } from "../lib/parser.ts"; import Pharos, { pharosInstance } from "../lib/parser.ts";
import type { LayoutLoad } from "./$types"; import type { LayoutLoad } from "./$types";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { browser } from "$app/environment";
export const load: LayoutLoad = () => { /**
// Initialize NDK with new relay management system * Attempts to restore the user's authentication session from localStorage.
const ndk = initNdk(); * Handles extension, Amber (NIP-46), and npub login methods.
ndkInstance.set(ndk); */
async function restoreAuthSession() {
try { try {
const pubkey = getPersistedLogin(); const pubkey = getPersistedLogin();
const loginMethod = localStorage.getItem(loginMethodStorageKey); const loginMethod = localStorage.getItem(loginMethodStorageKey);
@ -111,9 +112,19 @@ export const load: LayoutLoad = () => {
`Failed to restore login: ${e}\n\nContinuing with anonymous session.`, `Failed to restore login: ${e}\n\nContinuing with anonymous session.`,
); );
} }
}
export const load: LayoutLoad = () => {
// Initialize NDK with new relay management system
const ndk = initNdk();
ndkInstance.set(ndk);
if (browser) {
restoreAuthSession();
}
const parser = new Pharos(ndk); const parser = new Pharos(ndk);
pharosInstance.set(parser); pharosInstance.set(parser);
return { return {
ndk, ndk,

33
src/routes/publication/+page.server.ts

@ -1,6 +1,22 @@
import { redirect } from "@sveltejs/kit"; import { redirect } from "@sveltejs/kit";
import type { PageServerLoad } from "./$types"; import type { PageServerLoad } from "./$types";
// Route pattern constants
const ROUTES = {
PUBLICATION_BASE: "/publication",
NADDR: "/publication/naddr",
NEVENT: "/publication/nevent",
ID: "/publication/id",
D_TAG: "/publication/d",
START: "/start",
} as const;
// Identifier prefixes
const IDENTIFIER_PREFIXES = {
NADDR: "naddr",
NEVENT: "nevent",
} as const;
export const load: PageServerLoad = ({ url }) => { export const load: PageServerLoad = ({ url }) => {
const id = url.searchParams.get("id"); const id = url.searchParams.get("id");
const dTag = url.searchParams.get("d"); const dTag = url.searchParams.get("d");
@ -8,19 +24,18 @@ export const load: PageServerLoad = ({ url }) => {
// Handle backward compatibility for old query-based routes // Handle backward compatibility for old query-based routes
if (id) { if (id) {
// Check if id is an naddr or nevent // Check if id is an naddr or nevent
if (id.startsWith("naddr")) { if (id.startsWith(IDENTIFIER_PREFIXES.NADDR)) {
throw redirect(301, `/publication/naddr/${id}`); throw redirect(301, `${ROUTES.NADDR}/${id}`);
} else if (id.startsWith("nevent")) { } else if (id.startsWith(IDENTIFIER_PREFIXES.NEVENT)) {
throw redirect(301, `/publication/nevent/${id}`); throw redirect(301, `${ROUTES.NEVENT}/${id}`);
} else { } else {
// Assume it's a hex ID // Assume it's a hex ID
throw redirect(301, `/publication/id/${id}`); throw redirect(301, `${ROUTES.ID}/${id}`);
} }
} else if (dTag) { } else if (dTag) {
throw redirect(301, `/publication/d/${dTag}`); throw redirect(301, `${ROUTES.D_TAG}/${dTag}`);
} }
// If no query parameters, redirect to the start page or show publication feed\ // If no query parameters, redirect to the start page
// AI-TODO: Redirect to a "not found" page. throw redirect(301, ROUTES.START);
throw redirect(301, "/start");
}; };

89
src/routes/publication/[type]/[identifier]/+layout.server.ts

@ -1,95 +1,12 @@
import { error } from "@sveltejs/kit"; import { error } from "@sveltejs/kit";
import type { LayoutServerLoad } from "./$types"; import type { LayoutServerLoad } from "./$types";
import type { NDKEvent } from "@nostr-dev-kit/ndk"; import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { getActiveRelaySetAsNDKRelaySet } from "../../../../lib/ndk.ts"; import { getMatchingTags, fetchEventById, fetchEventByDTag, fetchEventByNaddr, fetchEventByNevent } from "../../../../lib/utils/nostrUtils.ts";
import { getMatchingTags } from "../../../../lib/utils/nostrUtils.ts";
import { naddrDecode, neventDecode } from "../../../../lib/utils.ts";
import type NDK from "@nostr-dev-kit/ndk";
// AI-TODO: Use `fetchEventWithFallback` from `nostrUtils.ts` to retrieve events in this file.
/**
* Fetches an event by hex ID
*/
async function fetchEventById(ndk: NDK, id: string): Promise<NDKEvent> {
try {
const event = await ndk.fetchEvent(id);
if (!event) {
throw new Error(`Event not found for ID: ${id}`);
}
return event;
} catch (err) {
throw error(404, `Failed to fetch publication root event.\n${err}`);
}
}
/**
* Fetches an event by d tag
*/
async function fetchEventByDTag(ndk: NDK, dTag: string): Promise<NDKEvent> {
try {
const relaySet = await getActiveRelaySetAsNDKRelaySet(ndk, true);
const events = await ndk.fetchEvents(
{ "#d": [dTag] },
{ closeOnEose: false },
relaySet,
);
if (!events || events.size === 0) {
throw new Error(`Event not found for d tag: ${dTag}`);
}
// Choose the event with the latest created_at timestamp when multiple events share the same d tag
const sortedEvents = Array.from(events).sort((a, b) => (b.created_at || 0) - (a.created_at || 0));
return sortedEvents[0];
} catch (err) {
throw error(404, `Failed to fetch publication root event.\n${err}`);
}
}
/**
* Fetches an event by naddr identifier
*/
async function fetchEventByNaddr(ndk: NDK, naddr: string): Promise<NDKEvent> {
try {
const decoded = naddrDecode(naddr);
const relaySet = await getActiveRelaySetAsNDKRelaySet(ndk, true);
const filter = {
kinds: [decoded.kind],
authors: [decoded.pubkey],
"#d": [decoded.identifier],
};
const event = await ndk.fetchEvent(filter, { closeOnEose: false }, relaySet);
if (!event) {
throw new Error(`Event not found for naddr: ${naddr}`);
}
return event;
} catch (err) {
throw error(404, `Failed to fetch publication root event.\n${err}`);
}
}
/**
* Fetches an event by nevent identifier
*/
async function fetchEventByNevent(ndk: NDK, nevent: string): Promise<NDKEvent> {
try {
const decoded = neventDecode(nevent);
const event = await ndk.fetchEvent(decoded.id);
if (!event) {
throw new Error(`Event not found for nevent: ${nevent}`);
}
return event;
} catch (err) {
throw error(404, `Failed to fetch publication root event.\n${err}`);
}
}
export const load: LayoutServerLoad = async ({ params, parent, url }) => { export const load: LayoutServerLoad = async ({ params, parent, url }) => {
const { type, identifier } = params; const { type, identifier } = params;
const { ndk } = await parent(); // deno-lint-ignore no-explicit-any
const { ndk } = (await parent()) as any;
if (!ndk) { if (!ndk) {
throw error(500, "NDK not available"); throw error(500, "NDK not available");

89
src/routes/publication/[type]/[identifier]/+page.server.ts

@ -1,95 +1,12 @@
import { error } from "@sveltejs/kit"; import { error } from "@sveltejs/kit";
import type { PageServerLoad } from "./$types"; import type { PageServerLoad } from "./$types";
import type { NDKEvent } from "@nostr-dev-kit/ndk"; import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { getActiveRelaySetAsNDKRelaySet } from "../../../../lib/ndk.ts"; import { getMatchingTags, fetchEventById, fetchEventByDTag, fetchEventByNaddr, fetchEventByNevent } from "../../../../lib/utils/nostrUtils.ts";
import { getMatchingTags } from "../../../../lib/utils/nostrUtils.ts";
import { naddrDecode, neventDecode } from "../../../../lib/utils.ts";
import type NDK from "@nostr-dev-kit/ndk";
// AI-TODO: Use `fetchEventWithFallback` from `nostrUtils.ts` to retrieve events in this file.
/**
* Fetches an event by hex ID
*/
async function fetchEventById(ndk: NDK, id: string): Promise<NDKEvent> {
try {
const event = await ndk.fetchEvent(id);
if (!event) {
throw new Error(`Event not found for ID: ${id}`);
}
return event;
} catch (err) {
throw error(404, `Failed to fetch publication root event.\n${err}`);
}
}
/**
* Fetches an event by d tag
*/
async function fetchEventByDTag(ndk: NDK, dTag: string): Promise<NDKEvent> {
try {
const relaySet = await getActiveRelaySetAsNDKRelaySet(ndk, true); // true for inbox relays
const events = await ndk.fetchEvents(
{ "#d": [dTag] },
{ closeOnEose: false },
relaySet,
);
if (!events || events.size === 0) {
throw new Error(`Event not found for d tag: ${dTag}`);
}
// AI-NOTE: Choose the event with the latest created_at timestamp when multiple events share the same d tag
const sortedEvents = Array.from(events).sort((a, b) => (b.created_at || 0) - (a.created_at || 0));
return sortedEvents[0];
} catch (err) {
throw error(404, `Failed to fetch publication root event.\n${err}`);
}
}
/**
* Fetches an event by naddr identifier
*/
async function fetchEventByNaddr(ndk: NDK, naddr: string): Promise<NDKEvent> {
try {
const decoded = naddrDecode(naddr);
const relaySet = await getActiveRelaySetAsNDKRelaySet(ndk, true);
const filter = {
kinds: [decoded.kind],
authors: [decoded.pubkey],
"#d": [decoded.identifier],
};
const event = await ndk.fetchEvent(filter, { closeOnEose: false }, relaySet);
if (!event) {
throw new Error(`Event not found for naddr: ${naddr}`);
}
return event;
} catch (err) {
throw error(404, `Failed to fetch publication root event.\n${err}`);
}
}
/**
* Fetches an event by nevent identifier
*/
async function fetchEventByNevent(ndk: NDK, nevent: string): Promise<NDKEvent> {
try {
const decoded = neventDecode(nevent);
const event = await ndk.fetchEvent(decoded.id);
if (!event) {
throw new Error(`Event not found for nevent: ${nevent}`);
}
return event;
} catch (err) {
throw error(404, `Failed to fetch publication root event.\n${err}`);
}
}
export const load: PageServerLoad = async ({ params, parent }) => { export const load: PageServerLoad = async ({ params, parent }) => {
const { type, identifier } = params; const { type, identifier } = params;
const { ndk } = await parent(); // deno-lint-ignore no-explicit-any
const { ndk } = (await parent()) as any;
if (!ndk) { if (!ndk) {
throw error(500, "NDK not available"); throw error(500, "NDK not available");

Loading…
Cancel
Save