@opentui/core 0.0.0-20250930-6541ec7f → 0.0.0-20250930-d50102aa

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.
Files changed (42) hide show
  1. package/3d.js +5 -3
  2. package/3d.js.map +2 -2
  3. package/README.md +5 -1
  4. package/highlights-eq9cgrbb.scm +604 -0
  5. package/highlights-ghv9g403.scm +205 -0
  6. package/{index-kvwmgj67.js → index-0p8687g8.js} +1092 -105
  7. package/{index-kvwmgj67.js.map → index-0p8687g8.js.map} +19 -8
  8. package/index-cc14z67g.js +3846 -0
  9. package/index-cc14z67g.js.map +12 -0
  10. package/index.js +394 -240
  11. package/index.js.map +6 -4
  12. package/lib/data-paths.d.ts +26 -0
  13. package/lib/debounce.d.ts +42 -0
  14. package/lib/env.d.ts +2 -1
  15. package/lib/hast-styled-text.d.ts +3 -23
  16. package/lib/index.d.ts +4 -0
  17. package/lib/queue.d.ts +15 -0
  18. package/lib/singleton.d.ts +2 -0
  19. package/lib/styled-text.d.ts +0 -15
  20. package/lib/syntax-style.d.ts +36 -0
  21. package/lib/tree-sitter/assets/update.d.ts +11 -0
  22. package/lib/tree-sitter/client.d.ts +42 -0
  23. package/lib/tree-sitter/default-parsers.d.ts +2 -0
  24. package/lib/tree-sitter/download-utils.d.ts +21 -0
  25. package/lib/tree-sitter/index.d.ts +10 -0
  26. package/lib/tree-sitter/parser.worker.d.ts +1 -0
  27. package/lib/tree-sitter/resolve-ft.d.ts +2 -0
  28. package/lib/tree-sitter/types.d.ts +64 -0
  29. package/lib/tree-sitter-styled-text.d.ts +7 -0
  30. package/lib/validate-dir-name.d.ts +1 -0
  31. package/package.json +12 -7
  32. package/parser.worker.d.ts +1 -0
  33. package/parser.worker.js +5 -0
  34. package/parser.worker.js.map +9 -0
  35. package/renderables/Code.d.ts +31 -0
  36. package/renderables/Text.d.ts +10 -67
  37. package/renderables/TextBufferRenderable.d.ts +81 -0
  38. package/renderables/index.d.ts +2 -0
  39. package/testing.js +3 -2
  40. package/testing.js.map +2 -2
  41. package/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  42. package/tree-sitter-typescript-zxjzwt75.wasm +0 -0
@@ -1,31 +1,10 @@
1
1
  // @bun
2
- var __create = Object.create;
3
- var __getProtoOf = Object.getPrototypeOf;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __toESM = (mod, isNodeMode, target) => {
8
- target = mod != null ? __create(__getProtoOf(mod)) : {};
9
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
- for (let key of __getOwnPropNames(mod))
11
- if (!__hasOwnProp.call(to, key))
12
- __defProp(to, key, {
13
- get: () => mod[key],
14
- enumerable: true
15
- });
16
- return to;
17
- };
18
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
- var __export = (target, all) => {
20
- for (var name in all)
21
- __defProp(target, name, {
22
- get: all[name],
23
- enumerable: true,
24
- configurable: true,
25
- set: (newValue) => all[name] = () => newValue
26
- });
27
- };
28
- var __require = import.meta.require;
2
+ import {
3
+ DownloadUtils,
4
+ __export,
5
+ __require,
6
+ parser_worker_default
7
+ } from "./index-cc14z67g.js";
29
8
 
30
9
  // ../../node_modules/yoga-layout/dist/src/index.js
31
10
  var exports_src = {};
