@arborium/arborium 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"arborium.js","sources":["../src/wasi-shims.ts","../src/loader.ts","../src/detect.ts"],"sourcesContent":["/**\n * Minimal WASI shims for browser environment.\n * These provide stub implementations for WASI interfaces that\n * the grammar plugins require but don't actually use.\n */\n\n// Error type for WASI I/O\nclass WasiError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WasiError';\n }\n}\n\n// Minimal stream implementation\nclass OutputStream {\n write(_contents: Uint8Array): bigint {\n // Silently discard output\n return BigInt(0);\n }\n\n blockingWriteAndFlush(_contents: Uint8Array): void {\n // No-op\n }\n\n blockingFlush(): void {\n // No-op\n }\n\n checkWrite(): bigint {\n return BigInt(1024 * 1024); // Allow large writes\n }\n\n subscribe(): void {\n // No-op\n }\n}\n\nclass InputStream {\n read(_len: bigint): Uint8Array {\n return new Uint8Array(0);\n }\n\n blockingRead(_len: bigint): Uint8Array {\n return new Uint8Array(0);\n }\n\n subscribe(): void {\n // No-op\n }\n}\n\n// Create the WASI import object expected by jco-generated modules\nexport function createWasiImports() {\n const stdout = new OutputStream();\n const stderr = new OutputStream();\n const stdin = new InputStream();\n\n // WASI interface implementations\n const environment = {\n getEnvironment: (): Array<[string, string]> => [],\n getArguments: (): string[] => [],\n };\n\n const exit = {\n exit: (status: { tag: string; val?: number }): void => {\n if (status.tag === 'err') {\n throw new WasiError(`WASI exit with error: ${status.val}`);\n }\n },\n };\n\n const stdinIface = { getStdin: () => stdin };\n const stdoutIface = { getStdout: () => stdout };\n const stderrIface = { getStderr: () => stderr };\n\n const wallClock = {\n now: (): { seconds: bigint; nanoseconds: number } => {\n const ms = Date.now();\n return {\n seconds: BigInt(Math.floor(ms / 1000)),\n nanoseconds: (ms % 1000) * 1_000_000,\n };\n },\n resolution: (): { seconds: bigint; nanoseconds: number } => {\n return { seconds: BigInt(0), nanoseconds: 1_000_000 };\n },\n };\n\n const filesystemTypes = {\n Descriptor: class {},\n DirectoryEntryStream: class {},\n filesystemErrorCode: () => null,\n };\n\n const preopens = {\n getDirectories: (): Array<[unknown, string]> => [],\n };\n\n const ioError = { Error: WasiError };\n const streams = { InputStream, OutputStream };\n\n const random = {\n getRandomBytes: (len: bigint): Uint8Array => {\n const bytes = new Uint8Array(Number(len));\n crypto.getRandomValues(bytes);\n return bytes;\n },\n getRandomU64: (): bigint => {\n const bytes = new Uint8Array(8);\n crypto.getRandomValues(bytes);\n const view = new DataView(bytes.buffer);\n return view.getBigUint64(0, true);\n },\n };\n\n // Return both versioned (@0.2.3) and unversioned imports for compatibility\n return {\n // Unversioned (used by published grammars)\n 'wasi:cli/environment': environment,\n 'wasi:cli/exit': exit,\n 'wasi:cli/stdin': stdinIface,\n 'wasi:cli/stdout': stdoutIface,\n 'wasi:cli/stderr': stderrIface,\n 'wasi:clocks/wall-clock': wallClock,\n 'wasi:filesystem/types': filesystemTypes,\n 'wasi:filesystem/preopens': preopens,\n 'wasi:io/error': ioError,\n 'wasi:io/streams': streams,\n 'wasi:random/random': random,\n\n // Versioned @0.2.3 (for newer builds)\n 'wasi:cli/environment@0.2.3': environment,\n 'wasi:cli/exit@0.2.3': exit,\n 'wasi:cli/stdin@0.2.3': stdinIface,\n 'wasi:cli/stdout@0.2.3': stdoutIface,\n 'wasi:cli/stderr@0.2.3': stderrIface,\n 'wasi:clocks/wall-clock@0.2.3': wallClock,\n 'wasi:filesystem/types@0.2.3': filesystemTypes,\n 'wasi:filesystem/preopens@0.2.3': preopens,\n 'wasi:io/error@0.2.3': ioError,\n 'wasi:io/streams@0.2.3': streams,\n 'wasi:random/random@0.2.3': random,\n };\n}\n\n// Grammar types import (the plugin exports these)\nexport const grammarTypesImport = {\n 'arborium:grammar/types@0.1.0': {\n // Types are just interfaces, nothing to export\n },\n};\n","/**\n * Arborium loader - loads grammar plugins and highlights code.\n *\n * Architecture:\n * 1. Fetch plugins.json from arborium.bearcove.eu to get grammar CDN URLs\n * 2. Load grammar WIT components on demand from @arborium/<lang> packages\n * 3. Parse and highlight using the grammar's tree-sitter parser\n */\n\nimport { createWasiImports, grammarTypesImport } from './wasi-shims.js';\nimport type { ParseResult, ArboriumConfig, Grammar, Span, Injection } from './types.js';\n\n// Default config\nexport const defaultConfig: Required<ArboriumConfig> = {\n manual: false,\n theme: 'tokyo-night',\n selector: 'pre code',\n cdn: 'jsdelivr',\n version: '0.700.0',\n pluginsUrl: 'https://arborium.bearcove.eu/plugins.json',\n hostUrl: '', // Empty means use CDN based on version\n};\n\n// Rust host module (loaded on demand)\ninterface HostModule {\n highlight: (language: string, source: string) => string;\n isLanguageAvailable: (language: string) => boolean;\n}\nlet hostModule: HostModule | null = null;\nlet hostLoadPromise: Promise<HostModule | null> | null = null;\n\n// Merged config\nlet config: Required<ArboriumConfig> = { ...defaultConfig };\n\n// Grammar plugins cache\nconst grammarCache = new Map<string, GrammarPlugin>();\n\n// Plugin manifest from plugins.json\ninterface PluginEntry {\n language: string;\n package: string;\n version: string;\n cdn_js: string;\n cdn_wasm: string;\n local_js: string;\n local_wasm: string;\n}\n\ninterface PluginsManifest {\n dev_mode: boolean;\n generated_at: string;\n entries: PluginEntry[];\n}\n\nlet pluginsManifest: PluginsManifest | null = null;\n\n// Languages we know are available (from plugins.json)\nlet availableLanguages: Set<string> = new Set();\n\n/** WIT Result type as returned by jco-generated code */\ntype WitResult<T, E> =\n | { tag: 'ok'; val: T }\n | { tag: 'err'; val: E };\n\n/** Plugin interface as exported by jco-generated WIT components */\ninterface JcoPlugin {\n languageId(): string;\n injectionLanguages(): string[];\n createSession(): number;\n freeSession(session: number): void;\n setText(session: number, text: string): void;\n parse(session: number): WitResult<ParseResult, { message: string }>;\n}\n\n/** A loaded grammar plugin (WIT component) */\ninterface GrammarPlugin {\n languageId: string;\n injectionLanguages: string[];\n parse: (text: string) => ParseResult;\n}\n\n/** Load the plugins manifest */\nasync function loadPluginsManifest(): Promise<void> {\n if (pluginsManifest) return;\n\n console.debug(`[arborium] Loading plugins manifest: ${config.pluginsUrl}`);\n const response = await fetch(config.pluginsUrl);\n if (!response.ok) {\n throw new Error(`Failed to load plugins.json: ${response.status}`);\n }\n pluginsManifest = await response.json();\n\n // Populate available languages\n availableLanguages = new Set(pluginsManifest!.entries.map(e => e.language));\n console.debug(`[arborium] Available languages: ${Array.from(availableLanguages).join(', ')}`);\n}\n\n/** Load a grammar plugin */\nasync function loadGrammarPlugin(language: string): Promise<GrammarPlugin | null> {\n // Check cache\n const cached = grammarCache.get(language);\n if (cached) {\n console.debug(`[arborium] Grammar '${language}' found in cache`);\n return cached;\n }\n\n // Ensure manifest is loaded\n await loadPluginsManifest();\n\n // Find language entry\n const entry = pluginsManifest?.entries.find(e => e.language === language);\n if (!entry) {\n console.debug(`[arborium] Grammar '${language}' not found in manifest`);\n return null;\n }\n\n try {\n // Always use CDN URLs for grammars (they're published packages)\n // hostUrl only affects the host module loading\n const jsUrl = entry.cdn_js;\n const baseUrl = jsUrl.substring(0, jsUrl.lastIndexOf('/'));\n\n console.debug(`[arborium] Loading grammar '${language}' from ${jsUrl}`);\n // Dynamically import the JS module\n const module = await import(/* @vite-ignore */ jsUrl);\n\n // Create a getCoreModule function that fetches WASM files by path\n const getCoreModule = async (path: string): Promise<WebAssembly.Module> => {\n const wasmUrl = `${baseUrl}/${path}`;\n const response = await fetch(wasmUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch WASM ${path}: ${response.status}`);\n }\n const bytes = await response.arrayBuffer();\n return WebAssembly.compile(bytes);\n };\n\n // Create WASI imports\n const wasiImports = createWasiImports();\n const imports = {\n ...wasiImports,\n ...grammarTypesImport,\n };\n\n // Instantiate the jco-generated component\n const instance = await module.instantiate(getCoreModule, imports);\n\n // Get the plugin interface\n const jcoPlugin = (instance.plugin || instance['arborium:grammar/plugin@0.1.0']) as JcoPlugin;\n if (!jcoPlugin) {\n console.error(`Grammar '${language}' missing plugin interface`);\n return null;\n }\n\n // Wrap as GrammarPlugin with session-based parsing\n const plugin: GrammarPlugin = {\n languageId: language,\n injectionLanguages: jcoPlugin.injectionLanguages?.() ?? [],\n parse: (text: string) => {\n const session = jcoPlugin.createSession();\n try {\n jcoPlugin.setText(session, text);\n const result = jcoPlugin.parse(session);\n\n // Handle various result shapes from jco\n // Some versions return { tag: 'ok', val: ParseResult }\n // Others might return ParseResult directly\n if (result.tag === 'err') {\n const err = result.val as { message?: string };\n console.error(`[arborium] Parse error: ${err?.message}`);\n return { spans: [], injections: [] };\n }\n\n // Extract the actual value - could be result.val or result itself\n const val = result.tag === 'ok' ? result.val : result;\n if (!val || typeof val !== 'object') {\n console.error(`[arborium] Unexpected parse result:`, result);\n return { spans: [], injections: [] };\n }\n\n // Access spans/injections with type coercion\n const parsed = val as { spans?: Span[]; injections?: Injection[] };\n return {\n spans: parsed.spans || [],\n injections: parsed.injections || [],\n };\n } finally {\n jcoPlugin.freeSession(session);\n }\n },\n };\n\n grammarCache.set(language, plugin);\n console.debug(`[arborium] Grammar '${language}' loaded successfully`);\n return plugin;\n } catch (e) {\n console.error(`[arborium] Failed to load grammar '${language}':`, e);\n return null;\n }\n}\n\n// Handle to plugin mapping for the host interface\nconst handleToPlugin = new Map<number, GrammarPlugin>();\nlet nextHandle = 1;\n\n/** Setup window.arboriumHost for the Rust host to call into */\nfunction setupHostInterface(): void {\n (window as any).arboriumHost = {\n /** Check if a language is available (sync) */\n isLanguageAvailable(language: string): boolean {\n return availableLanguages.has(language) || grammarCache.has(language);\n },\n\n /** Load a grammar and return a handle (async) */\n async loadGrammar(language: string): Promise<number> {\n const plugin = await loadGrammarPlugin(language);\n if (!plugin) return 0; // 0 = not found\n\n // Check if we already have a handle\n for (const [handle, p] of handleToPlugin) {\n if (p === plugin) return handle;\n }\n\n // Create new handle\n const handle = nextHandle++;\n handleToPlugin.set(handle, plugin);\n return handle;\n },\n\n /** Parse text using a grammar handle (sync) */\n parse(handle: number, text: string): ParseResult {\n const plugin = handleToPlugin.get(handle);\n if (!plugin) return { spans: [], injections: [] };\n return plugin.parse(text);\n },\n };\n}\n\n/** Get the host URL based on config */\nfunction getHostUrl(): string {\n if (config.hostUrl) {\n return config.hostUrl;\n }\n // Use CDN\n const cdn = config.cdn;\n const version = config.version;\n let baseUrl: string;\n if (cdn === 'jsdelivr') {\n baseUrl = 'https://cdn.jsdelivr.net/npm';\n } else if (cdn === 'unpkg') {\n baseUrl = 'https://unpkg.com';\n } else {\n baseUrl = cdn;\n }\n const versionSuffix = version === 'latest' ? '' : `@${version}`;\n return `${baseUrl}/@arborium/arborium${versionSuffix}/dist`;\n}\n\n/** Load the Rust host module */\nasync function loadHost(): Promise<HostModule | null> {\n if (hostModule) return hostModule;\n if (hostLoadPromise) return hostLoadPromise;\n\n hostLoadPromise = (async () => {\n // Setup the interface the host imports\n setupHostInterface();\n\n const hostUrl = getHostUrl();\n const jsUrl = `${hostUrl}/arborium_host.js`;\n const wasmUrl = `${hostUrl}/arborium_host_bg.wasm`;\n\n console.debug(`[arborium] Loading host from ${jsUrl}`);\n try {\n const module = await import(/* @vite-ignore */ jsUrl);\n await module.default(wasmUrl);\n\n hostModule = {\n highlight: module.highlight,\n isLanguageAvailable: module.isLanguageAvailable,\n };\n console.debug(`[arborium] Host loaded successfully`);\n return hostModule;\n } catch (e) {\n console.error('[arborium] Failed to load host:', e);\n return null;\n }\n })();\n\n return hostLoadPromise;\n}\n\n/** Highlight source code */\nexport async function highlight(language: string, source: string, _config?: ArboriumConfig): Promise<string> {\n // Try to use the Rust host (handles injections properly)\n const host = await loadHost();\n if (host) {\n try {\n return host.highlight(language, source);\n } catch (e) {\n console.warn('Host highlight failed, falling back to JS:', e);\n }\n }\n\n // Fallback to JS-only highlighting (no injection support)\n const plugin = await loadGrammarPlugin(language);\n if (!plugin) {\n return escapeHtml(source);\n }\n\n const result = plugin.parse(source);\n return spansToHtml(source, result.spans);\n}\n\n/** Load a grammar for direct use */\nexport async function loadGrammar(language: string, _config?: ArboriumConfig): Promise<Grammar | null> {\n const plugin = await loadGrammarPlugin(language);\n if (!plugin) return null;\n\n return {\n languageId: () => plugin.languageId,\n injectionLanguages: () => plugin.injectionLanguages,\n highlight: async (source: string) => {\n const result = plugin.parse(source);\n return spansToHtml(source, result.spans);\n },\n parse: (source: string) => plugin.parse(source),\n dispose: () => {\n // No-op for now, plugins are cached\n },\n };\n}\n\n/** Convert spans to HTML */\nexport function spansToHtml(source: string, spans: Span[]): string {\n // Sort spans by start position\n const sorted = [...spans].sort((a, b) => a.start - b.start);\n\n let html = '';\n let pos = 0;\n\n for (const span of sorted) {\n // Skip overlapping spans\n if (span.start < pos) continue;\n\n // Add text before span\n if (span.start > pos) {\n html += escapeHtml(source.slice(pos, span.start));\n }\n\n // Get tag for capture\n const tag = getTagForCapture(span.capture);\n const text = escapeHtml(source.slice(span.start, span.end));\n\n if (tag) {\n html += `<a-${tag}>${text}</a-${tag}>`;\n } else {\n html += text;\n }\n\n pos = span.end;\n }\n\n // Add remaining text\n if (pos < source.length) {\n html += escapeHtml(source.slice(pos));\n }\n\n return html;\n}\n\n/** Get the short tag for a capture name */\nfunction getTagForCapture(capture: string): string | null {\n if (capture.startsWith('keyword') || capture === 'include' || capture === 'conditional') {\n return 'k';\n }\n if (capture.startsWith('function') || capture.startsWith('method')) {\n return 'f';\n }\n if (capture.startsWith('string') || capture === 'character') {\n return 's';\n }\n if (capture.startsWith('comment')) {\n return 'c';\n }\n if (capture.startsWith('type')) {\n return 't';\n }\n if (capture.startsWith('variable')) {\n return 'v';\n }\n if (capture.startsWith('number') || capture === 'float') {\n return 'n';\n }\n if (capture.startsWith('operator')) {\n return 'o';\n }\n if (capture.startsWith('punctuation')) {\n return 'p';\n }\n if (capture.startsWith('tag')) {\n return 'tg';\n }\n if (capture.startsWith('attribute')) {\n return 'at';\n }\n return null;\n}\n\n/** Escape HTML special characters */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/** Get current config, optionally merging with overrides */\nexport function getConfig(overrides?: Partial<ArboriumConfig>): Required<ArboriumConfig> {\n if (overrides) {\n return { ...config, ...overrides };\n }\n return { ...config };\n}\n\n/** Set/merge config */\nexport function setConfig(newConfig: Partial<ArboriumConfig>): void {\n config = { ...config, ...newConfig };\n}\n\n/** Check if a language is available */\nexport async function isLanguageAvailable(language: string): Promise<boolean> {\n await loadPluginsManifest();\n return availableLanguages.has(language);\n}\n\n/** Get list of available languages */\nexport async function getAvailableLanguages(): Promise<string[]> {\n await loadPluginsManifest();\n return Array.from(availableLanguages);\n}\n","/**\n * Simple language detection heuristics.\n * Not meant to be comprehensive - just catches common cases.\n */\n\n/** Shebang patterns */\nconst SHEBANG_PATTERNS: Array<[RegExp, string]> = [\n [/^#!.*\\bpython[23]?\\b/, 'python'],\n [/^#!.*\\bnode\\b/, 'javascript'],\n [/^#!.*\\bdeno\\b/, 'typescript'],\n [/^#!.*\\bbun\\b/, 'typescript'],\n [/^#!.*\\bruby\\b/, 'ruby'],\n [/^#!.*\\bperl\\b/, 'perl'],\n [/^#!.*\\bphp\\b/, 'php'],\n [/^#!.*\\bbash\\b/, 'bash'],\n [/^#!.*\\bzsh\\b/, 'zsh'],\n [/^#!.*\\bsh\\b/, 'bash'],\n [/^#!.*\\blua\\b/, 'lua'],\n [/^#!.*\\bawk\\b/, 'awk'],\n];\n\n/** Keyword fingerprints - first few unique keywords that identify a language */\nconst KEYWORD_FINGERPRINTS: Array<[RegExp, string]> = [\n // Rust - distinctive keywords\n [/\\b(fn|impl|trait|pub\\s+fn|let\\s+mut|&mut|->)\\b/, 'rust'],\n\n // Go - distinctive keywords\n [/\\b(func|package\\s+\\w+|import\\s+\\(|go\\s+func|chan\\s+\\w+)\\b/, 'go'],\n\n // Python - distinctive patterns\n [/\\b(def\\s+\\w+\\s*\\(|import\\s+\\w+|from\\s+\\w+\\s+import|class\\s+\\w+:)\\b/, 'python'],\n\n // TypeScript - distinctive type annotations\n [/:\\s*(string|number|boolean|void)\\b|\\binterface\\s+\\w+\\s*\\{/, 'typescript'],\n\n // JavaScript - distinctive patterns (after TS check)\n [/\\b(const|let|var)\\s+\\w+\\s*=|function\\s+\\w+\\s*\\(|=>\\s*\\{/, 'javascript'],\n\n // Ruby - distinctive keywords\n [/\\b(def\\s+\\w+|end\\b|do\\s*\\|.*\\||puts\\s+|require\\s+['\"])\\b/, 'ruby'],\n\n // Java - distinctive patterns\n [/\\b(public\\s+class|private\\s+\\w+|System\\.out\\.println)\\b/, 'java'],\n\n // C++ - distinctive patterns\n [/\\b(#include\\s*<|std::|template\\s*<|nullptr|cout\\s*<<)\\b/, 'cpp'],\n\n // C - distinctive patterns (after C++ check)\n [/\\b(#include\\s*[<\"]|printf\\s*\\(|int\\s+main\\s*\\(|void\\s+\\w+\\s*\\()\\b/, 'c'],\n\n // C# - distinctive patterns\n [/\\b(namespace\\s+\\w+|using\\s+System|public\\s+static\\s+void)\\b/, 'c-sharp'],\n\n // PHP - distinctive patterns\n [/<\\?php|\\$\\w+\\s*=/, 'php'],\n\n // Swift - distinctive patterns\n [/\\b(func\\s+\\w+|var\\s+\\w+:\\s*\\w+|let\\s+\\w+:\\s*\\w+|@objc)\\b/, 'swift'],\n\n // Kotlin - distinctive patterns\n [/\\b(fun\\s+\\w+|val\\s+\\w+|var\\s+\\w+:|data\\s+class)\\b/, 'kotlin'],\n\n // Scala - distinctive patterns\n [/\\b(def\\s+\\w+|val\\s+\\w+|var\\s+\\w+|object\\s+\\w+|case\\s+class)\\b/, 'scala'],\n\n // Haskell - distinctive patterns\n [/\\b(module\\s+\\w+|import\\s+qualified|data\\s+\\w+\\s*=|::\\s*\\w+\\s*->)\\b/, 'haskell'],\n\n // Elixir - distinctive patterns\n [/\\b(defmodule\\s+\\w+|def\\s+\\w+|defp\\s+\\w+|\\|>)\\b/, 'elixir'],\n\n // Lua - distinctive patterns\n [/\\b(local\\s+\\w+\\s*=|function\\s+\\w+\\.\\w+|require\\s*\\()\\b/, 'lua'],\n\n // SQL - distinctive patterns\n [/\\b(SELECT\\s+.*\\s+FROM|INSERT\\s+INTO|CREATE\\s+TABLE|ALTER\\s+TABLE)\\b/i, 'sql'],\n\n // Shell/Bash - distinctive patterns\n [/\\b(if\\s+\\[\\s*|then\\b|fi\\b|echo\\s+[\"']|export\\s+\\w+=)\\b/, 'bash'],\n\n // YAML - distinctive patterns\n [/^\\s*[\\w-]+:\\s*[\\w\\-\"'[{]|^---\\s*$/, 'yaml'],\n\n // JSON - distinctive patterns\n [/^\\s*\\{[\\s\\S]*\"[\\w-]+\":\\s*/, 'json'],\n\n // TOML - distinctive patterns\n [/^\\s*\\[[\\w.-]+\\]\\s*$|^\\s*\\w+\\s*=\\s*[\"'\\d\\[]/, 'toml'],\n\n // HTML - distinctive patterns\n [/<(!DOCTYPE|html|head|body|div|span|p|a\\s)/i, 'html'],\n\n // CSS - distinctive patterns\n [/^\\s*[\\w.#@][\\w\\s,#.:>+~-]*\\{[^}]*\\}|@media\\s|@import\\s/, 'css'],\n\n // Markdown - distinctive patterns\n [/^#{1,6}\\s+\\w|^\\s*[-*+]\\s+\\w|^\\s*\\d+\\.\\s+\\w|```\\w*\\n/, 'markdown'],\n\n // XML - distinctive patterns\n [/<\\?xml|<[\\w:-]+\\s+xmlns/, 'xml'],\n\n // Dockerfile\n [/^FROM\\s+\\w+|^RUN\\s+|^COPY\\s+|^ENTRYPOINT\\s+/m, 'dockerfile'],\n\n // Nginx config\n [/\\b(server\\s*\\{|location\\s+[\\/~]|proxy_pass\\s+)\\b/, 'nginx'],\n\n // Zig\n [/\\b(pub\\s+fn|const\\s+\\w+\\s*=|@import\\(|comptime)\\b/, 'zig'],\n];\n\n/**\n * Detect the language of a code snippet.\n * Returns null if detection fails.\n */\nexport function detectLanguage(source: string): string | null {\n // Check shebang first (most reliable)\n const firstLine = source.split('\\n')[0];\n for (const [pattern, language] of SHEBANG_PATTERNS) {\n if (pattern.test(firstLine)) {\n return language;\n }\n }\n\n // Check keyword fingerprints\n for (const [pattern, language] of KEYWORD_FINGERPRINTS) {\n if (pattern.test(source)) {\n return language;\n }\n }\n\n return null;\n}\n\n/**\n * Extract language from class name (e.g., \"language-rust\" -> \"rust\")\n */\nexport function extractLanguageFromClass(className: string): string | null {\n const match = className.match(/\\blanguage-(\\w+)\\b/);\n return match ? match[1] : null;\n}\n\n/**\n * Normalize language identifier (handle aliases)\n */\nexport function normalizeLanguage(lang: string): string {\n const aliases: Record<string, string> = {\n js: 'javascript',\n ts: 'typescript',\n py: 'python',\n rb: 'ruby',\n rs: 'rust',\n sh: 'bash',\n shell: 'bash',\n yml: 'yaml',\n cs: 'c-sharp',\n csharp: 'c-sharp',\n 'c++': 'cpp',\n 'c#': 'c-sharp',\n 'f#': 'fsharp',\n dockerfile: 'dockerfile',\n docker: 'dockerfile',\n makefile: 'make',\n plaintext: 'text',\n plain: 'text',\n txt: 'text',\n };\n\n const lower = lang.toLowerCase();\n return aliases[lower] || lower;\n}\n"],"names":["WasiError","message","OutputStream","_contents","InputStream","_len","createWasiImports","stdout","stderr","stdin","environment","exit","status","stdinIface","stdoutIface","stderrIface","wallClock","ms","filesystemTypes","preopens","ioError","streams","random","len","bytes","grammarTypesImport","defaultConfig","hostModule","hostLoadPromise","config","grammarCache","pluginsManifest","availableLanguages","loadPluginsManifest","response","e","loadGrammarPlugin","language","cached","entry","jsUrl","baseUrl","module","getCoreModule","path","wasmUrl","imports","instance","jcoPlugin","plugin","text","session","result","err","val","parsed","handleToPlugin","nextHandle","setupHostInterface","handle","p","getHostUrl","cdn","version","versionSuffix","loadHost","hostUrl","highlight","source","_config","host","escapeHtml","spansToHtml","loadGrammar","spans","sorted","b","html","pos","span","tag","getTagForCapture","capture","getConfig","overrides","SHEBANG_PATTERNS","KEYWORD_FINGERPRINTS","detectLanguage","firstLine","pattern","extractLanguageFromClass","className","match","normalizeLanguage","lang","aliases","lower"],"mappings":"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"}
@@ -1,482 +0,0 @@
1
- let wasm;
2
-
3
- function addToExternrefTable0(obj) {
4
- const idx = wasm.__externref_table_alloc();
5
- wasm.__wbindgen_externrefs.set(idx, obj);
6
- return idx;
7
- }
8
-
9
- function _assertClass(instance, klass) {
10
- if (!(instance instanceof klass)) {
11
- throw new Error(`expected instance of ${klass.name}`);
12
- }
13
- }
14
-
15
- const CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')
16
- ? { register: () => {}, unregister: () => {} }
17
- : new FinalizationRegistry(state => state.dtor(state.a, state.b));
18
-
19
- let cachedDataViewMemory0 = null;
20
- function getDataViewMemory0() {
21
- if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
22
- cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
23
- }
24
- return cachedDataViewMemory0;
25
- }
26
-
27
- function getStringFromWasm0(ptr, len) {
28
- ptr = ptr >>> 0;
29
- return decodeText(ptr, len);
30
- }
31
-
32
- let cachedUint8ArrayMemory0 = null;
33
- function getUint8ArrayMemory0() {
34
- if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
35
- cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
36
- }
37
- return cachedUint8ArrayMemory0;
38
- }
39
-
40
- function handleError(f, args) {
41
- try {
42
- return f.apply(this, args);
43
- } catch (e) {
44
- const idx = addToExternrefTable0(e);
45
- wasm.__wbindgen_exn_store(idx);
46
- }
47
- }
48
-
49
- function isLikeNone(x) {
50
- return x === undefined || x === null;
51
- }
52
-
53
- function makeMutClosure(arg0, arg1, dtor, f) {
54
- const state = { a: arg0, b: arg1, cnt: 1, dtor };
55
- const real = (...args) => {
56
-
57
- // First up with a closure we increment the internal reference
58
- // count. This ensures that the Rust closure environment won't
59
- // be deallocated while we're invoking it.
60
- state.cnt++;
61
- const a = state.a;
62
- state.a = 0;
63
- try {
64
- return f(a, state.b, ...args);
65
- } finally {
66
- state.a = a;
67
- real._wbg_cb_unref();
68
- }
69
- };
70
- real._wbg_cb_unref = () => {
71
- if (--state.cnt === 0) {
72
- state.dtor(state.a, state.b);
73
- state.a = 0;
74
- CLOSURE_DTORS.unregister(state);
75
- }
76
- };
77
- CLOSURE_DTORS.register(real, state, state);
78
- return real;
79
- }
80
-
81
- function passStringToWasm0(arg, malloc, realloc) {
82
- if (realloc === undefined) {
83
- const buf = cachedTextEncoder.encode(arg);
84
- const ptr = malloc(buf.length, 1) >>> 0;
85
- getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
86
- WASM_VECTOR_LEN = buf.length;
87
- return ptr;
88
- }
89
-
90
- let len = arg.length;
91
- let ptr = malloc(len, 1) >>> 0;
92
-
93
- const mem = getUint8ArrayMemory0();
94
-
95
- let offset = 0;
96
-
97
- for (; offset < len; offset++) {
98
- const code = arg.charCodeAt(offset);
99
- if (code > 0x7F) break;
100
- mem[ptr + offset] = code;
101
- }
102
- if (offset !== len) {
103
- if (offset !== 0) {
104
- arg = arg.slice(offset);
105
- }
106
- ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
107
- const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
108
- const ret = cachedTextEncoder.encodeInto(arg, view);
109
-
110
- offset += ret.written;
111
- ptr = realloc(ptr, len, offset, 1) >>> 0;
112
- }
113
-
114
- WASM_VECTOR_LEN = offset;
115
- return ptr;
116
- }
117
-
118
- let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
119
- cachedTextDecoder.decode();
120
- const MAX_SAFARI_DECODE_BYTES = 2146435072;
121
- let numBytesDecoded = 0;
122
- function decodeText(ptr, len) {
123
- numBytesDecoded += len;
124
- if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
125
- cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
126
- cachedTextDecoder.decode();
127
- numBytesDecoded = len;
128
- }
129
- return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
130
- }
131
-
132
- const cachedTextEncoder = new TextEncoder();
133
-
134
- if (!('encodeInto' in cachedTextEncoder)) {
135
- cachedTextEncoder.encodeInto = function (arg, view) {
136
- const buf = cachedTextEncoder.encode(arg);
137
- view.set(buf);
138
- return {
139
- read: arg.length,
140
- written: buf.length
141
- };
142
- }
143
- }
144
-
145
- let WASM_VECTOR_LEN = 0;
146
-
147
- function wasm_bindgen__convert__closures_____invoke__hdf270ce0da308ff1(arg0, arg1, arg2) {
148
- wasm.wasm_bindgen__convert__closures_____invoke__hdf270ce0da308ff1(arg0, arg1, arg2);
149
- }
150
-
151
- function wasm_bindgen__convert__closures_____invoke__h089a09d160a6520b(arg0, arg1, arg2, arg3) {
152
- wasm.wasm_bindgen__convert__closures_____invoke__h089a09d160a6520b(arg0, arg1, arg2, arg3);
153
- }
154
-
155
- const HighlightConfigFinalization = (typeof FinalizationRegistry === 'undefined')
156
- ? { register: () => {}, unregister: () => {} }
157
- : new FinalizationRegistry(ptr => wasm.__wbg_highlightconfig_free(ptr >>> 0, 1));
158
-
159
- /**
160
- * Configuration for highlighting.
161
- */
162
- export class HighlightConfig {
163
- __destroy_into_raw() {
164
- const ptr = this.__wbg_ptr;
165
- this.__wbg_ptr = 0;
166
- HighlightConfigFinalization.unregister(this);
167
- return ptr;
168
- }
169
- free() {
170
- const ptr = this.__destroy_into_raw();
171
- wasm.__wbg_highlightconfig_free(ptr, 0);
172
- }
173
- /**
174
- * @param {number} depth
175
- */
176
- setMaxInjectionDepth(depth) {
177
- wasm.highlightconfig_setMaxInjectionDepth(this.__wbg_ptr, depth);
178
- }
179
- constructor() {
180
- const ret = wasm.highlightconfig_new();
181
- this.__wbg_ptr = ret >>> 0;
182
- HighlightConfigFinalization.register(this, this.__wbg_ptr, this);
183
- return this;
184
- }
185
- }
186
- if (Symbol.dispose) HighlightConfig.prototype[Symbol.dispose] = HighlightConfig.prototype.free;
187
-
188
- /**
189
- * Highlight source code, resolving injections recursively.
190
- *
191
- * This uses the shared `AsyncHighlighter` from `arborium_highlight`,
192
- * ensuring the same injection handling logic as Rust native.
193
- * @param {string} language
194
- * @param {string} source
195
- * @returns {Promise<string>}
196
- */
197
- export function highlight(language, source) {
198
- const ptr0 = passStringToWasm0(language, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
199
- const len0 = WASM_VECTOR_LEN;
200
- const ptr1 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
201
- const len1 = WASM_VECTOR_LEN;
202
- const ret = wasm.highlight(ptr0, len0, ptr1, len1);
203
- return ret;
204
- }
205
-
206
- /**
207
- * Highlight with custom configuration.
208
- * @param {string} language
209
- * @param {string} source
210
- * @param {HighlightConfig} config
211
- * @returns {Promise<string>}
212
- */
213
- export function highlightWithConfig(language, source, config) {
214
- const ptr0 = passStringToWasm0(language, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
215
- const len0 = WASM_VECTOR_LEN;
216
- const ptr1 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
217
- const len1 = WASM_VECTOR_LEN;
218
- _assertClass(config, HighlightConfig);
219
- var ptr2 = config.__destroy_into_raw();
220
- const ret = wasm.highlightWithConfig(ptr0, len0, ptr1, len1, ptr2);
221
- return ret;
222
- }
223
-
224
- /**
225
- * Check if a language is available for highlighting.
226
- * @param {string} language
227
- * @returns {boolean}
228
- */
229
- export function isLanguageAvailable(language) {
230
- const ptr0 = passStringToWasm0(language, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
231
- const len0 = WASM_VECTOR_LEN;
232
- const ret = wasm.isLanguageAvailable(ptr0, len0);
233
- return ret !== 0;
234
- }
235
-
236
- const EXPECTED_RESPONSE_TYPES = new Set(['basic', 'cors', 'default']);
237
-
238
- async function __wbg_load(module, imports) {
239
- if (typeof Response === 'function' && module instanceof Response) {
240
- if (typeof WebAssembly.instantiateStreaming === 'function') {
241
- try {
242
- return await WebAssembly.instantiateStreaming(module, imports);
243
- } catch (e) {
244
- const validResponse = module.ok && EXPECTED_RESPONSE_TYPES.has(module.type);
245
-
246
- if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
247
- console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
248
-
249
- } else {
250
- throw e;
251
- }
252
- }
253
- }
254
-
255
- const bytes = await module.arrayBuffer();
256
- return await WebAssembly.instantiate(bytes, imports);
257
- } else {
258
- const instance = await WebAssembly.instantiate(module, imports);
259
-
260
- if (instance instanceof WebAssembly.Instance) {
261
- return { instance, module };
262
- } else {
263
- return instance;
264
- }
265
- }
266
- }
267
-
268
- function __wbg_get_imports() {
269
- const imports = {};
270
- imports.wbg = {};
271
- imports.wbg.__wbg___wbindgen_boolean_get_dea25b33882b895b = function(arg0) {
272
- const v = arg0;
273
- const ret = typeof(v) === 'boolean' ? v : undefined;
274
- return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
275
- };
276
- imports.wbg.__wbg___wbindgen_is_function_8d400b8b1af978cd = function(arg0) {
277
- const ret = typeof(arg0) === 'function';
278
- return ret;
279
- };
280
- imports.wbg.__wbg___wbindgen_is_null_dfda7d66506c95b5 = function(arg0) {
281
- const ret = arg0 === null;
282
- return ret;
283
- };
284
- imports.wbg.__wbg___wbindgen_is_undefined_f6b95eab589e0269 = function(arg0) {
285
- const ret = arg0 === undefined;
286
- return ret;
287
- };
288
- imports.wbg.__wbg___wbindgen_number_get_9619185a74197f95 = function(arg0, arg1) {
289
- const obj = arg1;
290
- const ret = typeof(obj) === 'number' ? obj : undefined;
291
- getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
292
- getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
293
- };
294
- imports.wbg.__wbg___wbindgen_string_get_a2a31e16edf96e42 = function(arg0, arg1) {
295
- const obj = arg1;
296
- const ret = typeof(obj) === 'string' ? obj : undefined;
297
- var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
298
- var len1 = WASM_VECTOR_LEN;
299
- getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
300
- getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
301
- };
302
- imports.wbg.__wbg___wbindgen_throw_dd24417ed36fc46e = function(arg0, arg1) {
303
- throw new Error(getStringFromWasm0(arg0, arg1));
304
- };
305
- imports.wbg.__wbg__wbg_cb_unref_87dfb5aaa0cbcea7 = function(arg0) {
306
- arg0._wbg_cb_unref();
307
- };
308
- imports.wbg.__wbg_call_3020136f7a2d6e44 = function() { return handleError(function (arg0, arg1, arg2) {
309
- const ret = arg0.call(arg1, arg2);
310
- return ret;
311
- }, arguments) };
312
- imports.wbg.__wbg_call_abb4ff46ce38be40 = function() { return handleError(function (arg0, arg1) {
313
- const ret = arg0.call(arg1);
314
- return ret;
315
- }, arguments) };
316
- imports.wbg.__wbg_from_29a8414a7a7cd19d = function(arg0) {
317
- const ret = Array.from(arg0);
318
- return ret;
319
- };
320
- imports.wbg.__wbg_get_6b7bd52aca3f9671 = function(arg0, arg1) {
321
- const ret = arg0[arg1 >>> 0];
322
- return ret;
323
- };
324
- imports.wbg.__wbg_get_af9dab7e9603ea93 = function() { return handleError(function (arg0, arg1) {
325
- const ret = Reflect.get(arg0, arg1);
326
- return ret;
327
- }, arguments) };
328
- imports.wbg.__wbg_isLanguageAvailable_4c54f1a0e6d0f988 = function(arg0, arg1) {
329
- const ret = arboriumHost.isLanguageAvailable(getStringFromWasm0(arg0, arg1));
330
- return ret;
331
- };
332
- imports.wbg.__wbg_length_d45040a40c570362 = function(arg0) {
333
- const ret = arg0.length;
334
- return ret;
335
- };
336
- imports.wbg.__wbg_loadGrammar_ed5aea14822a78db = function() { return handleError(function (arg0, arg1) {
337
- const ret = arboriumHost.loadGrammar(getStringFromWasm0(arg0, arg1));
338
- return ret;
339
- }, arguments) };
340
- imports.wbg.__wbg_new_ff12d2b041fb48f1 = function(arg0, arg1) {
341
- try {
342
- var state0 = {a: arg0, b: arg1};
343
- var cb0 = (arg0, arg1) => {
344
- const a = state0.a;
345
- state0.a = 0;
346
- try {
347
- return wasm_bindgen__convert__closures_____invoke__h089a09d160a6520b(a, state0.b, arg0, arg1);
348
- } finally {
349
- state0.a = a;
350
- }
351
- };
352
- const ret = new Promise(cb0);
353
- return ret;
354
- } finally {
355
- state0.a = state0.b = 0;
356
- }
357
- };
358
- imports.wbg.__wbg_new_no_args_cb138f77cf6151ee = function(arg0, arg1) {
359
- const ret = new Function(getStringFromWasm0(arg0, arg1));
360
- return ret;
361
- };
362
- imports.wbg.__wbg_parse_98cc2457c24f4b01 = function(arg0, arg1, arg2) {
363
- const ret = arboriumHost.parse(arg0 >>> 0, getStringFromWasm0(arg1, arg2));
364
- return ret;
365
- };
366
- imports.wbg.__wbg_queueMicrotask_9b549dfce8865860 = function(arg0) {
367
- const ret = arg0.queueMicrotask;
368
- return ret;
369
- };
370
- imports.wbg.__wbg_queueMicrotask_fca69f5bfad613a5 = function(arg0) {
371
- queueMicrotask(arg0);
372
- };
373
- imports.wbg.__wbg_resolve_fd5bfbaa4ce36e1e = function(arg0) {
374
- const ret = Promise.resolve(arg0);
375
- return ret;
376
- };
377
- imports.wbg.__wbg_static_accessor_GLOBAL_769e6b65d6557335 = function() {
378
- const ret = typeof global === 'undefined' ? null : global;
379
- return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
380
- };
381
- imports.wbg.__wbg_static_accessor_GLOBAL_THIS_60cf02db4de8e1c1 = function() {
382
- const ret = typeof globalThis === 'undefined' ? null : globalThis;
383
- return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
384
- };
385
- imports.wbg.__wbg_static_accessor_SELF_08f5a74c69739274 = function() {
386
- const ret = typeof self === 'undefined' ? null : self;
387
- return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
388
- };
389
- imports.wbg.__wbg_static_accessor_WINDOW_a8924b26aa92d024 = function() {
390
- const ret = typeof window === 'undefined' ? null : window;
391
- return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
392
- };
393
- imports.wbg.__wbg_then_429f7caf1026411d = function(arg0, arg1, arg2) {
394
- const ret = arg0.then(arg1, arg2);
395
- return ret;
396
- };
397
- imports.wbg.__wbg_then_4f95312d68691235 = function(arg0, arg1) {
398
- const ret = arg0.then(arg1);
399
- return ret;
400
- };
401
- imports.wbg.__wbindgen_cast_2241b6af4c4b2941 = function(arg0, arg1) {
402
- // Cast intrinsic for `Ref(String) -> Externref`.
403
- const ret = getStringFromWasm0(arg0, arg1);
404
- return ret;
405
- };
406
- imports.wbg.__wbindgen_cast_3b1a32895b770b74 = function(arg0, arg1) {
407
- // Cast intrinsic for `Closure(Closure { dtor_idx: 10, function: Function { arguments: [Externref], shim_idx: 11, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
408
- const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen__closure__destroy__hd7b7e163837b9c9e, wasm_bindgen__convert__closures_____invoke__hdf270ce0da308ff1);
409
- return ret;
410
- };
411
- imports.wbg.__wbindgen_init_externref_table = function() {
412
- const table = wasm.__wbindgen_externrefs;
413
- const offset = table.grow(4);
414
- table.set(0, undefined);
415
- table.set(offset + 0, undefined);
416
- table.set(offset + 1, null);
417
- table.set(offset + 2, true);
418
- table.set(offset + 3, false);
419
- };
420
-
421
- return imports;
422
- }
423
-
424
- function __wbg_finalize_init(instance, module) {
425
- wasm = instance.exports;
426
- __wbg_init.__wbindgen_wasm_module = module;
427
- cachedDataViewMemory0 = null;
428
- cachedUint8ArrayMemory0 = null;
429
-
430
-
431
- wasm.__wbindgen_start();
432
- return wasm;
433
- }
434
-
435
- function initSync(module) {
436
- if (wasm !== undefined) return wasm;
437
-
438
-
439
- if (typeof module !== 'undefined') {
440
- if (Object.getPrototypeOf(module) === Object.prototype) {
441
- ({module} = module)
442
- } else {
443
- console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
444
- }
445
- }
446
-
447
- const imports = __wbg_get_imports();
448
- if (!(module instanceof WebAssembly.Module)) {
449
- module = new WebAssembly.Module(module);
450
- }
451
- const instance = new WebAssembly.Instance(module, imports);
452
- return __wbg_finalize_init(instance, module);
453
- }
454
-
455
- async function __wbg_init(module_or_path) {
456
- if (wasm !== undefined) return wasm;
457
-
458
-
459
- if (typeof module_or_path !== 'undefined') {
460
- if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
461
- ({module_or_path} = module_or_path)
462
- } else {
463
- console.warn('using deprecated parameters for the initialization function; pass a single object instead')
464
- }
465
- }
466
-
467
- if (typeof module_or_path === 'undefined') {
468
- module_or_path = new URL('arborium_host_bg.wasm', import.meta.url);
469
- }
470
- const imports = __wbg_get_imports();
471
-
472
- if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
473
- module_or_path = fetch(module_or_path);
474
- }
475
-
476
- const { instance, module } = await __wbg_load(await module_or_path, imports);
477
-
478
- return __wbg_finalize_init(instance, module);
479
- }
480
-
481
- export { initSync };
482
- export default __wbg_init;
Binary file
package/dist/detect.d.ts DELETED
@@ -1,17 +0,0 @@
1
- /**
2
- * Simple language detection heuristics.
3
- * Not meant to be comprehensive - just catches common cases.
4
- */
5
- /**
6
- * Detect the language of a code snippet.
7
- * Returns null if detection fails.
8
- */
9
- export declare function detectLanguage(source: string): string | null;
10
- /**
11
- * Extract language from class name (e.g., "language-rust" -> "rust")
12
- */
13
- export declare function extractLanguageFromClass(className: string): string | null;
14
- /**
15
- * Normalize language identifier (handle aliases)
16
- */
17
- export declare function normalizeLanguage(lang: string): string;
package/dist/iife.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * @arborium/arborium IIFE bundle
3
- *
4
- * Drop-in auto-highlighter that runs on page load.
5
- * Configuration via data attributes or window.Arborium object.
6
- */
7
- import type { ArboriumConfig } from './types.js';
8
- /** Public API for manual highlighting */
9
- export declare function highlightAll(config?: ArboriumConfig): Promise<void>;
10
- /** Public API for highlighting a specific element */
11
- export declare function highlightElement(element: HTMLElement, language?: string, config?: ArboriumConfig): Promise<void>;
package/dist/index.d.ts DELETED
@@ -1,8 +0,0 @@
1
- /**
2
- * @arborium/arborium - High-performance syntax highlighting
3
- *
4
- * ESM entry point for programmatic usage.
5
- */
6
- export { loadGrammar, highlight, spansToHtml, getConfig } from './loader.js';
7
- export { detectLanguage, extractLanguageFromClass, normalizeLanguage } from './detect.js';
8
- export type { Grammar, Span, Injection, ParseResult, ArboriumConfig, } from './types.js';
package/dist/loader.d.ts DELETED
@@ -1,24 +0,0 @@
1
- /**
2
- * Arborium loader - loads grammar plugins and highlights code.
3
- *
4
- * Architecture:
5
- * 1. Fetch plugins.json from arborium.bearcove.eu to get grammar CDN URLs
6
- * 2. Load grammar WIT components on demand from @arborium/<lang> packages
7
- * 3. Parse and highlight using the grammar's tree-sitter parser
8
- */
9
- import type { ArboriumConfig, Grammar, Span } from './types.js';
10
- export declare const defaultConfig: Required<ArboriumConfig>;
11
- /** Highlight source code */
12
- export declare function highlight(language: string, source: string, _config?: ArboriumConfig): Promise<string>;
13
- /** Load a grammar for direct use */
14
- export declare function loadGrammar(language: string, _config?: ArboriumConfig): Promise<Grammar | null>;
15
- /** Convert spans to HTML */
16
- export declare function spansToHtml(source: string, spans: Span[]): string;
17
- /** Get current config, optionally merging with overrides */
18
- export declare function getConfig(overrides?: Partial<ArboriumConfig>): Required<ArboriumConfig>;
19
- /** Set/merge config */
20
- export declare function setConfig(newConfig: Partial<ArboriumConfig>): void;
21
- /** Check if a language is available */
22
- export declare function isLanguageAvailable(language: string): Promise<boolean>;
23
- /** Get list of available languages */
24
- export declare function getAvailableLanguages(): Promise<string[]>;