@opentui/core 0.0.0-20250929-69eb6c87 → 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;
@@ -7318,6 +8354,16 @@ class Renderable extends BaseRenderable {
7318
8354
  if (zIndexIndex !== -1) {
7319
8355
  this._childrenInZIndexOrder.splice(zIndexIndex, 1);
7320
8356
  }
8357
+ if (this._forceLayoutUpdateFor) {
8358
+ const forceIndex = this._forceLayoutUpdateFor.findIndex((obj2) => obj2.id === id);
8359
+ if (forceIndex !== -1) {
8360
+ this._forceLayoutUpdateFor?.splice(forceIndex, 1);
8361
+ }
8362
+ }
8363
+ const newChildIndex = this._newChildren.findIndex((obj2) => obj2.id === id);
8364
+ if (newChildIndex !== -1) {
8365
+ this._newChildren?.splice(newChildIndex, 1);
8366
+ }
7321
8367
  this.childrenPrimarySortDirty = true;
7322
8368
  }
7323
8369
  }
@@ -7766,17 +8812,17 @@ function delegate(mapping, vnode) {
7766
8812
  }
7767
8813
 
7768
8814
  // src/console.ts
7769
- import { EventEmitter as EventEmitter4 } from "events";
8815
+ import { EventEmitter as EventEmitter6 } from "events";
7770
8816
  import { Console } from "console";
7771
8817
  import fs from "fs";
7772
- import path from "path";
8818
+ import path4 from "path";
7773
8819
  import util2 from "util";
7774
8820
 
7775
8821
  // src/lib/output.capture.ts
7776
8822
  import { Writable } from "stream";
7777
- import { EventEmitter as EventEmitter3 } from "events";
8823
+ import { EventEmitter as EventEmitter5 } from "events";
7778
8824
 