@@ -4188,60 +4167,9 @@ function isStyledText(obj) {
4188
4167
  class StyledText {
4189
4168
  [BrandedStyledText] = true;
4190
4169
  chunks;
4191
- textRenderable;
4192
4170
  constructor(chunks) {
4193
4171
  this.chunks = chunks;
4194
4172
  }
4195
- mount(textRenderable) {
4196
- this.textRenderable = textRenderable;
4197
- }
4198
- insert(chunk, index) {
4199
- const originalLength = this.chunks.length;
4200
- if (this.textRenderable) {
4201
- this.textRenderable.insertChunk(chunk, index ?? originalLength);
4202
- let newChunks;
4203
- if (index === undefined || index === originalLength) {
4204
- newChunks = [...this.chunks, chunk];
4205
- } else {
4206
- newChunks = [...this.chunks.slice(0, index), chunk, ...this.chunks.slice(index)];
4207
- }
4208
- this.chunks = newChunks;
4209
- }
4210
- return this;
4211
- }
4212
- remove(chunk) {
4213
- if (this.textRenderable) {
4214
- this.textRenderable.removeChunk(chunk);
4215
- const originalLength = this.chunks.length;
4216
- const index = this.chunks.indexOf(chunk);
4217
- if (index === -1)
4218
- return this;
4219
- let newChunks;
4220
- if (index === originalLength - 1) {
4221
- newChunks = this.chunks.slice(0, -1);
4222
- } else {
4223
- newChunks = [...this.chunks.slice(0, index), ...this.chunks.slice(index + 1)];
4224
- }
4225
- this.chunks = newChunks;
4226
- }
4227
- return this;
4228
- }
4229
- replace(chunk, oldChunk) {
4230
- if (this.textRenderable) {
4231
- this.textRenderable.replaceChunk(chunk, oldChunk);
4232
- const index = this.chunks.indexOf(oldChunk);
4233
- if (index === -1)
4234
- return this;
4235
- let newChunks;
4236
- if (index === this.chunks.length - 1) {
4237
- newChunks = [...this.chunks.slice(0, -1), chunk];
4238
- } else {
4239
- newChunks = [...this.chunks.slice(0, index), chunk, ...this.chunks.slice(index + 1)];
4240
- }
4241
- this.chunks = newChunks;
4242
- }
4243
- return this;
4244
- }
4245
4173
  }
4246
4174
  function stringToStyledText(content) {
4247
4175
  const chunk = {
@@ -4337,7 +4265,36 @@ function t(strings, ...values) {
4337
4265
  return new StyledText(chunks);
4338
4266
  }
4339
4267
 
4340
- // src/lib/hast-styled-text.ts
4268
+ // src/lib/syntax-style.ts
4269
+ function convertThemeToStyles(theme) {
4270
+ const flatStyles = {};
4271
+ for (const tokenStyle of theme) {
4272
+ const styleDefinition = {};
4273
+ if (tokenStyle.style.foreground) {
4274
+ styleDefinition.fg = parseColor(tokenStyle.style.foreground);
4275
+ }
4276
+ if (tokenStyle.style.background) {
4277
+ styleDefinition.bg = parseColor(tokenStyle.style.background);
4278
+ }
4279
+ if (tokenStyle.style.bold !== undefined) {
4280
+ styleDefinition.bold = tokenStyle.style.bold;
4281
+ }
4282
+ if (tokenStyle.style.italic !== undefined) {
4283
+ styleDefinition.italic = tokenStyle.style.italic;
4284
+ }
4285
+ if (tokenStyle.style.underline !== undefined) {
4286
+ styleDefinition.underline = tokenStyle.style.underline;
4287
+ }
4288
+ if (tokenStyle.style.dim !== undefined) {
4289
+ styleDefinition.dim = tokenStyle.style.dim;
4290
+ }
4291
+ for (const scope of tokenStyle.scope) {
4292
+ flatStyles[scope] = styleDefinition;
4293
+ }
4294
+ }
4295
+ return flatStyles;
4296
+ }
4297
+
4341
4298
  class SyntaxStyle {
4342
4299
  styles;
4343
4300
  mergedStyleCache;
@@ -4345,6 +4302,10 @@ class SyntaxStyle {
4345
4302
  this.styles = styles;
4346
4303
  this.mergedStyleCache = new Map;
4347
4304
  }
4305
+ static fromTheme(theme) {
4306
+ const flatStyles = convertThemeToStyles(theme);
4307
+ return new SyntaxStyle(flatStyles);
4308
+ }
4348
4309
  mergeStyles(...styleNames) {
4349
4310
  const cacheKey = styleNames.join(":");
4350
4311
  const cached = this.mergedStyleCache.get(cacheKey);
@@ -4352,7 +4313,7 @@ class SyntaxStyle {
4352
4313
  return cached;
4353
4314
  const styleDefinition = {};
4354
4315
  for (const name of styleNames) {
4355
- const style = this.styles[name];
4316
+ const style = this.getStyle(name);
4356
4317
  if (!style)
4357
4318
  continue;
4358
4319
  if (style.fg)
@@ -4382,6 +4343,18 @@ class SyntaxStyle {
4382
4343
  this.mergedStyleCache.set(cacheKey, merged);
4383
4344
  return merged;
4384
4345
  }
4346
+ getStyle(name) {
4347
+ if (Object.prototype.hasOwnProperty.call(this.styles, name)) {
4348
+ return this.styles[name];
4349
+ }
4350
+ if (name.includes(".")) {
4351
+ const baseName = name.split(".")[0];
4352
+ if (Object.prototype.hasOwnProperty.call(this.styles, baseName)) {
4353
+ return this.styles[baseName];
4354
+ }
4355
+ }
4356
+ return;
4357
+ }
4385
4358
  clearCache() {
4386
4359
  this.mergedStyleCache.clear();
4387
4360
  }
@@ -4389,6 +4362,8 @@ class SyntaxStyle {
4389
4362
  return this.mergedStyleCache.size;
4390
4363
  }
4391
4364
  }
4365
+
4366
+ // src/lib/hast-styled-text.ts
4392
4367
  function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
4393
4368
  const chunks = [];
4394
4369
  if (node.type === "text") {
@@ -4923,9 +4898,19 @@ function singleton(key, factory) {
4923
4898
  }
4924
4899
  return bag[key];
4925
4900
  }
4901
+ function destroySingleton(key) {
4902
+ const bag = globalThis[singletonCacheSymbol];
4903
+ if (bag && key in bag) {
4904
+ delete bag[key];
4905
+ }
4906
+ }
4907
+ function hasSingleton(key) {
4908
+ const bag = globalThis[singletonCacheSymbol];
4909
+ return bag && key in bag;
4910
+ }
4926
4911
 
4927
4912
  // src/lib/env.ts
4928
- var envRegistry = {};
4913
+ var envRegistry = singleton("env-registry", () => ({}));
4929
4914
  function registerEnvVar(config) {
4930
4915
  const existing = envRegistry[config.name];
4931
4916
  if (existing) {
@@ -4983,8 +4968,14 @@ class EnvStore {
4983
4968
  has(key) {
4984
4969
  return key in envRegistry;
4985
4970
  }
4971
+ clearCache() {
4972
+ this.parsedValues.clear();
4973
+ }
4986
4974
  }
4987
4975
  var envStore = singleton("env-store", () => new EnvStore);
4976
+ function clearEnvCache() {
4977
+ envStore.clearCache();
4978
+ }
4988
4979
  function generateEnvMarkdown() {
4989
4980
  const configs = Object.values(envRegistry);
4990
4981
  if (configs.length === 0) {
@@ -5073,6 +5064,980 @@ var env = new Proxy({}, {
5073
5064
  return;
5074
5065
  }
5075
5066
  });
5067
+
5068
+ // src/lib/tree-sitter-styled-text.ts
5069
+ function treeSitterToTextChunks(content, highlights, syntaxStyle) {
5070
+ const chunks = [];
5071
+ const defaultStyle = syntaxStyle.getStyle("default");
5072
+ let currentIndex = 0;
5073
+ for (let i = 0;i < highlights.length; i++) {
5074
+ const [startIndex, endIndex, group] = highlights[i];
5075
+ if (startIndex < currentIndex)
5076
+ continue;
5077
+ if (currentIndex < startIndex) {
5078
+ const text2 = content.slice(currentIndex, startIndex);
5079
+ chunks.push({
5080
+ __isChunk: true,
5081
+ text: text2,
5082
+ fg: defaultStyle?.fg,
5083
+ bg: defaultStyle?.bg,
5084
+ attributes: defaultStyle ? createTextAttributes({
5085
+ bold: defaultStyle.bold,
5086
+ italic: defaultStyle.italic,
5087
+ underline: defaultStyle.underline,
5088
+ dim: defaultStyle.dim
5089
+ }) : 0
5090
+ });
5091
+ currentIndex = startIndex;
5092
+ }
5093
+ let resolvedStyle = syntaxStyle.getStyle(group);
5094
+ let j = i + 1;
5095
+ while (j < highlights.length && highlights[j][0] === startIndex) {
5096
+ const [, , nextGroup] = highlights[j];
5097
+ const nextStyle = syntaxStyle.getStyle(nextGroup);
5098
+ if (nextStyle) {
5099
+ resolvedStyle = nextStyle;
5100
+ }
5101
+ j++;
5102
+ }
5103
+ i = j - 1;
5104
+ const text = content.slice(startIndex, endIndex);
5105
+ const styleToUse = resolvedStyle || defaultStyle;
5106
+ chunks.push({
5107
+ __isChunk: true,
5108
+ text,
5109
+ fg: styleToUse?.fg,
5110
+ bg: styleToUse?.bg,
5111
+ attributes: styleToUse ? createTextAttributes({
5112
+ bold: styleToUse.bold,
5113
+ italic: styleToUse.italic,
5114
+ underline: styleToUse.underline,
5115
+ dim: styleToUse.dim
5116
+ }) : 0
5117
+ });
5118
+ currentIndex = endIndex;
5119
+ }
5120
+ if (currentIndex < content.length) {
5121
+ const text = content.slice(currentIndex);
5122
+ chunks.push({
5123
+ __isChunk: true,
5124
+ text,
5125
+ fg: defaultStyle?.fg,
5126
+ bg: defaultStyle?.bg,
5127
+ attributes: defaultStyle ? createTextAttributes({
5128
+ bold: defaultStyle.bold,
5129
+ italic: defaultStyle.italic,
5130
+ underline: defaultStyle.underline,
5131
+ dim: defaultStyle.dim
5132
+ }) : 0
5133
+ });
5134
+ }
5135
+ return chunks;
5136
+ }
5137
+ async function treeSitterToStyledText(content, filetype, syntaxStyle, client) {
5138
+ const result = await client.highlightOnce(content, filetype);
5139
+ if (result.highlights && result.highlights.length > 0) {
5140
+ const chunks = treeSitterToTextChunks(content, result.highlights, syntaxStyle);
5141
+ return new StyledText(chunks);
5142
+ } else {
5143
+ const defaultStyle = syntaxStyle.mergeStyles("default");
5144
+ const chunks = [
5145
+ {
5146
+ __isChunk: true,
5147
+ text: content,
5148
+ fg: defaultStyle.fg,
5149
+ bg: defaultStyle.bg,
5150
+ attributes: defaultStyle.attributes
5151
+ }
5152
+ ];
5153
+ return new StyledText(chunks);
5154
+ }
5155
+ }
5156
+
5157
+ // src/lib/tree-sitter/client.ts
5158
+ import { EventEmitter as EventEmitter2 } from "events";
5159
+
5160
+ // src/lib/debounce.ts
5161
+ var TIMERS_MAP = new Map;
5162
+
5163
+ class DebounceController {
5164
+ scopeId;
5165
+ constructor(scopeId) {
5166
+ this.scopeId = scopeId;
5167
+ if (!TIMERS_MAP.has(this.scopeId)) {
5168
+ TIMERS_MAP.set(this.scopeId, new Map);
5169
+ }
5170
+ }
5171
+ debounce(id, ms, fn) {
5172
+ const scopeMap = TIMERS_MAP.get(this.scopeId);
5173
+ return new Promise((resolve, reject) => {
5174
+ if (scopeMap.has(id)) {
5175
+ clearTimeout(scopeMap.get(id));
5176
+ }
5177
+ const timerId = setTimeout(() => {
5178
+ try {
5179
+ resolve(fn());
5180
+ } catch (error) {
5181
+ reject(error);
5182
+ }
5183
+ scopeMap.delete(id);
5184
+ }, ms);
5185
+ scopeMap.set(id, timerId);
5186
+ });
5187
+ }
5188
+ clearDebounce(id) {
5189
+ const scopeMap = TIMERS_MAP.get(this.scopeId);
5190
+ if (scopeMap && scopeMap.has(id)) {
5191
+ clearTimeout(scopeMap.get(id));
5192
+ scopeMap.delete(id);
5193
+ }
5194
+ }
5195
+ clear() {
5196
+ const scopeMap = TIMERS_MAP.get(this.scopeId);
5197
+ if (scopeMap) {
5198
+ scopeMap.forEach((timerId) => clearTimeout(timerId));
5199
+ scopeMap.clear();
5200
+ }
5201
+ }
5202
+ }
5203
+ function createDebounce(scopeId) {
5204
+ return new DebounceController(scopeId);
5205
+ }
5206
+ function clearDebounceScope(scopeId) {
5207
+ const scopeMap = TIMERS_MAP.get(scopeId);
5208
+ if (scopeMap) {
5209
+ scopeMap.forEach((timerId) => clearTimeout(timerId));
5210
+ scopeMap.clear();
5211
+ }
5212
+ }
5213
+
5214
+ // src/lib/queue.ts
5215
+ class ProcessQueue {
5216
+ processor;
5217
+ queue = [];
5218
+ processing = false;
5219
+ autoProcess = true;
5220
+ constructor(processor, autoProcess = true) {
5221
+ this.processor = processor;
5222
+ this.autoProcess = autoProcess;
5223
+ }
5224
+ enqueue(item) {
5225
+ this.queue.push(item);
5226
+ if (!this.processing && this.autoProcess) {
5227
+ this.processQueue();
5228
+ }
5229
+ }
5230
+ processQueue() {
5231
+ if (this.queue.length === 0) {
5232
+ return;
5233
+ }
5234
+ this.processing = true;
5235
+ queueMicrotask(async () => {
5236
+ if (this.queue.length === 0) {
5237
+ this.processing = false;
5238
+ return;
5239
+ }
5240
+ const item = this.queue.shift();
5241
+ try {
5242
+ await this.processor(item);
5243
+ } catch (error) {
5244
+ console.error("Error processing queue item:", error);
5245
+ }
5246
+ if (this.queue.length > 0) {
5247
+ this.processQueue();
5248
+ } else {
5249
+ this.processing = false;
5250
+ }
5251
+ });
5252
+ }
5253
+ clear() {
5254
+ this.queue = [];
5255
+ }
5256
+ isProcessing() {
5257
+ return this.processing;
5258
+ }
5259
+ size() {
5260
+ return this.queue.length;
5261
+ }
5262
+ }
5263
+
5264
+ // src/lib/tree-sitter/default-parsers.ts
5265
+ import { resolve, dirname } from "path";
5266
+ import { fileURLToPath } from "url";
5267
+
5268
+ // src/lib/tree-sitter/assets/javascript/highlights.scm
5269
+ var highlights_default = "./highlights-ghv9g403.scm";
5270
+
5271
+ // src/lib/tree-sitter/assets/javascript/tree-sitter-javascript.wasm
5272
+ var tree_sitter_javascript_default = "./tree-sitter-javascript-nd0q4pe9.wasm";
5273
+
5274
+ // src/lib/tree-sitter/assets/typescript/highlights.scm
5275
+ var highlights_default2 = "./highlights-eq9cgrbb.scm";
5276
+
5277
+ // src/lib/tree-sitter/assets/typescript/tree-sitter-typescript.wasm
5278
+ var tree_sitter_typescript_default = "./tree-sitter-typescript-zxjzwt75.wasm";
5279
+
5280
+ // src/lib/tree-sitter/default-parsers.ts
5281
+ var _cachedParsers;
5282
+ function getParsers() {
5283
+ if (!_cachedParsers) {
5284
+ _cachedParsers = [
5285
+ {
5286
+ filetype: "javascript",
5287
+ queries: {
5288
+ highlights: [resolve(dirname(fileURLToPath(import.meta.url)), highlights_default)]
5289
+ },
5290
+ wasm: resolve(dirname(fileURLToPath(import.meta.url)), tree_sitter_javascript_default)
5291
+ },
5292
+ {
5293
+ filetype: "typescript",
5294
+ queries: {
5295
+ highlights: [resolve(dirname(fileURLToPath(import.meta.url)), highlights_default2)]
5296
+ },
5297
+ wasm: resolve(dirname(fileURLToPath(import.meta.url)), tree_sitter_typescript_default)
5298
+ }
5299
+ ];
5300
+ }
5301
+ return _cachedParsers;
5302
+ }
5303
+
5304
+ // src/lib/tree-sitter/client.ts
5305
+ import { resolve as resolve2, isAbsolute } from "path";
5306
+ var DEFAULT_PARSERS = getParsers();
5307
+ function addDefaultParsers(parsers) {
5308
+ for (const parser of parsers) {
5309
+ const existingIndex = DEFAULT_PARSERS.findIndex((p) => p.filetype === parser.filetype);
5310
+ if (existingIndex >= 0) {
5311
+ DEFAULT_PARSERS[existingIndex] = parser;
5312
+ } else {
5313
+ DEFAULT_PARSERS.push(parser);
5314
+ }
5315
+ }
5316
+ }
5317
+
5318
+ class TreeSitterClient extends EventEmitter2 {
5319
+ initialized = false;
5320
+ worker;
5321
+ buffers = new Map;
5322
+ initializePromise;
5323
+ initializeResolvers;
5324
+ messageCallbacks = new Map;
5325
+ messageIdCounter = 0;
5326
+ editQueues = new Map;
5327
+ debouncer;
5328
+ options;
5329
+ constructor(options) {
5330
+ super();
5331
+ this.options = options;
5332
+ this.debouncer = createDebounce("tree-sitter-client");
5333
+ this.startWorker();
5334
+ }
5335
+ emitError(error, bufferId) {
5336
+ if (this.listenerCount("error") > 0) {
5337
+ this.emit("error", error, bufferId);
5338
+ }
5339
+ }
5340
+ emitWarning(warning, bufferId) {
5341
+ if (this.listenerCount("warning") > 0) {
5342
+ this.emit("warning", warning, bufferId);
5343
+ }
5344
+ }
5345
+ startWorker() {
5346
+ if (this.worker) {
5347
+ return;
5348
+ }
5349
+ const workerPath = this.options.workerPath || parser_worker_default;
5350
+ this.worker = new Worker(workerPath);
5351
+ this.worker.onmessage = this.handleWorkerMessage.bind(this);
5352
+ this.worker.onerror = (error) => {
5353
+ console.error("TreeSitter worker error:", error.message);
5354
+ if (this.initializeResolvers) {
5355
+ clearTimeout(this.initializeResolvers.timeoutId);
5356
+ this.initializeResolvers.reject(new Error(`Worker error: ${error.message}`));
5357
+ this.initializeResolvers = undefined;
5358
+ }
5359
+ this.emitError(`Worker error: ${error.message}`);
5360
+ };
5361
+ }
5362
+ stopWorker() {
5363
+ if (!this.worker) {
5364
+ return;
5365
+ }
5366
+ this.worker.terminate();
5367
+ this.worker = undefined;
5368
+ }
5369
+ handleReset() {
5370
+ this.buffers.clear();
5371
+ this.stopWorker();
5372
+ this.startWorker();
5373
+ this.initializePromise = undefined;
5374
+ this.initializeResolvers = undefined;
5375
+ return this.initialize();
5376
+ }
5377
+ async initialize() {
5378
+ if (this.initializePromise) {
5379
+ return this.initializePromise;
5380
+ }
5381
+ this.initializePromise = new Promise((resolve3, reject) => {
5382
+ const timeoutMs = this.options.initTimeout ?? 1e4;
5383
+ const timeoutId = setTimeout(() => {
5384
+ const error = new Error("Worker initialization timed out");
5385
+ console.error("TreeSitter client:", error.message);
5386
+ this.initializeResolvers = undefined;
5387
+ reject(error);
5388
+ }, timeoutMs);
5389
+ this.initializeResolvers = { resolve: resolve3, reject, timeoutId };
5390
+ this.worker?.postMessage({
5391
+ type: "INIT",
5392
+ dataPath: this.options.dataPath
5393
+ });
5394
+ });
5395
+ await this.initializePromise;
5396
+ await this.registerDefaultParsers();
5397
+ return this.initializePromise;
5398
+ }
5399
+ async registerDefaultParsers() {
5400
+ for (const parser of DEFAULT_PARSERS) {
5401
+ this.addFiletypeParser(parser);
5402
+ }
5403
+ }
5404
+ addFiletypeParser(filetypeParser) {
5405
+ const isUrl = (path) => path.startsWith("http://") || path.startsWith("https://");
5406
+ const resolvedParser = {
5407
+ ...filetypeParser,
5408
+ wasm: isUrl(filetypeParser.wasm) || isAbsolute(filetypeParser.wasm) ? filetypeParser.wasm : resolve2(filetypeParser.wasm),
5409
+ queries: {
5410
+ highlights: filetypeParser.queries.highlights.map((path) => isUrl(path) || isAbsolute(path) ? path : resolve2(path))
5411
+ }
5412
+ };
5413
+ this.worker?.postMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser: resolvedParser });
5414
+ }
5415
+ async getPerformance() {
5416
+ const messageId = `performance_${this.messageIdCounter++}`;
5417
+ return new Promise((resolve3) => {
5418
+ this.messageCallbacks.set(messageId, resolve3);
5419
+ this.worker?.postMessage({ type: "GET_PERFORMANCE", messageId });
5420
+ });
5421
+ }
5422
+ async highlightOnce(content, filetype) {
5423
+ if (!this.initialized) {
5424
+ try {
5425
+ await this.initialize();
5426
+ } catch (error) {
5427
+ return { error: "Could not highlight because of initialization error" };
5428
+ }
5429
+ }
5430
+ const messageId = `oneshot_${this.messageIdCounter++}`;
5431
+ return new Promise((resolve3) => {
5432
+ this.messageCallbacks.set(messageId, resolve3);
5433
+ this.worker?.postMessage({
5434
+ type: "ONESHOT_HIGHLIGHT",
5435
+ content,
5436
+ filetype,
5437
+ messageId
5438
+ });
5439
+ });
5440
+ }
5441
+ handleWorkerMessage(event) {
5442
+ const { type, bufferId, error, highlights, warning, messageId, hasParser, performance: performance2, version } = event.data;
5443
+ if (type === "HIGHLIGHT_RESPONSE") {
5444
+ const buffer = this.buffers.get(bufferId);
5445
+ if (!buffer || !buffer.hasParser)
5446
+ return;
5447
+ if (buffer.version !== version) {
5448
+ this.resetBuffer(bufferId, buffer.version, buffer.content);
5449
+ return;
5450
+ }
5451
+ this.emit("highlights:response", bufferId, version, highlights);
5452
+ }
5453
+ if (type === "INIT_RESPONSE") {
5454
+ if (this.initializeResolvers) {
5455
+ clearTimeout(this.initializeResolvers.timeoutId);
5456
+ if (error) {
5457
+ console.error("TreeSitter client initialization failed:", error);
5458
+ this.initializeResolvers.reject(new Error(error));
5459
+ } else {
5460
+ this.initialized = true;
5461
+ this.initializeResolvers.resolve();
5462
+ }
5463
+ this.initializeResolvers = undefined;
5464
+ return;
5465
+ }
5466
+ }
5467
+ if (type === "PARSER_INIT_RESPONSE") {
5468
+ const callback = this.messageCallbacks.get(messageId);
5469
+ if (callback) {
5470
+ this.messageCallbacks.delete(messageId);
5471
+ callback({ hasParser, warning, error });
5472
+ }
5473
+ return;
5474
+ }
5475
+ if (type === "PRELOAD_PARSER_RESPONSE") {
5476
+ const callback = this.messageCallbacks.get(messageId);
5477
+ if (callback) {
5478
+ this.messageCallbacks.delete(messageId);
5479
+ callback({ hasParser });
5480
+ }
5481
+ return;
5482
+ }
5483
+ if (type === "BUFFER_DISPOSED") {
5484
+ const callback = this.messageCallbacks.get(`dispose_${bufferId}`);
5485
+ if (callback) {
5486
+ this.messageCallbacks.delete(`dispose_${bufferId}`);
5487
+ callback(true);
5488
+ }
5489
+ this.emit("buffer:disposed", bufferId);
5490
+ return;
5491
+ }
5492
+ if (type === "PERFORMANCE_RESPONSE") {
5493
+ const callback = this.messageCallbacks.get(messageId);
5494
+ if (callback) {
5495
+ this.messageCallbacks.delete(messageId);
5496
+ callback(performance2);
5497
+ }
5498
+ return;
5499
+ }
5500
+ if (type === "ONESHOT_HIGHLIGHT_RESPONSE") {
5501
+ const callback = this.messageCallbacks.get(messageId);
5502
+ if (callback) {
5503
+ this.messageCallbacks.delete(messageId);
5504
+ callback({ highlights, warning, error });
5505
+ }
5506
+ return;
5507
+ }
5508
+ if (type === "UPDATE_DATA_PATH_RESPONSE") {
5509
+ const callback = this.messageCallbacks.get(messageId);
5510
+ if (callback) {
5511
+ this.messageCallbacks.delete(messageId);
5512
+ callback({ error });
5513
+ }
5514
+ return;
5515
+ }
5516
+ if (warning) {
5517
+ this.emitWarning(warning, bufferId);
5518
+ return;
5519
+ }
5520
+ if (error) {
5521
+ this.emitError(error, bufferId);
5522
+ return;
5523
+ }
5524
+ if (type === "WORKER_LOG") {
5525
+ const { logType, data } = event.data;
5526
+ const message = data.join(" ");
5527
+ this.emit("worker:log", logType, message);
5528
+ if (logType === "log") {
5529
+ console.log("Worker stdout:", ...data);
5530
+ } else if (logType === "error") {
5531
+ console.error("Worker stderr:", ...data);
5532
+ }
5533
+ return;
5534
+ }
5535
+ }
5536
+ async preloadParser(filetype) {
5537
+ const messageId = `has_parser_${this.messageIdCounter++}`;
5538
+ const response = await new Promise((resolve3) => {
5539
+ this.messageCallbacks.set(messageId, resolve3);
5540
+ this.worker?.postMessage({
5541
+ type: "PRELOAD_PARSER",
5542
+ filetype,
5543
+ messageId
5544
+ });
5545
+ });
5546
+ return response.hasParser;
5547
+ }
5548
+ async createBuffer(id, content, filetype, version = 1, autoInitialize = true) {
5549
+ if (!this.initialized) {
5550
+ if (!autoInitialize) {
5551
+ this.emitError("Could not create buffer because client is not initialized");
5552
+ return false;
5553
+ }
5554
+ try {
5555
+ await this.initialize();
5556
+ } catch (error) {
5557
+ this.emitError("Could not create buffer because of initialization error");
5558
+ return false;
5559
+ }
5560
+ }
5561
+ if (this.buffers.has(id)) {
5562
+ throw new Error(`Buffer with id ${id} already exists`);
5563
+ }
5564
+ this.buffers.set(id, { id, content, filetype, version, hasParser: false });
5565
+ const messageId = `init_${this.messageIdCounter++}`;
5566
+ const response = await new Promise((resolve3) => {
5567
+ this.messageCallbacks.set(messageId, resolve3);
5568
+ this.worker?.postMessage({
5569
+ type: "INITIALIZE_PARSER",
5570
+ bufferId: id,
5571
+ version,
5572
+ content,
5573
+ filetype,
5574
+ messageId
5575
+ });
5576
+ });
5577
+ if (!response.hasParser) {
5578
+ this.emit("buffer:initialized", id, false);
5579
+ if (filetype !== "plaintext") {
5580
+ this.emitWarning(response.warning || response.error || "Buffer has no parser", id);
5581
+ }
5582
+ return false;
5583
+ }
5584
+ const bufferState = { id, content, filetype, version, hasParser: true };
5585
+ this.buffers.set(id, bufferState);
5586
+ this.emit("buffer:initialized", id, true);
5587
+ return true;
5588
+ }
5589
+ async updateBuffer(id, edits, newContent, version) {
5590
+ if (!this.initialized) {
5591
+ return;
5592
+ }
5593
+ const buffer = this.buffers.get(id);
5594
+ if (!buffer || !buffer.hasParser) {
5595
+ return;
5596
+ }
5597
+ this.buffers.set(id, { ...buffer, content: newContent, version });
5598
+ if (!this.editQueues.has(id)) {
5599
+ this.editQueues.set(id, new ProcessQueue((item) => this.processEdit(id, item.edits, item.newContent, item.version, item.isReset)));
5600
+ }
5601
+ const bufferQueue = this.editQueues.get(id);
5602
+ bufferQueue.enqueue({ edits, newContent, version });
5603
+ }
5604
+ async processEdit(bufferId, edits, newContent, version, isReset = false) {
5605
+ this.worker?.postMessage({
5606
+ type: isReset ? "RESET_BUFFER" : "HANDLE_EDITS",
5607
+ bufferId,
5608
+ version,
5609
+ content: newContent,
5610
+ edits
5611
+ });
5612
+ }
5613
+ async removeBuffer(bufferId) {
5614
+ if (!this.initialized) {
5615
+ return;
5616
+ }
5617
+ this.buffers.delete(bufferId);
5618
+ if (this.editQueues.has(bufferId)) {
5619
+ this.editQueues.get(bufferId)?.clear();
5620
+ this.editQueues.delete(bufferId);
5621
+ }
5622
+ if (this.worker) {
5623
+ await new Promise((resolve3) => {
5624
+ const messageId = `dispose_${bufferId}`;
5625
+ this.messageCallbacks.set(messageId, resolve3);
5626
+ try {
5627
+ this.worker.postMessage({
5628
+ type: "DISPOSE_BUFFER",
5629
+ bufferId
5630
+ });
5631
+ } catch (error) {
5632
+ console.error("Error disposing buffer", error);
5633
+ resolve3(false);
5634
+ }
5635
+ setTimeout(() => {
5636
+ if (this.messageCallbacks.has(messageId)) {
5637
+ this.messageCallbacks.delete(messageId);
5638
+ console.warn({ bufferId }, "Timed out waiting for buffer to be disposed");
5639
+ resolve3(false);
5640
+ }
5641
+ }, 3000);
5642
+ });
5643
+ }
5644
+ this.debouncer.clearDebounce(`reset-${bufferId}`);
5645
+ }
5646
+ async destroy() {
5647
+ if (this.initializeResolvers) {
5648
+ clearTimeout(this.initializeResolvers.timeoutId);
5649
+ this.initializeResolvers = undefined;
5650
+ }
5651
+ for (const [messageId, callback] of this.messageCallbacks.entries()) {
5652
+ if (typeof callback === "function") {
5653
+ try {
5654
+ callback({ error: "Client destroyed" });
5655
+ } catch (e) {}
5656
+ }
5657
+ }
5658
+ this.messageCallbacks.clear();
5659
+ clearDebounceScope("tree-sitter-client");
5660
+ this.debouncer.clear();
5661
+ this.editQueues.clear();
5662
+ this.buffers.clear();
5663
+ this.stopWorker();
5664
+ this.initialized = false;
5665
+ this.initializePromise = undefined;
5666
+ }
5667
+ async resetBuffer(bufferId, version, content) {
5668
+ if (!this.initialized) {
5669
+ return;
5670
+ }
5671
+ const buffer = this.buffers.get(bufferId);
5672
+ if (!buffer || !buffer.hasParser) {
5673
+ this.emitError("Cannot reset buffer with no parser", bufferId);
5674
+ return;
5675
+ }
5676
+ this.buffers.set(bufferId, { ...buffer, content, version });
5677
+ this.debouncer.debounce(`reset-${bufferId}`, 10, () => this.processEdit(bufferId, [], content, version, true));
5678
+ }
5679
+ getBuffer(bufferId) {
5680
+ return this.buffers.get(bufferId);
5681
+ }
5682
+ getAllBuffers() {
5683
+ return Array.from(this.buffers.values());
5684
+ }
5685
+ isInitialized() {
5686
+ return this.initialized;
5687
+ }
5688
+ async setDataPath(dataPath) {
5689
+ if (this.options.dataPath === dataPath) {
5690
+ return;
5691
+ }
5692
+ this.options.dataPath = dataPath;
5693
+ if (this.initialized && this.worker) {
5694
+ const messageId = `update_datapath_${this.messageIdCounter++}`;
5695
+ return new Promise((resolve3, reject) => {
5696
+ this.messageCallbacks.set(messageId, (response) => {
5697
+ if (response.error) {
5698
+ reject(new Error(response.error));
5699
+ } else {
5700
+ resolve3();
5701
+ }
5702
+ });
5703
+ this.worker.postMessage({
5704
+ type: "UPDATE_DATA_PATH",
5705
+ dataPath,
5706
+ messageId
5707
+ });
5708
+ });
5709
+ }
5710
+ }
5711
+ }
5712
+
5713
+ // src/lib/data-paths.ts
5714
+ import os from "os";
5715
+ import path from "path";
5716
+ import { EventEmitter as EventEmitter3 } from "events";
5717
+
5718
+ // src/lib/validate-dir-name.ts
5719
+ function isValidDirectoryName(name) {
5720
+ if (!name || typeof name !== "string") {
5721
+ return false;
5722
+ }
5723
+ if (name.trim().length === 0) {
5724
+ return false;
5725
+ }
5726
+ const reservedNames = [
5727
+ "CON",
5728
+ "PRN",
5729
+ "AUX",
5730
+ "NUL",
5731
+ "COM1",
5732
+ "COM2",
5733
+ "COM3",
5734
+ "COM4",
5735
+ "COM5",
5736
+ "COM6",
5737
+ "COM7",
5738
+ "COM8",
5739
+ "COM9",
5740
+ "LPT1",
5741
+ "LPT2",
5742
+ "LPT3",
5743
+ "LPT4",
5744
+ "LPT5",
5745
+ "LPT6",
5746
+ "LPT7",
5747
+ "LPT8",
5748
+ "LPT9"
5749
+ ];
5750
+ if (reservedNames.includes(name.toUpperCase())) {
5751
+ return false;
5752
+ }
5753
+ const invalidChars = /[<>:"|?*\/\\\x00-\x1f]/;
5754
+ if (invalidChars.test(name)) {
5755
+ return false;
5756
+ }
5757
+ if (name.endsWith(".") || name.endsWith(" ")) {
5758
+ return false;
5759
+ }
5760
+ if (name === "." || name === "..") {
5761
+ return false;
5762
+ }
5763
+ return true;
5764
+ }
5765
+
5766
+ // src/lib/data-paths.ts
5767
+ registerEnvVar({
5768
+ name: "XDG_CONFIG_HOME",
5769
+ description: "Base directory for user-specific configuration files",
5770
+ type: "string",
5771
+ default: ""
5772
+ });
5773
+ registerEnvVar({
5774
+ name: "XDG_DATA_HOME",
5775
+ description: "Base directory for user-specific data files",
5776
+ type: "string",
5777
+ default: ""
5778
+ });
5779
+
5780
+ class DataPathsManager extends EventEmitter3 {
5781
+ _appName;
5782
+ _globalConfigPath;
5783
+ _globalConfigFile;
5784
+ _localConfigFile;
5785
+ _globalDataPath;
5786
+ constructor() {
5787
+ super();
5788
+ this._appName = "opentui";
5789
+ }
5790
+ get appName() {
5791
+ return this._appName;
5792
+ }
5793
+ set appName(value) {
5794
+ if (!isValidDirectoryName(value)) {
5795
+ throw new Error(`Invalid app name "${value}": must be a valid directory name`);
5796
+ }
5797
+ if (this._appName !== value) {
5798
+ this._appName = value;
5799
+ this._globalConfigPath = undefined;
5800
+ this._globalConfigFile = undefined;
5801
+ this._localConfigFile = undefined;
5802
+ this._globalDataPath = undefined;
5803
+ this.emit("paths:changed", this.toObject());
5804
+ }
5805
+ }
5806
+ get globalConfigPath() {
5807
+ if (this._globalConfigPath === undefined) {
5808
+ const homeDir = os.homedir();
5809
+ const xdgConfigHome = env.XDG_CONFIG_HOME;
5810
+ const baseConfigDir = xdgConfigHome || path.join(homeDir, ".config");
5811
+ this._globalConfigPath = path.join(baseConfigDir, this._appName);
5812
+ }
5813
+ return this._globalConfigPath;
5814
+ }
5815
+ get globalConfigFile() {
5816
+ if (this._globalConfigFile === undefined) {
5817
+ this._globalConfigFile = path.join(this.globalConfigPath, "init.ts");
5818
+ }
5819
+ return this._globalConfigFile;
5820
+ }
5821
+ get localConfigFile() {
5822
+ if (this._localConfigFile === undefined) {
5823
+ this._localConfigFile = path.join(process.cwd(), `.${this._appName}.ts`);
5824
+ }
5825
+ return this._localConfigFile;
5826
+ }
5827
+ get globalDataPath() {
5828
+ if (this._globalDataPath === undefined) {
5829
+ const homeDir = os.homedir();
5830
+ const xdgDataHome = env.XDG_DATA_HOME;
5831
+ const baseDataDir = xdgDataHome || path.join(homeDir, ".local/share");
5832
+ this._globalDataPath = path.join(baseDataDir, this._appName);
5833
+ }
5834
+ return this._globalDataPath;
5835
+ }
5836
+ toObject() {
5837
+ return {
5838
+ globalConfigPath: this.globalConfigPath,
5839
+ globalConfigFile: this.globalConfigFile,
5840
+ localConfigFile: this.localConfigFile,
5841
+ globalDataPath: this.globalDataPath
5842
+ };
5843
+ }
5844
+ }
5845
+ function getDataPaths() {
5846
+ return singleton("data-paths-opentui", () => new DataPathsManager);
5847
+ }
5848
+
5849
+ // src/lib/tree-sitter/resolve-ft.ts
5850
+ function extToFiletype(extension) {
5851
+ const extensionToFiletype = new Map([
5852
+ ["js", "javascript"],
5853
+ ["jsx", "javascriptreact"],
5854
+ ["ts", "typescript"],
5855
+ ["tsx", "typescriptreact"],
5856
+ ["md", "markdown"],
5857
+ ["json", "json"],
5858
+ ["py", "python"],
5859
+ ["rb", "ruby"],
5860
+ ["go", "go"],
5861
+ ["rs", "rust"],
5862
+ ["c", "c"],
5863
+ ["cpp", "cpp"],
5864
+ ["h", "c"],
5865
+ ["hpp", "cpp"],
5866
+ ["html", "html"],
5867
+ ["css", "css"],
5868
+ ["scss", "scss"],
5869
+ ["less", "less"],
5870
+ ["sh", "shell"],
5871
+ ["bash", "shell"],
5872
+ ["zsh", "shell"],
5873
+ ["vim", "vim"],
5874
+ ["yaml", "yaml"],
5875
+ ["yml", "yaml"],
5876
+ ["toml", "toml"],
5877
+ ["xml", "xml"],
5878
+ ["zig", "zig"]
5879
+ ]);
5880
+ return extensionToFiletype.get(extension);
5881
+ }
5882
+ function pathToFiletype(path2) {
5883
+ if (typeof path2 !== "string")
5884
+ return;
5885
+ const lastDot = path2.lastIndexOf(".");
5886
+ if (lastDot === -1 || lastDot === path2.length - 1) {
5887
+ return;
5888
+ }
5889
+ const extension = path2.substring(lastDot + 1);
5890
+ return extToFiletype(extension);
5891
+ }
5892
+
5893
+ // src/lib/tree-sitter/assets/update.ts
5894
+ import { readFile, writeFile, mkdir } from "fs/promises";
5895
+ import * as path2 from "path";
5896
+ var __dirname = "/Users/runner/work/opentui/opentui/packages/core/src/lib/tree-sitter/assets";
5897
+ function getDefaultOptions() {
5898
+ return {
5899
+ configPath: path2.resolve(__dirname, "../parsers-config.json"),
5900
+ assetsDir: path2.resolve(__dirname),
5901
+ outputPath: path2.resolve(__dirname, "../default-parsers.ts")
5902
+ };
5903
+ }
5904
+ async function loadConfig(configPath) {
5905
+ const configContent = await readFile(configPath, "utf-8");
5906
+ return JSON.parse(configContent);
5907
+ }
5908
+ async function downloadLanguage(filetype, languageUrl, assetsDir, outputPath) {
5909
+ const languageDir = path2.join(assetsDir, filetype);
5910
+ const languageFilename = path2.basename(languageUrl);
5911
+ const languagePath = path2.join(languageDir, languageFilename);
5912
+ const result = await DownloadUtils.downloadToPath(languageUrl, languagePath);
5913
+ if (result.error) {
5914
+ throw new Error(`Failed to download language for ${filetype}: ${result.error}`);
5915
+ }
5916
+ return "./" + path2.relative(path2.dirname(outputPath), languagePath);
5917
+ }
5918
+ async function downloadAndCombineQueries(filetype, queryUrls, assetsDir, outputPath) {
5919
+ const queriesDir = path2.join(assetsDir, filetype);
5920
+ const highlightsPath = path2.join(queriesDir, "highlights.scm");
5921
+ const queryContents = [];
5922
+ for (let i = 0;i < queryUrls.length; i++) {
5923
+ const queryUrl = queryUrls[i];
5924
+ console.log(` Downloading query ${i + 1}/${queryUrls.length}: ${queryUrl}`);
5925
+ try {
5926
+ const response = await fetch(queryUrl);
5927
+ if (!response.ok) {
5928
+ console.warn(`Failed to download query from ${queryUrl}: ${response.statusText}`);
5929
+ continue;
5930
+ }
5931
+ const content = await response.text();
5932
+ if (content.trim()) {
5933
+ queryContents.push(`; Query from: ${queryUrl}
5934
+ ${content}`);
5935
+ console.log(` \u2713 Downloaded ${content.split(`
5936
+ `).length} lines`);
5937
+ }
5938
+ } catch (error) {
5939
+ console.warn(`Failed to download query from ${queryUrl}: ${error}`);
5940
+ continue;
5941
+ }
5942
+ }
5943
+ const combinedContent = queryContents.join(`
5944
+
5945
+ `);
5946
+ await writeFile(highlightsPath, combinedContent, "utf-8");
5947
+ console.log(` Combined ${queryContents.length} queries into ${highlightsPath}`);
5948
+ return "./" + path2.relative(path2.dirname(outputPath), highlightsPath);
5949
+ }
5950
+ async function generateDefaultParsersFile(parsers, outputPath) {
5951
+ const imports = parsers.map((parser) => {
5952
+ const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
5953
+ return `import ${safeFiletype}_highlights from "${parser.highlightsPath}" with { type: "file" }
5954
+ import ${safeFiletype}_language from "${parser.languagePath}" with { type: "file" }`;
5955
+ }).join(`
5956
+ `);
5957
+ const parserDefinitions = parsers.map((parser) => {
5958
+ const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
5959
+ return ` {
5960
+ filetype: "${parser.filetype}",
5961
+ queries: {
5962
+ highlights: [resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_highlights)],
5963
+ },
5964
+ wasm: resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_language),
5965
+ }`;
5966
+ }).join(`,
5967
+ `);
5968
+ const fileContent = `// This file is generated by assets/update.ts - DO NOT EDIT MANUALLY
5969
+ // Run 'bun assets/update.ts' to regenerate this file
5970
+ // Last generated: ${new Date().toISOString()}
5971
+
5972
+ import type { FiletypeParserOptions } from "./types"
5973
+ import { resolve, dirname } from "path"
5974
+ import { fileURLToPath } from "url"
5975
+
5976
+ ${imports}
5977
+
5978
+ // Cached parsers to avoid re-resolving paths on every call
5979
+ let _cachedParsers: FiletypeParserOptions[] | undefined
5980
+
5981
+ export function getParsers(): FiletypeParserOptions[] {
5982
+ if (!_cachedParsers) {
5983
+ _cachedParsers = [
5984
+ ${parserDefinitions},
5985
+ ]
5986
+ }
5987
+ return _cachedParsers
5988
+ }
5989
+ `;
5990
+ await mkdir(path2.dirname(outputPath), { recursive: true });
5991
+ await writeFile(outputPath, fileContent, "utf-8");
5992
+ console.log(`Generated ${path2.basename(outputPath)} with ${parsers.length} parsers`);
5993
+ }
5994
+ async function main(options) {
5995
+ const opts = { ...getDefaultOptions(), ...options };
5996
+ try {
5997
+ console.log("Loading parsers configuration...");
5998
+ console.log(` Config: ${opts.configPath}`);
5999
+ console.log(` Assets Dir: ${opts.assetsDir}`);
6000
+ console.log(` Output: ${opts.outputPath}`);
6001
+ const config = await loadConfig(opts.configPath);
6002
+ console.log(`Found ${config.parsers.length} parsers to process`);
6003
+ const generatedParsers = [];
6004
+ for (const parser of config.parsers) {
6005
+ console.log(`Processing ${parser.filetype}...`);
6006
+ console.log(` Downloading language...`);
6007
+ const languagePath = await downloadLanguage(parser.filetype, parser.wasm, opts.assetsDir, opts.outputPath);
6008
+ console.log(` Downloading ${parser.queries.highlights.length} highlight queries...`);
6009
+ const highlightsPath = await downloadAndCombineQueries(parser.filetype, parser.queries.highlights, opts.assetsDir, opts.outputPath);
6010
+ generatedParsers.push({
6011
+ filetype: parser.filetype,
6012
+ languagePath,
6013
+ highlightsPath
6014
+ });
6015
+ console.log(` \u2713 Completed ${parser.filetype}`);
6016
+ }
6017
+ console.log("Generating output file...");
6018
+ await generateDefaultParsersFile(generatedParsers, opts.outputPath);
6019
+ console.log("\u2705 Update completed successfully!");
6020
+ } catch (error) {
6021
+ console.error("\u274C Update failed:", error);
6022
+ process.exit(1);
6023
+ }
6024
+ }
6025
+ if (false) {}
6026
+
6027
+ // src/lib/tree-sitter/index.ts
6028
+ function getTreeSitterClient() {
6029
+ const dataPathsManager = getDataPaths();
6030
+ const defaultOptions = {
6031
+ dataPath: dataPathsManager.globalDataPath
6032
+ };
6033
+ return singleton("tree-sitter-client", () => {
6034
+ const client2 = new TreeSitterClient(defaultOptions);
6035
+ dataPathsManager.on("paths:changed", (paths) => {
6036
+ client2.setDataPath(paths.globalDataPath);
6037
+ });
6038
+ return client2;
6039
+ });
6040
+ }
5076
6041
  // src/zig.ts
5077
6042
  import { dlopen, toArrayBuffer as toArrayBuffer2, JSCallback, ptr } from "bun:ffi";
5078
6043
  import { existsSync } from "fs";
@@ -6380,7 +7345,7 @@ class TextBuffer {
6380
7345
  }
6381
7346
 
6382
7347
  // src/Renderable.ts
6383
- import { EventEmitter as EventEmitter2 } from "events";
7348
+ import { EventEmitter as EventEmitter4 } from "events";
6384
7349
 
6385
7350
  // src/lib/renderable.validations.ts
6386
7351
  function validateOptions(id, options) {
@@ -6473,7 +7438,7 @@ function isRenderable(obj) {
6473
7438
  return !!obj?.[BrandedRenderable];
6474
7439
  }
6475
7440
 
6476
- class BaseRenderable extends EventEmitter2 {
7441
+ class BaseRenderable extends EventEmitter4 {
6477
7442
  [BrandedRenderable] = true;
6478
7443
  static renderableNumber = 1;
6479
7444
  _id;
@@ -7776,17 +8741,17 @@ function delegate(mapping, vnode) {
7776
8741
  }
7777
8742
 
7778
8743
  // src/console.ts
7779
- import { EventEmitter as EventEmitter4 } from "events";
8744
+ import { EventEmitter as EventEmitter6 } from "events";
7780
8745
  import { Console } from "console";
7781
8746
  import fs from "fs";
7782
- import path from "path";
8747
+ import path3 from "path";
7783
8748
  import util2 from "util";
7784
8749
 
7785
8750
  // src/lib/output.capture.ts
7786
8751
  import { Writable } from "stream";
7787
- import { EventEmitter as EventEmitter3 } from "events";
8752
+ import { EventEmitter as EventEmitter5 } from "events";
7788
8753
 
7789
- class Capture extends EventEmitter3 {
8754
+ class Capture extends EventEmitter5 {
7790
8755
  output = [];
7791
8756
  constructor() {
7792
8757
  super();
@@ -7862,7 +8827,7 @@ registerEnvVar({
7862
8827
  default: false
7863
8828
  });
7864
8829
 
7865
- class TerminalConsoleCache extends EventEmitter4 {
8830
+ class TerminalConsoleCache extends EventEmitter6 {
7866
8831
  _cachedLogs = [];
7867
8832
  MAX_CACHE_SIZE = 1000;
7868
8833
  _collectCallerInfo = false;
@@ -7983,7 +8948,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
7983
8948
  };
7984
8949
  var INDENT_WIDTH = 2;
7985
8950
 
7986
- class TerminalConsole extends EventEmitter4 {
8951
+ class TerminalConsole extends EventEmitter6 {
7987
8952
  isVisible = false;
7988
8953
  isFocused = false;
7989
8954
  renderer;
@@ -8422,7 +9387,7 @@ class TerminalConsole extends EventEmitter4 {
8422
9387
  try {
8423
9388
  const timestamp = Date.now();
8424
9389
  const filename = `_console_${timestamp}.log`;
8425
- const filepath = path.join(process.cwd(), filename);
9390
+ const filepath = path3.join(process.cwd(), filename);
8426
9391
  const allLogEntries = [...this._allLogEntries, ...terminalConsoleCache.cachedLogs];
8427
9392
  const logLines = [];
8428
9393
  for (const [date, level, args, callerInfo] of allLogEntries) {
@@ -8443,7 +9408,7 @@ class TerminalConsole extends EventEmitter4 {
8443
9408
  }
8444
9409
 
8445
9410
  // src/renderer.ts
8446
- import { EventEmitter as EventEmitter5 } from "events";
9411
+ import { EventEmitter as EventEmitter7 } from "events";
8447
9412
 
8448
9413
  // src/lib/objects-in-viewport.ts
8449
9414
  function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
@@ -8533,6 +9498,18 @@ registerEnvVar({
8533
9498
  type: "boolean",
8534
9499
  default: false
8535
9500
  });
9501
+ registerEnvVar({
9502
+ name: "OTUI_USE_ALTERNATE_SCREEN",
9503
+ description: "Whether to use the console. Will not capture console output if set to false.",
9504
+ type: "boolean",
9505
+ default: true
9506
+ });
9507
+ registerEnvVar({
9508
+ name: "OTUI_OVERRIDE_STDOUT",
9509
+ description: "Override the stdout stream. This is useful for debugging.",
9510
+ type: "boolean",
9511
+ default: true
9512
+ });
8536
9513
 
8537
9514
  class MouseEvent {
8538
9515
  type;
@@ -8595,13 +9572,17 @@ var rendererTracker = singleton("RendererTracker", () => {
8595
9572
  renderers.delete(renderer);
8596
9573
  if (renderers.size === 0) {
8597
9574
  process.stdin.pause();
9575
+ if (hasSingleton("tree-sitter-client")) {
9576
+ getTreeSitterClient().destroy();
9577
+ destroySingleton("tree-sitter-client");
9578
+ }
8598
9579
  }
8599
9580
  }
8600
9581
  };
8601
9582
  });
8602
9583
  async function createCliRenderer(config = {}) {
8603
9584
  if (process.argv.includes("--delay-start")) {
8604
- await new Promise((resolve) => setTimeout(resolve, 5000));
9585
+ await new Promise((resolve4) => setTimeout(resolve4, 5000));
8605
9586
  }
8606
9587
  const stdin = config.stdin || process.stdin;
8607
9588
  const stdout = config.stdout || process.stdout;
@@ -8628,7 +9609,7 @@ var CliRenderEvents;
8628
9609
  ((CliRenderEvents2) => {
8629
9610
  CliRenderEvents2["DEBUG_OVERLAY_TOGGLE"] = "debugOverlay:toggle";
8630
9611
  })(CliRenderEvents ||= {});
8631
- class CliRenderer extends EventEmitter5 {
9612
+ class CliRenderer extends EventEmitter7 {
8632
9613
  static animationFrameId = 0;
8633
9614
  lib;
8634
9615
  rendererPtr;
@@ -8689,7 +9670,7 @@ class CliRenderer extends EventEmitter5 {
8689
9670
  resizeDebounceDelay = 100;
8690
9671
  enableMouseMovement = false;
8691
9672
  _useMouse = true;
8692
- _useAlternateScreen = true;
9673
+ _useAlternateScreen = env.OTUI_USE_ALTERNATE_SCREEN;
8693
9674
  capturedRenderable;
8694
9675
  lastOverRenderableNum = 0;
8695
9676
  lastOverRenderable;
@@ -8720,9 +9701,9 @@ class CliRenderer extends EventEmitter5 {
8720
9701
  handleError = ((error) => {
8721
9702
  this.stop();
8722
9703
  this.destroy();
8723
- new Promise((resolve) => {
9704
+ new Promise((resolve4) => {
8724
9705
  setTimeout(() => {
8725
- resolve(true);
9706
+ resolve4(true);
8726
9707
  }, 100);
8727
9708
  }).then(() => {
8728
9709
  this.realStdoutWrite.call(this.stdout, `
@@ -8801,7 +9782,7 @@ Captured output:
8801
9782
  this.maxStatSamples = config.maxStatSamples || 300;
8802
9783
  this.enableMouseMovement = config.enableMouseMovement || true;
8803
9784
  this._useMouse = config.useMouse ?? true;
8804
- this._useAlternateScreen = config.useAlternateScreen ?? true;
9785
+ this._useAlternateScreen = config.useAlternateScreen ?? env.OTUI_USE_ALTERNATE_SCREEN;
8805
9786
  this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
8806
9787
  this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
8807
9788
  this.postProcessFns = config.postProcessFns || [];
@@ -8809,7 +9790,9 @@ Captured output:
8809
9790
  if (this.memorySnapshotInterval > 0) {
8810
9791
  this.startMemorySnapshotTimer();
8811
9792
  }
8812
- this.stdout.write = this.interceptStdoutWrite.bind(this);
9793
+ if (env.OTUI_OVERRIDE_STDOUT) {
9794
+ this.stdout.write = this.interceptStdoutWrite.bind(this);
9795
+ }
8813
9796
  process.on("SIGWINCH", this.sigwinchHandler);
8814
9797
  process.on("warning", this.warningHandler);
8815
9798
  process.on("uncaughtException", this.handleError);
@@ -9041,16 +10024,16 @@ Captured output:
9041
10024
  if (this._terminalIsSetup)
9042
10025
  return;
9043
10026
  this._terminalIsSetup = true;
9044
- await new Promise((resolve) => {
10027
+ await new Promise((resolve4) => {
9045
10028
  const timeout = setTimeout(() => {
9046
10029
  this.stdin.off("data", capListener);
9047
- resolve(true);
10030
+ resolve4(true);
9048
10031
  }, 100);
9049
10032
  const capListener = (str) => {
9050
10033
  clearTimeout(timeout);
9051
10034
  this.lib.processCapabilityResponse(this.rendererPtr, str);
9052
10035
  this.stdin.off("data", capListener);
9053
- resolve(true);
10036
+ resolve4(true);
9054
10037
  };
9055
10038
  this.stdin.on("data", capListener);
9056
10039
  this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
@@ -9450,7 +10433,11 @@ Captured output:
9450
10433
  this._isRunning = false;
9451
10434
  this.waitingForPixelResolution = false;
9452
10435
  this.capturedRenderable = undefined;
9453
- this.root.destroyRecursively();
10436
+ try {
10437
+ this.root.destroyRecursively();
10438
+ } catch (e) {
10439
+ console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e));
10440
+ }
9454
10441
  this._keyHandler.destroy();
9455
10442
  this._console.deactivate();
9456
10443
  this.disableStdoutInterception();
@@ -9688,7 +10675,7 @@ Captured output:
9688
10675
  }
9689
10676
  }
9690
10677
 
9691
- export { __toESM, __commonJS, __export, __require, Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, ANSI, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, DebugOverlayCorner, createTextAttributes, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, t, SyntaxStyle, hastToStyledText, parseAlign, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, generateEnvMarkdown, generateEnvColored, env, TextBuffer, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, CliRenderer };
10678
+ export { Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, ANSI, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, DebugOverlayCorner, createTextAttributes, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, t, convertThemeToStyles, SyntaxStyle, hastToStyledText, parseAlign, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extToFiletype, pathToFiletype, main, getTreeSitterClient, TextBuffer, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, CliRenderer };
9692
10679
 
9693
- //# debugId=B65C4E4D90FC9D3564756E2164756E21
9694
- //# sourceMappingURL=index-kvwmgj67.js.map
10680
+ //# debugId=68D4874E884EA10964756E2164756E21
10681
+ //# sourceMappingURL=index-0p8687g8.js.map