diff --git a/src/lib/utils/markup/basicMarkupParser.ts b/src/lib/utils/markup/basicMarkupParser.ts index 232e433..781ed23 100644 --- a/src/lib/utils/markup/basicMarkupParser.ts +++ b/src/lib/utils/markup/basicMarkupParser.ts @@ -2,23 +2,25 @@ import { processNostrIdentifiers } from '../nostrUtils'; import * as emoji from 'node-emoji'; import { nip19 } from 'nostr-tools'; -// Regular expressions for basic markup elements +/* Regex constants for basic markup parsing */ + +// Text formatting const BOLD_REGEX = /(\*\*|[*])((?:[^*\n]|\*(?!\*))+)\1/g; const ITALIC_REGEX = /\b(_[^_\n]+_|\b__[^_\n]+__)\b/g; const STRIKETHROUGH_REGEX = /~~([^~\n]+)~~|~([^~\n]+)~/g; const HASHTAG_REGEX = /(?[ \t]?.*)(?:\n\1[ \t]*(?!>).*)*$/gm; -// markup patterns -const markup_LINK = /\[([^\]]+)\]\(([^)]+)\)/g; -const markup_IMAGE = /!\[([^\]]*)\]\(([^)]+)\)/g; +// Block elements +const BLOCKQUOTE_REGEX = /^([ \t]*>[ \t]?.*)(?:\n\1[ \t]*(?!>).*)*$/gm; -// URL patterns +// Links and media +const MARKUP_LINK = /\[([^\]]+)\]\(([^)]+)\)/g; +const MARKUP_IMAGE = /!\[([^\]]*)\]\(([^)]+)\)/g; const WSS_URL = /wss:\/\/[^\s<>"]+/g; const DIRECT_LINK = /(?"]+)(?!["'])/g; // Media URL patterns -const IMAGE_URL_REGEX = /https?:\/\/[^\s<]+\.(?:jpg|jpeg|gif|png|webp)(?:[^\s<]*)?/i; +const IMAGE_EXTENSIONS = /\.(jpg|jpeg|gif|png|webp|svg)$/i; const VIDEO_URL_REGEX = /https?:\/\/[^\s<]+\.(?:mp4|webm|mov|avi)(?:[^\s<]*)?/i; const AUDIO_URL_REGEX = /https?:\/\/[^\s<]+\.(?:mp3|wav|ogg|m4a)(?:[^\s<]*)?/i; const YOUTUBE_URL_REGEX = /https?:\/\/(?:www\.)?(?:youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/|youtube-nocookie\.com\/embed\/)([a-zA-Z0-9_-]{11})(?:[^\s<]*)?/i; @@ -207,7 +209,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); @@ -222,7 +224,7 @@ function processBasicFormatting(content: string): string { return ``; } // Only render if the url ends with a direct image extension - if (/\.(jpg|jpeg|gif|png|webp|svg)$/i.test(url.split('?')[0])) { + if (IMAGE_EXTENSIONS.test(url.split('?')[0])) { return `${alt}`; } // Otherwise, render as a clickable link @@ -230,7 +232,7 @@ function processBasicFormatting(content: string): string { }); // Process markup links - processedText = processedText.replace(markup_LINK, (match, text, url) => + processedText = processedText.replace(MARKUP_LINK, (match, text, url) => `${text}` ); @@ -257,7 +259,7 @@ function processBasicFormatting(content: string): string { return ``; } // Only render if the url ends with a direct image extension - if (/\.(jpg|jpeg|gif|png|webp|svg)$/i.test(clean.split('?')[0])) { + if (IMAGE_EXTENSIONS.test(clean.split('?')[0])) { return `Embedded media`; } // Otherwise, render as a clickable link diff --git a/src/lib/utils/npubCache.ts b/src/lib/utils/npubCache.ts index 55bf8cc..085c148 100644 --- a/src/lib/utils/npubCache.ts +++ b/src/lib/utils/npubCache.ts @@ -15,6 +15,32 @@ class NpubCache { return key in this.cache; } + delete(key: string): boolean { + if (key in this.cache) { + delete this.cache[key]; + return true; + } + return false; + } + + deleteMany(keys: string[]): number { + let deleted = 0; + for (const key of keys) { + if (this.delete(key)) { + deleted++; + } + } + return deleted; + } + + clear(): void { + this.cache = {}; + } + + size(): number { + return Object.keys(this.cache).length; + } + getAll(): Record { return { ...this.cache }; }