@fairyhunter13/opentui-core 0.1.88 → 0.1.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (570) hide show
  1. package/dev/keypress-debug-renderer.ts +148 -0
  2. package/dev/keypress-debug.ts +43 -0
  3. package/dev/print-env-vars.ts +32 -0
  4. package/dev/test-tmux-graphics-334.sh +68 -0
  5. package/dev/thai-debug-test.ts +68 -0
  6. package/docs/development.md +141 -0
  7. package/docs/env-vars.md +140 -0
  8. package/docs/getting-started.md +353 -0
  9. package/docs/renderables-vs-constructs.md +159 -0
  10. package/docs/tree-sitter.md +311 -0
  11. package/package.json +61 -52
  12. package/scripts/build.ts +400 -0
  13. package/scripts/publish.ts +60 -0
  14. package/src/3d/SpriteResourceManager.ts +286 -0
  15. package/src/3d/SpriteUtils.ts +71 -0
  16. package/src/3d/TextureUtils.ts +196 -0
  17. package/src/3d/ThreeRenderable.ts +197 -0
  18. package/src/3d/WGPURenderer.ts +294 -0
  19. package/src/3d/animation/ExplodingSpriteEffect.ts +513 -0
  20. package/src/3d/animation/PhysicsExplodingSpriteEffect.ts +429 -0
  21. package/src/3d/animation/SpriteAnimator.ts +633 -0
  22. package/src/3d/animation/SpriteParticleGenerator.ts +435 -0
  23. package/src/3d/canvas.ts +464 -0
  24. package/src/3d/index.ts +12 -0
  25. package/src/3d/physics/PlanckPhysicsAdapter.ts +72 -0
  26. package/src/3d/physics/RapierPhysicsAdapter.ts +66 -0
  27. package/src/3d/physics/physics-interface.ts +31 -0
  28. package/src/3d/shaders/supersampling.wgsl +201 -0
  29. package/src/3d.ts +3 -0
  30. package/src/NativeSpanFeed.ts +300 -0
  31. package/src/Renderable.ts +1698 -0
  32. package/src/__snapshots__/buffer.test.ts.snap +28 -0
  33. package/src/animation/Timeline.test.ts +2709 -0
  34. package/src/animation/Timeline.ts +598 -0
  35. package/src/ansi.ts +18 -0
  36. package/src/benchmark/latest-all-bench-run.json +707 -0
  37. package/src/benchmark/latest-async-bench-run.json +336 -0
  38. package/src/benchmark/latest-default-bench-run.json +657 -0
  39. package/src/benchmark/latest-large-bench-run.json +707 -0
  40. package/src/benchmark/latest-quick-bench-run.json +207 -0
  41. package/src/benchmark/markdown-benchmark.ts +1804 -0
  42. package/src/benchmark/native-span-feed-async-benchmark.ts +355 -0
  43. package/src/benchmark/native-span-feed-benchmark.md +56 -0
  44. package/src/benchmark/native-span-feed-benchmark.ts +596 -0
  45. package/src/benchmark/native-span-feed-compare.ts +280 -0
  46. package/src/benchmark/renderer-benchmark.ts +754 -0
  47. package/src/benchmark/text-table-benchmark.ts +947 -0
  48. package/src/buffer.test.ts +291 -0
  49. package/src/buffer.ts +519 -0
  50. package/src/console.test.ts +612 -0
  51. package/src/console.ts +1255 -0
  52. package/src/edit-buffer.test.ts +1769 -0
  53. package/src/edit-buffer.ts +411 -0
  54. package/src/editor-view.test.ts +1032 -0
  55. package/src/editor-view.ts +284 -0
  56. package/src/examples/ascii-font-selection-demo.ts +245 -0
  57. package/src/examples/assets/Water_2_M_Normal.jpg +0 -0
  58. package/src/examples/assets/concrete.png +0 -0
  59. package/src/examples/assets/crate.png +0 -0
  60. package/src/examples/assets/crate_emissive.png +0 -0
  61. package/src/examples/assets/forrest_background.png +0 -0
  62. package/src/examples/assets/hast-example.json +1018 -0
  63. package/src/examples/assets/heart.png +0 -0
  64. package/src/examples/assets/main_char_heavy_attack.png +0 -0
  65. package/src/examples/assets/main_char_idle.png +0 -0
  66. package/src/examples/assets/main_char_jump_end.png +0 -0
  67. package/src/examples/assets/main_char_jump_landing.png +0 -0
  68. package/src/examples/assets/main_char_jump_start.png +0 -0
  69. package/src/examples/assets/main_char_run_loop.png +0 -0
  70. package/src/examples/assets/roughness_map.jpg +0 -0
  71. package/src/examples/build.ts +115 -0
  72. package/src/examples/code-demo.ts +584 -0
  73. package/src/examples/console-demo.ts +358 -0
  74. package/src/examples/core-plugin-slots-demo.ts +759 -0
  75. package/src/examples/diff-demo.ts +699 -0
  76. package/src/examples/draggable-three-demo.ts +259 -0
  77. package/src/examples/editor-demo.ts +322 -0
  78. package/src/examples/extmarks-demo.ts +204 -0
  79. package/src/examples/focus-restore-demo.ts +310 -0
  80. package/src/examples/fonts.ts +245 -0
  81. package/src/examples/fractal-shader-demo.ts +268 -0
  82. package/src/examples/framebuffer-demo.ts +674 -0
  83. package/src/examples/full-unicode-demo.ts +181 -0
  84. package/src/examples/golden-star-demo.ts +933 -0
  85. package/src/examples/grayscale-buffer-demo.ts +249 -0
  86. package/src/examples/hast-syntax-highlighting-demo.ts +129 -0
  87. package/src/examples/index.ts +925 -0
  88. package/src/examples/input-demo.ts +377 -0
  89. package/src/examples/input-select-layout-demo.ts +425 -0
  90. package/src/examples/install.sh +143 -0
  91. package/src/examples/keypress-debug-demo.ts +452 -0
  92. package/src/examples/lib/HexList.ts +122 -0
  93. package/src/examples/lib/PaletteGrid.ts +125 -0
  94. package/src/examples/lib/standalone-keys.ts +25 -0
  95. package/src/examples/lib/tab-controller.ts +243 -0
  96. package/src/examples/lights-phong-demo.ts +290 -0
  97. package/src/examples/link-demo.ts +220 -0
  98. package/src/examples/live-state-demo.ts +480 -0
  99. package/src/examples/markdown-demo.ts +620 -0
  100. package/src/examples/mouse-interaction-demo.ts +428 -0
  101. package/src/examples/nested-zindex-demo.ts +357 -0
  102. package/src/examples/opacity-example.ts +235 -0
  103. package/src/examples/opentui-demo.ts +1057 -0
  104. package/src/examples/physx-planck-2d-demo.ts +507 -0
  105. package/src/examples/physx-rapier-2d-demo.ts +526 -0
  106. package/src/examples/relative-positioning-demo.ts +323 -0
  107. package/src/examples/scroll-example.ts +214 -0
  108. package/src/examples/scrollbox-mouse-test.ts +112 -0
  109. package/src/examples/scrollbox-overlay-hit-test.ts +206 -0
  110. package/src/examples/select-demo.ts +237 -0
  111. package/src/examples/shader-cube-demo.ts +772 -0
  112. package/src/examples/simple-layout-example.ts +591 -0
  113. package/src/examples/slider-demo.ts +617 -0
  114. package/src/examples/split-mode-demo.ts +445 -0
  115. package/src/examples/sprite-animation-demo.ts +443 -0
  116. package/src/examples/sprite-particle-generator-demo.ts +486 -0
  117. package/src/examples/static-sprite-demo.ts +193 -0
  118. package/src/examples/sticky-scroll-example.ts +308 -0
  119. package/src/examples/styled-text-demo.ts +282 -0
  120. package/src/examples/tab-select-demo.ts +219 -0
  121. package/src/examples/terminal-title.ts +29 -0
  122. package/src/examples/terminal.ts +305 -0
  123. package/src/examples/text-node-demo.ts +416 -0
  124. package/src/examples/text-selection-demo.ts +377 -0
  125. package/src/examples/text-table-demo.ts +503 -0
  126. package/src/examples/text-truncation-demo.ts +481 -0
  127. package/src/examples/text-wrap.ts +757 -0
  128. package/src/examples/texture-loading-demo.ts +259 -0
  129. package/src/examples/timeline-example.ts +670 -0
  130. package/src/examples/transparency-demo.ts +241 -0
  131. package/src/examples/vnode-composition-demo.ts +404 -0
  132. package/src/index.ts +22 -0
  133. package/src/lib/KeyHandler.integration.test.ts +292 -0
  134. package/src/lib/KeyHandler.stopPropagation.test.ts +289 -0
  135. package/src/lib/KeyHandler.test.ts +662 -0
  136. package/src/lib/KeyHandler.ts +222 -0
  137. package/src/lib/RGBA.test.ts +984 -0
  138. package/src/lib/RGBA.ts +204 -0
  139. package/src/lib/ascii.font.ts +330 -0
  140. package/src/lib/border.test.ts +83 -0
  141. package/src/lib/border.ts +168 -0
  142. package/src/lib/bunfs.test.ts +27 -0
  143. package/src/lib/bunfs.ts +18 -0
  144. package/src/lib/clipboard.test.ts +41 -0
  145. package/src/lib/clipboard.ts +47 -0
  146. package/src/lib/clock.ts +31 -0
  147. package/src/lib/data-paths.test.ts +133 -0
  148. package/src/lib/data-paths.ts +109 -0
  149. package/src/lib/debounce.ts +106 -0
  150. package/src/lib/detect-links.test.ts +98 -0
  151. package/src/lib/detect-links.ts +56 -0
  152. package/src/lib/env.test.ts +228 -0
  153. package/src/lib/env.ts +209 -0
  154. package/src/lib/extmarks-history.ts +51 -0
  155. package/src/lib/extmarks-multiwidth.test.ts +322 -0
  156. package/src/lib/extmarks.test.ts +3457 -0
  157. package/src/lib/extmarks.ts +843 -0
  158. package/src/lib/fonts/block.json +405 -0
  159. package/src/lib/fonts/grid.json +265 -0
  160. package/src/lib/fonts/huge.json +741 -0
  161. package/src/lib/fonts/pallet.json +314 -0
  162. package/src/lib/fonts/shade.json +591 -0
  163. package/src/lib/fonts/slick.json +321 -0
  164. package/src/lib/fonts/tiny.json +69 -0
  165. package/src/lib/hast-styled-text.ts +59 -0
  166. package/src/lib/index.ts +21 -0
  167. package/src/lib/keymapping.test.ts +280 -0
  168. package/src/lib/keymapping.ts +87 -0
  169. package/src/lib/objects-in-viewport.test.ts +787 -0
  170. package/src/lib/objects-in-viewport.ts +153 -0
  171. package/src/lib/output.capture.ts +58 -0
  172. package/src/lib/parse.keypress-kitty.protocol.test.ts +340 -0
  173. package/src/lib/parse.keypress-kitty.test.ts +663 -0
  174. package/src/lib/parse.keypress-kitty.ts +439 -0
  175. package/src/lib/parse.keypress.test.ts +1849 -0
  176. package/src/lib/parse.keypress.ts +397 -0
  177. package/src/lib/parse.mouse.test.ts +552 -0
  178. package/src/lib/parse.mouse.ts +232 -0
  179. package/src/lib/paste.ts +16 -0
  180. package/src/lib/queue.ts +65 -0
  181. package/src/lib/renderable.validations.test.ts +87 -0
  182. package/src/lib/renderable.validations.ts +83 -0
  183. package/src/lib/scroll-acceleration.ts +98 -0
  184. package/src/lib/selection.ts +240 -0
  185. package/src/lib/singleton.ts +28 -0
  186. package/src/lib/stdin-parser.test.ts +1676 -0
  187. package/src/lib/stdin-parser.ts +1248 -0
  188. package/src/lib/styled-text.ts +178 -0
  189. package/src/lib/terminal-capability-detection.test.ts +202 -0
  190. package/src/lib/terminal-capability-detection.ts +79 -0
  191. package/src/lib/terminal-palette.test.ts +878 -0
  192. package/src/lib/terminal-palette.ts +383 -0
  193. package/src/lib/tree-sitter/assets/README.md +118 -0
  194. package/src/lib/tree-sitter/assets/update.ts +331 -0
  195. package/src/lib/tree-sitter/assets.d.ts +9 -0
  196. package/src/lib/tree-sitter/cache.test.ts +270 -0
  197. package/src/lib/tree-sitter/client.test.ts +1061 -0
  198. package/src/lib/tree-sitter/client.ts +615 -0
  199. package/src/lib/tree-sitter/default-parsers.ts +80 -0
  200. package/src/lib/tree-sitter/download-utils.ts +148 -0
  201. package/src/lib/tree-sitter/index.ts +28 -0
  202. package/src/lib/tree-sitter/parser.worker.ts +1001 -0
  203. package/src/lib/tree-sitter/parsers-config.ts +75 -0
  204. package/src/lib/tree-sitter/resolve-ft.ts +62 -0
  205. package/src/lib/tree-sitter/types.ts +81 -0
  206. package/src/lib/tree-sitter-styled-text.test.ts +1253 -0
  207. package/src/lib/tree-sitter-styled-text.ts +306 -0
  208. package/src/lib/validate-dir-name.ts +55 -0
  209. package/src/lib/yoga.options.test.ts +628 -0
  210. package/src/lib/yoga.options.ts +346 -0
  211. package/src/plugins/core-slot.ts +579 -0
  212. package/src/plugins/registry.ts +377 -0
  213. package/src/plugins/types.ts +46 -0
  214. package/src/post/filters.ts +888 -0
  215. package/src/renderables/ASCIIFont.ts +219 -0
  216. package/src/renderables/Box.test.ts +160 -0
  217. package/src/renderables/Box.ts +295 -0
  218. package/src/renderables/Code.test.ts +2062 -0
  219. package/src/renderables/Code.ts +357 -0
  220. package/src/renderables/Diff.regression.test.ts +226 -0
  221. package/src/renderables/Diff.test.ts +3027 -0
  222. package/src/renderables/Diff.ts +1209 -0
  223. package/src/renderables/EditBufferRenderable.ts +764 -0
  224. package/src/renderables/FrameBuffer.ts +47 -0
  225. package/src/renderables/Input.test.ts +1228 -0
  226. package/src/renderables/Input.ts +245 -0
  227. package/src/renderables/LineNumberRenderable.ts +675 -0
  228. package/src/renderables/Markdown.ts +1106 -0
  229. package/src/renderables/ScrollBar.ts +422 -0
  230. package/src/renderables/ScrollBox.ts +883 -0
  231. package/src/renderables/Select.test.ts +1010 -0
  232. package/src/renderables/Select.ts +523 -0
  233. package/src/renderables/Slider.test.ts +456 -0
  234. package/src/renderables/Slider.ts +347 -0
  235. package/src/renderables/TabSelect.test.ts +197 -0
  236. package/src/renderables/TabSelect.ts +455 -0
  237. package/src/renderables/Text.selection-buffer.test.ts +123 -0
  238. package/src/renderables/Text.test.ts +2660 -0
  239. package/src/renderables/Text.ts +147 -0
  240. package/src/renderables/TextBufferRenderable.ts +518 -0
  241. package/src/renderables/TextNode.test.ts +1058 -0
  242. package/src/renderables/TextNode.ts +325 -0
  243. package/src/renderables/TextTable.test.ts +1421 -0
  244. package/src/renderables/TextTable.ts +1344 -0
  245. package/src/renderables/Textarea.ts +732 -0
  246. package/src/renderables/TimeToFirstDraw.ts +89 -0
  247. package/src/renderables/__snapshots__/Code.test.ts.snap +13 -0
  248. package/src/renderables/__snapshots__/Diff.test.ts.snap +785 -0
  249. package/src/renderables/__snapshots__/Text.test.ts.snap +421 -0
  250. package/src/renderables/__snapshots__/TextTable.test.ts.snap +215 -0
  251. package/src/renderables/__tests__/LineNumberRenderable.scrollbox-simple.test.ts +144 -0
  252. package/src/renderables/__tests__/LineNumberRenderable.scrollbox.test.ts +816 -0
  253. package/src/renderables/__tests__/LineNumberRenderable.test.ts +1787 -0
  254. package/src/renderables/__tests__/LineNumberRenderable.wrapping.test.ts +85 -0
  255. package/src/renderables/__tests__/Markdown.test.ts +2287 -0
  256. package/src/renderables/__tests__/MultiRenderable.selection.test.ts +87 -0
  257. package/src/renderables/__tests__/Textarea.buffer.test.ts +682 -0
  258. package/src/renderables/__tests__/Textarea.destroyed-events.test.ts +675 -0
  259. package/src/renderables/__tests__/Textarea.editing.test.ts +2041 -0
  260. package/src/renderables/__tests__/Textarea.error-handling.test.ts +35 -0
  261. package/src/renderables/__tests__/Textarea.events.test.ts +738 -0
  262. package/src/renderables/__tests__/Textarea.highlights.test.ts +590 -0
  263. package/src/renderables/__tests__/Textarea.keybinding.test.ts +3149 -0
  264. package/src/renderables/__tests__/Textarea.paste.test.ts +357 -0
  265. package/src/renderables/__tests__/Textarea.rendering.test.ts +1864 -0
  266. package/src/renderables/__tests__/Textarea.scroll.test.ts +733 -0
  267. package/src/renderables/__tests__/Textarea.selection.test.ts +1590 -0
  268. package/src/renderables/__tests__/Textarea.stress.test.ts +670 -0
  269. package/src/renderables/__tests__/Textarea.undo-redo.test.ts +383 -0
  270. package/src/renderables/__tests__/Textarea.visual-lines.test.ts +310 -0
  271. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.code.test.ts.snap +221 -0
  272. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox-simple.test.ts.snap +89 -0
  273. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox.test.ts.snap +457 -0
  274. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.test.ts.snap +158 -0
  275. package/src/renderables/__tests__/__snapshots__/Textarea.rendering.test.ts.snap +387 -0
  276. package/src/renderables/__tests__/markdown-parser.test.ts +217 -0
  277. package/src/renderables/__tests__/renderable-test-utils.ts +60 -0
  278. package/src/renderables/composition/README.md +8 -0
  279. package/src/renderables/composition/VRenderable.ts +32 -0
  280. package/src/renderables/composition/constructs.ts +127 -0
  281. package/src/renderables/composition/vnode.ts +289 -0
  282. package/src/renderables/index.ts +22 -0
  283. package/src/renderables/markdown-parser.ts +66 -0
  284. package/src/renderer.ts +2363 -0
  285. package/src/runtime-plugin-support.ts +39 -0
  286. package/src/runtime-plugin.ts +144 -0
  287. package/src/syntax-style.test.ts +841 -0
  288. package/src/syntax-style.ts +264 -0
  289. package/src/testing/README.md +210 -0
  290. package/src/testing/capture-spans.test.ts +194 -0
  291. package/src/testing/integration.test.ts +276 -0
  292. package/src/testing/manual-clock.ts +106 -0
  293. package/src/testing/mock-keys.test.ts +1356 -0
  294. package/src/testing/mock-keys.ts +449 -0
  295. package/src/testing/mock-mouse.test.ts +218 -0
  296. package/src/testing/mock-mouse.ts +247 -0
  297. package/src/testing/mock-tree-sitter-client.ts +73 -0
  298. package/src/testing/spy.ts +13 -0
  299. package/src/testing/test-recorder.test.ts +415 -0
  300. package/src/testing/test-recorder.ts +145 -0
  301. package/src/testing/test-renderer.ts +116 -0
  302. package/src/testing.ts +7 -0
  303. package/src/tests/__snapshots__/absolute-positioning.snapshot.test.ts.snap +481 -0
  304. package/src/tests/__snapshots__/renderable.snapshot.test.ts.snap +19 -0
  305. package/src/tests/__snapshots__/scrollbox.test.ts.snap +29 -0
  306. package/src/tests/absolute-positioning.snapshot.test.ts +638 -0
  307. package/src/tests/allocator-stats.test.ts +38 -0
  308. package/src/tests/destroy-during-render.test.ts +200 -0
  309. package/src/tests/hover-cursor.test.ts +98 -0
  310. package/src/tests/native-span-feed-async.test.ts +173 -0
  311. package/src/tests/native-span-feed-close.test.ts +120 -0
  312. package/src/tests/native-span-feed-coverage.test.ts +227 -0
  313. package/src/tests/native-span-feed-edge-cases.test.ts +352 -0
  314. package/src/tests/native-span-feed-use-after-free.test.ts +45 -0
  315. package/src/tests/opacity.test.ts +123 -0
  316. package/src/tests/renderable.snapshot.test.ts +524 -0
  317. package/src/tests/renderable.test.ts +1281 -0
  318. package/src/tests/renderer.console-startup.test.ts +65 -0
  319. package/src/tests/renderer.control.test.ts +364 -0
  320. package/src/tests/renderer.core-slot-binding.test.ts +952 -0
  321. package/src/tests/renderer.cursor.test.ts +26 -0
  322. package/src/tests/renderer.destroy-during-render.test.ts +110 -0
  323. package/src/tests/renderer.focus-restore.test.ts +228 -0
  324. package/src/tests/renderer.focus.test.ts +251 -0
  325. package/src/tests/renderer.idle.test.ts +219 -0
  326. package/src/tests/renderer.input.test.ts +2145 -0
  327. package/src/tests/renderer.kitty-flags.test.ts +195 -0
  328. package/src/tests/renderer.mouse.test.ts +1269 -0
  329. package/src/tests/renderer.palette.test.ts +629 -0
  330. package/src/tests/renderer.selection.test.ts +49 -0
  331. package/src/tests/renderer.slot-registry.test.ts +649 -0
  332. package/src/tests/renderer.useMouse.test.ts +50 -0
  333. package/src/tests/runtime-plugin-support.fixture.ts +11 -0
  334. package/src/tests/runtime-plugin-support.test.ts +28 -0
  335. package/src/tests/runtime-plugin.fixture.ts +40 -0
  336. package/src/tests/runtime-plugin.test.ts +190 -0
  337. package/src/tests/scrollbox-culling-bug.test.ts +114 -0
  338. package/src/tests/scrollbox-hitgrid-resize.test.ts +136 -0
  339. package/src/tests/scrollbox-hitgrid.test.ts +909 -0
  340. package/src/tests/scrollbox.test.ts +1530 -0
  341. package/src/tests/wrap-resize-perf.test.ts +229 -0
  342. package/src/tests/yoga-setters.test.ts +921 -0
  343. package/src/text-buffer-view.test.ts +705 -0
  344. package/src/text-buffer-view.ts +189 -0
  345. package/src/text-buffer.test.ts +347 -0
  346. package/src/text-buffer.ts +250 -0
  347. package/src/types.ts +152 -0
  348. package/src/utils.ts +88 -0
  349. package/src/zig/ansi.zig +268 -0
  350. package/src/zig/bench/README.md +50 -0
  351. package/src/zig/bench/buffer-draw-text-buffer_bench.zig +887 -0
  352. package/src/zig/bench/edit-buffer_bench.zig +476 -0
  353. package/src/zig/bench/native-span-feed_bench.zig +100 -0
  354. package/src/zig/bench/rope-markers_bench.zig +713 -0
  355. package/src/zig/bench/rope_bench.zig +514 -0
  356. package/src/zig/bench/styled-text_bench.zig +470 -0
  357. package/src/zig/bench/text-buffer-coords_bench.zig +362 -0
  358. package/src/zig/bench/text-buffer-view_bench.zig +459 -0
  359. package/src/zig/bench/text-chunk-graphemes_bench.zig +273 -0
  360. package/src/zig/bench/utf8_bench.zig +799 -0
  361. package/src/zig/bench-utils.zig +431 -0
  362. package/src/zig/bench.zig +217 -0
  363. package/src/zig/buffer.zig +2223 -0
  364. package/src/zig/build.zig +289 -0
  365. package/src/zig/build.zig.zon +16 -0
  366. package/src/zig/edit-buffer.zig +825 -0
  367. package/src/zig/editor-view.zig +802 -0
  368. package/src/zig/event-bus.zig +13 -0
  369. package/src/zig/event-emitter.zig +65 -0
  370. package/src/zig/file-logger.zig +92 -0
  371. package/src/zig/grapheme.zig +599 -0
  372. package/src/zig/lib.zig +1834 -0
  373. package/src/zig/link.zig +333 -0
  374. package/src/zig/logger.zig +43 -0
  375. package/src/zig/mem-registry.zig +125 -0
  376. package/src/zig/native-span-feed-bench-lib.zig +7 -0
  377. package/src/zig/native-span-feed.zig +708 -0
  378. package/src/zig/renderer.zig +1386 -0
  379. package/src/zig/rope.zig +1220 -0
  380. package/src/zig/syntax-style.zig +161 -0
  381. package/src/zig/terminal.zig +975 -0
  382. package/src/zig/test.zig +70 -0
  383. package/src/zig/tests/README.md +18 -0
  384. package/src/zig/tests/buffer_test.zig +2526 -0
  385. package/src/zig/tests/edit-buffer-history_test.zig +271 -0
  386. package/src/zig/tests/edit-buffer_test.zig +1689 -0
  387. package/src/zig/tests/editor-view_test.zig +3299 -0
  388. package/src/zig/tests/event-emitter_test.zig +249 -0
  389. package/src/zig/tests/grapheme_test.zig +1304 -0
  390. package/src/zig/tests/link_test.zig +190 -0
  391. package/src/zig/tests/mem-registry_test.zig +473 -0
  392. package/src/zig/tests/memory_leak_regression_test.zig +159 -0
  393. package/src/zig/tests/native-span-feed_test.zig +1264 -0
  394. package/src/zig/tests/renderer_test.zig +1010 -0
  395. package/src/zig/tests/rope-nested_test.zig +712 -0
  396. package/src/zig/tests/rope_fuzz_test.zig +238 -0
  397. package/src/zig/tests/rope_test.zig +2362 -0
  398. package/src/zig/tests/segment-merge.test.zig +148 -0
  399. package/src/zig/tests/syntax-style_test.zig +557 -0
  400. package/src/zig/tests/terminal_test.zig +719 -0
  401. package/src/zig/tests/text-buffer-drawing_test.zig +3237 -0
  402. package/src/zig/tests/text-buffer-highlights_test.zig +666 -0
  403. package/src/zig/tests/text-buffer-iterators_test.zig +776 -0
  404. package/src/zig/tests/text-buffer-segment_test.zig +320 -0
  405. package/src/zig/tests/text-buffer-selection_test.zig +1035 -0
  406. package/src/zig/tests/text-buffer-selection_viewport_test.zig +358 -0
  407. package/src/zig/tests/text-buffer-view_test.zig +3649 -0
  408. package/src/zig/tests/text-buffer_test.zig +2191 -0
  409. package/src/zig/tests/unicode-width-map.zon +3909 -0
  410. package/src/zig/tests/utf8_no_zwj_test.zig +260 -0
  411. package/src/zig/tests/utf8_test.zig +4057 -0
  412. package/src/zig/tests/utf8_wcwidth_cursor_test.zig +267 -0
  413. package/src/zig/tests/utf8_wcwidth_test.zig +357 -0
  414. package/src/zig/tests/word-wrap-editing_test.zig +498 -0
  415. package/src/zig/tests/wrap-cache-perf_test.zig +113 -0
  416. package/src/zig/text-buffer-iterators.zig +499 -0
  417. package/src/zig/text-buffer-segment.zig +404 -0
  418. package/src/zig/text-buffer-view.zig +1371 -0
  419. package/src/zig/text-buffer.zig +1180 -0
  420. package/src/zig/utf8.zig +1948 -0
  421. package/src/zig/utils.zig +9 -0
  422. package/src/zig-structs.ts +261 -0
  423. package/src/zig.ts +3843 -0
  424. package/tsconfig.build.json +22 -0
  425. package/tsconfig.json +28 -0
  426. package/3d/SpriteResourceManager.d.ts +0 -74
  427. package/3d/SpriteUtils.d.ts +0 -13
  428. package/3d/TextureUtils.d.ts +0 -24
  429. package/3d/ThreeRenderable.d.ts +0 -40
  430. package/3d/WGPURenderer.d.ts +0 -61
  431. package/3d/animation/ExplodingSpriteEffect.d.ts +0 -71
  432. package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +0 -76
  433. package/3d/animation/SpriteAnimator.d.ts +0 -124
  434. package/3d/animation/SpriteParticleGenerator.d.ts +0 -62
  435. package/3d/canvas.d.ts +0 -44
  436. package/3d/index.d.ts +0 -12
  437. package/3d/physics/PlanckPhysicsAdapter.d.ts +0 -19
  438. package/3d/physics/RapierPhysicsAdapter.d.ts +0 -19
  439. package/3d/physics/physics-interface.d.ts +0 -27
  440. package/3d.d.ts +0 -2
  441. package/3d.js +0 -34042
  442. package/3d.js.map +0 -155
  443. package/LICENSE +0 -21
  444. package/NativeSpanFeed.d.ts +0 -41
  445. package/Renderable.d.ts +0 -334
  446. package/animation/Timeline.d.ts +0 -126
  447. package/ansi.d.ts +0 -13
  448. package/buffer.d.ts +0 -107
  449. package/console.d.ts +0 -143
  450. package/edit-buffer.d.ts +0 -98
  451. package/editor-view.d.ts +0 -73
  452. package/index-e4hzc2j2.js +0 -113
  453. package/index-e4hzc2j2.js.map +0 -10
  454. package/index-nkrr8a4c.js +0 -18415
  455. package/index-nkrr8a4c.js.map +0 -64
  456. package/index-nyw5p3ep.js +0 -12619
  457. package/index-nyw5p3ep.js.map +0 -43
  458. package/index.d.ts +0 -21
  459. package/index.js +0 -430
  460. package/index.js.map +0 -9
  461. package/lib/KeyHandler.d.ts +0 -61
  462. package/lib/RGBA.d.ts +0 -25
  463. package/lib/ascii.font.d.ts +0 -508
  464. package/lib/border.d.ts +0 -49
  465. package/lib/bunfs.d.ts +0 -7
  466. package/lib/clipboard.d.ts +0 -17
  467. package/lib/clock.d.ts +0 -15
  468. package/lib/data-paths.d.ts +0 -26
  469. package/lib/debounce.d.ts +0 -42
  470. package/lib/detect-links.d.ts +0 -6
  471. package/lib/env.d.ts +0 -42
  472. package/lib/extmarks-history.d.ts +0 -17
  473. package/lib/extmarks.d.ts +0 -89
  474. package/lib/hast-styled-text.d.ts +0 -17
  475. package/lib/index.d.ts +0 -21
  476. package/lib/keymapping.d.ts +0 -25
  477. package/lib/objects-in-viewport.d.ts +0 -24
  478. package/lib/output.capture.d.ts +0 -24
  479. package/lib/parse.keypress-kitty.d.ts +0 -2
  480. package/lib/parse.keypress.d.ts +0 -26
  481. package/lib/parse.mouse.d.ts +0 -30
  482. package/lib/paste.d.ts +0 -7
  483. package/lib/queue.d.ts +0 -15
  484. package/lib/renderable.validations.d.ts +0 -12
  485. package/lib/scroll-acceleration.d.ts +0 -43
  486. package/lib/selection.d.ts +0 -63
  487. package/lib/singleton.d.ts +0 -7
  488. package/lib/stdin-parser.d.ts +0 -76
  489. package/lib/styled-text.d.ts +0 -63
  490. package/lib/terminal-capability-detection.d.ts +0 -30
  491. package/lib/terminal-palette.d.ts +0 -50
  492. package/lib/tree-sitter/assets/update.d.ts +0 -11
  493. package/lib/tree-sitter/client.d.ts +0 -47
  494. package/lib/tree-sitter/default-parsers.d.ts +0 -2
  495. package/lib/tree-sitter/download-utils.d.ts +0 -21
  496. package/lib/tree-sitter/index.d.ts +0 -8
  497. package/lib/tree-sitter/parser.worker.d.ts +0 -1
  498. package/lib/tree-sitter/parsers-config.d.ts +0 -38
  499. package/lib/tree-sitter/resolve-ft.d.ts +0 -2
  500. package/lib/tree-sitter/types.d.ts +0 -81
  501. package/lib/tree-sitter-styled-text.d.ts +0 -14
  502. package/lib/validate-dir-name.d.ts +0 -1
  503. package/lib/yoga.options.d.ts +0 -32
  504. package/parser.worker.js +0 -869
  505. package/parser.worker.js.map +0 -12
  506. package/plugins/core-slot.d.ts +0 -72
  507. package/plugins/registry.d.ts +0 -38
  508. package/plugins/types.d.ts +0 -34
  509. package/post/filters.d.ts +0 -105
  510. package/renderables/ASCIIFont.d.ts +0 -52
  511. package/renderables/Box.d.ts +0 -72
  512. package/renderables/Code.d.ts +0 -78
  513. package/renderables/Diff.d.ts +0 -142
  514. package/renderables/EditBufferRenderable.d.ts +0 -162
  515. package/renderables/FrameBuffer.d.ts +0 -16
  516. package/renderables/Input.d.ts +0 -67
  517. package/renderables/LineNumberRenderable.d.ts +0 -74
  518. package/renderables/Markdown.d.ts +0 -173
  519. package/renderables/ScrollBar.d.ts +0 -77
  520. package/renderables/ScrollBox.d.ts +0 -124
  521. package/renderables/Select.d.ts +0 -115
  522. package/renderables/Slider.d.ts +0 -44
  523. package/renderables/TabSelect.d.ts +0 -96
  524. package/renderables/Text.d.ts +0 -36
  525. package/renderables/TextBufferRenderable.d.ts +0 -105
  526. package/renderables/TextNode.d.ts +0 -91
  527. package/renderables/TextTable.d.ts +0 -140
  528. package/renderables/Textarea.d.ts +0 -114
  529. package/renderables/TimeToFirstDraw.d.ts +0 -24
  530. package/renderables/__tests__/renderable-test-utils.d.ts +0 -12
  531. package/renderables/composition/VRenderable.d.ts +0 -16
  532. package/renderables/composition/constructs.d.ts +0 -35
  533. package/renderables/composition/vnode.d.ts +0 -46
  534. package/renderables/index.d.ts +0 -22
  535. package/renderables/markdown-parser.d.ts +0 -10
  536. package/renderer.d.ts +0 -388
  537. package/runtime-plugin-support.d.ts +0 -3
  538. package/runtime-plugin-support.js +0 -29
  539. package/runtime-plugin-support.js.map +0 -10
  540. package/runtime-plugin.d.ts +0 -11
  541. package/runtime-plugin.js +0 -16
  542. package/runtime-plugin.js.map +0 -9
  543. package/syntax-style.d.ts +0 -54
  544. package/testing/manual-clock.d.ts +0 -16
  545. package/testing/mock-keys.d.ts +0 -81
  546. package/testing/mock-mouse.d.ts +0 -38
  547. package/testing/mock-tree-sitter-client.d.ts +0 -23
  548. package/testing/spy.d.ts +0 -7
  549. package/testing/test-recorder.d.ts +0 -61
  550. package/testing/test-renderer.d.ts +0 -23
  551. package/testing.d.ts +0 -6
  552. package/testing.js +0 -675
  553. package/testing.js.map +0 -15
  554. package/text-buffer-view.d.ts +0 -42
  555. package/text-buffer.d.ts +0 -67
  556. package/types.d.ts +0 -131
  557. package/utils.d.ts +0 -14
  558. package/zig-structs.d.ts +0 -155
  559. package/zig.d.ts +0 -351
  560. /package/{assets → src/lib/tree-sitter/assets}/javascript/highlights.scm +0 -0
  561. /package/{assets → src/lib/tree-sitter/assets}/javascript/tree-sitter-javascript.wasm +0 -0
  562. /package/{assets → src/lib/tree-sitter/assets}/markdown/highlights.scm +0 -0
  563. /package/{assets → src/lib/tree-sitter/assets}/markdown/injections.scm +0 -0
  564. /package/{assets → src/lib/tree-sitter/assets}/markdown/tree-sitter-markdown.wasm +0 -0
  565. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/highlights.scm +0 -0
  566. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
  567. /package/{assets → src/lib/tree-sitter/assets}/typescript/highlights.scm +0 -0
  568. /package/{assets → src/lib/tree-sitter/assets}/typescript/tree-sitter-typescript.wasm +0 -0
  569. /package/{assets → src/lib/tree-sitter/assets}/zig/highlights.scm +0 -0
  570. /package/{assets → src/lib/tree-sitter/assets}/zig/tree-sitter-zig.wasm +0 -0
