Browse Source

Fix warnings and errors thrown be Deno's linter

master
buttercat1791 8 months ago
parent
commit
3b7ffb913f
  1. 1
      playwright.config.ts
  2. 17
      src/app.d.ts
  3. 6
      src/lib/components/publications/PublicationFeed.svelte
  4. 3
      src/lib/navigator/EventNetwork/utils/forceSimulation.ts
  5. 8
      src/lib/navigator/EventNetwork/utils/networkBuilder.ts
  6. 93
      src/lib/ndk.ts
  7. 16
      src/lib/parser.ts
  8. 10
      src/lib/services/publisher.ts
  9. 2
      src/lib/state.ts
  10. 4
      src/lib/stores.ts
  11. 4
      src/lib/stores/networkStore.ts
  12. 27
      src/lib/stores/userStore.ts
  13. 2
      src/lib/types.ts
  14. 8
      src/lib/utils.ts
  15. 8
      src/lib/utils/ZettelParser.ts
  16. 13
      src/lib/utils/event_input_utils.ts
  17. 18
      src/lib/utils/event_search.ts
  18. 5
      src/lib/utils/indexEventCache.ts
  19. 14
      src/lib/utils/markup/advancedAsciidoctorPostProcessor.ts
  20. 24
      src/lib/utils/markup/advancedMarkupParser.ts
  21. 25
      src/lib/utils/markup/asciidoctorExtensions.ts
  22. 8
      src/lib/utils/markup/basicMarkupParser.ts
  23. 11
      src/lib/utils/network_detection.ts
  24. 21
      src/lib/utils/nostrEventService.ts
  25. 26
      src/lib/utils/nostrUtils.ts
  26. 30
      src/lib/utils/profile_search.ts
  27. 7
      src/lib/utils/relayDiagnostics.ts
  28. 34
      src/lib/utils/relay_management.ts
  29. 5
      src/lib/utils/searchCache.ts
  30. 6
      src/lib/utils/search_types.ts
  31. 7
      src/lib/utils/search_utils.ts
  32. 46
      src/lib/utils/subscription_search.ts
  33. 15
      src/routes/+layout.ts
  34. 6
      src/routes/+page.svelte
  35. 15
      src/routes/publication/+page.ts
  36. 3
      vite.config.ts

1
playwright.config.ts

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
import { defineConfig, devices } from "@playwright/test";
import process from "node:process";
/**
* Read environment variables from file.

17
src/app.d.ts vendored

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
// See https://kit.svelte.dev/docs/types#app
import NDK, { NDKEvent } from "@nostr-dev-kit/ndk";
import Pharos from "./lib/parser.ts";
import { NDKEvent, NDKNip07Signer } from "@nostr-dev-kit/ndk";
import { HLJSApi } from "highlight.js";
// for information about these interfaces
declare global {
@ -9,13 +9,24 @@ declare global { @@ -9,13 +9,24 @@ declare global {
// interface Error {}
// interface Locals {}
interface PageData {
waitable?: Promise<any>;
waitable?: Promise<unknown>;
publicationType?: string;
indexEvent?: NDKEvent;
url?: URL;
}
// interface Platform {}
}
var hljs: HLJSApi;
// deno-lint-ignore no-explicit-any
var MathJax: any;
var nostr: NDKNip07Signer & {
getRelays: () => Promise<Record<string, Record<string, boolean | undefined>>>;
// deno-lint-ignore no-explicit-any
signEvent: (event: any) => Promise<any>;
};
}
export {};

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

@ -35,10 +35,6 @@ @@ -35,10 +35,6 @@
// Event management
let allIndexEvents: NDKEvent[] = $state([]);
let cutoffTimestamp: number = $derived(
eventsInView?.at(eventsInView.length - 1)?.created_at ??
new Date().getTime(),
);
// Initialize relays and fetch events
async function initializeAndFetch() {
@ -371,8 +367,6 @@ @@ -371,8 +367,6 @@
</script>
<div class="flex flex-col space-y-4">
<div
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 w-full"
>

3
src/lib/navigator/EventNetwork/utils/forceSimulation.ts

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
// deno-lint-ignore-file no-explicit-any
/**
* D3 Force Simulation Utilities
*
@ -5,7 +6,7 @@ @@ -5,7 +6,7 @@
* graph simulations for the event network visualization.
*/
import type { NetworkNode, NetworkLink } from "../types";
import type { NetworkNode, NetworkLink } from "../types.ts";
import * as d3 from "d3";
// Configuration

8
src/lib/navigator/EventNetwork/utils/networkBuilder.ts