7779
- class Capture extends EventEmitter3 {
8825
+ class Capture extends EventEmitter5 {
7780
8826
  output = [];
7781
8827
  constructor() {
7782
8828
  super();
@@ -7852,7 +8898,7 @@ registerEnvVar({
7852
8898
  default: false
7853
8899
  });
7854
8900
 
7855
- class TerminalConsoleCache extends EventEmitter4 {
8901
+ class TerminalConsoleCache extends EventEmitter6 {
7856
8902
  _cachedLogs = [];
7857
8903
  MAX_CACHE_SIZE = 1000;
7858
8904
  _collectCallerInfo = false;
@@ -7973,7 +9019,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
7973
9019
  };
7974
9020
  var INDENT_WIDTH = 2;
7975
9021
 
7976
- class TerminalConsole extends EventEmitter4 {
9022
+ class TerminalConsole extends EventEmitter6 {
7977
9023
  isVisible = false;
7978
9024
  isFocused = false;
7979
9025
  renderer;
@@ -8412,7 +9458,7 @@ class TerminalConsole extends EventEmitter4 {
8412
9458
  try {
8413
9459
  const timestamp = Date.now();
8414
9460
  const filename = `_console_${timestamp}.log`;
8415
- const filepath = path.join(process.cwd(), filename);
9461
+ const filepath = path4.join(process.cwd(), filename);
8416
9462
  const allLogEntries = [...this._allLogEntries, ...terminalConsoleCache.cachedLogs];
8417
9463
  const logLines = [];
8418
9464
  for (const [date, level, args, callerInfo] of allLogEntries) {
@@ -8433,7 +9479,7 @@ class TerminalConsole extends EventEmitter4 {
8433
9479
  }
8434
9480
 
8435
9481
  // src/renderer.ts
8436
- import { EventEmitter as EventEmitter5 } from "events";
9482
+ import { EventEmitter as EventEmitter7 } from "events";
8437
9483
 
8438
9484
  // src/lib/objects-in-viewport.ts
8439
9485
  function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
@@ -8585,13 +9631,17 @@ var rendererTracker = singleton("RendererTracker", () => {
8585
9631
  renderers.delete(renderer);
8586
9632
  if (renderers.size === 0) {
8587
9633
  process.stdin.pause();
9634
+ if (hasSingleton("tree-sitter-client")) {
9635
+ getTreeSitterClient().destroy();
9636
+ destroySingleton("tree-sitter-client");
9637
+ }
8588
9638
  }
8589
9639
  }
8590
9640
  };
8591
9641
  });
8592
9642
  async function createCliRenderer(config = {}) {
8593
9643
  if (process.argv.includes("--delay-start")) {
8594
- await new Promise((resolve) => setTimeout(resolve, 5000));
9644
+ await new Promise((resolve2) => setTimeout(resolve2, 5000));
8595
9645
  }
8596
9646
  const stdin = config.stdin || process.stdin;
8597
9647
  const stdout = config.stdout || process.stdout;
@@ -8618,14 +9668,14 @@ var CliRenderEvents;
8618
9668
  ((CliRenderEvents2) => {
8619
9669
  CliRenderEvents2["DEBUG_OVERLAY_TOGGLE"] = "debugOverlay:toggle";
8620
9670
  })(CliRenderEvents ||= {});
8621
- class CliRenderer extends EventEmitter5 {
9671
+ class CliRenderer extends EventEmitter7 {
8622
9672
  static animationFrameId = 0;
8623
9673
  lib;
8624
9674
  rendererPtr;
8625
9675
  stdin;
8626
9676
  stdout;
8627
9677
  exitOnCtrlC;
8628
- isDestroyed = false;
9678
+ _isDestroyed = false;
8629
9679
  nextRenderBuffer;
8630
9680
  currentRenderBuffer;
8631
9681
  _isRunning = false;
@@ -8710,9 +9760,9 @@ class CliRenderer extends EventEmitter5 {
8710
9760
  handleError = ((error) => {
8711
9761
  this.stop();
8712
9762
  this.destroy();
8713
- new Promise((resolve) => {
9763
+ new Promise((resolve2) => {
8714
9764
  setTimeout(() => {
8715
- resolve(true);
9765
+ resolve2(true);
8716
9766
  }, 100);
8717
9767
  }).then(() => {
8718
9768
  this.realStdoutWrite.call(this.stdout, `
@@ -8831,6 +9881,9 @@ Captured output:
8831
9881
  }
8832
9882
  this.setupInput();
8833
9883
  }
9884
+ get isDestroyed() {
9885
+ return this._isDestroyed;
9886
+ }
8834
9887
  registerLifecyclePass(renderable) {
8835
9888
  this.lifecyclePasses.add(renderable);
8836
9889
  }
@@ -9028,16 +10081,16 @@ Captured output:
9028
10081
  if (this._terminalIsSetup)
9029
10082
  return;
9030
10083
  this._terminalIsSetup = true;
9031
- await new Promise((resolve) => {
10084
+ await new Promise((resolve2) => {
9032
10085
  const timeout = setTimeout(() => {
9033
10086
  this.stdin.off("data", capListener);
9034
- resolve(true);
10087
+ resolve2(true);
9035
10088
  }, 100);
9036
10089
  const capListener = (str) => {
9037
10090
  clearTimeout(timeout);
9038
10091
  this.lib.processCapabilityResponse(this.rendererPtr, str);
9039
10092
  this.stdin.off("data", capListener);
9040
- resolve(true);
10093
+ resolve2(true);
9041
10094
  };
9042
10095
  this.stdin.on("data", capListener);
9043
10096
  this.lib.setupTerminal(this.rendererPtr, this._useAlternateScreen);
@@ -9194,7 +10247,7 @@ Captured output:
9194
10247
  return false;
9195
10248
  }
9196
10249
  takeMemorySnapshot() {
9197
- if (this.isDestroyed)
10250
+ if (this._isDestroyed)
9198
10251
  return;
9199
10252
  const memoryUsage = process.memoryUsage();
9200
10253
  this.lastMemorySnapshot = {
@@ -9227,7 +10280,7 @@ Captured output:
9227
10280
  }
9228
10281
  }
9229
10282
  handleResize(width, height) {
9230
- if (this.isDestroyed)
10283
+ if (this._isDestroyed)
9231
10284
  return;
9232
10285
  if (this._splitHeight > 0) {
9233
10286
  this.processResize(width, height);
@@ -9386,7 +10439,7 @@ Captured output:
9386
10439
  this.controlState = this._isRunning ? "auto_started" /* AUTO_STARTED */ : "idle" /* IDLE */;
9387
10440
  }
9388
10441
  internalStart() {
9389
- if (!this._isRunning && !this.isDestroyed) {
10442
+ if (!this._isRunning && !this._isDestroyed) {
9390
10443
  this._isRunning = true;
9391
10444
  if (this.memorySnapshotInterval > 0) {
9392
10445
  this.startMemorySnapshotTimer();
@@ -9406,7 +10459,7 @@ Captured output:
9406
10459
  this.internalStop();
9407
10460
  }
9408
10461
  internalStop() {
9409
- if (this.isRunning && !this.isDestroyed) {
10462
+ if (this.isRunning && !this._isDestroyed) {
9410
10463
  this._isRunning = false;
9411
10464
  if (this.memorySnapshotTimer) {
9412
10465
  clearInterval(this.memorySnapshotTimer);
@@ -9427,9 +10480,9 @@ Captured output:
9427
10480
  if (this.memorySnapshotTimer) {
9428
10481
  clearInterval(this.memorySnapshotTimer);
9429
10482
  }
9430
- if (this.isDestroyed)
10483
+ if (this._isDestroyed)
9431
10484
  return;
9432
- this.isDestroyed = true;
10485
+ this._isDestroyed = true;
9433
10486
  if (this.renderTimeout) {
9434
10487
  clearTimeout(this.renderTimeout);
9435
10488
  this.renderTimeout = null;
@@ -9437,7 +10490,11 @@ Captured output:
9437
10490
  this._isRunning = false;
9438
10491
  this.waitingForPixelResolution = false;
9439
10492
  this.capturedRenderable = undefined;
9440
- 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
+ }
9441
10498
  this._keyHandler.destroy();
9442
10499
  this._console.deactivate();
9443
10500
  this.disableStdoutInterception();
@@ -9462,7 +10519,7 @@ Captured output:
9462
10519
  this.loop();
9463
10520
  }
9464
10521
  async loop() {
9465
- if (this.rendering || this.isDestroyed)
10522
+ if (this.rendering || this._isDestroyed)
9466
10523
  return;
9467
10524
  this.rendering = true;
9468
10525
  if (this.renderTimeout) {
@@ -9506,17 +10563,17 @@ Captured output:
9506
10563
  postProcessFn(this.nextRenderBuffer, deltaTime);
9507
10564
  }
9508
10565
  this._console.renderToBuffer(this.nextRenderBuffer);
9509
- if (!this.isDestroyed) {
10566
+ if (!this._isDestroyed) {
9510
10567
  this.renderNative();
9511
- }
9512
- const overallFrameTime = performance.now() - overallStart;
9513
- this.lib.updateStats(this.rendererPtr, overallFrameTime, this.renderStats.fps, this.renderStats.frameCallbackTime);
9514
- if (this.gatherStats) {
9515
- this.collectStatSample(overallFrameTime);
9516
- }
9517
- if (this._isRunning) {
9518
- const delay = Math.max(1, this.targetFrameTime - Math.floor(overallFrameTime));
9519
- this.renderTimeout = setTimeout(() => this.loop(), delay);
10568
+ const overallFrameTime = performance.now() - overallStart;
10569
+ this.lib.updateStats(this.rendererPtr, overallFrameTime, this.renderStats.fps, this.renderStats.frameCallbackTime);
10570
+ if (this.gatherStats) {
10571
+ this.collectStatSample(overallFrameTime);
10572
+ }
10573
+ if (this._isRunning) {
10574
+ const delay = Math.max(1, this.targetFrameTime - Math.floor(overallFrameTime));
10575
+ this.renderTimeout = setTimeout(() => this.loop(), delay);
10576
+ }
9520
10577
  }
9521
10578
  this.rendering = false;
9522
10579
  if (this.immediateRerenderRequested) {
@@ -9675,7 +10732,7 @@ Captured output:
9675
10732
  }
9676
10733
  }
9677
10734
 
9678
- 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 };
9679
10736
 
9680
- //# debugId=0B29BE27CDCDF3A264756E2164756E21
9681
- //# sourceMappingURL=index-yd5hcdcm.js.map
10737
+ //# debugId=259CDC2839F0878D64756E2164756E21
10738
+ //# sourceMappingURL=index-h87jjatk.js.map