@@ -0,0 +1,331 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { readFile, writeFile, mkdir } from "fs/promises"
4
+ import * as path from "path"
5
+ import { DownloadUtils } from "../download-utils.js"
6
+ import { parseArgs } from "util"
7
+ import type { FiletypeParserOptions } from "../types.js"
8
+ import { readdir } from "fs/promises"
9
+
10
+ interface ParsersConfig {
11
+ parsers: FiletypeParserOptions[]
12
+ }
13
+
14
+ interface GeneratedParser {
15
+ filetype: string
16
+ languagePath: string
17
+ highlightsPath: string
18
+ injectionsPath?: string
19
+ injectionMapping?: any
20
+ }
21
+
22
+ export interface UpdateOptions {
23
+ /** Path to parsers-config.json */
24
+ configPath: string
25
+ /** Directory where .wasm and .scm files will be downloaded */
26
+ assetsDir: string
27
+ /** Path where the generated TypeScript file will be written */
28
+ outputPath: string
29
+ }
30
+
31
+ function getDefaultOptions(): UpdateOptions {
32
+ return {
33
+ configPath: path.resolve(__dirname, "../parsers-config"),
34
+ assetsDir: path.resolve(__dirname),
35
+ outputPath: path.resolve(__dirname, "../default-parsers.ts"),
36
+ }
37
+ }
38
+
39
+ async function loadConfig(configPath: string): Promise<ParsersConfig> {
40
+ let ext = path.extname(configPath)
41
+ let resolvedConfigPath = configPath
42
+
43
+ if (ext === "") {
44
+ const files = await readdir(path.dirname(configPath))
45
+ const file = files.find(
46
+ (file) =>
47
+ file.startsWith(path.basename(configPath)) &&
48
+ (file.endsWith(".json") || file.endsWith(".ts") || file.endsWith(".js")),
49
+ )
50
+ if (!file) {
51
+ throw new Error(`No config file found for ${configPath}`)
52
+ }
53
+ resolvedConfigPath = path.join(path.dirname(configPath), file)
54
+ ext = path.extname(resolvedConfigPath)
55
+ }
56
+
57
+ if (ext === ".json") {
58
+ const configContent = await readFile(resolvedConfigPath, "utf-8")
59
+ return JSON.parse(configContent)
60
+ } else if (ext === ".ts" || ext === ".js") {
61
+ const { default: configContent } = await import(resolvedConfigPath)
62
+ return configContent
63
+ }
64
+ throw new Error(`Unsupported config file extension: ${ext}`)
65
+ }
66
+
67
+ async function downloadLanguage(
68
+ filetype: string,
69
+ languageUrl: string,
70
+ assetsDir: string,
71
+ outputPath: string,
72
+ ): Promise<string> {
73
+ const languageDir = path.join(assetsDir, filetype)
74
+ const languageFilename = path.basename(languageUrl)
75
+ const languagePath = path.join(languageDir, languageFilename)
76
+
77
+ const result = await DownloadUtils.downloadToPath(languageUrl, languagePath)
78
+
79
+ if (result.error) {
80
+ throw new Error(`Failed to download language for ${filetype}: ${result.error}`)
81
+ }
82
+
83
+ return "./" + path.relative(path.dirname(outputPath), languagePath)
84
+ }
85
+
86
+ async function downloadAndCombineQueries(
87
+ filetype: string,
88
+ queryUrls: string[],
89
+ assetsDir: string,
90
+ outputPath: string,
91
+ queryType: "highlights" | "injections",
92
+ configPath: string,
93
+ ): Promise<string> {
94
+ const queriesDir = path.join(assetsDir, filetype)
95
+ const queryPath = path.join(queriesDir, `${queryType}.scm`)
96
+
97
+ const queryContents: string[] = []
98
+
99
+ for (let i = 0; i < queryUrls.length; i++) {
100
+ const queryUrl = queryUrls[i]
101
+
102
+ if (queryUrl.startsWith("./")) {
103
+ console.log(` Using local query ${i + 1}/${queryUrls.length}: ${queryUrl}`)
104
+
105
+ try {
106
+ const localPath = path.resolve(path.dirname(configPath), queryUrl)
107
+ const content = await readFile(localPath, "utf-8")
108
+
109
+ if (content.trim()) {
110
+ queryContents.push(content)
111
+ console.log(` ✓ Loaded ${content.split("\n").length} lines from local file`)
112
+ }
113
+ } catch (error) {
114
+ console.warn(`Failed to read local query from ${queryUrl}: ${error}`)
115
+ continue
116
+ }
117
+ } else {
118
+ console.log(` Downloading query ${i + 1}/${queryUrls.length}: ${queryUrl}`)
119
+
120
+ try {
121
+ const response = await fetch(queryUrl)
122
+ if (!response.ok) {
123
+ console.warn(`Failed to download query from ${queryUrl}: ${response.statusText}`)
124
+ continue
125
+ }
126
+
127
+ const content = await response.text()
128
+ if (content.trim()) {
129
+ queryContents.push(`; Query from: ${queryUrl}\n${content}`)
130
+ console.log(` ✓ Downloaded ${content.split("\n").length} lines`)
131
+ }
132
+ } catch (error) {
133
+ console.warn(`Failed to download query from ${queryUrl}: ${error}`)
134
+ continue
135
+ }
136
+ }
137
+ }
138
+
139
+ const combinedContent = queryContents.join("\n\n")
140
+ await writeFile(queryPath, combinedContent, "utf-8")
141
+
142
+ console.log(` Combined ${queryContents.length} queries into ${queryPath}`)
143
+
144
+ return "./" + path.relative(path.dirname(outputPath), queryPath)
145
+ }
146
+
147
+ async function generateDefaultParsersFile(parsers: GeneratedParser[], outputPath: string): Promise<void> {
148
+ const imports = parsers
149
+ .map((parser) => {
150
+ const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_")
151
+ const lines = [
152
+ `import ${safeFiletype}_highlights from "${parser.highlightsPath}" with { type: "file" }`,
153
+ `import ${safeFiletype}_language from "${parser.languagePath}" with { type: "file" }`,
154
+ ]
155
+ if (parser.injectionsPath) {
156
+ lines.push(`import ${safeFiletype}_injections from "${parser.injectionsPath}" with { type: "file" }`)
157
+ }
158
+ return lines.join("\n")
159
+ })
160
+ .join("\n")
161
+
162
+ const parserDefinitions = parsers
163
+ .map((parser) => {
164
+ const safeFiletype = parser.filetype.replace(/[^a-zA-Z0-9]/g, "_")
165
+ const queriesLines = [
166
+ ` highlights: [resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_highlights)],`,
167
+ ]
168
+ if (parser.injectionsPath) {
169
+ queriesLines.push(
170
+ ` injections: [resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_injections)],`,
171
+ )
172
+ }
173
+
174
+ const injectionMappingLine = parser.injectionMapping
175
+ ? ` injectionMapping: ${JSON.stringify(parser.injectionMapping, null, 10)},`
176
+ : ""
177
+
178
+ return ` {
179
+ filetype: "${parser.filetype}",
180
+ queries: {
181
+ ${queriesLines.join("\n")}
182
+ },
183
+ wasm: resolve(dirname(fileURLToPath(import.meta.url)), ${safeFiletype}_language),${injectionMappingLine ? "\n" + injectionMappingLine : ""}
184
+ }`
185
+ })
186
+ .join(",\n")
187
+
188
+ const fileContent = `// This file is generated by assets/update.ts - DO NOT EDIT MANUALLY
189
+ // Run 'bun assets/update.ts' to regenerate this file
190
+ // Last generated: ${new Date().toISOString()}
191
+
192
+ import type { FiletypeParserOptions } from "./types"
193
+ import { resolve, dirname } from "path"
194
+ import { fileURLToPath } from "url"
195
+
196
+ ${imports}
197
+
198
+ // Cached parsers to avoid re-resolving paths on every call
199
+ let _cachedParsers: FiletypeParserOptions[] | undefined
200
+
201
+ export function getParsers(): FiletypeParserOptions[] {
202
+ if (!_cachedParsers) {
203
+ _cachedParsers = [
204
+ ${parserDefinitions},
205
+ ]
206
+ }
207
+ return _cachedParsers
208
+ }
209
+ `
210
+
211
+ await mkdir(path.dirname(outputPath), { recursive: true })
212
+ await writeFile(outputPath, fileContent, "utf-8")
213
+ console.log(`Generated ${path.basename(outputPath)} with ${parsers.length} parsers`)
214
+ }
215
+
216
+ async function main(options?: Partial<UpdateOptions>): Promise<void> {
217
+ const opts = { ...getDefaultOptions(), ...options }
218
+
219
+ try {
220
+ console.log("Loading parsers configuration...")
221
+ console.log(` Config: ${opts.configPath}`)
222
+ console.log(` Assets Dir: ${opts.assetsDir}`)
223
+ console.log(` Output: ${opts.outputPath}`)
224
+
225
+ const config = await loadConfig(opts.configPath)
226
+
227
+ console.log(`Found ${config.parsers.length} parsers to process`)
228
+
229
+ const generatedParsers: GeneratedParser[] = []
230
+
231
+ for (const parser of config.parsers) {
232
+ console.log(`Processing ${parser.filetype}...`)
233
+
234
+ console.log(` Downloading language...`)
235
+ const languagePath = await downloadLanguage(parser.filetype, parser.wasm, opts.assetsDir, opts.outputPath)
236
+
237
+ console.log(` Downloading ${parser.queries.highlights.length} highlight queries...`)
238
+ const highlightsPath = await downloadAndCombineQueries(
239
+ parser.filetype,
240
+ parser.queries.highlights,
241
+ opts.assetsDir,
242
+ opts.outputPath,
243
+ "highlights",
244
+ opts.configPath,
245
+ )
246
+
247
+ let injectionsPath: string | undefined
248
+ if (parser.queries.injections && parser.queries.injections.length > 0) {
249
+ console.log(` Downloading ${parser.queries.injections.length} injection queries...`)
250
+ injectionsPath = await downloadAndCombineQueries(
251
+ parser.filetype,
252
+ parser.queries.injections,
253
+ opts.assetsDir,
254
+ opts.outputPath,
255
+ "injections",
256
+ opts.configPath,
257
+ )
258
+ }
259
+
260
+ generatedParsers.push({
261
+ filetype: parser.filetype,
262
+ languagePath,
263
+ highlightsPath,
264
+ injectionsPath,
265
+ injectionMapping: parser.injectionMapping,
266
+ })
267
+
268
+ console.log(` ✓ Completed ${parser.filetype}`)
269
+ }
270
+
271
+ console.log("Generating output file...")
272
+ await generateDefaultParsersFile(generatedParsers, opts.outputPath)
273
+
274
+ console.log("✅ Update completed successfully!")
275
+ } catch (error) {
276
+ console.error("❌ Update failed:", error)
277
+ process.exit(1)
278
+ }
279
+ }
280
+
281
+ function parseCLIArgs(): Partial<UpdateOptions> | null {
282
+ try {
283
+ const { values } = parseArgs({
284
+ args: Bun.argv.slice(2),
285
+ options: {
286
+ config: { type: "string" },
287
+ assets: { type: "string" },
288
+ output: { type: "string" },
289
+ help: { type: "boolean" },
290
+ },
291
+ strict: true,
292
+ })
293
+
294
+ if (values.help) {
295
+ console.log(`Usage: bun update.ts [options]
296
+
297
+ Options:
298
+ --config <path> Path to parsers-config.json
299
+ --assets <path> Directory where .wasm and .scm files will be downloaded
300
+ --output <path> Path where the generated TypeScript file will be written
301
+ --help Show this help message
302
+
303
+ Examples:
304
+ # Use default paths (for OpenTUI core development)
305
+ bun update.ts
306
+
307
+ # Use custom paths (for application integration)
308
+ bun update.ts --config ./my-parsers.json --assets ./src/parsers --output ./src/parsers.ts
309
+ `)
310
+ process.exit(0)
311
+ }
312
+
313
+ const options: Partial<UpdateOptions> = {}
314
+ if (values.config) options.configPath = path.resolve(values.config)
315
+ if (values.assets) options.assetsDir = path.resolve(values.assets)
316
+ if (values.output) options.outputPath = path.resolve(values.output)
317
+
318
+ return Object.keys(options).length > 0 ? options : null
319
+ } catch (error) {
320
+ console.error(`Error parsing arguments: ${error}`)
321
+ console.log("Run with --help for usage information")
322
+ process.exit(1)
323
+ }
324
+ }
325
+
326
+ if (import.meta.main) {
327
+ const cliOptions = parseCLIArgs()
328
+ main(cliOptions || undefined)
329
+ }
330
+
331
+ export { main as updateAssets }
@@ -0,0 +1,9 @@
1
+ declare module "*.scm" {
2
+ const value: string
3
+ export default value
4
+ }
5
+
6
+ declare module "*.wasm" {
7
+ const value: string
8
+ export default value
9
+ }
@@ -0,0 +1,270 @@
1
+ import { test, expect, beforeEach, beforeAll, afterAll, describe } from "bun:test"
2
+ import { TreeSitterClient, addDefaultParsers } from "./client.js"
3
+ import { tmpdir } from "node:os"
4
+ import { join, resolve } from "node:path"
5
+ import { mkdir, readdir, stat } from "node:fs/promises"
6
+ import { readFileSync } from "node:fs"
7
+ import type { FiletypeParserOptions } from "./types.js"
8
+
9
+ describe("TreeSitterClient Caching", () => {
10
+ let dataPath: string
11
+ let testServer: any
12
+ const TEST_PORT = 55231
13
+ const BASE_URL = `http://localhost:${TEST_PORT}`
14
+
15
+ beforeAll(async () => {
16
+ const assetsDir = resolve(__dirname, "assets")
17
+ testServer = Bun.serve({
18
+ port: TEST_PORT,
19
+ fetch(req) {
20
+ const url = new URL(req.url)
21
+ const filePath = join(assetsDir, url.pathname)
22
+ return new Response(readFileSync(filePath))
23
+ },
24
+ })
25
+ })
26
+
27
+ afterAll(async () => {
28
+ if (testServer) {
29
+ testServer.stop()
30
+ }
31
+ })
32
+
33
+ beforeEach(async () => {
34
+ dataPath = join(tmpdir(), "tree-sitter-cache-test-" + Math.random().toString(36).slice(2))
35
+ await mkdir(dataPath, { recursive: true })
36
+ })
37
+
38
+ test("should create storage directories on initialization", async () => {
39
+ const client = new TreeSitterClient({ dataPath })
40
+ await client.initialize()
41
+
42
+ const languagesDir = join(dataPath, "tree-sitter", "languages")
43
+ const queriesDir = join(dataPath, "tree-sitter", "queries")
44
+
45
+ const languagesStat = await stat(languagesDir)
46
+ const queriesStat = await stat(queriesDir)
47
+
48
+ expect(languagesStat.isDirectory()).toBe(true)
49
+ expect(queriesStat.isDirectory()).toBe(true)
50
+
51
+ await client.destroy()
52
+ })
53
+
54
+ test("should cache downloaded language files", async () => {
55
+ const client = new TreeSitterClient({ dataPath })
56
+ await client.initialize()
57
+
58
+ // Add URL-based parser for this test
59
+ client.addFiletypeParser({
60
+ filetype: "javascript",
61
+ queries: {
62
+ highlights: [`${BASE_URL}/javascript/highlights.scm`],
63
+ },
64
+ wasm: `${BASE_URL}/javascript/tree-sitter-javascript.wasm`,
65
+ })
66
+
67
+ const hasParser = await client.preloadParser("javascript")
68
+ expect(hasParser).toBe(true)
69
+
70
+ const languagesDir = join(dataPath, "tree-sitter", "languages")
71
+ const cachedFiles = await readdir(languagesDir)
72
+
73
+ expect(cachedFiles).toContain("tree-sitter-javascript.wasm")
74
+
75
+ await client.destroy()
76
+ })
77
+
78
+ test("should cache downloaded highlight queries", async () => {
79
+ const client = new TreeSitterClient({ dataPath })
80
+ await client.initialize()
81
+
82
+ // Add URL-based parser for this test
83
+ client.addFiletypeParser({
84
+ filetype: "javascript",
85
+ queries: {
86
+ highlights: [`${BASE_URL}/javascript/highlights.scm`],
87
+ },
88
+ wasm: `${BASE_URL}/javascript/tree-sitter-javascript.wasm`,
89
+ })
90
+
91
+ const hasParser = await client.preloadParser("javascript")
92
+ expect(hasParser).toBe(true)
93
+
94
+ const queriesDir = join(dataPath, "tree-sitter", "queries")
95
+ const cachedQueries = await readdir(queriesDir)
96
+
97
+ const scmFiles = cachedQueries.filter((file) => file.endsWith(".scm"))
98
+ expect(scmFiles.length).toBeGreaterThan(0)
99
+
100
+ await client.destroy()
101
+ })
102
+
103
+ // TODO: This is flaky, there must be a more reliable way to test this
104
+ test.skip("should reuse cached files across client instances", async () => {
105
+ const jsParser: FiletypeParserOptions = {
106
+ filetype: "javascript",
107
+ queries: {
108
+ highlights: [`${BASE_URL}/javascript/highlights.scm`],
109
+ },
110
+ wasm: `${BASE_URL}/javascript/tree-sitter-javascript.wasm`,
111
+ }
112
+
113
+ let client1 = new TreeSitterClient({ dataPath })
114
+ await client1.initialize()
115
+ client1.addFiletypeParser(jsParser)
116
+
117
+ console.log("=== First client (should download) ===")
118
+ const start1 = Date.now()
119
+ const hasParser1 = await client1.preloadParser("javascript")
120
+ const duration1 = Date.now() - start1
121
+ expect(hasParser1).toBe(true)
122
+
123
+ await client1.destroy()
124
+
125
+ let client2 = new TreeSitterClient({ dataPath })
126
+ await client2.initialize()
127
+ client2.addFiletypeParser(jsParser)
128
+
129
+ console.log("=== Second client (should use cache) ===")
130
+ const start2 = Date.now()
131
+ const hasParser2 = await client2.preloadParser("javascript")
132
+ const duration2 = Date.now() - start2
133
+ expect(hasParser2).toBe(true)
134
+
135
+ console.log(`First client: ${duration1}ms, Second client: ${duration2}ms`)
136
+
137
+ expect(duration2).toBeLessThanOrEqual(duration1)
138
+ expect(duration2).toBeLessThan(100) // Should be very fast with cache
139
+
140
+ await client2.destroy()
141
+ })
142
+
143
+ test("should handle multiple parsers with independent caching", async () => {
144
+ const client = new TreeSitterClient({ dataPath })
145
+ await client.initialize()
146
+
147
+ // Add URL-based parsers for this test
148
+ client.addFiletypeParser({
149
+ filetype: "javascript",
150
+ queries: {
151
+ highlights: [`${BASE_URL}/javascript/highlights.scm`],
152
+ },
153
+ wasm: `${BASE_URL}/javascript/tree-sitter-javascript.wasm`,
154
+ })
155
+ client.addFiletypeParser({
156
+ filetype: "typescript",
157
+ queries: {
158
+ highlights: [`${BASE_URL}/typescript/highlights.scm`],
159
+ },
160
+ wasm: `${BASE_URL}/typescript/tree-sitter-typescript.wasm`,
161
+ })
162
+
163
+ const hasJS = await client.preloadParser("javascript")
164
+ const hasTS = await client.preloadParser("typescript")
165
+
166
+ expect(hasJS).toBe(true)
167
+ expect(hasTS).toBe(true)
168
+
169
+ const languagesDir = join(dataPath, "tree-sitter", "languages")
170
+ const cachedFiles = await readdir(languagesDir)
171
+
172
+ expect(cachedFiles).toContain("tree-sitter-javascript.wasm")
173
+ expect(cachedFiles).toContain("tree-sitter-typescript.wasm")
174
+
175
+ const queriesDir = join(dataPath, "tree-sitter", "queries")
176
+ const cachedQueries = await readdir(queriesDir)
177
+ const scmFiles = cachedQueries.filter((file) => file.endsWith(".scm"))
178
+
179
+ expect(scmFiles.length).toBe(2)
180
+
181
+ await client.destroy()
182
+ })
183
+
184
+ test("should store files in dataPath subdirectories", async () => {
185
+ const client = new TreeSitterClient({ dataPath })
186
+ await client.initialize()
187
+
188
+ // Add URL-based parser for this test
189
+ client.addFiletypeParser({
190
+ filetype: "javascript",
191
+ queries: {
192
+ highlights: [`${BASE_URL}/javascript/highlights.scm`],
193
+ },
194
+ wasm: `${BASE_URL}/javascript/tree-sitter-javascript.wasm`,
195
+ })
196
+
197
+ const hasParser = await client.preloadParser("javascript")
198
+ expect(hasParser).toBe(true)
199
+
200
+ const languagesDir = join(dataPath, "tree-sitter", "languages")
201
+ const queriesDir = join(dataPath, "tree-sitter", "queries")
202
+
203
+ const languagesStat = await stat(languagesDir)
204
+ const queriesStat = await stat(queriesDir)
205
+
206
+ expect(languagesStat.isDirectory()).toBe(true)
207
+ expect(queriesStat.isDirectory()).toBe(true)
208
+
209
+ const cachedFiles = await readdir(languagesDir)
210
+ expect(cachedFiles).toContain("tree-sitter-javascript.wasm")
211
+
212
+ await client.destroy()
213
+ })
214
+
215
+ test("should handle directory creation errors gracefully", async () => {
216
+ const invalidDataPath = "/invalid/path/that/cannot/be/created"
217
+ const client = new TreeSitterClient({ dataPath: invalidDataPath })
218
+
219
+ await expect(client.initialize()).rejects.toThrow()
220
+
221
+ await client.destroy()
222
+ })
223
+
224
+ test("should handle data path changes", async () => {
225
+ const initialDataPath = join(tmpdir(), "tree-sitter-initial-" + Math.random().toString(36).slice(2))
226
+ const newDataPath = join(tmpdir(), "tree-sitter-new-" + Math.random().toString(36).slice(2))
227
+
228
+ await mkdir(initialDataPath, { recursive: true })
229
+ await mkdir(newDataPath, { recursive: true })
230
+
231
+ const client = new TreeSitterClient({ dataPath: initialDataPath })
232
+ await client.initialize()
233
+
234
+ // Add URL-based parsers for this test
235
+ client.addFiletypeParser({
236
+ filetype: "javascript",
237
+ queries: {
238
+ highlights: [`${BASE_URL}/javascript/highlights.scm`],
239
+ },
240
+ wasm: `${BASE_URL}/javascript/tree-sitter-javascript.wasm`,
241
+ })
242
+
243
+ const hasParser1 = await client.preloadParser("javascript")
244
+ expect(hasParser1).toBe(true)
245
+
246
+ const initialLanguagesDir = join(initialDataPath, "tree-sitter", "languages")
247
+ const initialFiles = await readdir(initialLanguagesDir)
248
+ expect(initialFiles).toContain("tree-sitter-javascript.wasm")
249
+
250
+ await client.setDataPath(newDataPath)
251
+
252
+ // Add typescript parser for the new data path
253
+ client.addFiletypeParser({
254
+ filetype: "typescript",
255
+ queries: {
256
+ highlights: [`${BASE_URL}/typescript/highlights.scm`],
257
+ },
258
+ wasm: `${BASE_URL}/typescript/tree-sitter-typescript.wasm`,
259
+ })
260
+
261
+ const hasParser2 = await client.preloadParser("typescript")
262
+ expect(hasParser2).toBe(true)
263
+
264
+ const newLanguagesDir = join(newDataPath, "tree-sitter", "languages")
265
+ const newFiles = await readdir(newLanguagesDir)
266
+ expect(newFiles).toContain("tree-sitter-typescript.wasm")
267
+
268
+ await client.destroy()
269
+ })
270
+ })