@opentui/core 0.1.24 → 0.1.26
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.
- package/3d.js +1 -1
- package/README.md +5 -1
- package/Renderable.d.ts +18 -8
- package/animation/Timeline.d.ts +2 -1
- package/ansi.d.ts +2 -17
- package/assets/javascript/highlights.scm +205 -0
- package/assets/javascript/tree-sitter-javascript.wasm +0 -0
- package/assets/typescript/highlights.scm +604 -0
- package/assets/typescript/tree-sitter-typescript.wasm +0 -0
- package/{index-0yx9rnxg.js → index-pxa2sv92.js} +1798 -258
- package/index-pxa2sv92.js.map +52 -0
- package/index.js +449 -246
- package/index.js.map +15 -13
- package/lib/KeyHandler.d.ts +51 -9
- package/lib/data-paths.d.ts +26 -0
- package/lib/debounce.d.ts +42 -0
- package/lib/env.d.ts +42 -0
- package/lib/hast-styled-text.d.ts +3 -23
- package/lib/index.d.ts +6 -0
- package/lib/parse.keypress.d.ts +2 -2
- package/lib/queue.d.ts +15 -0
- package/lib/scroll-acceleration.d.ts +43 -0
- package/{singleton.d.ts → lib/singleton.d.ts} +2 -0
- package/lib/styled-text.d.ts +0 -15
- package/lib/syntax-style.d.ts +36 -0
- package/lib/tree-sitter/assets/update.d.ts +11 -0
- package/lib/tree-sitter/client.d.ts +46 -0
- package/lib/tree-sitter/default-parsers.d.ts +2 -0
- package/lib/tree-sitter/download-utils.d.ts +21 -0
- package/lib/tree-sitter/index.d.ts +10 -0
- package/lib/tree-sitter/parser.worker.d.ts +1 -0
- package/lib/tree-sitter/resolve-ft.d.ts +2 -0
- package/lib/tree-sitter/types.d.ts +64 -0
- package/lib/tree-sitter-styled-text.d.ts +7 -0
- package/lib/validate-dir-name.d.ts +1 -0
- package/package.json +21 -8
- package/parser.worker.js +640 -0
- package/parser.worker.js.map +11 -0
- package/renderables/ASCIIFont.d.ts +1 -1
- package/renderables/Code.d.ts +31 -0
- package/renderables/Input.d.ts +4 -4
- package/renderables/ScrollBar.d.ts +2 -2
- package/renderables/ScrollBox.d.ts +7 -3
- package/renderables/Select.d.ts +2 -2
- package/renderables/TabSelect.d.ts +2 -2
- package/renderables/Text.d.ts +11 -65
- package/renderables/TextBufferRenderable.d.ts +81 -0
- package/renderables/TextNode.d.ts +1 -0
- package/renderables/index.d.ts +2 -0
- package/renderer.d.ts +5 -3
- package/testing/mock-keys.d.ts +1 -0
- package/testing/spy.d.ts +7 -0
- package/testing/test-renderer.d.ts +1 -0
- package/testing.d.ts +1 -0
- package/testing.js +31 -6
- package/testing.js.map +6 -5
- package/types.d.ts +2 -1
- package/zig.d.ts +1 -0
- package/index-0yx9rnxg.js.map +0 -38
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/tree-sitter/parser.worker.ts", "../src/lib/tree-sitter/download-utils.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Parser, Query, Tree, Language } from \"web-tree-sitter\"\nimport type { Edit, QueryCapture, Range } from \"web-tree-sitter\"\nimport { mkdir } from \"fs/promises\"\nimport * as path from \"path\"\nimport type {\n HighlightRange,\n HighlightResponse,\n SimpleHighlight,\n FiletypeParserOptions,\n PerformanceStats,\n} from \"./types\"\nimport { DownloadUtils } from \"./download-utils\"\nimport { isMainThread } from \"worker_threads\"\n\nconst self = globalThis\n\ntype ParserState = {\n parser: Parser\n tree: Tree\n queries: {\n highlights: Query\n }\n}\n\ninterface FiletypeParser {\n filetype: string\n queries: {\n highlights: Query\n }\n language: Language\n}\n\ninterface ReusableParserState {\n parser: Parser\n filetypeParser: FiletypeParser\n}\n\nclass ParserWorker {\n private bufferParsers: Map<number, ParserState> = new Map()\n private filetypeParserOptions: Map<string, FiletypeParserOptions> = new Map()\n private filetypeParsers: Map<string, FiletypeParser> = new Map()\n private filetypeParserPromises: Map<string, Promise<FiletypeParser | undefined>> = new Map()\n private reusableParsers: Map<string, ReusableParserState> = new Map()\n private reusableParserPromises: Map<string, Promise<ReusableParserState | undefined>> = new Map()\n private initializePromise: Promise<void> | undefined\n public performance: PerformanceStats\n private dataPath: string | undefined\n private initialized: boolean = false\n\n constructor() {\n this.performance = {\n averageParseTime: 0,\n parseTimes: [],\n averageQueryTime: 0,\n queryTimes: [],\n }\n }\n\n private async fetchHighlightQueries(sources: string[], filetype: string): Promise<string> {\n if (!this.dataPath) {\n return \"\"\n }\n return DownloadUtils.fetchHighlightQueries(sources, this.dataPath, filetype)\n }\n\n async initialize({ dataPath }: { dataPath: string }) {\n if (this.initializePromise) {\n return this.initializePromise\n }\n this.initializePromise = new Promise(async (resolve, reject) => {\n this.dataPath = dataPath\n\n try {\n await mkdir(path.join(dataPath, \"languages\"), { recursive: true })\n await mkdir(path.join(dataPath, \"queries\"), { recursive: true })\n\n let { default: treeWasm } = await import(\"web-tree-sitter/web-tree-sitter.wasm\" as string, {\n with: { type: \"wasm\" },\n })\n\n if (/\\$bunfs/.test(treeWasm)) {\n treeWasm = \"/$bunfs/root/\" + path.parse(treeWasm).base\n }\n\n await Parser.init({\n locateFile() {\n return treeWasm\n },\n })\n\n this.initialized = true\n resolve()\n } catch (error) {\n reject(error)\n }\n })\n return this.initializePromise\n }\n\n public addFiletypeParser(filetypeParser: FiletypeParserOptions) {\n this.filetypeParserOptions.set(filetypeParser.filetype, filetypeParser)\n }\n\n private async createQueries(\n filetypeParser: FiletypeParserOptions,\n language: Language,\n ): Promise<\n | {\n highlights: Query\n }\n | undefined\n > {\n try {\n // Fetch all highlight queries from URLs/paths and concatenate them\n const highlightQueryContent = await this.fetchHighlightQueries(\n filetypeParser.queries.highlights,\n filetypeParser.filetype,\n )\n if (!highlightQueryContent) {\n console.error(\"Failed to fetch highlight queries for:\", filetypeParser.filetype)\n return undefined\n }\n\n const query = new Query(language, highlightQueryContent)\n return {\n highlights: query,\n }\n } catch (error) {\n console.error(error)\n return undefined\n }\n }\n\n private async loadLanguage(languageSource: string): Promise<Language | undefined> {\n if (!this.initialized || !this.dataPath) {\n return undefined\n }\n\n const result = await DownloadUtils.downloadOrLoad(languageSource, this.dataPath, \"languages\", \".wasm\", false)\n\n if (result.error) {\n console.error(`Error loading language ${languageSource}:`, result.error)\n return undefined\n }\n\n if (!result.filePath) {\n return undefined\n }\n\n try {\n const language = await Language.load(result.filePath)\n return language\n } catch (error) {\n console.error(`Error loading language from ${result.filePath}:`, error)\n return undefined\n }\n }\n\n private async resolveFiletypeParser(filetype: string): Promise<FiletypeParser | undefined> {\n if (this.filetypeParsers.has(filetype)) {\n return this.filetypeParsers.get(filetype)\n }\n\n if (this.filetypeParserPromises.has(filetype)) {\n return this.filetypeParserPromises.get(filetype)\n }\n\n const loadingPromise = this.loadFiletypeParser(filetype)\n this.filetypeParserPromises.set(filetype, loadingPromise)\n\n try {\n const result = await loadingPromise\n if (result) {\n this.filetypeParsers.set(filetype, result)\n }\n return result\n } finally {\n this.filetypeParserPromises.delete(filetype)\n }\n }\n\n private async loadFiletypeParser(filetype: string): Promise<FiletypeParser | undefined> {\n const filetypeParserOptions = this.filetypeParserOptions.get(filetype)\n if (!filetypeParserOptions) {\n return undefined\n }\n const language = await this.loadLanguage(filetypeParserOptions.wasm)\n if (!language) {\n return undefined\n }\n const queries = await this.createQueries(filetypeParserOptions, language)\n if (!queries) {\n console.error(\"Failed to create queries for:\", filetype)\n return undefined\n }\n const filetypeParser: FiletypeParser = {\n ...filetypeParserOptions,\n queries,\n language,\n }\n return filetypeParser\n }\n\n public async preloadParser(filetype: string) {\n return this.resolveFiletypeParser(filetype)\n }\n\n private async getReusableParser(filetype: string): Promise<ReusableParserState | undefined> {\n if (this.reusableParsers.has(filetype)) {\n return this.reusableParsers.get(filetype)\n }\n\n if (this.reusableParserPromises.has(filetype)) {\n return this.reusableParserPromises.get(filetype)\n }\n\n const creationPromise = this.createReusableParser(filetype)\n this.reusableParserPromises.set(filetype, creationPromise)\n\n try {\n const result = await creationPromise\n if (result) {\n this.reusableParsers.set(filetype, result)\n }\n return result\n } finally {\n this.reusableParserPromises.delete(filetype)\n }\n }\n\n private async createReusableParser(filetype: string): Promise<ReusableParserState | undefined> {\n const filetypeParser = await this.resolveFiletypeParser(filetype)\n if (!filetypeParser) {\n return undefined\n }\n\n const parser = new Parser()\n parser.setLanguage(filetypeParser.language)\n\n const reusableState: ReusableParserState = {\n parser,\n filetypeParser,\n }\n\n return reusableState\n }\n\n async handleInitializeParser(\n bufferId: number,\n version: number,\n content: string,\n filetype: string,\n messageId: string,\n ) {\n const filetypeParser = await this.resolveFiletypeParser(filetype)\n\n if (!filetypeParser) {\n self.postMessage({\n type: \"PARSER_INIT_RESPONSE\",\n bufferId,\n messageId,\n hasParser: false,\n warning: `No parser available for filetype ${filetype}`,\n })\n return\n }\n\n const parser = new Parser()\n parser.setLanguage(filetypeParser.language)\n const tree = parser.parse(content)\n if (!tree) {\n self.postMessage({\n type: \"PARSER_INIT_RESPONSE\",\n bufferId,\n messageId,\n hasParser: false,\n error: \"Failed to parse buffer\",\n })\n return\n }\n\n const parserState = { parser, tree, queries: filetypeParser.queries }\n this.bufferParsers.set(bufferId, parserState)\n\n self.postMessage({\n type: \"PARSER_INIT_RESPONSE\",\n bufferId,\n messageId,\n hasParser: true,\n })\n const highlights = this.initialQuery(parserState)\n self.postMessage({\n type: \"HIGHLIGHT_RESPONSE\",\n bufferId,\n version,\n ...highlights,\n })\n }\n\n private initialQuery(parserState: ParserState) {\n const query = parserState.queries.highlights\n const matches: QueryCapture[] = query.captures(parserState.tree.rootNode)\n return this.getHighlights(parserState, matches)\n }\n\n private editToRange(edit: Edit): Range {\n return {\n startPosition: {\n column: edit.startPosition.column,\n row: edit.startPosition.row,\n },\n endPosition: {\n column: edit.newEndPosition.column,\n row: edit.newEndPosition.row,\n },\n startIndex: edit.startIndex,\n endIndex: edit.newEndIndex,\n }\n }\n\n async handleEdits(\n bufferId: number,\n content: string,\n edits: Edit[],\n ): Promise<{ highlights?: HighlightResponse[]; warning?: string; error?: string }> {\n const parserState = this.bufferParsers.get(bufferId)\n if (!parserState) {\n return { warning: \"No parser state found for buffer\" }\n }\n\n for (const edit of edits) {\n parserState.tree.edit(edit)\n }\n\n // Parse the buffer\n const startParse = performance.now()\n\n const newTree = parserState.parser.parse(content, parserState.tree)\n\n const endParse = performance.now()\n const parseTime = endParse - startParse\n this.performance.parseTimes.push(parseTime)\n if (this.performance.parseTimes.length > 10) {\n this.performance.parseTimes.shift()\n }\n this.performance.averageParseTime =\n this.performance.parseTimes.reduce((acc, time) => acc + time, 0) / this.performance.parseTimes.length\n\n if (!newTree) {\n return { error: \"Failed to parse buffer\" }\n }\n\n const changedRanges = parserState.tree.getChangedRanges(newTree)\n parserState.tree = newTree\n\n const startQuery = performance.now()\n const matches: QueryCapture[] = []\n\n // If no changed ranges detected, use the edit ranges as fallback\n if (changedRanges.length === 0) {\n edits.forEach((edit) => {\n const range = this.editToRange(edit)\n changedRanges.push(range)\n })\n }\n\n for (const range of changedRanges) {\n let node = parserState.tree.rootNode.descendantForPosition(range.startPosition, range.endPosition)\n\n if (!node) {\n continue\n }\n\n // If we got the root node, query with range to limit scope\n if (node.equals(parserState.tree.rootNode)) {\n // WHY ARE RANGES NOT WORKING!?\n // The changed ranges are not returning anything in some cases\n // Even this shit somehow returns many lines before the actual range,\n // and even though expanded by 1000 bytes it does not capture much beyond the actual range.\n // So freaking weird.\n const rangeCaptures = parserState.queries.highlights.captures(\n node,\n // WTF!?\n {\n startIndex: range.startIndex - 100,\n endIndex: range.endIndex + 1000,\n },\n )\n matches.push(...rangeCaptures)\n continue\n }\n\n // For smaller nodes, walk up until we find a node that fully contains the range\n while (node && !this.nodeContainsRange(node, range)) {\n node = node.parent\n }\n\n if (!node) {\n node = parserState.tree.rootNode\n }\n\n const nodeCaptures = parserState.queries.highlights.captures(node)\n matches.push(...nodeCaptures)\n }\n\n const endQuery = performance.now()\n const queryTime = endQuery - startQuery\n this.performance.queryTimes.push(queryTime)\n if (this.performance.queryTimes.length > 10) {\n this.performance.queryTimes.shift()\n }\n this.performance.averageQueryTime =\n this.performance.queryTimes.reduce((acc, time) => acc + time, 0) / this.performance.queryTimes.length\n\n return this.getHighlights(parserState, matches)\n }\n\n private nodeContainsRange(node: any, range: any): boolean {\n return (\n node.startPosition.row <= range.startPosition.row &&\n node.endPosition.row >= range.endPosition.row &&\n (node.startPosition.row < range.startPosition.row || node.startPosition.column <= range.startPosition.column) &&\n (node.endPosition.row > range.endPosition.row || node.endPosition.column >= range.endPosition.column)\n )\n }\n\n private getHighlights(parserState: ParserState, matches: QueryCapture[]): { highlights: HighlightResponse[] } {\n const lineHighlights: Map<number, Map<number, HighlightRange>> = new Map()\n const droppedHighlights: Map<number, Map<number, HighlightRange>> = new Map()\n\n for (const match of matches) {\n const node = match.node\n const startLine = node.startPosition.row\n const endLine = node.endPosition.row\n\n const highlight = {\n startCol: node.startPosition.column,\n endCol: node.endPosition.column,\n group: match.name,\n }\n\n if (!lineHighlights.has(startLine)) {\n lineHighlights.set(startLine, new Map())\n droppedHighlights.set(startLine, new Map())\n }\n if (lineHighlights.get(startLine)?.has(node.id)) {\n droppedHighlights.get(startLine)?.set(node.id, lineHighlights.get(startLine)?.get(node.id)!)\n }\n lineHighlights.get(startLine)?.set(node.id, highlight)\n\n if (startLine !== endLine) {\n for (let line = startLine + 1; line <= endLine; line++) {\n if (!lineHighlights.has(line)) {\n lineHighlights.set(line, new Map())\n }\n const hl: HighlightRange = {\n startCol: 0,\n endCol: node.endPosition.column,\n group: match.name,\n }\n lineHighlights.get(line)?.set(node.id, hl)\n }\n }\n }\n\n return {\n highlights: Array.from(lineHighlights.entries()).map(([line, lineHighlights]) => ({\n line,\n highlights: Array.from(lineHighlights.values()),\n droppedHighlights: droppedHighlights.get(line) ? Array.from(droppedHighlights.get(line)!.values()) : [],\n })),\n }\n }\n\n private getSimpleHighlights(matches: QueryCapture[]): SimpleHighlight[] {\n const highlights: SimpleHighlight[] = []\n\n for (const match of matches) {\n const node = match.node\n highlights.push([node.startIndex, node.endIndex, match.name])\n }\n\n return highlights\n }\n\n async handleResetBuffer(\n bufferId: number,\n version: number,\n content: string,\n ): Promise<{ highlights?: HighlightResponse[]; warning?: string; error?: string }> {\n const parserState = this.bufferParsers.get(bufferId)\n if (!parserState) {\n return { warning: \"No parser state found for buffer\" }\n }\n\n const newTree = parserState.parser.parse(content)\n\n if (!newTree) {\n return { error: \"Failed to parse buffer during reset\" }\n }\n\n parserState.tree = newTree\n const matches = parserState.queries.highlights.captures(parserState.tree.rootNode)\n\n return this.getHighlights(parserState, matches)\n }\n\n disposeBuffer(bufferId: number): void {\n const parserState = this.bufferParsers.get(bufferId)\n if (!parserState) {\n return\n }\n\n parserState.tree.delete()\n parserState.parser.delete()\n\n this.bufferParsers.delete(bufferId)\n }\n\n async handleOneShotHighlight(content: string, filetype: string, messageId: string): Promise<void> {\n const reusableState = await this.getReusableParser(filetype)\n\n if (!reusableState) {\n self.postMessage({\n type: \"ONESHOT_HIGHLIGHT_RESPONSE\",\n messageId,\n hasParser: false,\n warning: `No parser available for filetype ${filetype}`,\n })\n return\n }\n\n const tree = reusableState.parser.parse(content)\n\n if (!tree) {\n self.postMessage({\n type: \"ONESHOT_HIGHLIGHT_RESPONSE\",\n messageId,\n hasParser: false,\n error: \"Failed to parse content\",\n })\n return\n }\n\n try {\n const matches = reusableState.filetypeParser.queries.highlights.captures(tree.rootNode)\n const highlights = this.getSimpleHighlights(matches)\n\n self.postMessage({\n type: \"ONESHOT_HIGHLIGHT_RESPONSE\",\n messageId,\n hasParser: true,\n highlights,\n })\n } finally {\n tree.delete()\n }\n }\n\n async updateDataPath(dataPath: string): Promise<void> {\n this.dataPath = dataPath\n\n try {\n await mkdir(path.join(dataPath, \"languages\"), { recursive: true })\n await mkdir(path.join(dataPath, \"queries\"), { recursive: true })\n } catch (error) {\n throw new Error(`Failed to update data path: ${error}`)\n }\n }\n}\nif (!isMainThread) {\n const worker = new ParserWorker()\n\n function logMessage(type: \"log\" | \"error\", ...args: any[]) {\n self.postMessage({\n type: \"WORKER_LOG\",\n logType: type,\n data: args,\n })\n }\n console.log = (...args) => logMessage(\"log\", ...args)\n console.error = (...args) => logMessage(\"error\", ...args)\n\n // @ts-ignore - we'll fix this in the future for sure\n self.onmessage = async (e: MessageEvent) => {\n const { type, bufferId, version, content, filetype, edits, filetypeParser, messageId, dataPath } = e.data\n\n try {\n switch (type) {\n case \"INIT\":\n try {\n await worker.initialize({ dataPath })\n self.postMessage({ type: \"INIT_RESPONSE\" })\n } catch (error) {\n self.postMessage({\n type: \"INIT_RESPONSE\",\n error: error instanceof Error ? error.stack || error.message : String(error),\n })\n }\n break\n\n case \"ADD_FILETYPE_PARSER\":\n worker.addFiletypeParser(filetypeParser)\n break\n\n case \"PRELOAD_PARSER\":\n const maybeParser = await worker.preloadParser(filetype)\n self.postMessage({ type: \"PRELOAD_PARSER_RESPONSE\", messageId, hasParser: !!maybeParser })\n break\n\n case \"INITIALIZE_PARSER\":\n await worker.handleInitializeParser(bufferId, version, content, filetype, messageId)\n break\n\n case \"HANDLE_EDITS\":\n const response = await worker.handleEdits(bufferId, content, edits)\n if (response.highlights && response.highlights.length > 0) {\n self.postMessage({ type: \"HIGHLIGHT_RESPONSE\", bufferId, version, ...response })\n } else if (response.warning) {\n self.postMessage({ type: \"WARNING\", bufferId, warning: response.warning })\n } else if (response.error) {\n self.postMessage({ type: \"ERROR\", bufferId, error: response.error })\n }\n break\n\n case \"GET_PERFORMANCE\":\n self.postMessage({ type: \"PERFORMANCE_RESPONSE\", performance: worker.performance, messageId })\n break\n\n case \"RESET_BUFFER\":\n const resetResponse = await worker.handleResetBuffer(bufferId, version, content)\n if (resetResponse.highlights && resetResponse.highlights.length > 0) {\n self.postMessage({ type: \"HIGHLIGHT_RESPONSE\", bufferId, version, ...resetResponse })\n } else if (resetResponse.warning) {\n self.postMessage({ type: \"WARNING\", bufferId, warning: resetResponse.warning })\n } else if (resetResponse.error) {\n self.postMessage({ type: \"ERROR\", bufferId, error: resetResponse.error })\n }\n break\n\n case \"DISPOSE_BUFFER\":\n worker.disposeBuffer(bufferId)\n self.postMessage({ type: \"BUFFER_DISPOSED\", bufferId })\n break\n\n case \"ONESHOT_HIGHLIGHT\":\n await worker.handleOneShotHighlight(content, filetype, messageId)\n break\n\n case \"UPDATE_DATA_PATH\":\n try {\n await worker.updateDataPath(dataPath)\n self.postMessage({ type: \"UPDATE_DATA_PATH_RESPONSE\", messageId })\n } catch (error) {\n self.postMessage({\n type: \"UPDATE_DATA_PATH_RESPONSE\",\n messageId,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n break\n\n default:\n self.postMessage({\n type: \"ERROR\",\n bufferId,\n error: `Unknown message type: ${type}`,\n })\n }\n } catch (error) {\n self.postMessage({\n type: \"ERROR\",\n bufferId,\n error: error instanceof Error ? error.stack || error.message : String(error),\n })\n }\n }\n}\n",
|
|
6
|
+
"import { mkdir, writeFile } from \"fs/promises\"\nimport * as path from \"path\"\n\nexport interface DownloadResult {\n content?: ArrayBuffer\n filePath?: string\n error?: string\n}\n\nexport class DownloadUtils {\n private static hashUrl(url: string): string {\n let hash = 0\n for (let i = 0; i < url.length; i++) {\n const char = url.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash\n }\n return Math.abs(hash).toString(16)\n }\n\n /**\n * Download a file from URL or load from local path, with caching support\n */\n static async downloadOrLoad(\n source: string,\n cacheDir: string,\n cacheSubdir: string,\n fileExtension: string,\n useHashForCache: boolean = true,\n filetype?: string,\n ): Promise<DownloadResult> {\n const isUrl = source.startsWith(\"http://\") || source.startsWith(\"https://\")\n\n if (isUrl) {\n let cacheFileName: string\n if (useHashForCache) {\n const hash = this.hashUrl(source)\n cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`\n } else {\n cacheFileName = path.basename(source)\n }\n const cacheFile = path.join(cacheDir, cacheSubdir, cacheFileName)\n\n // Ensure cache directory exists\n await mkdir(path.dirname(cacheFile), { recursive: true })\n\n try {\n const cachedContent = await Bun.file(cacheFile).arrayBuffer()\n if (cachedContent.byteLength > 0) {\n console.log(`Loaded from cache: ${cacheFile} (${source})`)\n return { content: cachedContent, filePath: cacheFile }\n }\n } catch (error) {\n // Cache miss, continue to fetch\n }\n\n try {\n console.log(`Downloading from URL: ${source}`)\n const response = await fetch(source)\n if (!response.ok) {\n return { error: `Failed to fetch from ${source}: ${response.statusText}` }\n }\n const content = await response.arrayBuffer()\n\n try {\n await writeFile(cacheFile, Buffer.from(content))\n console.log(`Cached: ${source}`)\n } catch (cacheError) {\n console.warn(`Failed to cache: ${cacheError}`)\n }\n\n return { content, filePath: cacheFile }\n } catch (error) {\n return { error: `Error downloading from ${source}: ${error}` }\n }\n } else {\n try {\n console.log(`Loading from local path: ${source}`)\n const content = await Bun.file(source).arrayBuffer()\n return { content, filePath: source }\n } catch (error) {\n return { error: `Error loading from local path ${source}: ${error}` }\n }\n }\n }\n\n /**\n * Download and save a file to a specific target path\n */\n static async downloadToPath(source: string, targetPath: string): Promise<DownloadResult> {\n const isUrl = source.startsWith(\"http://\") || source.startsWith(\"https://\")\n\n await mkdir(path.dirname(targetPath), { recursive: true })\n\n if (isUrl) {\n try {\n console.log(`Downloading from URL: ${source}`)\n const response = await fetch(source)\n if (!response.ok) {\n return { error: `Failed to fetch from ${source}: ${response.statusText}` }\n }\n const content = await response.arrayBuffer()\n\n await writeFile(targetPath, Buffer.from(content))\n console.log(`Downloaded: ${source} -> ${targetPath}`)\n\n return { content, filePath: targetPath }\n } catch (error) {\n return { error: `Error downloading from ${source}: ${error}` }\n }\n } else {\n try {\n console.log(`Copying from local path: ${source}`)\n const content = await Bun.file(source).arrayBuffer()\n await writeFile(targetPath, Buffer.from(content))\n return { content, filePath: targetPath }\n } catch (error) {\n return { error: `Error copying from local path ${source}: ${error}` }\n }\n }\n }\n\n /**\n * Fetch multiple highlight queries and concatenate them\n */\n static async fetchHighlightQueries(sources: string[], cacheDir: string, filetype: string): Promise<string> {\n const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype))\n const queryResults = await Promise.all(queryPromises)\n\n const validQueries = queryResults.filter((query) => query.trim().length > 0)\n return validQueries.join(\"\\n\")\n }\n\n private static async fetchHighlightQuery(source: string, cacheDir: string, filetype: string): Promise<string> {\n const result = await this.downloadOrLoad(source, cacheDir, \"queries\", \".scm\", true, filetype)\n\n if (result.error) {\n console.error(`Error fetching highlight query from ${source}:`, result.error)\n return \"\"\n }\n\n if (result.content) {\n return new TextDecoder().decode(result.content)\n }\n\n return \"\"\n }\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "E28996FCD9507DC064756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -4,7 +4,7 @@ import { type fonts, type ASCIIFontName } from "../lib/ascii.font";
|
|
|
4
4
|
import { RGBA } from "../lib/RGBA";
|
|
5
5
|
import { FrameBufferRenderable } from "./FrameBuffer";
|
|
6
6
|
import type { RenderContext } from "../types";
|
|
7
|
-
export interface ASCIIFontOptions extends RenderableOptions<ASCIIFontRenderable> {
|
|
7
|
+
export interface ASCIIFontOptions extends Omit<RenderableOptions<ASCIIFontRenderable>, "width" | "height"> {
|
|
8
8
|
text?: string;
|
|
9
9
|
font?: ASCIIFontName;
|
|
10
10
|
fg?: RGBA | RGBA[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type RenderContext } from "../types";
|
|
2
|
+
import { SyntaxStyle } from "../lib/syntax-style";
|
|
3
|
+
import { TreeSitterClient } from "../lib/tree-sitter";
|
|
4
|
+
import { TextBufferRenderable, type TextBufferOptions } from "./TextBufferRenderable";
|
|
5
|
+
export interface CodeOptions extends TextBufferOptions {
|
|
6
|
+
content?: string;
|
|
7
|
+
filetype?: string;
|
|
8
|
+
syntaxStyle: SyntaxStyle;
|
|
9
|
+
treeSitterClient?: TreeSitterClient;
|
|
10
|
+
}
|
|
11
|
+
export declare class CodeRenderable extends TextBufferRenderable {
|
|
12
|
+
private _content;
|
|
13
|
+
private _filetype?;
|
|
14
|
+
private _syntaxStyle;
|
|
15
|
+
private _isHighlighting;
|
|
16
|
+
private _treeSitterClient;
|
|
17
|
+
private _pendingRehighlight;
|
|
18
|
+
protected _contentDefaultOptions: {
|
|
19
|
+
content: string;
|
|
20
|
+
};
|
|
21
|
+
constructor(ctx: RenderContext, options: CodeOptions);
|
|
22
|
+
get content(): string;
|
|
23
|
+
set content(value: string);
|
|
24
|
+
get filetype(): string | undefined;
|
|
25
|
+
set filetype(value: string);
|
|
26
|
+
get syntaxStyle(): SyntaxStyle;
|
|
27
|
+
set syntaxStyle(value: SyntaxStyle);
|
|
28
|
+
private updateContent;
|
|
29
|
+
private fallback;
|
|
30
|
+
private createFallbackStyledText;
|
|
31
|
+
}
|
package/renderables/Input.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OptimizedBuffer } from "../buffer";
|
|
2
|
-
import type {
|
|
2
|
+
import type { KeyEvent } from "../lib/KeyHandler";
|
|
3
3
|
import { type ColorInput } from "../lib/RGBA";
|
|
4
4
|
import { Renderable, type RenderableOptions } from "../Renderable";
|
|
5
5
|
import type { RenderContext } from "../types";
|
|
@@ -54,9 +54,9 @@ export declare class InputRenderable extends Renderable {
|
|
|
54
54
|
set placeholder(placeholder: string);
|
|
55
55
|
get cursorPosition(): number;
|
|
56
56
|
set cursorPosition(position: number);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
handleKeyPress(key:
|
|
57
|
+
insertText(text: string): void;
|
|
58
|
+
deleteCharacter(direction: "backward" | "forward"): void;
|
|
59
|
+
handleKeyPress(key: KeyEvent | string): boolean;
|
|
60
60
|
set maxLength(maxLength: number);
|
|
61
61
|
set backgroundColor(value: ColorInput);
|
|
62
62
|
set textColor(value: ColorInput);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { OptimizedBuffer } from "../buffer";
|
|
2
2
|
import { RGBA, type ColorInput } from "../lib";
|
|
3
|
-
import type {
|
|
3
|
+
import type { KeyEvent } from "../lib/KeyHandler";
|
|
4
4
|
import { Renderable, type RenderableOptions } from "../Renderable";
|
|
5
5
|
import type { RenderContext } from "../types";
|
|
6
6
|
import { SliderRenderable, type SliderOptions } from "./Slider";
|
|
@@ -42,7 +42,7 @@ export declare class ScrollBarRenderable extends Renderable {
|
|
|
42
42
|
private updateSliderFromScrollState;
|
|
43
43
|
scrollBy(delta: number, unit?: ScrollUnit): void;
|
|
44
44
|
private recalculateVisibility;
|
|
45
|
-
handleKeyPress(key:
|
|
45
|
+
handleKeyPress(key: KeyEvent | string): boolean;
|
|
46
46
|
}
|
|
47
47
|
export interface ArrowOptions extends RenderableOptions<ArrowRenderable> {
|
|
48
48
|
direction: "up" | "down" | "left" | "right";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type KeyEvent } from "../lib";
|
|
2
|
+
import { type ScrollAcceleration } from "../lib/scroll-acceleration";
|
|
2
3
|
import type { Renderable, RenderableOptions } from "../Renderable";
|
|
3
4
|
import type { MouseEvent } from "../renderer";
|
|
4
5
|
import type { RenderContext } from "../types";
|
|
@@ -22,6 +23,7 @@ export interface ScrollBoxOptions extends BoxOptions<ScrollBoxRenderable> {
|
|
|
22
23
|
stickyStart?: "bottom" | "top" | "left" | "right";
|
|
23
24
|
scrollX?: boolean;
|
|
24
25
|
scrollY?: boolean;
|
|
26
|
+
scrollAcceleration?: ScrollAcceleration;
|
|
25
27
|
}
|
|
26
28
|
export declare class ScrollBoxRenderable extends BoxRenderable {
|
|
27
29
|
static idCounter: number;
|
|
@@ -51,6 +53,7 @@ export declare class ScrollBoxRenderable extends BoxRenderable {
|
|
|
51
53
|
private _stickyScrollRight;
|
|
52
54
|
private _stickyStart?;
|
|
53
55
|
private _hasManualScroll;
|
|
56
|
+
private scrollAccel;
|
|
54
57
|
get stickyScroll(): boolean;
|
|
55
58
|
set stickyScroll(value: boolean);
|
|
56
59
|
get stickyStart(): "bottom" | "top" | "left" | "right" | undefined;
|
|
@@ -63,7 +66,7 @@ export declare class ScrollBoxRenderable extends BoxRenderable {
|
|
|
63
66
|
get scrollHeight(): number;
|
|
64
67
|
private updateStickyState;
|
|
65
68
|
private applyStickyStart;
|
|
66
|
-
constructor(ctx: RenderContext, { wrapperOptions, viewportOptions, contentOptions, rootOptions, scrollbarOptions, verticalScrollbarOptions, horizontalScrollbarOptions, stickyScroll, stickyStart, scrollX, scrollY, ...options }: ScrollBoxOptions);
|
|
69
|
+
constructor(ctx: RenderContext, { wrapperOptions, viewportOptions, contentOptions, rootOptions, scrollbarOptions, verticalScrollbarOptions, horizontalScrollbarOptions, stickyScroll, stickyStart, scrollX, scrollY, scrollAcceleration, ...options }: ScrollBoxOptions);
|
|
67
70
|
protected onUpdate(deltaTime: number): void;
|
|
68
71
|
scrollBy(delta: number | {
|
|
69
72
|
x: number;
|
|
@@ -74,10 +77,11 @@ export declare class ScrollBoxRenderable extends BoxRenderable {
|
|
|
74
77
|
y: number;
|
|
75
78
|
}): void;
|
|
76
79
|
add(obj: Renderable | VNode<any, any[]>, index?: number): number;
|
|
80
|
+
insertBefore(obj: Renderable | VNode<any, any[]> | unknown, anchor?: Renderable | unknown): number;
|
|
77
81
|
remove(id: string): void;
|
|
78
82
|
getChildren(): Renderable[];
|
|
79
83
|
protected onMouseEvent(event: MouseEvent): void;
|
|
80
|
-
handleKeyPress(key:
|
|
84
|
+
handleKeyPress(key: KeyEvent | string): boolean;
|
|
81
85
|
startAutoScroll(mouseX: number, mouseY: number): void;
|
|
82
86
|
updateAutoScroll(mouseX: number, mouseY: number): void;
|
|
83
87
|
stopAutoScroll(): void;
|
package/renderables/Select.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { OptimizedBuffer } from "../buffer";
|
|
2
2
|
import { fonts } from "../lib/ascii.font";
|
|
3
|
-
import type {
|
|
3
|
+
import type { KeyEvent } from "../lib/KeyHandler";
|
|
4
4
|
import { type ColorInput } from "../lib/RGBA";
|
|
5
5
|
import { Renderable, type RenderableOptions } from "../Renderable";
|
|
6
6
|
import type { RenderContext } from "../types";
|
|
@@ -81,7 +81,7 @@ export declare class SelectRenderable extends Renderable {
|
|
|
81
81
|
setSelectedIndex(index: number): void;
|
|
82
82
|
private updateScrollOffset;
|
|
83
83
|
protected onResize(width: number, height: number): void;
|
|
84
|
-
handleKeyPress(key:
|
|
84
|
+
handleKeyPress(key: KeyEvent | string): boolean;
|
|
85
85
|
get showScrollIndicator(): boolean;
|
|
86
86
|
set showScrollIndicator(show: boolean);
|
|
87
87
|
get showDescription(): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Renderable, type RenderableOptions } from "../Renderable";
|
|
2
2
|
import { OptimizedBuffer } from "../buffer";
|
|
3
3
|
import { type ColorInput } from "../lib/RGBA";
|
|
4
|
-
import type {
|
|
4
|
+
import type { KeyEvent } from "../lib/KeyHandler";
|
|
5
5
|
import type { RenderContext } from "../types";
|
|
6
6
|
export interface TabSelectOption {
|
|
7
7
|
name: string;
|
|
@@ -63,7 +63,7 @@ export declare class TabSelectRenderable extends Renderable {
|
|
|
63
63
|
protected onResize(width: number, height: number): void;
|
|
64
64
|
setTabWidth(tabWidth: number): void;
|
|
65
65
|
getTabWidth(): number;
|
|
66
|
-
handleKeyPress(key:
|
|
66
|
+
handleKeyPress(key: KeyEvent | string): boolean;
|
|
67
67
|
get options(): TabSelectOption[];
|
|
68
68
|
set options(options: TabSelectOption[]);
|
|
69
69
|
set backgroundColor(color: ColorInput);
|
package/renderables/Text.d.ts
CHANGED
|
@@ -1,93 +1,39 @@
|
|
|
1
|
-
import { BaseRenderable
|
|
2
|
-
import { Selection } from "../lib/selection";
|
|
1
|
+
import { BaseRenderable } from "../Renderable";
|
|
3
2
|
import { StyledText } from "../lib/styled-text";
|
|
4
3
|
import { type TextChunk } from "../text-buffer";
|
|
5
4
|
import { RGBA } from "../lib/RGBA";
|
|
6
5
|
import { type RenderContext } from "../types";
|
|
7
|
-
import type { OptimizedBuffer } from "../buffer";
|
|
8
6
|
import { RootTextNodeRenderable, TextNodeRenderable } from "./TextNode";
|
|
9
|
-
|
|
7
|
+
import { TextBufferRenderable, type TextBufferOptions } from "./TextBufferRenderable";
|
|
8
|
+
export interface TextOptions extends TextBufferOptions {
|
|
10
9
|
content?: StyledText | string;
|
|
11
|
-
fg?: string | RGBA;
|
|
12
|
-
bg?: string | RGBA;
|
|
13
|
-
selectionBg?: string | RGBA;
|
|
14
|
-
selectionFg?: string | RGBA;
|
|
15
|
-
selectable?: boolean;
|
|
16
|
-
attributes?: number;
|
|
17
|
-
wrap?: boolean;
|
|
18
|
-
wrapMode?: "char" | "word";
|
|
19
10
|
}
|
|
20
|
-
export declare class TextRenderable extends
|
|
21
|
-
selectable: boolean;
|
|
11
|
+
export declare class TextRenderable extends TextBufferRenderable {
|
|
22
12
|
private _text;
|
|
23
|
-
private
|
|
24
|
-
private _defaultBg;
|
|
25
|
-
private _defaultAttributes;
|
|
26
|
-
private _selectionBg;
|
|
27
|
-
private _selectionFg;
|
|
28
|
-
private _wrap;
|
|
29
|
-
private _wrapMode;
|
|
30
|
-
private lastLocalSelection;
|
|
31
|
-
private textBuffer;
|
|
32
|
-
private _lineInfo;
|
|
13
|
+
private _hasManualStyledText;
|
|
33
14
|
protected rootTextNode: RootTextNodeRenderable;
|
|
34
|
-
protected
|
|
15
|
+
protected _contentDefaultOptions: {
|
|
35
16
|
content: string;
|
|
36
|
-
fg: RGBA;
|
|
37
|
-
bg: RGBA;
|
|
38
|
-
selectionBg: undefined;
|
|
39
|
-
selectionFg: undefined;
|
|
40
|
-
selectable: true;
|
|
41
|
-
attributes: number;
|
|
42
|
-
wrap: true;
|
|
43
|
-
wrapMode: "char" | "word";
|
|
44
17
|
};
|
|
45
18
|
constructor(ctx: RenderContext, options: TextOptions);
|
|
46
19
|
private updateTextBuffer;
|
|
47
20
|
private clearChunks;
|
|
48
21
|
get content(): StyledText;
|
|
49
|
-
get plainText(): string;
|
|
50
|
-
get textLength(): number;
|
|
51
22
|
get chunks(): TextChunk[];
|
|
52
23
|
get textNode(): RootTextNodeRenderable;
|
|
53
24
|
set content(value: StyledText | string);
|
|
54
|
-
get fg(): RGBA;
|
|
55
|
-
set fg(value: RGBA | string | undefined);
|
|
56
|
-
get selectionBg(): RGBA | undefined;
|
|
57
|
-
set selectionBg(value: RGBA | string | undefined);
|
|
58
|
-
get selectionFg(): RGBA | undefined;
|
|
59
|
-
set selectionFg(value: RGBA | string | undefined);
|
|
60
|
-
get bg(): RGBA;
|
|
61
|
-
set bg(value: RGBA | string | undefined);
|
|
62
|
-
get attributes(): number;
|
|
63
|
-
set attributes(value: number);
|
|
64
|
-
get wrap(): boolean;
|
|
65
|
-
set wrap(value: boolean);
|
|
66
|
-
get wrapMode(): "char" | "word";
|
|
67
|
-
set wrapMode(value: "char" | "word");
|
|
68
|
-
protected onResize(width: number, height: number): void;
|
|
69
|
-
private updateLocalSelection;
|
|
70
|
-
private updateTextInfo;
|
|
71
|
-
private setupMeasureFunc;
|
|
72
25
|
insertChunk(chunk: TextChunk, index?: number): void;
|
|
73
|
-
|
|
74
|
-
|
|
26
|
+
removeChunkByObject(chunk: TextChunk): void;
|
|
27
|
+
replaceChunkByObject(chunk: TextChunk, oldChunk: TextChunk): void;
|
|
75
28
|
private updateTextFromNodes;
|
|
76
29
|
add(obj: TextNodeRenderable | StyledText | string, index?: number): number;
|
|
77
30
|
remove(id: string): void;
|
|
78
31
|
insertBefore(obj: BaseRenderable | any, anchor?: TextNodeRenderable): number;
|
|
79
32
|
getTextChildren(): BaseRenderable[];
|
|
80
33
|
clear(): void;
|
|
81
|
-
shouldStartSelection(x: number, y: number): boolean;
|
|
82
|
-
onSelectionChanged(selection: Selection | null): boolean;
|
|
83
|
-
getSelectedText(): string;
|
|
84
|
-
hasSelection(): boolean;
|
|
85
|
-
getSelection(): {
|
|
86
|
-
start: number;
|
|
87
|
-
end: number;
|
|
88
|
-
} | null;
|
|
89
34
|
onLifecyclePass: () => void;
|
|
90
|
-
|
|
91
|
-
protected
|
|
35
|
+
protected onFgChanged(newColor: RGBA): void;
|
|
36
|
+
protected onBgChanged(newColor: RGBA): void;
|
|
37
|
+
protected onAttributesChanged(newAttributes: number): void;
|
|
92
38
|
destroy(): void;
|
|
93
39
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Renderable, type RenderableOptions } from "../Renderable";
|
|
2
|
+
import { Selection, type LocalSelectionBounds } from "../lib/selection";
|
|
3
|
+
import { TextBuffer, type TextChunk } from "../text-buffer";
|
|
4
|
+
import { RGBA } from "../lib/RGBA";
|
|
5
|
+
import { type RenderContext } from "../types";
|
|
6
|
+
import type { OptimizedBuffer } from "../buffer";
|
|
7
|
+
import type { LineInfo } from "../zig";
|
|
8
|
+
export interface TextBufferOptions extends RenderableOptions<TextBufferRenderable> {
|
|
9
|
+
fg?: string | RGBA;
|
|
10
|
+
bg?: string | RGBA;
|
|
11
|
+
selectionBg?: string | RGBA;
|
|
12
|
+
selectionFg?: string | RGBA;
|
|
13
|
+
selectable?: boolean;
|
|
14
|
+
attributes?: number;
|
|
15
|
+
wrap?: boolean;
|
|
16
|
+
wrapMode?: "char" | "word";
|
|
17
|
+
}
|
|
18
|
+
export declare abstract class TextBufferRenderable extends Renderable {
|
|
19
|
+
selectable: boolean;
|
|
20
|
+
protected _defaultFg: RGBA;
|
|
21
|
+
protected _defaultBg: RGBA;
|
|
22
|
+
protected _defaultAttributes: number;
|
|
23
|
+
protected _selectionBg: RGBA | undefined;
|
|
24
|
+
protected _selectionFg: RGBA | undefined;
|
|
25
|
+
protected _wrap: boolean;
|
|
26
|
+
protected _wrapMode: "char" | "word";
|
|
27
|
+
protected lastLocalSelection: LocalSelectionBounds | null;
|
|
28
|
+
protected textBuffer: TextBuffer;
|
|
29
|
+
protected _lineInfo: LineInfo;
|
|
30
|
+
protected _defaultOptions: {
|
|
31
|
+
fg: RGBA;
|
|
32
|
+
bg: RGBA;
|
|
33
|
+
selectionBg: undefined;
|
|
34
|
+
selectionFg: undefined;
|
|
35
|
+
selectable: true;
|
|
36
|
+
attributes: number;
|
|
37
|
+
wrap: true;
|
|
38
|
+
wrapMode: "char" | "word";
|
|
39
|
+
};
|
|
40
|
+
constructor(ctx: RenderContext, options: TextBufferOptions);
|
|
41
|
+
get plainText(): string;
|
|
42
|
+
get textLength(): number;
|
|
43
|
+
get fg(): RGBA;
|
|
44
|
+
set fg(value: RGBA | string | undefined);
|
|
45
|
+
get selectionBg(): RGBA | undefined;
|
|
46
|
+
set selectionBg(value: RGBA | string | undefined);
|
|
47
|
+
get selectionFg(): RGBA | undefined;
|
|
48
|
+
set selectionFg(value: RGBA | string | undefined);
|
|
49
|
+
get bg(): RGBA;
|
|
50
|
+
set bg(value: RGBA | string | undefined);
|
|
51
|
+
get attributes(): number;
|
|
52
|
+
set attributes(value: number);
|
|
53
|
+
get wrap(): boolean;
|
|
54
|
+
set wrap(value: boolean);
|
|
55
|
+
get wrapMode(): "char" | "word";
|
|
56
|
+
set wrapMode(value: "char" | "word");
|
|
57
|
+
protected onResize(width: number, height: number): void;
|
|
58
|
+
protected refreshLocalSelection(): boolean;
|
|
59
|
+
private updateLocalSelection;
|
|
60
|
+
protected updateTextInfo(): void;
|
|
61
|
+
private updateLineInfo;
|
|
62
|
+
private updateWrapWidth;
|
|
63
|
+
private setupMeasureFunc;
|
|
64
|
+
insertChunk(chunk: TextChunk, index?: number): void;
|
|
65
|
+
removeChunk(index: number): void;
|
|
66
|
+
replaceChunk(index: number, chunk: TextChunk): void;
|
|
67
|
+
shouldStartSelection(x: number, y: number): boolean;
|
|
68
|
+
onSelectionChanged(selection: Selection | null): boolean;
|
|
69
|
+
getSelectedText(): string;
|
|
70
|
+
hasSelection(): boolean;
|
|
71
|
+
getSelection(): {
|
|
72
|
+
start: number;
|
|
73
|
+
end: number;
|
|
74
|
+
} | null;
|
|
75
|
+
render(buffer: OptimizedBuffer, deltaTime: number): void;
|
|
76
|
+
protected renderSelf(buffer: OptimizedBuffer): void;
|
|
77
|
+
destroy(): void;
|
|
78
|
+
protected onFgChanged(newColor: RGBA): void;
|
|
79
|
+
protected onBgChanged(newColor: RGBA): void;
|
|
80
|
+
protected onAttributesChanged(newAttributes: number): void;
|
|
81
|
+
}
|
|
@@ -57,6 +57,7 @@ export declare class TextNodeRenderable extends BaseRenderable {
|
|
|
57
57
|
get bg(): RGBA | undefined;
|
|
58
58
|
set attributes(attributes: number);
|
|
59
59
|
get attributes(): number;
|
|
60
|
+
findDescendantById(id: string): BaseRenderable | undefined;
|
|
60
61
|
}
|
|
61
62
|
export declare class RootTextNodeRenderable extends TextNodeRenderable {
|
|
62
63
|
private readonly ctx;
|
package/renderables/index.d.ts
CHANGED
package/renderer.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { TerminalConsole, type ConsoleOptions } from "./console";
|
|
|
8
8
|
import { type MouseEventType, type RawMouseEvent, type ScrollInfo } from "./lib/parse.mouse";
|
|
9
9
|
import { Selection } from "./lib/selection";
|
|
10
10
|
import { EventEmitter } from "events";
|
|
11
|
-
import { KeyHandler } from "./lib/KeyHandler";
|
|
11
|
+
import { KeyHandler, InternalKeyHandler } from "./lib/KeyHandler";
|
|
12
12
|
export interface CliRendererConfig {
|
|
13
13
|
stdin?: NodeJS.ReadStream;
|
|
14
14
|
stdout?: NodeJS.WriteStream;
|
|
@@ -75,7 +75,7 @@ export declare class CliRenderer extends EventEmitter implements RenderContext {
|
|
|
75
75
|
stdin: NodeJS.ReadStream;
|
|
76
76
|
private stdout;
|
|
77
77
|
private exitOnCtrlC;
|
|
78
|
-
private
|
|
78
|
+
private _isDestroyed;
|
|
79
79
|
nextRenderBuffer: OptimizedBuffer;
|
|
80
80
|
currentRenderBuffer: OptimizedBuffer;
|
|
81
81
|
private _isRunning;
|
|
@@ -141,9 +141,11 @@ export declare class CliRenderer extends EventEmitter implements RenderContext {
|
|
|
141
141
|
private _currentFocusedRenderable;
|
|
142
142
|
private lifecyclePasses;
|
|
143
143
|
private handleError;
|
|
144
|
+
private dumpOutputCache;
|
|
144
145
|
private exitHandler;
|
|
145
146
|
private warningHandler;
|
|
146
147
|
constructor(lib: RenderLib, rendererPtr: Pointer, stdin: NodeJS.ReadStream, stdout: NodeJS.WriteStream, width: number, height: number, config?: CliRendererConfig);
|
|
148
|
+
get isDestroyed(): boolean;
|
|
147
149
|
registerLifecyclePass(renderable: Renderable): void;
|
|
148
150
|
unregisterLifecyclePass(renderable: Renderable): void;
|
|
149
151
|
getLifecyclePasses(): Set<Renderable>;
|
|
@@ -159,6 +161,7 @@ export declare class CliRenderer extends EventEmitter implements RenderContext {
|
|
|
159
161
|
get resolution(): PixelResolution | null;
|
|
160
162
|
get console(): TerminalConsole;
|
|
161
163
|
get keyInput(): KeyHandler;
|
|
164
|
+
get _internalKeyInput(): InternalKeyHandler;
|
|
162
165
|
get terminalWidth(): number;
|
|
163
166
|
get terminalHeight(): number;
|
|
164
167
|
get useThread(): boolean;
|
|
@@ -194,7 +197,6 @@ export declare class CliRenderer extends EventEmitter implements RenderContext {
|
|
|
194
197
|
enabled?: boolean;
|
|
195
198
|
corner?: DebugOverlayCorner;
|
|
196
199
|
}): void;
|
|
197
|
-
clearTerminal(): void;
|
|
198
200
|
setTerminalTitle(title: string): void;
|
|
199
201
|
dumpHitGrid(): void;
|
|
200
202
|
dumpBuffers(timestamp?: number): void;
|
package/testing/mock-keys.d.ts
CHANGED
package/testing/spy.d.ts
ADDED
package/testing.d.ts
CHANGED
package/testing.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
+
ANSI,
|
|
3
4
|
CliRenderer,
|
|
4
5
|
resolveRenderLib
|
|
5
|
-
} from "./index-
|
|
6
|
+
} from "./index-pxa2sv92.js";
|
|
6
7
|
|
|
7
8
|
// src/testing/mock-keys.ts
|
|
8
9
|
var KeyCodes = {
|
|
@@ -126,6 +127,9 @@ function createMockKeys(renderer) {
|
|
|
126
127
|
const pressCtrlC = () => {
|
|
127
128
|
pressKey(KeyCodes.CTRL_C);
|
|
128
129
|
};
|
|
130
|
+
const pasteBracketedText = (text) => {
|
|
131
|
+
return pressKeys([ANSI.bracketedPasteStart, text, ANSI.bracketedPasteEnd]);
|
|
132
|
+
};
|
|
129
133
|
return {
|
|
130
134
|
pressKeys,
|
|
131
135
|
pressKey,
|
|
@@ -135,7 +139,8 @@ function createMockKeys(renderer) {
|
|
|
135
139
|
pressTab,
|
|
136
140
|
pressBackspace,
|
|
137
141
|
pressArrow,
|
|
138
|
-
pressCtrlC
|
|
142
|
+
pressCtrlC,
|
|
143
|
+
pasteBracketedText
|
|
139
144
|
};
|
|
140
145
|
}
|
|
141
146
|
|
|
@@ -288,6 +293,7 @@ function createMockMouse(renderer) {
|
|
|
288
293
|
// src/testing/test-renderer.ts
|
|
289
294
|
var decoder = new TextDecoder;
|
|
290
295
|
async function createTestRenderer(options) {
|
|
296
|
+
process.env.OTUI_USE_CONSOLE = "false";
|
|
291
297
|
const renderer = await setupTestRenderer({
|
|
292
298
|
...options,
|
|
293
299
|
useAlternateScreen: false,
|
|
@@ -296,17 +302,21 @@ async function createTestRenderer(options) {
|
|
|
296
302
|
renderer.disableStdoutInterception();
|
|
297
303
|
const mockInput = createMockKeys(renderer);
|
|
298
304
|
const mockMouse = createMockMouse(renderer);
|
|
305
|
+
const renderOnce = async () => {
|
|
306
|
+
await renderer.loop();
|
|
307
|
+
};
|
|
299
308
|
return {
|
|
300
309
|
renderer,
|
|
301
310
|
mockInput,
|
|
302
311
|
mockMouse,
|
|
303
|
-
renderOnce
|
|
304
|
-
await renderer.loop();
|
|
305
|
-
},
|
|
312
|
+
renderOnce,
|
|
306
313
|
captureCharFrame: () => {
|
|
307
314
|
const currentBuffer = renderer.currentRenderBuffer;
|
|
308
315
|
const frameBytes = currentBuffer.getRealCharBytes(true);
|
|
309
316
|
return decoder.decode(frameBytes);
|
|
317
|
+
},
|
|
318
|
+
resize: (width, height) => {
|
|
319
|
+
renderer.processResize(width, height);
|
|
310
320
|
}
|
|
311
321
|
};
|
|
312
322
|
}
|
|
@@ -331,13 +341,28 @@ async function setupTestRenderer(config) {
|
|
|
331
341
|
const renderer = new CliRenderer(ziglib, rendererPtr, stdin, stdout, width, height, config);
|
|
332
342
|
return renderer;
|
|
333
343
|
}
|
|
344
|
+
// src/testing/spy.ts
|
|
345
|
+
function createSpy() {
|
|
346
|
+
const calls = [];
|
|
347
|
+
const spy = (...args) => {
|
|
348
|
+
calls.push(args);
|
|
349
|
+
};
|
|
350
|
+
spy.calls = calls;
|
|
351
|
+
spy.callCount = () => calls.length;
|
|
352
|
+
spy.calledWith = (...expected) => {
|
|
353
|
+
return calls.some((call) => JSON.stringify(call) === JSON.stringify(expected));
|
|
354
|
+
};
|
|
355
|
+
spy.reset = () => calls.length = 0;
|
|
356
|
+
return spy;
|
|
357
|
+
}
|
|
334
358
|
export {
|
|
335
359
|
createTestRenderer,
|
|
360
|
+
createSpy,
|
|
336
361
|
createMockMouse,
|
|
337
362
|
createMockKeys,
|
|
338
363
|
MouseButtons,
|
|
339
364
|
KeyCodes
|
|
340
365
|
};
|
|
341
366
|
|
|
342
|
-
//# debugId=
|
|
367
|
+
//# debugId=6748818851F0715164756E2164756E21
|
|
343
368
|
//# sourceMappingURL=testing.js.map
|