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

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.
@@ -1763,7 +1763,7 @@ var BorderCharArrays = {
1763
1763
  };
1764
1764
 
1765
1765
  // src/lib/parse.keypress.ts
1766
- import { Buffer } from "buffer";
1766
+ import { Buffer as Buffer2 } from "buffer";
1767
1767
 
1768
1768
  // src/lib/parse.keypress-kitty.ts
1769
1769
  var kittyKeyMap = {
@@ -2080,7 +2080,7 @@ var isCtrlKey = (code) => {
2080
2080
  };
2081
2081
  var parseKeypress = (s = "", options = {}) => {
2082
2082
  let parts;
2083
- if (Buffer.isBuffer(s)) {
2083
+ if (Buffer2.isBuffer(s)) {
2084
2084
  if (s[0] > 127 && s[1] === undefined) {
2085
2085
  s[0] -= 128;
2086
2086
  s = "\x1B" + String(s);
@@ -4188,60 +4188,9 @@ function isStyledText(obj) {
4188
4188
  class StyledText {
4189
4189
  [BrandedStyledText] = true;
4190
4190
  chunks;
4191
- textRenderable;
4192
4191
  constructor(chunks) {
4193
4192
  this.chunks = chunks;
4194
4193
  }
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
4194
  }
4246
4195
  function stringToStyledText(content) {
4247
4196
  const chunk = {
@@ -4337,7 +4286,36 @@ function t(strings, ...values) {
4337
4286
  return new StyledText(chunks);
4338
4287
  }
4339
4288
 
4340
- // src/lib/hast-styled-text.ts
4289
+ // src/lib/syntax-style.ts
4290
+ function convertThemeToStyles(theme) {
4291
+ const flatStyles = {};
4292
+ for (const tokenStyle of theme) {
4293
+ const styleDefinition = {};
4294
+ if (tokenStyle.style.foreground) {
4295
+ styleDefinition.fg = parseColor(tokenStyle.style.foreground);
4296
+ }
4297
+ if (tokenStyle.style.background) {
4298
+ styleDefinition.bg = parseColor(tokenStyle.style.background);
4299
+ }
4300
+ if (tokenStyle.style.bold !== undefined) {
4301
+ styleDefinition.bold = tokenStyle.style.bold;
4302
+ }
4303
+ if (tokenStyle.style.italic !== undefined) {
4304
+ styleDefinition.italic = tokenStyle.style.italic;
4305
+ }
4306
+ if (tokenStyle.style.underline !== undefined) {
4307
+ styleDefinition.underline = tokenStyle.style.underline;
4308
+ }
4309
+ if (tokenStyle.style.dim !== undefined) {
4310
+ styleDefinition.dim = tokenStyle.style.dim;
4311
+ }
4312
+ for (const scope of tokenStyle.scope) {
4313
+ flatStyles[scope] = styleDefinition;
4314
+ }
4315
+ }
4316
+ return flatStyles;
4317
+ }
4318
+
4341
4319
  class SyntaxStyle {
4342
4320
  styles;
4343
4321
  mergedStyleCache;
@@ -4345,6 +4323,10 @@ class SyntaxStyle {
4345
4323
  this.styles = styles;
4346
4324
  this.mergedStyleCache = new Map;
4347
4325
  }
4326
+ static fromTheme(theme) {
4327
+ const flatStyles = convertThemeToStyles(theme);
4328
+ return new SyntaxStyle(flatStyles);
4329
+ }
4348
4330
  mergeStyles(...styleNames) {
4349
4331
  const cacheKey = styleNames.join(":");
4350
4332
  const cached = this.mergedStyleCache.get(cacheKey);
@@ -4352,7 +4334,7 @@ class SyntaxStyle {
4352
4334
  return cached;
4353
4335
  const styleDefinition = {};
4354
4336
  for (const name of styleNames) {
4355
- const style = this.styles[name];
4337
+ const style = this.getStyle(name);
4356
4338
  if (!style)
4357
4339
  continue;
4358
4340
  if (style.fg)
@@ -4382,6 +4364,18 @@ class SyntaxStyle {
4382
4364
  this.mergedStyleCache.set(cacheKey, merged);
4383
4365
  return merged;
4384
4366
  }
4367
+ getStyle(name) {
4368
+ if (Object.prototype.hasOwnProperty.call(this.styles, name)) {
4369
+ return this.styles[name];
4370
+ }
4371
+ if (name.includes(".")) {
4372
+ const baseName = name.split(".")[0];
4373
+ if (Object.prototype.hasOwnProperty.call(this.styles, baseName)) {
4374
+ return this.styles[baseName];
4375
+ }
4376
+ }
4377
+ return;
4378
+ }
4385
4379
  clearCache() {
4386
4380
  this.mergedStyleCache.clear();
4387
4381
  }
@@ -4389,6 +4383,8 @@ class SyntaxStyle {
4389
4383
  return this.mergedStyleCache.size;
4390
4384
  }
4391
4385
  }
4386
+
4387
+ // src/lib/hast-styled-text.ts
4392
4388
  function hastToTextChunks(node, syntaxStyle, parentStyles = []) {
4393
4389
  const chunks = [];
4394
4390
  if (node.type === "text") {
@@ -4923,9 +4919,19 @@ function singleton(key, factory) {
4923
4919
  }
4924
4920
  return bag[key];
4925
4921
  }
4922
+ function destroySingleton(key) {
4923
+ const bag = globalThis[singletonCacheSymbol];
4924
+ if (bag && key in bag) {
4925
+ delete bag[key];
4926
+ }
4927
+ }
4928
+ function hasSingleton(key) {
4929
+ const bag = globalThis[singletonCacheSymbol];
4930
+ return bag && key in bag;
4931
+ }
4926
4932
 
4927
4933
  // src/lib/env.ts
4928
- var envRegistry = {};
4934
+ var envRegistry = singleton("env-registry", () => ({}));
4929
4935
  function registerEnvVar(config) {
4930
4936
  const existing = envRegistry[config.name];
4931
4937
  if (existing) {
@@ -4983,8 +4989,14 @@ class EnvStore {
4983
4989
  has(key) {
4984
4990
  return key in envRegistry;
4985
4991
  }
4992
+ clearCache() {
4993
+ this.parsedValues.clear();
4994
+ }
4986
4995
  }
4987
4996
  var envStore = singleton("env-store", () => new EnvStore);
4997
+ function clearEnvCache() {
4998
+ envStore.clearCache();
4999
+ }
4988
5000
  function generateEnvMarkdown() {
4989
5001
  const configs = Object.values(envRegistry);
4990
5002
  if (configs.length === 0) {
@@ -5073,6 +5085,1030 @@ var env = new Proxy({}, {
5073
5085
  return;
5074
5086
  }
5075
5087
  });
5088
+
5089
+ // src/lib/tree-sitter-styled-text.ts
5090
+ function treeSitterToTextChunks(content, highlights, syntaxStyle) {
5091
+ const chunks = [];
5092
+ const defaultStyle = syntaxStyle.getStyle("default");
5093
+ let currentIndex = 0;
5094
+ for (let i = 0;i < highlights.length; i++) {
5095
+ const [startIndex, endIndex, group] = highlights[i];
5096
+ if (startIndex < currentIndex)
5097
+ continue;
5098
+ if (currentIndex < startIndex) {
5099
+ const text2 = content.slice(currentIndex, startIndex);
5100
+ chunks.push({
5101
+ __isChunk: true,
5102
+ text: text2,
5103
+ fg: defaultStyle?.fg,
5104
+ bg: defaultStyle?.bg,
5105
+ attributes: defaultStyle ? createTextAttributes({
5106
+ bold: defaultStyle.bold,
5107
+ italic: defaultStyle.italic,
5108
+ underline: defaultStyle.underline,
5109
+ dim: defaultStyle.dim
5110
+ }) : 0
5111
+ });
5112
+ currentIndex = startIndex;
5113
+ }
5114
+ let resolvedStyle = syntaxStyle.getStyle(group);
5115
+ let j = i + 1;
5116
+ while (j < highlights.length && highlights[j][0] === startIndex) {
5117
+ const [, , nextGroup] = highlights[j];
5118
+ const nextStyle = syntaxStyle.getStyle(nextGroup);
5119
+ if (nextStyle) {
5120
+ resolvedStyle = nextStyle;
5121
+ }
5122
+ j++;
5123
+ }
5124
+ i = j - 1;
5125
+ const text = content.slice(startIndex, endIndex);
5126
+ const styleToUse = resolvedStyle || defaultStyle;
5127
+ chunks.push({
5128
+ __isChunk: true,
5129
+ text,
5130
+ fg: styleToUse?.fg,
5131
+ bg: styleToUse?.bg,
5132
+ attributes: styleToUse ? createTextAttributes({
5133
+ bold: styleToUse.bold,
5134
+ italic: styleToUse.italic,
5135
+ underline: styleToUse.underline,
5136
+ dim: styleToUse.dim
5137
+ }) : 0
5138
+ });
5139
+ currentIndex = endIndex;
5140
+ }
5141
+ if (currentIndex < content.length) {
5142
+ const text = content.slice(currentIndex);
5143
+ chunks.push({
5144
+ __isChunk: true,
5145
+ text,
5146
+ fg: defaultStyle?.fg,
5147
+ bg: defaultStyle?.bg,
5148
+ attributes: defaultStyle ? createTextAttributes({
5149
+ bold: defaultStyle.bold,
5150
+ italic: defaultStyle.italic,
5151
+ underline: defaultStyle.underline,
5152
+ dim: defaultStyle.dim
5153
+ }) : 0
5154
+ });
5155
+ }
5156
+ return chunks;
5157
+ }
5158
+ async function treeSitterToStyledText(content, filetype, syntaxStyle, client) {
5159
+ const result = await client.highlightOnce(content, filetype);
5160
+ if (result.highlights && result.highlights.length > 0) {
5161
+ const chunks = treeSitterToTextChunks(content, result.highlights, syntaxStyle);
5162
+ return new StyledText(chunks);
5163
+ } else {
5164
+ const defaultStyle = syntaxStyle.mergeStyles("default");
5165
+ const chunks = [
5166
+ {
5167
+ __isChunk: true,
5168
+ text: content,
5169
+ fg: defaultStyle.fg,
5170
+ bg: defaultStyle.bg,
5171
+ attributes: defaultStyle.attributes
5172
+ }
5173
+ ];
5174
+ return new StyledText(chunks);
5175
+ }
5176
+ }
5177
+
5178
+ // src/lib/tree-sitter/client.ts
5179
+ import { EventEmitter as EventEmitter2 } from "events";
5180
+
5181
+ // src/lib/debounce.ts
5182
+ var TIMERS_MAP = new Map;
5183
+
5184
+ class DebounceController {
5185
+ scopeId;
5186
+ constructor(scopeId) {
5187
+ this.scopeId = scopeId;
5188
+ if (!TIMERS_MAP.has(this.scopeId)) {
5189
+ TIMERS_MAP.set(this.scopeId, new Map);
5190
+ }
5191
+ }
5192
+ debounce(id, ms, fn) {
5193
+ const scopeMap = TIMERS_MAP.get(this.scopeId);
5194
+ return new Promise((resolve, reject) => {
5195
+ if (scopeMap.has(id)) {
5196
+ clearTimeout(scopeMap.get(id));
5197
+ }
5198
+ const timerId = setTimeout(() => {
5199
+ try {
5200
+ resolve(fn());
5201
+ } catch (error) {
5202
+ reject(error);
5203
+ }
5204
+ scopeMap.delete(id);
5205
+ }, ms);
5206
+ scopeMap.set(id, timerId);
5207
+ });
5208
+ }
5209
+ clearDebounce(id) {
5210
+ const scopeMap = TIMERS_MAP.get(this.scopeId);
5211
+ if (scopeMap && scopeMap.has(id)) {
5212
+ clearTimeout(scopeMap.get(id));
5213
+ scopeMap.delete(id);
5214
+ }
5215
+ }
5216
+ clear() {
5217
+ const scopeMap = TIMERS_MAP.get(this.scopeId);
5218
+ if (scopeMap) {
5219
+ scopeMap.forEach((timerId) => clearTimeout(timerId));
5220
+ scopeMap.clear();
5221
+ }
5222
+ }
5223
+ }
5224
+ function createDebounce(scopeId) {
5225
+ return new DebounceController(scopeId);
5226
+ }
5227
+ function clearDebounceScope(scopeId) {
5228
+ const scopeMap = TIMERS_MAP.get(scopeId);
5229
+ if (scopeMap) {
5230
+ scopeMap.forEach((timerId) => clearTimeout(timerId));
5231
+ scopeMap.clear();
5232
+ }
5233
+ }
5234
+
5235
+ // src/lib/queue.ts
5236
+ class ProcessQueue {
5237
+ processor;
5238
+ queue = [];
5239
+ processing = false;
5240
+ autoProcess = true;
5241
+ constructor(processor, autoProcess = true) {
5242
+ this.processor = processor;
5243
+ this.autoProcess = autoProcess;
5244
+ }
5245
+ enqueue(item) {
5246
+ this.queue.push(item);
5247
+ if (!this.processing && this.autoProcess) {
5248
+ this.processQueue();
5249
+ }
5250
+ }
5251
+ processQueue() {
5252
+ if (this.queue.length === 0) {
5253
+ return;
5254
+ }
5255
+ this.processing = true;
5256
+ queueMicrotask(async () => {
5257
+ if (this.queue.length === 0) {
5258
+ this.processing = false;
5259
+ return;
5260
+ }
5261
+ const item = this.queue.shift();
5262
+ try {
5263
+ await this.processor(item);
5264
+ } catch (error) {
5265
+ console.error("Error processing queue item:", error);
5266
+ }
5267
+ if (this.queue.length > 0) {
5268
+ this.processQueue();
5269
+ } else {
5270
+ this.processing = false;
5271
+ }
5272
+ });
5273
+ }
5274
+ clear() {
5275
+ this.queue = [];
5276
+ }
5277
+ isProcessing() {
5278
+ return this.processing;
5279
+ }
5280
+ size() {
5281
+ return this.queue.length;
5282
+ }
5283
+ }
5284
+
5285
+ // src/lib/tree-sitter/assets/javascript/highlights.scm
5286
+ var highlights_default = "./highlights-ghv9g403.scm";
5287
+
5288
+ // src/lib/tree-sitter/assets/javascript/tree-sitter-javascript.wasm
5289
+ var tree_sitter_javascript_default = "./tree-sitter-javascript-nd0q4pe9.wasm";
5290
+
5291
+ // src/lib/tree-sitter/assets/typescript/highlights.scm
5292
+ var highlights_default2 = "./highlights-eq9cgrbb.scm";
5293
+
5294
+ // src/lib/tree-sitter/assets/typescript/tree-sitter-typescript.wasm
5295
+ var tree_sitter_typescript_default = "./tree-sitter-typescript-zxjzwt75.wasm";
5296
+
5297
+ // src/lib/tree-sitter/default-parsers.ts
5298
+ var DEFAULT_PARSERS = [
5299
+ {
5300
+ filetype: "javascript",
5301
+ queries: {
5302
+ highlights: [highlights_default]
5303
+ },
5304
+ wasm: tree_sitter_javascript_default
5305
+ },
5306
+ {
5307
+ filetype: "typescript",
5308
+ queries: {
5309
+ highlights: [highlights_default2]
5310
+ },
5311
+ wasm: tree_sitter_typescript_default
5312
+ }
5313
+ ];
5314
+
5315
+ // src/lib/tree-sitter/client.ts
5316
+ var DEFAULT_PARSERS2 = DEFAULT_PARSERS;
5317
+ function addDefaultParsers(parsers) {
5318
+ for (const parser of parsers) {
5319
+ const existingIndex = DEFAULT_PARSERS2.findIndex((p) => p.filetype === parser.filetype);
5320
+ if (existingIndex >= 0) {
5321
+ DEFAULT_PARSERS2[existingIndex] = parser;
5322
+ } else {
5323
+ DEFAULT_PARSERS2.push(parser);
5324
+ }
5325
+ }
5326
+ }
5327
+
5328
+ class TreeSitterClient extends EventEmitter2 {
5329
+ initialized = false;
5330
+ worker;
5331
+ buffers = new Map;
5332
+ initializePromise;
5333
+ initializeResolvers;
5334
+ messageCallbacks = new Map;
5335
+ messageIdCounter = 0;
5336
+ editQueues = new Map;
5337
+ debouncer;
5338
+ options;
5339
+ constructor(options) {
5340
+ super();
5341
+ this.options = options;
5342
+ this.debouncer = createDebounce("tree-sitter-client");
5343
+ this.startWorker();
5344
+ }
5345
+ startWorker() {
5346
+ if (this.worker) {
5347
+ return;
5348
+ }
5349
+ const workerPath = this.options.workerPath || new URL("./parser.worker.ts", import.meta.url);
5350
+ this.worker = new Worker(workerPath);
5351
+ this.worker.onmessage = this.handleWorkerMessage.bind(this);
5352
+ }
5353
+ stopWorker() {
5354
+ if (!this.worker) {
5355
+ return;
5356
+ }
5357
+ this.worker.terminate();
5358
+ this.worker = undefined;
5359
+ }
5360
+ handleReset() {
5361
+ this.buffers.clear();
5362
+ this.stopWorker();
5363
+ this.startWorker();
5364
+ this.initializePromise = undefined;
5365
+ this.initializeResolvers = undefined;
5366
+ return this.initialize();
5367
+ }
5368
+ async initialize() {
5369
+ if (this.initializePromise) {
5370
+ return this.initializePromise;
5371
+ }
5372
+ this.initializePromise = new Promise((resolve, reject) => {
5373
+ const timeoutMs = this.options.initTimeout ?? 1e4;
5374
+ const timeoutId = setTimeout(() => {
5375
+ this.initializeResolvers = undefined;
5376
+ reject(new Error("Worker initialization timed out"));
5377
+ }, timeoutMs);
5378
+ this.initializeResolvers = { resolve, reject, timeoutId };
5379
+ this.worker?.postMessage({
5380
+ type: "INIT",
5381
+ dataPath: this.options.dataPath
5382
+ });
5383
+ });
5384
+ await this.initializePromise;
5385
+ await this.registerDefaultParsers();
5386
+ return this.initializePromise;
5387
+ }
5388
+ async registerDefaultParsers() {
5389
+ for (const parser of DEFAULT_PARSERS2) {
5390
+ this.addFiletypeParser(parser);
5391
+ }
5392
+ }
5393
+ addFiletypeParser(filetypeParser) {
5394
+ this.worker?.postMessage({ type: "ADD_FILETYPE_PARSER", filetypeParser });
5395
+ }
5396
+ async getPerformance() {
5397
+ const messageId = `performance_${this.messageIdCounter++}`;
5398
+ return new Promise((resolve) => {
5399
+ this.messageCallbacks.set(messageId, resolve);
5400
+ this.worker?.postMessage({ type: "GET_PERFORMANCE", messageId });
5401
+ });
5402
+ }
5403
+ async highlightOnce(content, filetype) {
5404
+ if (!this.initialized) {
5405
+ try {
5406
+ await this.initialize();
5407
+ } catch (error) {
5408
+ return { error: "Could not highlight because of initialization error" };
5409
+ }
5410
+ }
5411
+ const messageId = `oneshot_${this.messageIdCounter++}`;
5412
+ return new Promise((resolve) => {
5413
+ this.messageCallbacks.set(messageId, resolve);
5414
+ this.worker?.postMessage({
5415
+ type: "ONESHOT_HIGHLIGHT",
5416
+ content,
5417
+ filetype,
5418
+ messageId
5419
+ });
5420
+ });
5421
+ }
5422
+ handleWorkerMessage(event) {
5423
+ const { type, bufferId, error, highlights, warning, messageId, hasParser, performance: performance2, version } = event.data;
5424
+ if (type === "HIGHLIGHT_RESPONSE") {
5425
+ const buffer = this.buffers.get(bufferId);
5426
+ if (!buffer || !buffer.hasParser)
5427
+ return;
5428
+ if (buffer.version !== version) {
5429
+ this.resetBuffer(bufferId, buffer.version, buffer.content);
5430
+ return;
5431
+ }
5432
+ this.emit("highlights:response", bufferId, version, highlights);
5433
+ }
5434
+ if (type === "INIT_RESPONSE") {
5435
+ if (this.initializeResolvers) {
5436
+ clearTimeout(this.initializeResolvers.timeoutId);
5437
+ if (error) {
5438
+ this.initializeResolvers.reject(new Error(error));
5439
+ } else {
5440
+ this.initialized = true;
5441
+ this.initializeResolvers.resolve();
5442
+ }
5443
+ this.initializeResolvers = undefined;
5444
+ return;
5445
+ }
5446
+ }
5447
+ if (type === "PARSER_INIT_RESPONSE") {
5448
+ const callback = this.messageCallbacks.get(messageId);
5449
+ if (callback) {
5450
+ this.messageCallbacks.delete(messageId);
5451
+ callback({ hasParser, warning, error });
5452
+ }
5453
+ return;
5454
+ }
5455
+ if (type === "PRELOAD_PARSER_RESPONSE") {
5456
+ const callback = this.messageCallbacks.get(messageId);
5457
+ if (callback) {
5458
+ this.messageCallbacks.delete(messageId);
5459
+ callback({ hasParser });
5460
+ }
5461
+ return;
5462
+ }
5463
+ if (type === "BUFFER_DISPOSED") {
5464
+ const callback = this.messageCallbacks.get(`dispose_${bufferId}`);
5465
+ if (callback) {
5466
+ this.messageCallbacks.delete(`dispose_${bufferId}`);
5467
+ callback(true);
5468
+ }
5469
+ this.emit("buffer:disposed", bufferId);
5470
+ return;
5471
+ }
5472
+ if (type === "PERFORMANCE_RESPONSE") {
5473
+ const callback = this.messageCallbacks.get(messageId);
5474
+ if (callback) {
5475
+ this.messageCallbacks.delete(messageId);
5476
+ callback(performance2);
5477
+ }
5478
+ return;
5479
+ }
5480
+ if (type === "ONESHOT_HIGHLIGHT_RESPONSE") {
5481
+ const callback = this.messageCallbacks.get(messageId);
5482
+ if (callback) {
5483
+ this.messageCallbacks.delete(messageId);
5484
+ callback({ highlights, warning, error });
5485
+ }
5486
+ return;
5487
+ }
5488
+ if (type === "UPDATE_DATA_PATH_RESPONSE") {
5489
+ const callback = this.messageCallbacks.get(messageId);
5490
+ if (callback) {
5491
+ this.messageCallbacks.delete(messageId);
5492
+ callback({ error });
5493
+ }
5494
+ return;
5495
+ }
5496
+ if (warning) {
5497
+ this.emit("warning", warning, bufferId);
5498
+ return;
5499
+ }
5500
+ if (error) {
5501
+ this.emit("error", error, bufferId);
5502
+ return;
5503
+ }
5504
+ if (type === "WORKER_LOG") {
5505
+ const { logType, data } = event.data;
5506
+ const message = data.join(" ");
5507
+ this.emit("worker:log", logType, message);
5508
+ if (logType === "log") {
5509
+ console.log("Worker stdout:", ...data);
5510
+ } else if (logType === "error") {
5511
+ console.error("Worker stderr:", ...data);
5512
+ }
5513
+ return;
5514
+ }
5515
+ }
5516
+ async preloadParser(filetype) {
5517
+ const messageId = `has_parser_${this.messageIdCounter++}`;
5518
+ const response = await new Promise((resolve) => {
5519
+ this.messageCallbacks.set(messageId, resolve);
5520
+ this.worker?.postMessage({
5521
+ type: "PRELOAD_PARSER",
5522
+ filetype,
5523
+ messageId
5524
+ });
5525
+ });
5526
+ return response.hasParser;
5527
+ }
5528
+ async createBuffer(id, content, filetype, version = 1, autoInitialize = true) {
5529
+ if (!this.initialized) {
5530
+ if (!autoInitialize) {
5531
+ this.emit("error", "Could not create buffer because client is not initialized");
5532
+ return false;
5533
+ }
5534
+ try {
5535
+ await this.initialize();
5536
+ } catch (error) {
5537
+ this.emit("error", "Could not create buffer because of initialization error");
5538
+ return false;
5539
+ }
5540
+ }
5541
+ if (this.buffers.has(id)) {
5542
+ throw new Error(`Buffer with id ${id} already exists`);
5543
+ }
5544
+ this.buffers.set(id, { id, content, filetype, version, hasParser: false });
5545
+ const messageId = `init_${this.messageIdCounter++}`;
5546
+ const response = await new Promise((resolve) => {
5547
+ this.messageCallbacks.set(messageId, resolve);
5548
+ this.worker?.postMessage({
5549
+ type: "INITIALIZE_PARSER",
5550
+ bufferId: id,
5551
+ version,
5552
+ content,
5553
+ filetype,
5554
+ messageId
5555
+ });
5556
+ });
5557
+ if (!response.hasParser) {
5558
+ this.emit("buffer:initialized", id, false);
5559
+ if (filetype !== "plaintext") {
5560
+ this.emit("warning", response.warning || response.error || "Buffer has no parser", id);
5561
+ }
5562
+ return false;
5563
+ }
5564
+ const bufferState = { id, content, filetype, version, hasParser: true };
5565
+ this.buffers.set(id, bufferState);
5566
+ this.emit("buffer:initialized", id, true);
5567
+ return true;
5568
+ }
5569
+ async updateBuffer(id, edits, newContent, version) {
5570
+ if (!this.initialized) {
5571
+ return;
5572
+ }
5573
+ const buffer = this.buffers.get(id);
5574
+ if (!buffer || !buffer.hasParser) {
5575
+ return;
5576
+ }
5577
+ this.buffers.set(id, { ...buffer, content: newContent, version });
5578
+ if (!this.editQueues.has(id)) {
5579
+ this.editQueues.set(id, new ProcessQueue((item) => this.processEdit(id, item.edits, item.newContent, item.version, item.isReset)));
5580
+ }
5581
+ const bufferQueue = this.editQueues.get(id);
5582
+ bufferQueue.enqueue({ edits, newContent, version });
5583
+ }
5584
+ async processEdit(bufferId, edits, newContent, version, isReset = false) {
5585
+ this.worker?.postMessage({
5586
+ type: isReset ? "RESET_BUFFER" : "HANDLE_EDITS",
5587
+ bufferId,
5588
+ version,
5589
+ content: newContent,
5590
+ edits
5591
+ });
5592
+ }
5593
+ async removeBuffer(bufferId) {
5594
+ if (!this.initialized) {
5595
+ return;
5596
+ }
5597
+ this.buffers.delete(bufferId);
5598
+ if (this.editQueues.has(bufferId)) {
5599
+ this.editQueues.get(bufferId)?.clear();
5600
+ this.editQueues.delete(bufferId);
5601
+ }
5602
+ if (this.worker) {
5603
+ await new Promise((resolve) => {
5604
+ const messageId = `dispose_${bufferId}`;
5605
+ this.messageCallbacks.set(messageId, resolve);
5606
+ try {
5607
+ this.worker.postMessage({
5608
+ type: "DISPOSE_BUFFER",
5609
+ bufferId
5610
+ });
5611
+ } catch (error) {
5612
+ console.error("Error disposing buffer", error);
5613
+ resolve(false);
5614
+ }
5615
+ setTimeout(() => {
5616
+ if (this.messageCallbacks.has(messageId)) {
5617
+ this.messageCallbacks.delete(messageId);
5618
+ console.warn({ bufferId }, "Timed out waiting for buffer to be disposed");
5619
+ resolve(false);
5620
+ }
5621
+ }, 3000);
5622
+ });
5623
+ }
5624
+ this.debouncer.clearDebounce(`reset-${bufferId}`);
5625
+ }
5626
+ async destroy() {
5627
+ if (this.initializeResolvers) {
5628
+ clearTimeout(this.initializeResolvers.timeoutId);
5629
+ this.initializeResolvers = undefined;
5630
+ }
5631
+ clearDebounceScope("tree-sitter-client");
5632
+ this.stopWorker();
5633
+ this.buffers.clear();
5634
+ this.editQueues.clear();
5635
+ this.initialized = false;
5636
+ this.initializePromise = undefined;
5637
+ }
5638
+ async resetBuffer(bufferId, version, content) {
5639
+ if (!this.initialized) {
5640
+ return;
5641
+ }
5642
+ const buffer = this.buffers.get(bufferId);
5643
+ if (!buffer || !buffer.hasParser) {
5644
+ this.emit("error", "Cannot reset buffer with no parser", bufferId);
5645
+ return;
5646
+ }
5647
+ this.buffers.set(bufferId, { ...buffer, content, version });
5648
+ this.debouncer.debounce(`reset-${bufferId}`, 10, () => this.processEdit(bufferId, [], content, version, true));
5649
+ }
5650
+ getBuffer(bufferId) {
5651
+ return this.buffers.get(bufferId);
5652
+ }
5653
+ getAllBuffers() {
5654
+ return Array.from(this.buffers.values());
5655
+ }
5656
+ isInitialized() {
5657
+ return this.initialized;
5658
+ }
5659
+ async setDataPath(dataPath) {
5660
+ if (this.options.dataPath === dataPath) {
5661
+ return;
5662
+ }
5663
+ this.options.dataPath = dataPath;
5664
+ if (this.initialized && this.worker) {
5665
+ const messageId = `update_datapath_${this.messageIdCounter++}`;
5666
+ return new Promise((resolve, reject) => {
5667
+ this.messageCallbacks.set(messageId, (response) => {
5668
+ if (response.error) {
5669
+ reject(new Error(response.error));
5670
+ } else {
5671
+ resolve();
5672
+ }
5673
+ });
5674
+ this.worker.postMessage({
5675
+ type: "UPDATE_DATA_PATH",
5676
+ dataPath,
5677
+ messageId
5678
+ });
5679
+ });
5680
+ }
5681
+ }
5682
+ }
5683
+
5684
+ // src/lib/data-paths.ts
5685
+ import os from "os";
5686
+ import path from "path";
5687
+ import { EventEmitter as EventEmitter3 } from "events";
5688
+
5689
+ // src/lib/validate-dir-name.ts
5690
+ function isValidDirectoryName(name) {
5691
+ if (!name || typeof name !== "string") {
5692
+ return false;
5693
+ }
5694
+ if (name.trim().length === 0) {
5695
+ return false;
5696
+ }
5697
+ const reservedNames = [
5698
+ "CON",
5699
+ "PRN",
5700
+ "AUX",
5701
+ "NUL",
5702
+ "COM1",
5703
+ "COM2",
5704
+ "COM3",
5705
+ "COM4",
5706
+ "COM5",
5707
+ "COM6",
5708
+ "COM7",
5709
+ "COM8",
5710
+ "COM9",
5711
+ "LPT1",
5712
+ "LPT2",
5713
+ "LPT3",
5714
+ "LPT4",
5715
+ "LPT5",
5716
+ "LPT6",
5717
+ "LPT7",
5718
+ "LPT8",
5719
+ "LPT9"
5720
+ ];
5721
+ if (reservedNames.includes(name.toUpperCase())) {
5722
+ return false;
5723
+ }
5724
+ const invalidChars = /[<>:"|?*\/\\\x00-\x1f]/;
5725
+ if (invalidChars.test(name)) {
5726
+ return false;
5727
+ }
5728
+ if (name.endsWith(".") || name.endsWith(" ")) {
5729
+ return false;
5730
+ }
5731
+ if (name === "." || name === "..") {
5732
+ return false;
5733
+ }
5734
+ return true;
5735
+ }
5736
+
5737
+ // src/lib/data-paths.ts
5738
+ registerEnvVar({
5739
+ name: "XDG_CONFIG_HOME",
5740
+ description: "Base directory for user-specific configuration files",
5741
+ type: "string",
5742
+ default: ""
5743
+ });
5744
+ registerEnvVar({
5745
+ name: "XDG_DATA_HOME",
5746
+ description: "Base directory for user-specific data files",
5747
+ type: "string",
5748
+ default: ""
5749
+ });
5750
+
5751
+ class DataPathsManager extends EventEmitter3 {
5752
+ _appName;
5753
+ _globalConfigPath;
5754
+ _globalConfigFile;
5755
+ _localConfigFile;
5756
+ _globalDataPath;
5757
+ constructor() {
5758
+ super();
5759
+ this._appName = "opentui";
5760
+ }
5761
+ get appName() {
5762
+ return this._appName;
5763
+ }
5764
+ set appName(value) {
5765
+ if (!isValidDirectoryName(value)) {
5766
+ throw new Error(`Invalid app name "${value}": must be a valid directory name`);
5767
+ }
5768
+ if (this._appName !== value) {
5769
+ this._appName = value;
5770
+ this._globalConfigPath = undefined;
5771
+ this._globalConfigFile = undefined;
5772
+ this._localConfigFile = undefined;
5773
+ this._globalDataPath = undefined;
5774
+ this.emit("paths:changed", this.toObject());
5775
+ }
5776
+ }
5777
+ get globalConfigPath() {
5778
+ if (this._globalConfigPath === undefined) {
5779
+ const homeDir = os.homedir();
5780
+ const xdgConfigHome = env.XDG_CONFIG_HOME;
5781
+ const baseConfigDir = xdgConfigHome || path.join(homeDir, ".config");
5782
+ this._globalConfigPath = path.join(baseConfigDir, this._appName);
5783
+ }
5784
+ return this._globalConfigPath;
5785
+ }
5786
+ get globalConfigFile() {
5787
+ if (this._globalConfigFile === undefined) {
5788
+ this._globalConfigFile = path.join(this.globalConfigPath, "init.ts");
5789
+ }
5790
+ return this._globalConfigFile;
5791
+ }
5792
+ get localConfigFile() {
5793
+ if (this._localConfigFile === undefined) {
5794
+ this._localConfigFile = path.join(process.cwd(), `.${this._appName}.ts`);
5795
+ }
5796
+ return this._localConfigFile;
5797
+ }
5798
+ get globalDataPath() {
5799
+ if (this._globalDataPath === undefined) {
5800
+ const homeDir = os.homedir();
5801
+ const xdgDataHome = env.XDG_DATA_HOME;
5802
+ const baseDataDir = xdgDataHome || path.join(homeDir, ".local/share");
5803
+ this._globalDataPath = path.join(baseDataDir, this._appName);
5804
+ }
5805
+ return this._globalDataPath;
5806
+ }
5807
+ toObject() {
5808
+ return {
5809
+ globalConfigPath: this.globalConfigPath,
5810
+ globalConfigFile: this.globalConfigFile,
5811
+ localConfigFile: this.localConfigFile,
5812
+ globalDataPath: this.globalDataPath
5813
+ };
5814
+ }
5815
+ }
5816
+ function getDataPaths() {
5817
+ return singleton("data-paths-opentui", () => new DataPathsManager);
5818
+ }
5819
+
5820
+ // src/lib/tree-sitter/resolve-ft.ts
5821
+ function extToFiletype(extension) {
5822
+ const extensionToFiletype = new Map([
5823
+ ["js", "javascript"],
5824
+ ["jsx", "javascriptreact"],
5825
+ ["ts", "typescript"],
5826
+ ["tsx", "typescriptreact"],
5827
+ ["md", "markdown"],
5828
+ ["json", "json"],
5829
+ ["py", "python"],
5830
+ ["rb", "ruby"],
5831
+ ["go", "go"],
5832
+ ["rs", "rust"],
5833
+ ["c", "c"],
5834
+ ["cpp", "cpp"],
5835
+ ["h", "c"],
5836
+ ["hpp", "cpp"],
5837
+ ["html", "html"],
5838
+ ["css", "css"],
5839
+ ["scss", "scss"],
5840
+ ["less", "less"],
5841
+ ["sh", "shell"],
5842
+ ["bash", "shell"],
5843
+ ["zsh", "shell"],
5844
+ ["vim", "vim"],
5845
+ ["yaml", "yaml"],
5846
+ ["yml", "yaml"],
5847
+ ["toml", "toml"],
5848
+ ["xml", "xml"],
5849
+ ["zig", "zig"]
5850
+ ]);
5851
+ return extensionToFiletype.get(extension);
5852
+ }
5853
+ function pathToFiletype(path2) {
5854
+ if (typeof path2 !== "string")
5855
+ return;
5856
+ const lastDot = path2.lastIndexOf(".");
5857
+ if (lastDot === -1 || lastDot === path2.length - 1) {
5858
+ return;
5859
+ }
5860
+ const extension = path2.substring(lastDot + 1);
5861
+ return extToFiletype(extension);
5862
+ }
5863
+
5864
+ // src/lib/tree-sitter/assets/update.ts
5865
+ import { readFile, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
5866
+ import * as path3 from "path";
5867
+
5868
+ // src/lib/tree-sitter/download-utils.ts
5869
+ import { mkdir, writeFile } from "fs/promises";
5870
+ import * as path2 from "path";
5871
+
5872
+ class DownloadUtils {
5873
+ static hashUrl(url) {
5874
+ let hash = 0;
5875
+ for (let i = 0;i < url.length; i++) {
5876
+ const char = url.charCodeAt(i);
5877
+ hash = (hash << 5) - hash + char;
5878
+ hash = hash & hash;
5879
+ }
5880
+ return Math.abs(hash).toString(16);
5881
+ }
5882
+ static async downloadOrLoad(source, cacheDir, cacheSubdir, fileExtension, useHashForCache = true, filetype) {
5883
+ const isUrl = source.startsWith("http://") || source.startsWith("https://");
5884
+ if (isUrl) {
5885
+ let cacheFileName;
5886
+ if (useHashForCache) {
5887
+ const hash = this.hashUrl(source);
5888
+ cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`;
5889
+ } else {
5890
+ cacheFileName = path2.basename(source);
5891
+ }
5892
+ const cacheFile = path2.join(cacheDir, cacheSubdir, cacheFileName);
5893
+ await mkdir(path2.dirname(cacheFile), { recursive: true });
5894
+ try {
5895
+ const cachedContent = await Bun.file(cacheFile).arrayBuffer();
5896
+ if (cachedContent.byteLength > 0) {
5897
+ console.log(`Loaded from cache: ${cacheFile} (${source})`);
5898
+ return { content: cachedContent, filePath: cacheFile };
5899
+ }
5900
+ } catch (error) {}
5901
+ try {
5902
+ console.log(`Downloading from URL: ${source}`);
5903
+ const response = await fetch(source);
5904
+ if (!response.ok) {
5905
+ return { error: `Failed to fetch from ${source}: ${response.statusText}` };
5906
+ }
5907
+ const content = await response.arrayBuffer();
5908
+ try {
5909
+ await writeFile(cacheFile, Buffer.from(content));
5910
+ console.log(`Cached: ${source}`);
5911
+ } catch (cacheError) {
5912
+ console.warn(`Failed to cache: ${cacheError}`);
5913
+ }
5914
+ return { content, filePath: cacheFile };
5915
+ } catch (error) {
5916
+ return { error: `Error downloading from ${source}: ${error}` };
5917
+ }
5918
+ } else {
5919
+ try {
5920
+ console.log(`Loading from local path: ${source}`);
5921
+ const content = await Bun.file(source).arrayBuffer();
5922
+ return { content, filePath: source };
5923
+ } catch (error) {
5924
+ return { error: `Error loading from local path ${source}: ${error}` };
5925
+ }
5926
+ }
5927
+ }
5928
+ static async downloadToPath(source, targetPath) {
5929
+ const isUrl = source.startsWith("http://") || source.startsWith("https://");
5930
+ await mkdir(path2.dirname(targetPath), { recursive: true });
5931
+ if (isUrl) {
5932
+ try {
5933
+ console.log(`Downloading from URL: ${source}`);
5934
+ const response = await fetch(source);
5935
+ if (!response.ok) {
5936
+ return { error: `Failed to fetch from ${source}: ${response.statusText}` };
5937
+ }
5938
+ const content = await response.arrayBuffer();
5939
+ await writeFile(targetPath, Buffer.from(content));
5940
+ console.log(`Downloaded: ${source} -> ${targetPath}`);
5941
+ return { content, filePath: targetPath };
5942
+ } catch (error) {
5943
+ return { error: `Error downloading from ${source}: ${error}` };
5944
+ }
5945
+ } else {
5946
+ try {
5947
+ console.log(`Copying from local path: ${source}`);
5948
+ const content = await Bun.file(source).arrayBuffer();
5949
+ await writeFile(targetPath, Buffer.from(content));
5950
+ return { content, filePath: targetPath };
5951
+ } catch (error) {
5952
+ return { error: `Error copying from local path ${source}: ${error}` };
5953
+ }
5954
+ }
5955
+ }
5956
+ static async fetchHighlightQueries(sources, cacheDir, filetype) {
5957
+ const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype));
5958
+ const queryResults = await Promise.all(queryPromises);
5959
+ const validQueries = queryResults.filter((query) => query.trim().length > 0);
5960
+ return validQueries.join(`
5961
+ `);
5962
+ }
5963
+ static async fetchHighlightQuery(source, cacheDir, filetype) {
5964
+ const result = await this.downloadOrLoad(source, cacheDir, "queries", ".scm", true, filetype);
5965
+ if (result.error) {
5966
+ console.error(`Error fetching highlight query from ${source}:`, result.error);
5967
+ return "";
5968
+ }
5969
+ if (result.content) {
5970
+ return new TextDecoder().decode(result.content);
5971
+ }
5972
+ return "";
5973
+ }
5974
+ }
5975
+
5976
+ // src/lib/tree-sitter/assets/update.ts
5977
+ var __dirname = "/Users/runner/work/opentui/opentui/packages/core/src/lib/tree-sitter/assets";
5978
+ function getDefaultOptions() {
5979
+ return {
5980
+ configPath: path3.resolve(__dirname, "../parsers-config.json"),
5981
+ assetsDir: path3.resolve(__dirname),
5982
+ outputPath: path3.resolve(__dirname, "../default-parsers.ts")
5983
+ };
5984
+ }
5985
+ async function loadConfig(configPath) {
5986
+ const configContent = await readFile(configPath, "utf-8");
5987
+ return JSON.parse(configContent);
5988
+ }
5989
+ async function downloadLanguage(filetype, languageUrl, assetsDir, outputPath) {
5990
+ const languageDir = path3.join(assetsDir, filetype);
5991
+ const languageFilename = path3.basename(languageUrl);
5992
+ const languagePath = path3.join(languageDir, languageFilename);
5993
+ const result = await DownloadUtils.downloadToPath(languageUrl, languagePath);
5994
+ if (result.error) {
5995
+ throw new Error(`Failed to download language for ${filetype}: ${result.error}`);
5996
+ }
5997
+ return "./" + path3.relative(path3.dirname(outputPath), languagePath);
5998
+ }
5999
+ async function downloadAndCombineQueries(filetype, queryUrls, assetsDir, outputPath) {
6000
+ const queriesDir = path3.join(assetsDir, filetype);
6001
+ const highlightsPath = path3.join(queriesDir, "highlights.scm");
6002
+ const queryContents = [];
6003
+ for (let i = 0;i < queryUrls.length; i++) {
6004
+ const queryUrl = queryUrls[i];
6005
+ console.log(` Downloading query ${i + 1}/${queryUrls.length}: ${queryUrl}`);
6006
+ try {
6007
+ const response = await fetch(queryUrl);
6008
+ if (!response.ok) {
6009
+ console.warn(`Failed to download query from ${queryUrl}: ${response.statusText}`);
6010
+ continue;
6011
+ }
6012
+ const content = await response.text();
6013
+ if (content.trim()) {
6014
+ queryContents.push(`; Query from: ${queryUrl}
6015
+ ${content}`);
6016
+ console.log(` \u2713 Downloaded ${content.split(`
6017
+ `).length} lines`);
6018
+ }
6019
+ } catch (error) {
6020
+ console.warn(`Failed to download query from ${queryUrl}: ${error}`);
6021
+ continue;
6022
+ }
6023
+ }
6024
+ const combinedContent = queryContents.join(`
6025
+
6026
+ `);
6027
+ await writeFile2(highlightsPath, combinedContent, "utf-8");
6028
+ console.log(` Combined ${queryContents.length} queries into ${highlightsPath}`);
6029
+ return "./" + path3.relative(path3.dirname(outputPath), highlightsPath);
6030
+ }
6031
+ async function generateDefaultParsersFile(parsers, outputPath) {
6032
+ const imports = parsers.map((parser) => {
6033
+ const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
6034
+ return `import ${safeFiletype}_highlights from "${parser.highlightsPath}" with { type: "file" }
6035
+ import ${safeFiletype}_language from "${parser.languagePath}" with { type: "file" }`;
6036
+ }).join(`
6037
+ `);
6038
+ const parserDefinitions = parsers.map((parser) => {
6039
+ const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_");
6040
+ return ` {
6041
+ filetype: "${parser.filetype}",
6042
+ queries: {
6043
+ highlights: [${safeFiletype}_highlights],
6044
+ },
6045
+ wasm: ${safeFiletype}_language,
6046
+ }`;
6047
+ }).join(`,
6048
+ `);
6049
+ const fileContent = `// This file is generated by assets/update.ts - DO NOT EDIT MANUALLY
6050
+ // Run 'bun assets/update.ts' to regenerate this file
6051
+ // Last generated: ${new Date().toISOString()}
6052
+
6053
+ import type { FiletypeParserOptions } from "./types"
6054
+
6055
+ ${imports}
6056
+
6057
+ export const DEFAULT_PARSERS: FiletypeParserOptions[] = [
6058
+ ${parserDefinitions},
6059
+ ]
6060
+ `;
6061
+ await mkdir2(path3.dirname(outputPath), { recursive: true });
6062
+ await writeFile2(outputPath, fileContent, "utf-8");
6063
+ console.log(`Generated ${path3.basename(outputPath)} with ${parsers.length} parsers`);
6064
+ }
6065
+ async function main(options) {
6066
+ const opts = { ...getDefaultOptions(), ...options };
6067
+ try {
6068
+ console.log("Loading parsers configuration...");
6069
+ console.log(` Config: ${opts.configPath}`);
6070
+ console.log(` Assets Dir: ${opts.assetsDir}`);
6071
+ console.log(` Output: ${opts.outputPath}`);
6072
+ const config = await loadConfig(opts.configPath);
6073
+ console.log(`Found ${config.parsers.length} parsers to process`);
6074
+ const generatedParsers = [];
6075
+ for (const parser of config.parsers) {
6076
+ console.log(`Processing ${parser.filetype}...`);
6077
+ console.log(` Downloading language...`);
6078
+ const languagePath = await downloadLanguage(parser.filetype, parser.wasm, opts.assetsDir, opts.outputPath);
6079
+ console.log(` Downloading ${parser.queries.highlights.length} highlight queries...`);
6080
+ const highlightsPath = await downloadAndCombineQueries(parser.filetype, parser.queries.highlights, opts.assetsDir, opts.outputPath);
6081
+ generatedParsers.push({
6082
+ filetype: parser.filetype,
6083
+ languagePath,
6084
+ highlightsPath
6085
+ });
6086
+ console.log(` \u2713 Completed ${parser.filetype}`);
6087
+ }
6088
+ console.log("Generating output file...");
6089
+ await generateDefaultParsersFile(generatedParsers, opts.outputPath);
6090
+ console.log("\u2705 Update completed successfully!");
6091
+ } catch (error) {
6092
+ console.error("\u274C Update failed:", error);
6093
+ process.exit(1);
6094
+ }
6095
+ }
6096
+ if (false) {}
6097
+
6098
+ // src/lib/tree-sitter/index.ts
6099
+ function getTreeSitterClient() {
6100
+ const dataPathsManager = getDataPaths();
6101
+ const defaultOptions = {
6102
+ dataPath: dataPathsManager.globalDataPath
6103
+ };
6104
+ return singleton("tree-sitter-client", () => {
6105
+ const client2 = new TreeSitterClient(defaultOptions);
6106
+ dataPathsManager.on("paths:changed", (paths) => {
6107
+ client2.setDataPath(paths.globalDataPath);
6108
+ });
6109
+ return client2;
6110
+ });
6111
+ }
5076
6112
  // src/zig.ts
5077
6113
  import { dlopen, toArrayBuffer as toArrayBuffer2, JSCallback, ptr } from "bun:ffi";
5078
6114
  import { existsSync } from "fs";
@@ -6380,7 +7416,7 @@ class TextBuffer {
6380
7416
  }
6381
7417
 
6382
7418
  // src/Renderable.ts
6383
- import { EventEmitter as EventEmitter2 } from "events";
7419
+ import { EventEmitter as EventEmitter4 } from "events";
6384
7420
 
6385
7421
  // src/lib/renderable.validations.ts
6386
7422
  function validateOptions(id, options) {
@@ -6473,7 +7509,7 @@ function isRenderable(obj) {
6473
7509
  return !!obj?.[BrandedRenderable];
6474
7510
  }
6475
7511
 
6476
- class BaseRenderable extends EventEmitter2 {
7512
+ class BaseRenderable extends EventEmitter4 {
6477
7513
  [BrandedRenderable] = true;
6478
7514
  static renderableNumber = 1;
6479
7515
  _id;
@@ -7776,17 +8812,17 @@ function delegate(mapping, vnode) {
7776
8812
  }
7777
8813
 
7778
8814
  // src/console.ts
7779
- import { EventEmitter as EventEmitter4 } from "events";
8815
+ import { EventEmitter as EventEmitter6 } from "events";
7780
8816
  import { Console } from "console";
7781
8817
  import fs from "fs";
7782
- import path from "path";
8818
+ import path4 from "path";
7783
8819
  import util2 from "util";
7784
8820
 
7785
8821
  // src/lib/output.capture.ts
7786
8822
  import { Writable } from "stream";
7787
- import { EventEmitter as EventEmitter3 } from "events";
8823
+ import { EventEmitter as EventEmitter5 } from "events";
7788
8824
 
7789
- class Capture extends EventEmitter3 {
8825
+ class Capture extends EventEmitter5 {
7790
8826
  output = [];
7791
8827
  constructor() {
7792
8828
  super();
@@ -7862,7 +8898,7 @@ registerEnvVar({
7862
8898
  default: false
7863
8899
  });
7864
8900
 
7865
- class TerminalConsoleCache extends EventEmitter4 {
8901
+ class TerminalConsoleCache extends EventEmitter6 {
7866
8902
  _cachedLogs = [];
7867
8903
  MAX_CACHE_SIZE = 1000;
7868
8904
  _collectCallerInfo = false;
@@ -7983,7 +9019,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
7983
9019
  };
7984
9020
  var INDENT_WIDTH = 2;
7985
9021
 
7986
- class TerminalConsole extends EventEmitter4 {
9022
+ class TerminalConsole extends EventEmitter6 {
7987
9023
  isVisible = false;
7988
9024
  isFocused = false;
7989
9025
  renderer;
@@ -8422,7 +9458,7 @@ class TerminalConsole extends EventEmitter4 {
8422
9458
  try {
8423
9459
  const timestamp = Date.now();
8424
9460
  const filename = `_console_${timestamp}.log`;
8425
- const filepath = path.join(process.cwd(), filename);
9461
+ const filepath = path4.join(process.cwd(), filename);
8426
9462
  const allLogEntries = [...this._allLogEntries, ...terminalConsoleCache.cachedLogs];
8427
9463
  const logLines = [];
8428
9464
  for (const [date, level, args, callerInfo] of allLogEntries) {
@@ -8443,7 +9479,7 @@ class TerminalConsole extends EventEmitter4 {
8443
9479
  }
8444
9480
 
8445
9481
  // src/renderer.ts
8446
- import { EventEmitter as EventEmitter5 } from "events";
9482
+ import { EventEmitter as EventEmitter7 } from "events";
8447
9483
 
8448
9484
  // src/lib/objects-in-viewport.ts
8449
9485
  function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
@@ -8595,13 +9631,17 @@ var rendererTracker = singleton("RendererTracker", () => {
8595
9631
  renderers.delete(renderer);
8596
9632
  if (renderers.size === 0) {
8597
9633
  process.stdin.pause();
9634
+ if (hasSingleton("tree-sitter-client")) {
9635
+ getTreeSitterClient().destroy();
9636
+ destroySingleton("tree-sitter-client");
9637
+ }
8598
9638
  }
8599
9639
  }
8600
9640
  };
8601
9641
  });
8602
9642
  async function createCliRenderer(config = {}) {
8603
9643
  if (process.argv.includes("--delay-start")) {
8604
- await new Promise((resolve) => setTimeout(resolve, 5000));
9644
+ await new Promise((resolve2) => setTimeout(resolve2, 5000));
8605
9645
  }
8606
9646
  const stdin = config.stdin || process.stdin;
8607
9647
  const stdout = config.stdout || process.stdout;
@@ -8628,7 +9668,7 @@ var CliRenderEvents;
8628
9668
  ((CliRenderEvents2) => {
8629
9669
  CliRenderEvents2["DEBUG_OVERLAY_TOGGLE"] = "debugOverlay:toggle";
8630
9670
  })(CliRenderEvents ||= {});
8631
- class CliRenderer extends EventEmitter5 {
9671
+ class CliRenderer extends EventEmitter7 {
8632
9672
  static animationFrameId = 0;
8633
9673
  lib;
8634
9674
  rendererPtr;
@@ -8720,9 +9760,9 @@ class CliRenderer extends EventEmitter5 {
8720
9760
  handleError = ((error) => {
8721
9761
  this.stop();
8722
9762
  this.destroy();
8723
- new Promise((resolve) => {
9763
+ new Promise((resolve2) => {
8724
9764
  setTimeout(() => {
8725
- resolve(true);
9765
+ resolve2(true);
8726
9766
  }, 100);
8727
9767
  }).then(() => {
8728
9768
  this.realStdoutWrite.call(this.stdout, `
@@ -9041,16 +10081,16 @@ Captured output:
9041
10081
  if (this._terminalIsSetup)
9042
10082
  return;
9043
10083
  this._terminalIsSetup = true;
9044
- await new Promise((resolve) => {
10084
+ await new Promise((resolve2) => {
9045
10085
  const timeout = setTimeout(() => {
9046
10086
  this.stdin.off("data", capListener);
9047
- resolve(true);
10087
+ resolve2(true);
9048
10088
  }, 100);
9049
10089
  const capListener = (str) => {
9050
10090
  clearTimeout(timeout);
9051
10091
  this.lib.processCapabilityResponse(this.rendererPtr, str);
9052
10092
  this.stdin.off("data", capListener);
9053
- resolve(true);
10093
+ resolve2(true);
9054
10094
  };
9055
10095
  this.stdin.on("data", capListener);
9056
10096
  this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
@@ -9450,7 +10490,11 @@ Captured output:
9450
10490
  this._isRunning = false;
9451
10491
  this.waitingForPixelResolution = false;
9452
10492
  this.capturedRenderable = undefined;
9453
- this.root.destroyRecursively();
10493
+ try {
10494
+ this.root.destroyRecursively();
10495
+ } catch (e) {
10496
+ console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e));
10497
+ }
9454
10498
  this._keyHandler.destroy();
9455
10499
  this._console.deactivate();
9456
10500
  this.disableStdoutInterception();
@@ -9688,7 +10732,7 @@ Captured output:
9688
10732
  }
9689
10733
  }
9690
10734
 
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 };
10735
+ 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, 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
10736
 
9693
- //# debugId=B65C4E4D90FC9D3564756E2164756E21
9694
- //# sourceMappingURL=index-kvwmgj67.js.map
10737
+ //# debugId=259CDC2839F0878D64756E2164756E21
10738
+ //# sourceMappingURL=index-h87jjatk.js.map