@ -6,10 +6,10 @@ @@ -6,10 +6,10 @@
*/
import type { NDKEvent } from "@nostr-dev-kit/ndk";
import type { NetworkNode, NetworkLink, GraphData, GraphState } from "../types";
import type { NetworkNode, GraphData, GraphState } from "../types.ts";
import { nip19 } from "nostr-tools";
import { activeInboxRelays, activeOutboxRelays } from "$lib/ndk";
import { getMatchingTags } from "$lib/utils/nostrUtils";
import { activeInboxRelays, activeOutboxRelays } from "../../../ndk.ts";
import { getMatchingTags } from "../../../utils/nostrUtils.ts";
import { get } from "svelte/store";
// Configuration
@ -20,7 +20,7 @@ const CONTENT_EVENT_KIND = 30041; @@ -20,7 +20,7 @@ const CONTENT_EVENT_KIND = 30041;
/**
* Debug logging function that only logs when DEBUG is true
*/
function debug(...args: any[]) {
function debug(...args: unknown[]) {
if (DEBUG) {
console.log("[NetworkBuilder]", ...args);
}

93
src/lib/ndk.ts

@ -8,29 +8,19 @@ import NDK, { @@ -8,29 +8,19 @@ import NDK, {
} from "@nostr-dev-kit/ndk";
import { get, writable, type Writable } from "svelte/store";
import {
secondaryRelays,
FeedType,
loginStorageKey,
communityRelays,
anonymousRelays,
searchRelays,
} from "./consts";
} from "./consts.ts";
import {
buildCompleteRelaySet,
testRelayConnection,
discoverLocalRelays,
getUserLocalRelays,
getUserBlockedRelays,
getUserOutboxRelays,
deduplicateRelayUrls,
} from "./utils/relay_management";
} from "./utils/relay_management.ts";
// Re-export testRelayConnection for components that need it
export { testRelayConnection };
import { startNetworkMonitoring, NetworkCondition } from "./utils/network_detection";
import { userStore } from "./stores/userStore";
import { userPubkey } from "$lib/stores/authStore.Svelte";
import { startNetworkStatusMonitoring, stopNetworkStatusMonitoring } from "./stores/networkStore";
import { userStore } from "./stores/userStore.ts";
import { userPubkey } from "./stores/authStore.Svelte.ts";
import { startNetworkStatusMonitoring, stopNetworkStatusMonitoring } from "./stores/networkStore.ts";
export const ndkInstance: Writable<NDK> = writable();
export const ndkSignedIn = writable(false);
@ -59,7 +49,7 @@ class CustomRelayAuthPolicy { @@ -59,7 +49,7 @@ class CustomRelayAuthPolicy {
* @param relay The relay to authenticate with
* @returns Promise that resolves when authentication is complete
*/
async authenticate(relay: NDKRelay): Promise<void> {
authenticate(relay: NDKRelay): void {
if (!this.ndk.signer || !this.ndk.activeUser) {
console.warn(
"[NDK.ts] No signer or active user available for relay authentication",
@ -84,7 +74,7 @@ class CustomRelayAuthPolicy { @@ -84,7 +74,7 @@ class CustomRelayAuthPolicy {
relay.on("notice", (message: string) => {
if (message.includes("auth-required")) {
console.debug(`[NDK.ts] Auth required from ${relay.url}:`, message);
this.handleAuthRequired(relay, message);
this.handleAuthRequired(relay);
}
});
@ -94,7 +84,7 @@ class CustomRelayAuthPolicy { @@ -94,7 +84,7 @@ class CustomRelayAuthPolicy {
});
// Listen for authentication failures
relay.on("auth:failed", (error: any) => {
relay.on("auth:failed", (error) => {
console.error(
`[NDK.ts] Authentication failed for ${relay.url}:`,
error,
@ -151,10 +141,7 @@ class CustomRelayAuthPolicy { @@ -151,10 +141,7 @@ class CustomRelayAuthPolicy {
/**
* Handles auth-required error from relay
*/
private async handleAuthRequired(
relay: NDKRelay,
message: string,
): Promise<void> {
private async handleAuthRequired(relay: NDKRelay): Promise<void> {
const challenge = this.challenges.get(relay.url);
if (challenge) {
await this.handleAuthChallenge(relay, challenge);
@ -173,13 +160,13 @@ export function checkEnvironmentForWebSocketDowngrade(): void { @@ -173,13 +160,13 @@ export function checkEnvironmentForWebSocketDowngrade(): void {
console.debug("[NDK.ts] Environment Check for WebSocket Protocol:");
const isLocalhost =
window.location.hostname === "localhost" ||
window.location.hostname === "127.0.0.1";
const isHttp = window.location.protocol === "http:";
const isHttps = window.location.protocol === "https:";
globalThis.location.hostname === "localhost" ||
globalThis.location.hostname === "127.0.0.1";
const isHttp = globalThis.location.protocol === "http:";
const isHttps = globalThis.location.protocol === "https:";
console.debug("[NDK.ts] - Is localhost:", isLocalhost);
console.debug("[NDK.ts] - Protocol:", window.location.protocol);
console.debug("[NDK.ts] - Protocol:", globalThis.location.protocol);
console.debug("[NDK.ts] - Is HTTP:", isHttp);
console.debug("[NDK.ts] - Is HTTPS:", isHttps);
@ -205,9 +192,9 @@ export function checkEnvironmentForWebSocketDowngrade(): void { @@ -205,9 +192,9 @@ export function checkEnvironmentForWebSocketDowngrade(): void {
*/
export function checkWebSocketSupport(): void {
console.debug("[NDK.ts] WebSocket Support Diagnostics:");
console.debug("[NDK.ts] - Protocol:", window.location.protocol);
console.debug("[NDK.ts] - Hostname:", window.location.hostname);
console.debug("[NDK.ts] - Port:", window.location.port);
console.debug("[NDK.ts] - Protocol:", globalThis.location.protocol);
console.debug("[NDK.ts] - Hostname:", globalThis.location.hostname);
console.debug("[NDK.ts] - Port:", globalThis.location.port);
console.debug("[NDK.ts] - User Agent:", navigator.userAgent);
// Test if secure WebSocket is supported
@ -266,46 +253,6 @@ function getRelayStorageKey(user: NDKUser, type: "inbox" | "outbox"): string { @@ -266,46 +253,6 @@ function getRelayStorageKey(user: NDKUser, type: "inbox" | "outbox"): string {
return `${loginStorageKey}/${user.pubkey}/${type}`;
}
/**
* Stores the user's relay lists in local storage.
* @param user The user for whom to store the relay lists.
* @param inboxes The user's inbox relays.
* @param outboxes The user's outbox relays.
*/
function persistRelays(
user: NDKUser,
inboxes: Set<NDKRelay>,
outboxes: Set<NDKRelay>,
): void {
localStorage.setItem(
getRelayStorageKey(user, "inbox"),
JSON.stringify(Array.from(inboxes).map((relay) => relay.url)),
);
localStorage.setItem(
getRelayStorageKey(user, "outbox"),
JSON.stringify(Array.from(outboxes).map((relay) => relay.url)),
);
}
/**
* Retrieves the user's relay lists from local storage.
* @param user The user for whom to retrieve the relay lists.
* @returns A tuple of relay sets of the form `[inboxRelays, outboxRelays]`. Either set may be
* empty if no relay lists were stored for the user.
*/
function getPersistedRelays(user: NDKUser): [Set<string>, Set<string>] {
const inboxes = new Set<string>(
JSON.parse(localStorage.getItem(getRelayStorageKey(user, "inbox")) ?? "[]"),
);
const outboxes = new Set<string>(
JSON.parse(
localStorage.getItem(getRelayStorageKey(user, "outbox")) ?? "[]",
),
);
return [inboxes, outboxes];
}
export function clearPersistedRelays(user: NDKUser): void {
localStorage.removeItem(getRelayStorageKey(user, "inbox"));
localStorage.removeItem(getRelayStorageKey(user, "outbox"));
@ -468,7 +415,7 @@ export async function refreshRelayStoresOnNetworkChange(ndk: NDK): Promise<void> @@ -468,7 +415,7 @@ export async function refreshRelayStoresOnNetworkChange(ndk: NDK): Promise<void>
* Starts network monitoring for relay optimization
* @param ndk NDK instance
*/
export function startNetworkMonitoringForRelays(ndk: NDK): void {
export function startNetworkMonitoringForRelays(): void {
// Use centralized network monitoring instead of separate monitoring
startNetworkStatusMonitoring();
}
@ -529,7 +476,7 @@ export function initNdk(): NDK { @@ -529,7 +476,7 @@ export function initNdk(): NDK {
// Update relay stores after connection
await updateActiveRelayStores(ndk);
// Start network monitoring for relay optimization
startNetworkMonitoringForRelays(ndk);
startNetworkMonitoringForRelays();
} catch (error) {
console.warn("[NDK.ts] Failed to connect NDK:", error);
@ -543,7 +490,7 @@ export function initNdk(): NDK { @@ -543,7 +490,7 @@ export function initNdk(): NDK {
// Still try to update relay stores even if connection failed
try {
await updateActiveRelayStores(ndk);
startNetworkMonitoringForRelays(ndk);
startNetworkMonitoringForRelays();
} catch (storeError) {
console.warn("[NDK.ts] Failed to update relay stores:", storeError);
}

16
src/lib/parser.ts

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
// deno-lint-ignore-file no-this-alias
import NDK, { NDKEvent } from "@nostr-dev-kit/ndk";
import asciidoctor from "asciidoctor";
import Processor from "asciidoctor";
import type {
AbstractBlock,
AbstractNode,
Asciidoctor,
Block,
Document,
Extensions,
@ -13,7 +13,7 @@ import type { @@ -13,7 +13,7 @@ import type {
import he from "he";
import { writable, type Writable } from "svelte/store";
import { zettelKinds } from "./consts.ts";
import { getMatchingTags } from "$lib/utils/nostrUtils";
import { getMatchingTags } from "./utils/nostrUtils.ts";
interface IndexMetadata {
authors?: string[];
@ -65,7 +65,7 @@ export default class Pharos { @@ -65,7 +65,7 @@ export default class Pharos {
* hierarchically to form the Abstract Syntax Tree (AST) representation of the document.
*/
private asciidoctor: Asciidoctor;
private asciidoctor;
private pharosExtensions: Extensions.Registry;
@ -140,7 +140,7 @@ export default class Pharos { @@ -140,7 +140,7 @@ export default class Pharos {
// #region Public API
constructor(ndk: NDK) {
this.asciidoctor = asciidoctor();
this.asciidoctor = Processor();
this.pharosExtensions = this.asciidoctor.Extensions.create();
this.ndk = ndk;
@ -164,9 +164,9 @@ export default class Pharos { @@ -164,9 +164,9 @@ export default class Pharos {
private async loadAdvancedExtensions(): Promise<void> {
try {
const { createAdvancedExtensions } = await import(
"./utils/markup/asciidoctorExtensions"
"./utils/markup/asciidoctorExtensions.ts"
);
const advancedExtensions = createAdvancedExtensions();
createAdvancedExtensions();
// Note: Extensions merging might not be available in this version
// We'll handle this in the parse method instead
} catch (error) {
@ -549,7 +549,7 @@ export default class Pharos { @@ -549,7 +549,7 @@ export default class Pharos {
* - Each ID of a node containing children is mapped to the set of IDs of its children.
*/
private treeProcessor(
treeProcessor: Extensions.TreeProcessor,
_: Extensions.TreeProcessor,
document: Document,
) {
this.rootNodeId = this.generateNodeId(document);

10
src/lib/services/publisher.ts

@ -1,12 +1,8 @@ @@ -1,12 +1,8 @@
import { get } from "svelte/store";
import { ndkInstance } from "$lib/ndk";
import { getMimeTags } from "$lib/utils/mime";
import {
parseAsciiDocSections,
type ZettelSection,
} from "$lib/utils/ZettelParser";
import { ndkInstance } from "../ndk.ts";
import { getMimeTags } from "../utils/mime.ts";
import { parseAsciiDocSections } from "../utils/ZettelParser.ts";
import { NDKRelaySet, NDKEvent } from "@nostr-dev-kit/ndk";
import { nip19 } from "nostr-tools";
export interface PublishResult {
success: boolean;

2
src/lib/state.ts

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
import { browser } from "$app/environment";
import { writable, type Writable } from "svelte/store";
import type { Tab } from "./types";
import type { Tab } from "./types.ts";
export const pathLoaded: Writable<boolean> = writable(false);

4
src/lib/stores.ts

@ -3,9 +3,9 @@ import { writable } from "svelte/store"; @@ -3,9 +3,9 @@ import { writable } from "svelte/store";
// The old feedType store is no longer needed since we use the new relay management system
// All relay selection is now handled by the activeInboxRelays and activeOutboxRelays stores in ndk.ts
export let idList = writable<string[]>([]);
export const idList = writable<string[]>([]);
export let alexandriaKinds = writable<number[]>([30040, 30041, 30818]);
export const alexandriaKinds = writable<number[]>([30040, 30041, 30818]);
export interface PublicationLayoutVisibility {
toc: boolean;

4
src/lib/stores/networkStore.ts

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
import { writable, type Writable } from 'svelte/store';
import { detectNetworkCondition, NetworkCondition, startNetworkMonitoring } from '$lib/utils/network_detection';
import { writable } from "svelte/store";
import { detectNetworkCondition, NetworkCondition, startNetworkMonitoring } from '../utils/network_detection.ts';
// Network status store
export const networkCondition = writable<NetworkCondition>(NetworkCondition.ONLINE);

27
src/lib/stores/userStore.ts

@ -1,17 +1,17 @@ @@ -1,17 +1,17 @@
import { writable, get } from "svelte/store";
import type { NostrProfile } from "$lib/utils/nostrUtils";
import type { NostrProfile } from "../utils/nostrUtils.ts";
import type { NDKUser, NDKSigner } from "@nostr-dev-kit/ndk";
import {
import NDK, {
NDKNip07Signer,
NDKRelayAuthPolicies,
NDKRelaySet,
NDKRelay,
} from "@nostr-dev-kit/ndk";
import { getUserMetadata } from "$lib/utils/nostrUtils";
import { ndkInstance, activeInboxRelays, activeOutboxRelays, updateActiveRelayStores } from "$lib/ndk";
import { loginStorageKey } from "$lib/consts";
import { getUserMetadata } from "../utils/nostrUtils.ts";
import { ndkInstance, activeInboxRelays, activeOutboxRelays, updateActiveRelayStores } from "../ndk.ts";
import { loginStorageKey } from "../consts.ts";
import { nip19 } from "nostr-tools";
import { userPubkey } from "$lib/stores/authStore.Svelte";
import { userPubkey } from "../stores/authStore.Svelte.ts";
export interface UserState {
pubkey: string | null;
@ -69,7 +69,7 @@ function getPersistedRelays(user: NDKUser): [Set<string>, Set<string>] { @@ -69,7 +69,7 @@ function getPersistedRelays(user: NDKUser): [Set<string>, Set<string>] {
}
async function getUserPreferredRelays(
ndk: any,
ndk: NDK,
user: NDKUser,
fallbacks: readonly string[] = [...get(activeInboxRelays), ...get(activeOutboxRelays)],
): Promise<[Set<NDKRelay>, Set<NDKRelay>]> {
@ -90,9 +90,9 @@ async function getUserPreferredRelays( @@ -90,9 +90,9 @@ async function getUserPreferredRelays(
const outboxRelays = new Set<NDKRelay>();
if (relayList == null) {
const relayMap = await window.nostr?.getRelays?.();
const relayMap = await globalThis.nostr?.getRelays?.();
Object.entries(relayMap ?? {}).forEach(
([url, relayType]: [string, any]) => {
([url, relayType]: [string, Record<string, boolean | undefined>]) => {
const relay = new NDKRelay(
url,
NDKRelayAuthPolicies.signIn({ ndk }),
@ -139,15 +139,6 @@ function persistLogin(user: NDKUser, method: "extension" | "amber" | "npub") { @@ -139,15 +139,6 @@ function persistLogin(user: NDKUser, method: "extension" | "amber" | "npub") {
localStorage.setItem(loginMethodStorageKey, method);
}
function getPersistedLoginMethod(): "extension" | "amber" | "npub" | null {
return (
(localStorage.getItem(loginMethodStorageKey) as
| "extension"
| "amber"
| "npub") ?? null
);
}
function clearLogin() {
localStorage.removeItem(loginStorageKey);
localStorage.removeItem(loginMethodStorageKey);

2
src/lib/types.ts

@ -3,7 +3,7 @@ export type Tab = { @@ -3,7 +3,7 @@ export type Tab = {
type: TabType;
parent?: number;
previous?: Tab;
data?: any;
data?: unknown;
};
export type TabType =

8
src/lib/utils.ts

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { nip19 } from "nostr-tools";
import { getMatchingTags } from "./utils/nostrUtils";
import { getMatchingTags } from "./utils/nostrUtils.ts";
export function neventEncode(event: NDKEvent, relays: string[]) {
return nip19.neventEncode({
@ -97,8 +97,8 @@ export function isElementInViewport(el: string | HTMLElement) { @@ -97,8 +97,8 @@ export function isElementInViewport(el: string | HTMLElement) {
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
(globalThis.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (globalThis.innerWidth || document.documentElement.clientWidth)
);
}
@ -169,7 +169,7 @@ Array.prototype.findIndexAsync = function <T>( @@ -169,7 +169,7 @@ Array.prototype.findIndexAsync = function <T>(
* @param wait The number of milliseconds to delay
* @returns A debounced version of the function
*/
export function debounce<T extends (...args: any[]) => any>(
export function debounce<T extends (...args: unknown[]) => unknown>(
func: T,
wait: number,
): (...args: Parameters<T>) => void {

8
src/lib/utils/ZettelParser.ts

@ -1,9 +1,3 @@ @@ -1,9 +1,3 @@
import { ndkInstance } from "$lib/ndk";
import { signEvent, getEventHash } from "$lib/utils/nostrUtils";
import { getMimeTags } from "$lib/utils/mime";
import { communityRelays } from "$lib/consts";
import { nip19 } from "nostr-tools";
export interface ZettelSection {
title: string;
content: string;
@ -37,7 +31,7 @@ export function splitAsciiDocByHeadingLevel( @@ -37,7 +31,7 @@ export function splitAsciiDocByHeadingLevel(
export function parseZettelSection(section: string): ZettelSection {
const lines = section.split("\n");
let title = "Untitled";
let contentLines: string[] = [];
const contentLines: string[] = [];
let inHeader = true;
let tags: string[][] = [];
tags = extractTags(section);

13
src/lib/utils/event_input_utils.ts

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
import type { NDKEvent } from "./nostrUtils";
import type { NDKEvent } from "./nostrUtils.ts";
import { get } from "svelte/store";
import { ndkInstance } from "$lib/ndk";
import { ndkInstance } from "../ndk.ts";
import { NDKEvent as NDKEventClass } from "@nostr-dev-kit/ndk";
import { EVENT_KINDS } from "./search_constants";
@ -149,13 +149,6 @@ function extractAsciiDocDocumentHeader(content: string): string | null { @@ -149,13 +149,6 @@ function extractAsciiDocDocumentHeader(content: string): string | null {
return match ? match[1].trim() : null;
}
/**
* Extracts all section headers (lines starting with '== ').
*/
function extractAsciiDocSectionHeaders(content: string): string[] {
return Array.from(content.matchAll(/^==\s+(.+)$/gm)).map((m) => m[1].trim());
}
/**
* Extracts the topmost Markdown # header (line starting with '# ').
*/
@ -181,7 +174,7 @@ function splitAsciiDocSections(content: string): { @@ -181,7 +174,7 @@ function splitAsciiDocSections(content: string): {
let current: string[] = [];
let foundFirstSection = false;
let hasPreamble = false;
let preambleContent: string[] = [];
const preambleContent: string[] = [];
for (const line of lines) {
// Skip document title lines (= header)

18
src/lib/utils/event_search.ts

@ -1,18 +1,18 @@ @@ -1,18 +1,18 @@
import { ndkInstance } from "$lib/ndk";
import { fetchEventWithFallback } from "$lib/utils/nostrUtils";
import { nip19 } from "$lib/utils/nostrUtils";
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { ndkInstance } from "../ndk.ts";
import { fetchEventWithFallback } from "./nostrUtils.ts";
import { nip19 } from "nostr-tools";
import { NDKEvent, NDKFilter } from "@nostr-dev-kit/ndk";
import { get } from "svelte/store";
import { wellKnownUrl, isValidNip05Address } from "./search_utils";
import { TIMEOUTS, VALIDATION } from "./search_constants";
import { wellKnownUrl, isValidNip05Address } from "./search_utils.ts";
import { TIMEOUTS, VALIDATION } from "./search_constants.ts";
/**
* Search for a single event by ID or filter
*/
export async function searchEvent(query: string): Promise<NDKEvent | null> {
// Clean the query and normalize to lowercase
let cleanedQuery = query.replace(/^nostr:/, "").toLowerCase();
let filterOrId: any = cleanedQuery;
const cleanedQuery = query.replace(/^nostr:/, "").toLowerCase();
let filterOrId: NDKFilter | string = cleanedQuery;
// If it's a valid hex string, try as event id first, then as pubkey (profile)
if (
@ -164,7 +164,7 @@ export async function findContainingIndexEvents( @@ -164,7 +164,7 @@ export async function findContainingIndexEvents(
): Promise<NDKEvent[]> {
// Support all content event kinds that can be contained in indexes
const contentEventKinds = [30041, 30818, 30040, 30023];
if (!contentEventKinds.includes(contentEvent.kind)) {
if (!contentEventKinds.includes(contentEvent.kind!)) {
return [];
}

5
src/lib/utils/indexEventCache.ts

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
import type { NDKEvent } from "./nostrUtils";
import { CACHE_DURATIONS, TIMEOUTS } from "./search_constants";
import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { CACHE_DURATIONS, TIMEOUTS } from "./search_constants.ts";
export interface IndexEventCacheEntry {
events: NDKEvent[];
@ -84,7 +84,6 @@ class IndexEventCache { @@ -84,7 +84,6 @@ class IndexEventCache {
* Clear expired entries from cache
*/
cleanup(): void {
const now = Date.now();
for (const [key, entry] of this.cache.entries()) {
if (this.isExpired(entry)) {
this.cache.delete(key);

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

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
import { postProcessAsciidoctorHtml } from "./asciidoctorPostProcessor";
import { postProcessAsciidoctorHtml } from "./asciidoctorPostProcessor.ts";
import plantumlEncoder from "plantuml-encoder";
/**
@ -25,16 +25,16 @@ export async function postProcessAdvancedAsciidoctorHtml( @@ -25,16 +25,16 @@ export async function postProcessAdvancedAsciidoctorHtml(
processedHtml = processTikZBlocks(processedHtml);
// After all processing, apply highlight.js if available
if (
typeof window !== "undefined" &&
typeof window.hljs?.highlightAll === "function"
typeof globalThis !== "undefined" &&
typeof globalThis.hljs?.highlightAll === "function"
) {
setTimeout(() => window.hljs!.highlightAll(), 0);
setTimeout(() => globalThis.hljs!.highlightAll(), 0);
}
if (
typeof window !== "undefined" &&
typeof (window as any).MathJax?.typesetPromise === "function"
typeof globalThis !== "undefined" &&
typeof globalThis.MathJax?.typesetPromise === "function"
) {
setTimeout(() => (window as any).MathJax.typesetPromise(), 0);
setTimeout(() => globalThis.MathJax.typesetPromise(), 0);
}
return processedHtml;
} catch (error) {

24
src/lib/utils/markup/advancedMarkupParser.ts

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
import { parseBasicmarkup } from "./basicMarkupParser";
import { parseBasicmarkup } from "./basicMarkupParser.ts";
import hljs from "highlight.js";
import "highlight.js/lib/common"; // Import common languages
import "highlight.js/styles/github-dark.css"; // Dark theme only
@ -35,14 +35,14 @@ const FOOTNOTE_DEFINITION_REGEX = /^\[\^([^\]]+)\]:\s*(.+)$/gm; @@ -35,14 +35,14 @@ const FOOTNOTE_DEFINITION_REGEX = /^\[\^([^\]]+)\]:\s*(.+)$/gm;
const CODE_BLOCK_REGEX = /^```(\w*)$/;
// LaTeX math regex patterns
const INLINE_MATH_REGEX = /\$([^$\n]+?)\$/g;
const DISPLAY_MATH_REGEX = /\$\$([\s\S]*?)\$\$/g;
const LATEX_BLOCK_REGEX = /\\\[([\s\S]*?)\\\]/g;
const LATEX_INLINE_REGEX = /\\\(([^)]+?)\\\)/g;
// const INLINE_MATH_REGEX = /\$([^$\n]+?)\$/g;
// const DISPLAY_MATH_REGEX = /\$\$([\s\S]*?)\$\$/g;
// const LATEX_BLOCK_REGEX = /\\\[([\s\S]*?)\\\]/g;
// const LATEX_INLINE_REGEX = /\\\(([^)]+?)\\\)/g;
// Add regex for LaTeX display math environments (e.g., \begin{pmatrix}...\end{pmatrix})
// Improved regex: match optional whitespace/linebreaks before and after, and allow for indented environments
const LATEX_ENV_BLOCK_REGEX =
/(?:^|\n)\s*\\begin\{([a-zA-Z*]+)\}([\s\S]*?)\\end\{\1\}\s*(?=\n|$)/gm;
// const LATEX_ENV_BLOCK_REGEX =
// /(?:^|\n)\s*\\begin\{([a-zA-Z*]+)\}([\s\S]*?)\\end\{\1\}\s*(?=\n|$)/gm;
/**
* Process headings (both styles)
@ -290,7 +290,7 @@ function processCodeBlocks(text: string): { @@ -290,7 +290,7 @@ function processCodeBlocks(text: string): {
if (currentLanguage.toLowerCase() === "json") {
try {
formattedCode = JSON.stringify(JSON.parse(code), null, 2);
} catch (e: unknown) {
} catch {
formattedCode = code;
}
}
@ -333,7 +333,7 @@ function processCodeBlocks(text: string): { @@ -333,7 +333,7 @@ function processCodeBlocks(text: string): {
if (currentLanguage.toLowerCase() === "json") {
try {
formattedCode = JSON.stringify(JSON.parse(code), null, 2);
} catch (e: unknown) {
} catch {
formattedCode = code;
}
}
@ -402,7 +402,7 @@ function restoreCodeBlocks(text: string, blocks: Map<string, string>): string { @@ -402,7 +402,7 @@ function restoreCodeBlocks(text: string, blocks: Map<string, string>): string {
*/
function processDollarMath(content: string): string {
// Display math: $$...$$ (multi-line, not empty)
content = content.replace(/\$\$([\s\S]*?\S[\s\S]*?)\$\$/g, (match, expr) => {
content = content.replace(/\$\$([\s\S]*?\S[\s\S]*?)\$\$/g, (_match, expr) => {
if (isLaTeXContent(expr)) {
return `<div class="math-block">$$${expr}$$</div>`;
} else {
@ -412,7 +412,7 @@ function processDollarMath(content: string): string { @@ -412,7 +412,7 @@ function processDollarMath(content: string): string {
}
});
// Inline math: $...$ (not empty, not just whitespace)
content = content.replace(/\$([^\s$][^$\n]*?)\$/g, (match, expr) => {
content = content.replace(/\$([^\s$][^$\n]*?)\$/g, (_match, expr) => {
if (isLaTeXContent(expr)) {
return `<span class="math-inline">$${expr}$</span>`;
} else {
@ -428,7 +428,7 @@ function processDollarMath(content: string): string { @@ -428,7 +428,7 @@ function processDollarMath(content: string): string {
*/
function processMathExpressions(content: string): string {
// Only process LaTeX within inline code blocks (backticks)
return content.replace(INLINE_CODE_REGEX, (match, code) => {
return content.replace(INLINE_CODE_REGEX, (_match, code) => {
const trimmedCode = code.trim();
// Check for unsupported LaTeX environments (like tabular) first

25
src/lib/utils/markup/asciidoctorExtensions.ts

@ -1,17 +1,6 @@ @@ -1,17 +1,6 @@
import { renderTikZ } from "./tikzRenderer";
import asciidoctor from "asciidoctor";
// Simple math rendering using MathJax CDN
function renderMath(content: string): string {
return `<div class="math-block" data-math="${encodeURIComponent(content)}">
<div class="math-content">${content}</div>
<script>
if (typeof MathJax !== 'undefined') {
MathJax.typesetPromise([document.querySelector('.math-content')]);
}
</script>
</div>`;
}
// deno-lint-ignore-file no-this-alias no-explicit-any
import Processor from "asciidoctor";
import { renderTikZ } from "./tikzRenderer.ts";
// Simple PlantUML rendering using PlantUML server
function renderPlantUML(content: string): string {
@ -27,7 +16,7 @@ function renderPlantUML(content: string): string { @@ -27,7 +16,7 @@ function renderPlantUML(content: string): string {
* including Asciimath/Latex, PlantUML, BPMN, and TikZ
*/
export function createAdvancedExtensions(): any {
const Asciidoctor = asciidoctor();
const Asciidoctor = Processor();
const extensions = Asciidoctor.Extensions.create();
// Math rendering extension (Asciimath/Latex)
@ -95,7 +84,7 @@ export function createAdvancedExtensions(): any { @@ -95,7 +84,7 @@ export function createAdvancedExtensions(): any {
/**
* Processes math blocks (stem blocks) and converts them to rendered HTML
*/
function processMathBlocks(treeProcessor: any, document: any): void {
function processMathBlocks(_: any, document: any): void {
const blocks = document.getBlocks();
for (const block of blocks) {
if (block.getContext() === "stem") {
@ -131,7 +120,7 @@ function processMathBlocks(treeProcessor: any, document: any): void { @@ -131,7 +120,7 @@ function processMathBlocks(treeProcessor: any, document: any): void {
/**
* Processes PlantUML blocks and converts them to rendered SVG
*/
function processPlantUMLBlocks(treeProcessor: any, document: any): void {
function processPlantUMLBlocks(_: any, document: any): void {
const blocks = document.getBlocks();
for (const block of blocks) {
@ -156,7 +145,7 @@ function processPlantUMLBlocks(treeProcessor: any, document: any): void { @@ -156,7 +145,7 @@ function processPlantUMLBlocks(treeProcessor: any, document: any): void {
/**
* Processes TikZ blocks and converts them to rendered SVG
*/
function processTikZBlocks(treeProcessor: any, document: any): void {
function processTikZBlocks(_: any, document: any): void {
const blocks = document.getBlocks();
for (const block of blocks) {

8
src/lib/utils/markup/basicMarkupParser.ts

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
import { processNostrIdentifiers } from "../nostrUtils";
import { processNostrIdentifiers } from "../nostrUtils.ts";
import * as emoji from "node-emoji";
import { nip19 } from "nostr-tools";
@ -236,7 +236,7 @@ function processBasicFormatting(content: string): string { @@ -236,7 +236,7 @@ function processBasicFormatting(content: string): string {
processedText = replaceAlexandriaNostrLinks(processedText);
// Process markup images first
processedText = processedText.replace(MARKUP_IMAGE, (match, alt, url) => {
processedText = processedText.replace(MARKUP_IMAGE, (_match, alt, url) => {
url = stripTrackingParams(url);
if (YOUTUBE_URL_REGEX.test(url)) {
const videoId = extractYouTubeVideoId(url);
@ -261,7 +261,7 @@ function processBasicFormatting(content: string): string { @@ -261,7 +261,7 @@ function processBasicFormatting(content: string): string {
// Process markup links
processedText = processedText.replace(
MARKUP_LINK,
(match, text, url) =>
(_match, text, url) =>
`<a href="${stripTrackingParams(url)}" class="text-primary-600 dark:text-primary-500 hover:underline" target="_blank" rel="noopener noreferrer">${text}</a>`,
);
@ -303,7 +303,7 @@ function processBasicFormatting(content: string): string { @@ -303,7 +303,7 @@ function processBasicFormatting(content: string): string {
});
processedText = processedText.replace(
STRIKETHROUGH_REGEX,
(match, doubleText, singleText) => {
(_match, doubleText, singleText) => {
const text = doubleText || singleText;
return `<del class="line-through">${text}</del>`;
},

11
src/lib/utils/network_detection.ts

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
import { deduplicateRelayUrls } from './relay_management';
import { deduplicateRelayUrls } from "./relay_management.ts";
/**
* Network conditions for relay selection
@ -26,7 +26,7 @@ export async function isNetworkOnline(): Promise<boolean> { @@ -26,7 +26,7 @@ export async function isNetworkOnline(): Promise<boolean> {
for (const endpoint of NETWORK_ENDPOINTS) {
try {
// Use a simple fetch without HEAD method to avoid CORS issues
const response = await fetch(endpoint, {
await fetch(endpoint, {
method: 'GET',
cache: 'no-cache',
signal: AbortSignal.timeout(3000),
@ -127,8 +127,7 @@ export function getRelaySetForNetworkCondition( @@ -127,8 +127,7 @@ export function getRelaySetForNetworkCondition(
outboxRelays: []
};
}
case NetworkCondition.SLOW:
case NetworkCondition.SLOW: {
// Local relays + low bandwidth relays when slow (deduplicated)
console.debug('[network_detection.ts] Using local + low bandwidth relays (slow network)');
const slowInboxRelays = deduplicateRelayUrls([...discoveredLocalRelays, ...lowbandwidthRelays]);
@ -137,7 +136,7 @@ export function getRelaySetForNetworkCondition( @@ -137,7 +136,7 @@ export function getRelaySetForNetworkCondition(
inboxRelays: slowInboxRelays,
outboxRelays: slowOutboxRelays
};
}
case NetworkCondition.ONLINE:
default:
// Full relay set when online
@ -177,7 +176,7 @@ export function startNetworkMonitoring( @@ -177,7 +176,7 @@ export function startNetworkMonitoring(
checkNetwork();
// Set up periodic monitoring
intervalId = window.setInterval(checkNetwork, checkInterval);
intervalId = globalThis.setInterval(checkNetwork, checkInterval);
// Return function to stop monitoring
return () => {

21
src/lib/utils/nostrEventService.ts

@ -1,10 +1,9 @@ @@ -1,10 +1,9 @@
import { nip19 } from "nostr-tools";
import { getEventHash, signEvent, prefixNostrAddresses } from "./nostrUtils";
import { getEventHash, signEvent, prefixNostrAddresses } from "./nostrUtils.ts";
import { get } from "svelte/store";
import { goto } from "$app/navigation";
import { EVENT_KINDS, TIME_CONSTANTS, TIMEOUTS } from "./search_constants";
import { activeInboxRelays, activeOutboxRelays } from "$lib/ndk";
import { ndkInstance } from "$lib/ndk";
import { EVENT_KINDS, TIME_CONSTANTS } from "./search_constants.ts";
import { ndkInstance } from "../ndk.ts";
import { NDKRelaySet, NDKEvent } from "@nostr-dev-kit/ndk";
export interface RootEventInfo {
@ -139,7 +138,6 @@ export function extractParentEventInfo(parent: NDKEvent): ParentEventInfo { @@ -139,7 +138,6 @@ export function extractParentEventInfo(parent: NDKEvent): ParentEventInfo {
*/
function buildRootScopeTags(
rootInfo: RootEventInfo,
parentInfo: ParentEventInfo,
): string[][] {
const tags: string[][] = [];
@ -292,7 +290,7 @@ export function buildReplyTags( @@ -292,7 +290,7 @@ export function buildReplyTags(
// For regular events, use E/e tags
if (isReplyToComment) {
// Reply to a comment - distinguish root from parent
addTags(tags, ...buildRootScopeTags(rootInfo, parentInfo));
addTags(tags, ...buildRootScopeTags(rootInfo));
addTags(
tags,
createTag("e", parent.id, parentInfo.parentRelay),
@ -301,7 +299,7 @@ export function buildReplyTags( @@ -301,7 +299,7 @@ export function buildReplyTags(
);
} else {
// Top-level comment or regular event
addTags(tags, ...buildRootScopeTags(rootInfo, parentInfo));
addTags(tags, ...buildRootScopeTags(rootInfo));
addTags(tags, ...buildParentScopeTags(parent, parentInfo, rootInfo));
}
}
@ -318,6 +316,7 @@ export async function createSignedEvent( @@ -318,6 +316,7 @@ export async function createSignedEvent(
pubkey: string,
kind: number,
tags: string[][],
// deno-lint-ignore no-explicit-any
): Promise<{ id: string; sig: string; event: any }> {
const prefixedContent = prefixNostrAddresses(content);
@ -337,8 +336,8 @@ export async function createSignedEvent( @@ -337,8 +336,8 @@ export async function createSignedEvent(
};
let sig, id;
if (typeof window !== "undefined" && window.nostr && window.nostr.signEvent) {
const signed = await window.nostr.signEvent(eventToSign);
if (typeof window !== "undefined" && globalThis.nostr && globalThis.nostr.signEvent) {
const signed = await globalThis.nostr.signEvent(eventToSign);
sig = signed.sig as string;
id = "id" in signed ? (signed.id as string) : getEventHash(eventToSign);
} else {
@ -364,7 +363,7 @@ export async function createSignedEvent( @@ -364,7 +363,7 @@ export async function createSignedEvent(
* @returns Promise that resolves to array of successful relay URLs
*/
export async function publishEvent(
event: NDKEvent | any,
event: NDKEvent,
relayUrls: string[],
): Promise<string[]> {
const successfulRelays: string[] = [];
@ -427,6 +426,7 @@ export function navigateToEvent(eventId: string): void { @@ -427,6 +426,7 @@ export function navigateToEvent(eventId: string): void {
}
// Helper functions to ensure relay and pubkey are always strings
// deno-lint-ignore no-explicit-any
function getRelayString(relay: any): string {
if (!relay) return "";
if (typeof relay === "string") return relay;
@ -434,6 +434,7 @@ function getRelayString(relay: any): string { @@ -434,6 +434,7 @@ function getRelayString(relay: any): string {
return "";
}
// deno-lint-ignore no-explicit-any
function getPubkeyString(pubkey: any): string {
if (!pubkey) return "";
if (typeof pubkey === "string") return pubkey;

26
src/lib/utils/nostrUtils.ts

@ -1,17 +1,17 @@ @@ -1,17 +1,17 @@
import { get } from "svelte/store";
import { nip19 } from "nostr-tools";
import { ndkInstance } from "$lib/ndk";
import { npubCache } from "./npubCache";
import { ndkInstance } from "../ndk.ts";
import { npubCache } from "./npubCache.ts";
import NDK, { NDKEvent, NDKRelaySet, NDKUser } from "@nostr-dev-kit/ndk";
import type { NDKFilter, NDKKind } from "@nostr-dev-kit/ndk";
import { communityRelays, secondaryRelays, anonymousRelays } from "$lib/consts";
import { activeInboxRelays, activeOutboxRelays } from "$lib/ndk";
import type { NDKFilter, NDKKind, NostrEvent } from "@nostr-dev-kit/ndk";
import { communityRelays, secondaryRelays } from "../consts.ts";
import { activeInboxRelays, activeOutboxRelays } from "../ndk.ts";
import { NDKRelaySet as NDKRelaySetFromNDK } from "@nostr-dev-kit/ndk";
import { sha256 } from "@noble/hashes/sha256";
import { sha256 } from "@noble/hashes/sha2.js";
import { schnorr } from "@noble/curves/secp256k1";
import { bytesToHex } from "@noble/hashes/utils";
import { wellKnownUrl } from "./search_utility";
import { TIMEOUTS, VALIDATION } from "./search_constants";
import { wellKnownUrl } from "./search_utility.ts";
import { VALIDATION } from "./search_constants.ts";
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>';
@ -442,7 +442,7 @@ export async function fetchEventWithFallback( @@ -442,7 +442,7 @@ export async function fetchEventWithFallback(
// Use both inbox and outbox relays for better event discovery
const inboxRelays = get(activeInboxRelays);
const outboxRelays = get(activeOutboxRelays);
const allRelays = [...(inboxRelays || []), ...(outboxRelays || [])];
const allRelays = [...inboxRelays, ...outboxRelays];
console.log("fetchEventWithFallback: Using inbox relays:", inboxRelays);
console.log("fetchEventWithFallback: Using outbox relays:", outboxRelays);
@ -464,7 +464,7 @@ export async function fetchEventWithFallback( @@ -464,7 +464,7 @@ export async function fetchEventWithFallback(
console.log("fetchEventWithFallback: Relay set size:", relaySet.relays.size);
console.log("fetchEventWithFallback: Filter:", filterOrId);
console.log("fetchEventWithFallback: Relay URLs:", Array.from(relaySet.relays).map((r: any) => r.url));
console.log("fetchEventWithFallback: Relay URLs:", Array.from(relaySet.relays).map((r) => r.url));
let found: NDKEvent | null = null;
@ -488,7 +488,7 @@ export async function fetchEventWithFallback( @@ -488,7 +488,7 @@ export async function fetchEventWithFallback(
if (!found) {
const timeoutSeconds = timeoutMs / 1000;
const relayUrls = Array.from(relaySet.relays).map((r: any) => r.url).join(", ");
const relayUrls = Array.from(relaySet.relays).map((r) => r.url).join(", ");
console.warn(
`fetchEventWithFallback: Event not found after ${timeoutSeconds}s timeout. Tried inbox relays: ${relayUrls}. Some relays may be offline or slow.`,
);
@ -501,7 +501,7 @@ export async function fetchEventWithFallback( @@ -501,7 +501,7 @@ export async function fetchEventWithFallback(
} catch (err) {
if (err instanceof Error && err.message === 'Timeout') {
const timeoutSeconds = timeoutMs / 1000;
const relayUrls = Array.from(relaySet.relays).map((r: any) => r.url).join(", ");
const relayUrls = Array.from(relaySet.relays).map((r) => r.url).join(", ");
console.warn(
`fetchEventWithFallback: Event fetch timed out after ${timeoutSeconds}s. Tried inbox relays: ${relayUrls}. Some relays may be offline or slow.`,
);
@ -536,7 +536,7 @@ export function createRelaySetFromUrls(relayUrls: string[], ndk: NDK) { @@ -536,7 +536,7 @@ export function createRelaySetFromUrls(relayUrls: string[], ndk: NDK) {
return NDKRelaySetFromNDK.fromRelayUrls(relayUrls, ndk);
}
export function createNDKEvent(ndk: NDK, rawEvent: any) {
export function createNDKEvent(ndk: NDK, rawEvent: NDKEvent | NostrEvent | undefined) {
return new NDKEvent(ndk, rawEvent);
}

30
src/lib/utils/profile_search.ts

@ -1,19 +1,16 @@ @@ -1,19 +1,16 @@
import { ndkInstance } from "$lib/ndk";
import { getUserMetadata, getNpubFromNip05 } from "$lib/utils/nostrUtils";
import { NDKRelaySet, NDKEvent } from "@nostr-dev-kit/ndk";
import { searchCache } from "$lib/utils/searchCache";
import { communityRelays, secondaryRelays } from "$lib/consts";
import { ndkInstance } from "../ndk.ts";
import { getUserMetadata, getNpubFromNip05 } from "./nostrUtils.ts";
import NDK, { NDKRelaySet, NDKEvent } from "@nostr-dev-kit/ndk";
import { searchCache } from "./searchCache.ts";
import { communityRelays, secondaryRelays } from "../consts.ts";
import { get } from "svelte/store";
import type { NostrProfile, ProfileSearchResult } from "./search_types";
import type { NostrProfile, ProfileSearchResult } from "./search_types.ts";
import {
fieldMatches,
nip05Matches,
normalizeSearchTerm,
COMMON_DOMAINS,
createProfileFromEvent,
} from "./search_utils";
import { checkCommunityStatus } from "./community_checker";
import { TIMEOUTS } from "./search_constants";
} from "./search_utils.ts";
/**
* Search for profiles by various criteria (display name, name, NIP-05, npub)
@ -92,7 +89,7 @@ export async function searchProfiles( @@ -92,7 +89,7 @@ export async function searchProfiles(
} else {
// Try NIP-05 search first (faster than relay search)
console.log("Starting NIP-05 search for:", normalizedSearchTerm);
foundProfiles = await searchNip05Domains(normalizedSearchTerm, ndk);
foundProfiles = await searchNip05Domains(normalizedSearchTerm);
console.log(
"NIP-05 search completed, found:",
foundProfiles.length,
@ -145,7 +142,6 @@ export async function searchProfiles( @@ -145,7 +142,6 @@ export async function searchProfiles(
*/
async function searchNip05Domains(
searchTerm: string,
ndk: any,
): Promise<NostrProfile[]> {
const foundProfiles: NostrProfile[] = [];
@ -260,10 +256,9 @@ async function searchNip05Domains( @@ -260,10 +256,9 @@ async function searchNip05Domains(
*/
async function quickRelaySearch(
searchTerm: string,
ndk: any,
ndk: NDK,
): Promise<NostrProfile[]> {
console.log("quickRelaySearch called with:", searchTerm);
const foundProfiles: NostrProfile[] = [];
// Normalize the search term for relay search
const normalizedSearchTerm = normalizeSearchTerm(searchTerm);
@ -286,7 +281,7 @@ async function quickRelaySearch( @@ -286,7 +281,7 @@ async function quickRelaySearch(
.filter(Boolean);
// Search all relays in parallel with short timeout
const searchPromises = relaySets.map(async (relaySet, index) => {
const searchPromises = relaySets.map((relaySet, index) => {
if (!relaySet) return [];
return new Promise<NostrProfile[]>((resolve) => {
@ -299,7 +294,8 @@ async function quickRelaySearch( @@ -299,7 +294,8 @@ async function quickRelaySearch(
const sub = ndk.subscribe(
{ kinds: [0] },
{ closeOnEose: true, relaySet },
{ closeOnEose: true },
relaySet,
);
sub.on("event", (event: NDKEvent) => {
@ -351,7 +347,7 @@ async function quickRelaySearch( @@ -351,7 +347,7 @@ async function quickRelaySearch(
foundInRelay.push(profile);
}
}
} catch (e) {
} catch {
// Invalid JSON or other error, skip
}
});

7
src/lib/utils/relayDiagnostics.ts

@ -1,6 +1,5 @@ @@ -1,6 +1,5 @@
import { activeInboxRelays, activeOutboxRelays } from "$lib/ndk";
import NDK from "@nostr-dev-kit/ndk";
import { TIMEOUTS } from "./search_constants";
import { activeInboxRelays, activeOutboxRelays } from "../ndk.ts";
import { TIMEOUTS } from "./search_constants.ts";
import { get } from "svelte/store";
export interface RelayDiagnostic {
@ -14,7 +13,7 @@ export interface RelayDiagnostic { @@ -14,7 +13,7 @@ export interface RelayDiagnostic {
/**
* Tests connection to a single relay
*/
export async function testRelay(url: string): Promise<RelayDiagnostic> {
export function testRelay(url: string): Promise<RelayDiagnostic> {
const startTime = Date.now();
return new Promise((resolve) => {

34
src/lib/utils/relay_management.ts

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
import NDK, { NDKRelay, NDKUser } from "@nostr-dev-kit/ndk";
import { communityRelays, searchRelays, secondaryRelays, anonymousRelays, lowbandwidthRelays, localRelays } from "../consts";
import { getRelaySetForNetworkCondition, NetworkCondition } from "./network_detection";
import { networkCondition } from "../stores/networkStore";
import NDK, { NDKKind, NDKRelay, NDKUser } from "@nostr-dev-kit/ndk";
import { searchRelays, secondaryRelays, anonymousRelays, lowbandwidthRelays, localRelays } from "../consts.ts";
import { getRelaySetForNetworkCondition } from "./network_detection.ts";
import { networkCondition } from "../stores/networkStore.ts";
import { get } from "svelte/store";
/**
@ -48,7 +48,7 @@ export function deduplicateRelayUrls(urls: string[]): string[] { @@ -48,7 +48,7 @@ export function deduplicateRelayUrls(urls: string[]): string[] {
* @param ndk The NDK instance
* @returns Promise that resolves to connection status
*/
export async function testRelayConnection(
export function testRelayConnection(
relayUrl: string,
ndk: NDK,
): Promise<{
@ -163,7 +163,7 @@ async function testLocalRelays(localRelayUrls: string[], ndk: NDK): Promise<stri @@ -163,7 +163,7 @@ async function testLocalRelays(localRelayUrls: string[], ndk: NDK): Promise<stri
} else {
console.debug(`[relay_management.ts] Local relay failed: ${url} - ${result.error}`);
}
} catch (error) {
} catch {
// Silently ignore local relay failures - they're optional
console.debug(`[relay_management.ts] Local relay error (ignored): ${url}`);
}
@ -188,7 +188,7 @@ export async function discoverLocalRelays(ndk: NDK): Promise<string[]> { @@ -188,7 +188,7 @@ export async function discoverLocalRelays(ndk: NDK): Promise<string[]> {
}
// Convert wss:// URLs from consts to ws:// for local testing
const localRelayUrls = localRelays.map(url =>
const localRelayUrls = localRelays.map((url: string) =>
url.replace(/^wss:\/\//, 'ws://')
);
@ -197,7 +197,7 @@ export async function discoverLocalRelays(ndk: NDK): Promise<string[]> { @@ -197,7 +197,7 @@ export async function discoverLocalRelays(ndk: NDK): Promise<string[]> {
// If no local relays are working, return empty array
// The network detection logic will provide fallback relays
return workingRelays;
} catch (error) {
} catch {
// Silently fail and return empty array
return [];
}
@ -213,7 +213,7 @@ export async function getUserLocalRelays(ndk: NDK, user: NDKUser): Promise<strin @@ -213,7 +213,7 @@ export async function getUserLocalRelays(ndk: NDK, user: NDKUser): Promise<strin
try {
const localRelayEvent = await ndk.fetchEvent(
{
kinds: [10432 as any],
kinds: [10432 as NDKKind],
authors: [user.pubkey],
},
{
@ -338,8 +338,8 @@ export async function getUserOutboxRelays(ndk: NDK, user: NDKUser): Promise<stri @@ -338,8 +338,8 @@ export async function getUserOutboxRelays(ndk: NDK, user: NDKUser): Promise<stri
export async function getExtensionRelays(): Promise<string[]> {
try {
// Check if we're in a browser environment with extension support
if (typeof window === 'undefined' || !window.nostr) {
console.debug('[relay_management.ts] No window.nostr available');
if (typeof window === 'undefined' || !globalThis.nostr) {
console.debug('[relay_management.ts] No globalThis.nostr available');
return [];
}
@ -348,10 +348,10 @@ export async function getExtensionRelays(): Promise<string[]> { @@ -348,10 +348,10 @@ export async function getExtensionRelays(): Promise<string[]> {
// Try to get relays from the extension's API
// Different extensions may expose their relay config differently
if (window.nostr.getRelays) {
if (globalThis.nostr.getRelays) {
console.debug('[relay_management.ts] getRelays() method found, calling it...');
try {
const relays = await window.nostr.getRelays();
const relays = await globalThis.nostr.getRelays();
console.debug('[relay_management.ts] getRelays() returned:', relays);
if (relays && typeof relays === 'object') {
// Convert relay object to array of URLs
@ -363,7 +363,7 @@ export async function getExtensionRelays(): Promise<string[]> { @@ -363,7 +363,7 @@ export async function getExtensionRelays(): Promise<string[]> {
console.debug('[relay_management.ts] Extension getRelays() failed:', error);
}
} else {
console.debug('[relay_management.ts] getRelays() method not found on window.nostr');
console.debug('[relay_management.ts] getRelays() method not found on globalThis.nostr');
}
// If getRelays() didn't work, try alternative methods
@ -457,7 +457,7 @@ export async function buildCompleteRelaySet( @@ -457,7 +457,7 @@ export async function buildCompleteRelaySet(
try {
blockedRelays = await getUserBlockedRelays(ndk, user);
console.debug('[relay_management.ts] buildCompleteRelaySet: User blocked relays:', blockedRelays);
} catch (error) {
} catch {
// Silently ignore blocked relay fetch errors
}
@ -511,8 +511,8 @@ export async function buildCompleteRelaySet( @@ -511,8 +511,8 @@ export async function buildCompleteRelaySet(
// Filter out blocked relays and deduplicate final sets
const finalRelaySet = {
inboxRelays: deduplicateRelayUrls(networkOptimizedRelaySet.inboxRelays.filter(r => !blockedRelays.includes(r))),
outboxRelays: deduplicateRelayUrls(networkOptimizedRelaySet.outboxRelays.filter(r => !blockedRelays.includes(r)))
inboxRelays: deduplicateRelayUrls(networkOptimizedRelaySet.inboxRelays.filter((r: string) => !blockedRelays.includes(r))),
outboxRelays: deduplicateRelayUrls(networkOptimizedRelaySet.outboxRelays.filter((r: string) => !blockedRelays.includes(r)))
};
// If no relays are working, use anonymous relays as fallback

5
src/lib/utils/searchCache.ts

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
import type { NDKEvent } from "./nostrUtils";
import { CACHE_DURATIONS, TIMEOUTS } from "./search_constants";
import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { CACHE_DURATIONS, TIMEOUTS } from "./search_constants.ts";
export interface SearchResult {
events: NDKEvent[];
@ -78,7 +78,6 @@ class SearchCache { @@ -78,7 +78,6 @@ class SearchCache {
* Clear expired entries from cache
*/
cleanup(): void {
const now = Date.now();
for (const [key, result] of this.cache.entries()) {
if (this.isExpired(result)) {
this.cache.delete(key);

6
src/lib/utils/search_types.ts

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { NDKEvent, NDKFilter, NDKSubscription } from "@nostr-dev-kit/ndk";
/**
* Extended NostrProfile interface for search results
@ -45,7 +45,7 @@ export type SearchSubscriptionType = "d" | "t" | "n"; @@ -45,7 +45,7 @@ export type SearchSubscriptionType = "d" | "t" | "n";
* Search filter configuration
*/
export interface SearchFilter {
filter: any;
filter: NDKFilter;
subscriptionType: string;
}
@ -65,5 +65,5 @@ export interface SecondOrderSearchParams { @@ -65,5 +65,5 @@ export interface SecondOrderSearchParams {
*/
export interface SearchCallbacks {
onSecondOrderUpdate?: (result: SearchResult) => void;
onSubscriptionCreated?: (sub: any) => void;
onSubscriptionCreated?: (sub: NDKSubscription) => void;
}

7
src/lib/utils/search_utils.ts

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
import { NDKEvent } from "@nostr-dev-kit/ndk";
/**
* Generate well-known NIP-05 URL
*/
@ -85,14 +87,15 @@ export const COMMON_DOMAINS = [ @@ -85,14 +87,15 @@ export const COMMON_DOMAINS = [
/**
* Check if an event is an emoji reaction (kind 7)
*/
export function isEmojiReaction(event: any): boolean {
export function isEmojiReaction(event: NDKEvent): boolean {
return event.kind === 7;
}
/**
* Create a profile object from event data
*/
export function createProfileFromEvent(event: any, profileData: any): any {
// deno-lint-ignore no-explicit-any
export function createProfileFromEvent(event: NDKEvent, profileData: any): any {
return {
name: profileData.name,
displayName: profileData.displayName || profileData.display_name,

46
src/lib/utils/subscription_search.ts

@ -1,26 +1,25 @@ @@ -1,26 +1,25 @@
import { ndkInstance } from "$lib/ndk";
import { getMatchingTags, getNpubFromNip05 } from "$lib/utils/nostrUtils";
import { nip19 } from "$lib/utils/nostrUtils";
// deno-lint-ignore-file no-explicit-any
import { ndkInstance } from "../ndk.ts";
import { getMatchingTags, getNpubFromNip05 } from "./nostrUtils.ts";
import { nip19 } from "./nostrUtils.ts";
import { NDKRelaySet, NDKEvent } from "@nostr-dev-kit/ndk";
import { searchCache } from "$lib/utils/searchCache";
import { communityRelays, searchRelays } from "$lib/consts";
import { searchCache } from "./searchCache.ts";
import { communityRelays, searchRelays } from "../consts.ts";
import { get } from "svelte/store";
import type {
SearchResult,
SearchSubscriptionType,
SearchFilter,
SearchCallbacks,
SecondOrderSearchParams,
} from "./search_types";
} from "./search_types.ts";
import {
fieldMatches,
nip05Matches,
normalizeSearchTerm,
COMMON_DOMAINS,
isEmojiReaction,
} from "./search_utils";
import { TIMEOUTS, SEARCH_LIMITS } from "./search_constants";
import { activeInboxRelays, activeOutboxRelays } from "$lib/ndk";
} from "./search_utils.ts";
import { TIMEOUTS, SEARCH_LIMITS } from "./search_constants.ts";
import { activeInboxRelays, activeOutboxRelays } from "../ndk.ts";
// Helper function to normalize URLs for comparison
const normalizeUrl = (url: string): string => {
@ -132,7 +131,6 @@ export async function searchBySubscription( @@ -132,7 +131,6 @@ export async function searchBySubscription(
searchFilter,
searchState,
callbacks,
abortSignal,
cleanup,
);
@ -160,7 +158,6 @@ export async function searchBySubscription( @@ -160,7 +158,6 @@ export async function searchBySubscription(
searchFilter,
searchState,
callbacks,
abortSignal,
cleanup,
);
}
@ -215,28 +212,32 @@ async function createSearchFilter( @@ -215,28 +212,32 @@ async function createSearchFilter(
});
switch (searchType) {
case "d":
case "d": {
const dFilter = {
filter: { "#d": [normalizedSearchTerm] },
subscriptionType: "d-tag",
};
console.log("subscription_search: Created d-tag filter:", dFilter);
return dFilter;
case "t":
}
case "t": {
const tFilter = {
filter: { "#t": [normalizedSearchTerm] },
subscriptionType: "t-tag",
};
console.log("subscription_search: Created t-tag filter:", tFilter);
return tFilter;
case "n":
}
case "n": {
const nFilter = await createProfileSearchFilter(normalizedSearchTerm);
console.log("subscription_search: Created profile filter:", nFilter);
return nFilter;
default:
}
default: {
throw new Error(`Unknown search type: ${searchType}`);
}
}
}
/**
* Create profile search filter
@ -257,7 +258,7 @@ async function createProfileSearchFilter( @@ -257,7 +258,7 @@ async function createProfileSearchFilter(
subscriptionType: "npub-specific",
};
}
} catch (e) {
} catch {
// Not a valid npub, continue with other strategies
}
@ -277,11 +278,11 @@ async function createProfileSearchFilter( @@ -277,11 +278,11 @@ async function createProfileSearchFilter(
subscriptionType: "nip05-found",
};
}
} catch (e) {
} catch {
// Continue to next domain
}
}
} catch (e) {
} catch {
// Fallback to reasonable profile search
}
@ -520,12 +521,11 @@ function createSearchResult( @@ -520,12 +521,11 @@ function createSearchResult(
/**
* Search other relays in background
*/
async function searchOtherRelaysInBackground(
function searchOtherRelaysInBackground(
searchType: SearchSubscriptionType,
searchFilter: SearchFilter,
searchState: any,
callbacks?: SearchCallbacks,
abortSignal?: AbortSignal,
cleanup?: () => void,
): Promise<SearchResult> {
const ndk = get(ndkInstance);
@ -578,7 +578,7 @@ async function searchOtherRelaysInBackground( @@ -578,7 +578,7 @@ async function searchOtherRelaysInBackground(
} else {
processContentEvent(event, searchType, searchState);
}
} catch (e) {
} catch {
// Invalid JSON or other error, skip
}
});

15
src/routes/+layout.ts

@ -1,11 +1,11 @@ @@ -1,11 +1,11 @@
import { getPersistedLogin, initNdk, ndkInstance } from "$lib/ndk";
import { getPersistedLogin, initNdk, ndkInstance } from "../lib/ndk.ts";
import {
loginWithExtension,
loginWithAmber,
loginWithNpub,
} from "$lib/stores/userStore";
import { loginMethodStorageKey } from "$lib/stores/userStore";
import Pharos, { pharosInstance } from "$lib/parser";
} from "../lib/stores/userStore.ts";
import { loginMethodStorageKey } from "../lib/stores/userStore.ts";
import Pharos, { pharosInstance } from "../lib/parser.ts";
import type { LayoutLoad } from "./$types";
import { get } from "svelte/store";
@ -35,10 +35,11 @@ export const load: LayoutLoad = () => { @@ -35,10 +35,11 @@ export const load: LayoutLoad = () => {
const localNsec = localStorage.getItem("amber/nsec");
if (localNsec) {
import("@nostr-dev-kit/ndk").then(
async ({ NDKNip46Signer, default: NDK }) => {
async ({ NDKNip46Signer }) => {
const ndk = get(ndkInstance);
try {
const amberSigner = NDKNip46Signer.nostrconnect(
// deno-lint-ignore no-explicit-any
const amberSigner = (NDKNip46Signer as any).nostrconnect(
ndk,
relay,
localNsec,
@ -52,7 +53,7 @@ export const load: LayoutLoad = () => { @@ -52,7 +53,7 @@ export const load: LayoutLoad = () => {
const user = await amberSigner.user();
await loginWithAmber(amberSigner, user);
console.log("Amber session restored.");
} catch (err) {
} catch {
// If reconnection fails, automatically fallback to npub-only mode
console.warn(
"Amber session could not be restored. Falling back to npub-only mode.",

6
src/routes/+page.svelte

@ -1,12 +1,8 @@ @@ -1,12 +1,8 @@
<script lang="ts">
import { Alert, Input } from "flowbite-svelte";
import { HammerSolid } from "flowbite-svelte-icons";
import { userStore } from "$lib/stores/userStore";
import { activeInboxRelays, ndkSignedIn } from "$lib/ndk";
import { Input } from "flowbite-svelte";
import PublicationFeed from "$lib/components/publications/PublicationFeed.svelte";
let searchQuery = $state("");
let user = $derived($userStore);
let eventCount = $state({ displayed: 0, total: 0 });
function handleEventCountUpdate(counts: { displayed: number; total: number }) {

15
src/routes/publication/+page.ts

@ -2,8 +2,9 @@ import { error } from "@sveltejs/kit"; @@ -2,8 +2,9 @@ import { error } from "@sveltejs/kit";
import type { Load } from "@sveltejs/kit";
import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { nip19 } from "nostr-tools";
import { getActiveRelaySetAsNDKRelaySet } from "$lib/ndk";
import { getMatchingTags } from "$lib/utils/nostrUtils";
import { getActiveRelaySetAsNDKRelaySet } from "../../lib/ndk.ts";
import { getMatchingTags } from "../../lib/utils/nostrUtils.ts";
import type NDK from "@nostr-dev-kit/ndk";
/**
* Decodes an naddr identifier and returns a filter object
@ -30,7 +31,7 @@ function decodeNaddr(id: string) { @@ -30,7 +31,7 @@ function decodeNaddr(id: string) {
/**
* Fetches an event by ID or filter
*/
async function fetchEventById(ndk: any, id: string): Promise<NDKEvent> {
async function fetchEventById(ndk: NDK, id: string): Promise<NDKEvent> {
const filter = decodeNaddr(id);
// Handle the case where filter is null (decoding error)
@ -66,7 +67,7 @@ async function fetchEventById(ndk: any, id: string): Promise<NDKEvent> { @@ -66,7 +67,7 @@ async function fetchEventById(ndk: any, id: string): Promise<NDKEvent> {
/**
* Fetches an event by d tag
*/
async function fetchEventByDTag(ndk: any, dTag: string): Promise<NDKEvent> {
async function fetchEventByDTag(ndk: NDK, dTag: string): Promise<NDKEvent> {
try {
const relaySet = await getActiveRelaySetAsNDKRelaySet(ndk, true); // true for inbox relays
const event = await ndk.fetchEvent(
@ -90,7 +91,7 @@ export const load: Load = async ({ @@ -90,7 +91,7 @@ export const load: Load = async ({
parent,
}: {
url: URL;
parent: () => Promise<any>;
parent: () => Promise<Partial<Record<string, NDK>>>;
}) => {
const id = url.searchParams.get("id");
const dTag = url.searchParams.get("d");
@ -102,8 +103,8 @@ export const load: Load = async ({ @@ -102,8 +103,8 @@ export const load: Load = async ({
// Fetch the event based on available parameters
const indexEvent = id
? await fetchEventById(ndk, id)
: await fetchEventByDTag(ndk, dTag!);
? await fetchEventById(ndk!, id)
: await fetchEventByDTag(ndk!, dTag!);
const publicationType = getMatchingTags(indexEvent, "type")[0]?.[1];

3
vite.config.ts

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
import { execSync } from "child_process";
import process from "node:process";
// Function to get the latest git tag
function getAppVersionString() {
@ -17,7 +18,7 @@ function getAppVersionString() { @@ -17,7 +18,7 @@ function getAppVersionString() {
// Get the latest git tag, assuming git is installed and tagged branch is available
const tag = execSync("git describe --tags --abbrev=0").toString().trim();
return tag;
} catch (error) {
} catch {
return "development";
}
}

Loading…
Cancel
Save