@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,286 @@
1
+ import * as THREE from "three"
2
+ import { TextureUtils } from "./TextureUtils.js"
3
+ import type { Scene } from "three"
4
+
5
+ export interface ResourceConfig {
6
+ imagePath: string
7
+ sheetNumFrames: number
8
+ }
9
+
10
+ export interface SheetProperties {
11
+ imagePath: string
12
+ sheetTilesetWidth: number
13
+ sheetTilesetHeight: number
14
+ sheetNumFrames: number
15
+ }
16
+
17
+ export interface InstanceManagerOptions {
18
+ maxInstances: number
19
+ renderOrder?: number
20
+ depthWrite?: boolean
21
+ name?: string
22
+ frustumCulled?: boolean
23
+ matrix?: THREE.Matrix4
24
+ }
25
+
26
+ export interface MeshPoolOptions {
27
+ geometry: () => THREE.BufferGeometry
28
+ material: THREE.Material
29
+ maxInstances: number
30
+ name?: string
31
+ }
32
+
33
+ const HIDDEN_MATRIX = new THREE.Matrix4().scale(new THREE.Vector3(0, 0, 0))
34
+
35
+ export class MeshPool {
36
+ private pools: Map<string, THREE.InstancedMesh[]> = new Map()
37
+
38
+ public acquireMesh(poolId: string, options: MeshPoolOptions): THREE.InstancedMesh {
39
+ const poolArray = this.pools.get(poolId) ?? []
40
+ this.pools.set(poolId, poolArray)
41
+
42
+ if (poolArray.length > 0) {
43
+ const mesh = poolArray.pop()!
44
+ mesh.material = options.material
45
+ mesh.count = options.maxInstances
46
+ return mesh
47
+ }
48
+
49
+ const mesh = new THREE.InstancedMesh(options.geometry(), options.material, options.maxInstances)
50
+
51
+ if (options.name) {
52
+ mesh.name = options.name
53
+ }
54
+
55
+ return mesh
56
+ }
57
+
58
+ public releaseMesh(poolId: string, mesh: THREE.InstancedMesh): void {
59
+ const poolArray = this.pools.get(poolId) ?? []
60
+ poolArray.push(mesh)
61
+ this.pools.set(poolId, poolArray)
62
+ }
63
+
64
+ public fill(poolId: string, options: MeshPoolOptions, count: number): void {
65
+ const poolArray = this.pools.get(poolId) ?? []
66
+ this.pools.set(poolId, poolArray)
67
+
68
+ for (let i = 0; i < count; i++) {
69
+ const mesh = new THREE.InstancedMesh(options.geometry(), options.material, options.maxInstances)
70
+
71
+ if (options.name) {
72
+ mesh.name = `${options.name}_${i}`
73
+ }
74
+
75
+ poolArray.push(mesh)
76
+ }
77
+ }
78
+
79
+ public clearPool(poolId: string): void {
80
+ const poolArray = this.pools.get(poolId)
81
+ if (poolArray) {
82
+ poolArray.forEach((mesh) => {
83
+ mesh.geometry.dispose()
84
+ if (Array.isArray(mesh.material)) {
85
+ mesh.material.forEach((mat) => mat.dispose())
86
+ } else {
87
+ mesh.material.dispose()
88
+ }
89
+ })
90
+ poolArray.length = 0
91
+ }
92
+ }
93
+
94
+ public clearAllPools(): void {
95
+ for (const poolId of this.pools.keys()) {
96
+ this.clearPool(poolId)
97
+ }
98
+ this.pools.clear()
99
+ }
100
+ }
101
+
102
+ export class InstanceManager {
103
+ private scene: Scene
104
+ private instancedMesh: THREE.InstancedMesh
105
+ private material: THREE.Material
106
+ private maxInstances: number
107
+ private _freeIndices: number[] = []
108
+ private instanceCount: number = 0
109
+ private _matrix: THREE.Matrix4
110
+
111
+ constructor(scene: Scene, geometry: THREE.BufferGeometry, material: THREE.Material, options: InstanceManagerOptions) {
112
+ this.scene = scene
113
+ this.material = material
114
+ this.maxInstances = options.maxInstances
115
+ this._matrix = options.matrix ?? HIDDEN_MATRIX
116
+
117
+ this.instancedMesh = new THREE.InstancedMesh(geometry, material, this.maxInstances)
118
+ this.instancedMesh.renderOrder = options.renderOrder ?? 0
119
+ this.instancedMesh.frustumCulled = options.frustumCulled ?? false
120
+ this.instancedMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage)
121
+
122
+ if (options.name) {
123
+ this.instancedMesh.name = options.name
124
+ }
125
+
126
+ for (let i = 0; i < this.maxInstances; i++) {
127
+ this._freeIndices.push(i)
128
+ this.instancedMesh.setMatrixAt(i, this._matrix)
129
+ }
130
+ this.instancedMesh.instanceMatrix.needsUpdate = true
131
+
132
+ this.scene.add(this.instancedMesh)
133
+ }
134
+
135
+ acquireInstanceSlot(): number {
136
+ if (this._freeIndices.length === 0) {
137
+ throw new Error(`[InstanceManager] Max instances (${this.maxInstances}) reached. Cannot acquire slot.`)
138
+ }
139
+ const instanceIndex = this._freeIndices.pop()!
140
+ this.instanceCount++
141
+ return instanceIndex
142
+ }
143
+
144
+ releaseInstanceSlot(instanceIndex: number): void {
145
+ if (instanceIndex >= 0 && instanceIndex < this.maxInstances) {
146
+ this.instancedMesh.setMatrixAt(instanceIndex, this._matrix)
147
+ this.instancedMesh.instanceMatrix.needsUpdate = true
148
+
149
+ if (!this._freeIndices.includes(instanceIndex)) {
150
+ this._freeIndices.push(instanceIndex)
151
+ this._freeIndices.sort((a, b) => a - b)
152
+ this.instanceCount--
153
+ }
154
+ } else {
155
+ console.warn(`[InstanceManager] Attempted to release invalid instanceIndex ${instanceIndex}`)
156
+ }
157
+ }
158
+
159
+ getInstanceCount(): number {
160
+ return this.instanceCount
161
+ }
162
+
163
+ getMaxInstances(): number {
164
+ return this.maxInstances
165
+ }
166
+
167
+ get hasFreeIndices(): boolean {
168
+ return this._freeIndices.length > 0
169
+ }
170
+
171
+ get mesh(): THREE.InstancedMesh {
172
+ return this.instancedMesh
173
+ }
174
+
175
+ dispose(): void {
176
+ this.scene.remove(this.instancedMesh)
177
+ this.instancedMesh.geometry.dispose()
178
+ if (Array.isArray(this.material)) {
179
+ this.material.forEach((mat) => mat.dispose())
180
+ } else {
181
+ this.material.dispose()
182
+ }
183
+ }
184
+ }
185
+
186
+ export class SpriteResource {
187
+ private _texture: THREE.DataTexture
188
+ private _sheetProperties: SheetProperties
189
+ private scene: Scene
190
+ private _meshPool: MeshPool
191
+
192
+ constructor(texture: THREE.DataTexture, sheetProperties: SheetProperties, scene: Scene) {
193
+ this._texture = texture
194
+ this._sheetProperties = sheetProperties
195
+ this.scene = scene
196
+ this._meshPool = new MeshPool()
197
+ }
198
+
199
+ public get texture(): THREE.DataTexture {
200
+ return this._texture
201
+ }
202
+
203
+ public get sheetProperties(): SheetProperties {
204
+ return this._sheetProperties
205
+ }
206
+
207
+ public get meshPool(): MeshPool {
208
+ return this._meshPool
209
+ }
210
+
211
+ public createInstanceManager(
212
+ geometry: THREE.BufferGeometry,
213
+ material: THREE.Material,
214
+ options: InstanceManagerOptions,
215
+ ): InstanceManager {
216
+ const managerOptions = {
217
+ ...options,
218
+ name: options.name ?? `InstancedSprites_${this._sheetProperties.imagePath.replace(/[^a-zA-Z0-9_]/g, "_")}`,
219
+ }
220
+
221
+ return new InstanceManager(this.scene, geometry, material, managerOptions)
222
+ }
223
+
224
+ public get uvTileSize(): THREE.Vector2 {
225
+ const uvTileWidth = 1.0 / this._sheetProperties.sheetNumFrames
226
+ const uvTileHeight = 1.0
227
+ return new THREE.Vector2(uvTileWidth, uvTileHeight)
228
+ }
229
+
230
+ public dispose(): void {
231
+ this._meshPool.clearAllPools()
232
+ }
233
+ }
234
+
235
+ export class SpriteResourceManager {
236
+ private resources: Map<string, SpriteResource> = new Map()
237
+ private textureCache: Map<string, THREE.DataTexture> = new Map()
238
+ private scene: Scene
239
+
240
+ constructor(scene: Scene) {
241
+ this.scene = scene
242
+ }
243
+
244
+ private getResourceKey(sheetProps: SheetProperties): string {
245
+ return sheetProps.imagePath
246
+ }
247
+
248
+ public async getOrCreateResource(texture: THREE.DataTexture, sheetProps: SheetProperties): Promise<SpriteResource> {
249
+ const resourceKey = this.getResourceKey(sheetProps)
250
+ let resource = this.resources.get(resourceKey)
251
+
252
+ if (!resource) {
253
+ resource = new SpriteResource(texture, sheetProps, this.scene)
254
+ this.resources.set(resourceKey, resource)
255
+ }
256
+
257
+ return resource
258
+ }
259
+
260
+ public async createResource(config: ResourceConfig): Promise<SpriteResource> {
261
+ let texture = this.textureCache.get(config.imagePath)
262
+ if (!texture) {
263
+ const loadedTexture = await TextureUtils.fromFile(config.imagePath)
264
+ if (!loadedTexture) {
265
+ throw new Error(`[SpriteResourceManager] Failed to load texture for ${config.imagePath}`)
266
+ }
267
+ loadedTexture.needsUpdate = true
268
+ texture = loadedTexture
269
+ this.textureCache.set(config.imagePath, texture)
270
+ }
271
+
272
+ const sheetProps: SheetProperties = {
273
+ imagePath: config.imagePath,
274
+ sheetTilesetWidth: texture.image.width,
275
+ sheetTilesetHeight: texture.image.height,
276
+ sheetNumFrames: config.sheetNumFrames,
277
+ }
278
+
279
+ return await this.getOrCreateResource(texture, sheetProps)
280
+ }
281
+
282
+ public clearCache(): void {
283
+ this.resources.clear()
284
+ this.textureCache.clear()
285
+ }
286
+ }
@@ -0,0 +1,71 @@
1
+ import { TextureUtils } from "./TextureUtils.js"
2
+ import { Sprite, SpriteMaterial, DataTexture, type SpriteMaterialParameters } from "three"
3
+
4
+ export class SheetSprite extends Sprite {
5
+ private _frameIndex: number = 0
6
+ private _numFrames: number = 0
7
+
8
+ constructor(material: SpriteMaterial, numFrames: number) {
9
+ super(material)
10
+ this._numFrames = numFrames
11
+ this.setIndex(0)
12
+ }
13
+
14
+ setIndex = (index: number) => {
15
+ this._frameIndex = index
16
+ this.material.map?.repeat.set(1 / this._numFrames, 1)
17
+ this.material.map?.offset.set(this._frameIndex / this._numFrames, 0)
18
+ }
19
+ }
20
+
21
+ export class SpriteUtils {
22
+ static async fromFile(
23
+ path: string,
24
+ {
25
+ materialParameters = {
26
+ alphaTest: 0.1,
27
+ depthWrite: true,
28
+ },
29
+ }: {
30
+ materialParameters?: Omit<SpriteMaterialParameters, "map">
31
+ } = {},
32
+ ): Promise<Sprite> {
33
+ const texture = await TextureUtils.fromFile(path)
34
+ if (!texture) {
35
+ throw new Error(`Failed to load sprite texture from ${path}`)
36
+ }
37
+
38
+ const spriteMaterial = new SpriteMaterial({ map: texture, ...materialParameters })
39
+ const sprite = new Sprite(spriteMaterial)
40
+
41
+ const textureAspectRatio = texture.image.width / texture.image.height
42
+
43
+ sprite.updateMatrix = function () {
44
+ this.matrix.compose(this.position, this.quaternion, this.scale.clone().setX(this.scale.x * textureAspectRatio))
45
+ }
46
+
47
+ return sprite
48
+ }
49
+
50
+ static async sheetFromFile(path: string, numFrames: number): Promise<SheetSprite> {
51
+ const spriteTexture = await TextureUtils.fromFile(path)
52
+
53
+ if (!spriteTexture) {
54
+ console.error("Failed to load sprite texture, exiting.")
55
+ process.exit(1)
56
+ }
57
+
58
+ const spriteMaterial = new SpriteMaterial({ map: spriteTexture })
59
+ const sprite = new SheetSprite(spriteMaterial, numFrames)
60
+
61
+ const singleFrameWidth = spriteTexture.image.width / numFrames
62
+ const singleFrameHeight = spriteTexture.image.height
63
+ const frameAspectRatio = singleFrameWidth / singleFrameHeight
64
+
65
+ sprite.updateMatrix = function () {
66
+ this.matrix.compose(this.position, this.quaternion, this.scale.clone().setX(this.scale.x * frameAspectRatio))
67
+ }
68
+
69
+ return sprite
70
+ }
71
+ }
@@ -0,0 +1,196 @@
1
+ import { readFile } from "node:fs/promises"
2
+ import { Color, Texture, DataTexture, NearestFilter, ClampToEdgeWrapping, RGBAFormat, UnsignedByteType } from "three"
3
+ import { Jimp } from "jimp"
4
+
5
+ interface SimpleImageData {
6
+ data: Uint8ClampedArray
7
+ width: number
8
+ height: number
9
+ }
10
+
11
+ // Utility class for loading and generating THREE.Texture instances
12
+ export class TextureUtils {
13
+ /**
14
+ * Loads a texture from a file path using sharp.
15
+ * Returns a THREE.Texture with ImageData attached to its .image property.
16
+ */
17
+ static async loadTextureFromFile(path: string): Promise<DataTexture | null> {
18
+ try {
19
+ const buffer = await readFile(path)
20
+ const image = await Jimp.read(buffer)
21
+
22
+ image.flip({ horizontal: false, vertical: true })
23
+
24
+ const texture = new DataTexture(
25
+ image.bitmap.data,
26
+ image.bitmap.width,
27
+ image.bitmap.height,
28
+ RGBAFormat,
29
+ UnsignedByteType,
30
+ )
31
+ texture.needsUpdate = true
32
+ texture.format = RGBAFormat
33
+ texture.magFilter = NearestFilter
34
+ texture.minFilter = NearestFilter
35
+ texture.wrapS = ClampToEdgeWrapping
36
+ texture.wrapT = ClampToEdgeWrapping
37
+ texture.flipY = false // Usually true for webGL, but our sampler flips V
38
+
39
+ return texture
40
+ } catch (error) {
41
+ console.error(`Failed to load texture from ${path}:`, error)
42
+ return null
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Alias for loadTextureFromFile for convenience.
48
+ */
49
+ static async fromFile(path: string): Promise<DataTexture | null> {
50
+ return this.loadTextureFromFile(path)
51
+ }
52
+
53
+ /**
54
+ * Creates a THREE.Texture with a checkerboard pattern.
55
+ */
56
+ static createCheckerboard(
57
+ size: number = 256,
58
+ color1: Color = new Color(1.0, 1.0, 1.0),
59
+ color2: Color = new Color(0.0, 0.0, 0.0),
60
+ checkSize: number = 32,
61
+ ): Texture {
62
+ const data = new Uint8ClampedArray(size * size * 4)
63
+
64
+ for (let y = 0; y < size; y++) {
65
+ for (let x = 0; x < size; x++) {
66
+ const isEvenX = Math.floor(x / checkSize) % 2 === 0
67
+ const isEvenY = Math.floor(y / checkSize) % 2 === 0
68
+ const color = (isEvenX && isEvenY) || (!isEvenX && !isEvenY) ? color1 : color2
69
+
70
+ const index = (y * size + x) * 4
71
+ data[index] = Math.floor(color.r * 255)
72
+ data[index + 1] = Math.floor(color.g * 255)
73
+ data[index + 2] = Math.floor(color.b * 255)
74
+ data[index + 3] = 255 // Alpha
75
+ }
76
+ }
77
+
78
+ const imageData: SimpleImageData = { data, width: size, height: size }
79
+ const texture = new DataTexture(data, size, size, RGBAFormat, UnsignedByteType)
80
+ texture.needsUpdate = true
81
+ texture.format = RGBAFormat
82
+ texture.magFilter = NearestFilter
83
+ texture.minFilter = NearestFilter
84
+ texture.wrapS = ClampToEdgeWrapping
85
+ texture.wrapT = ClampToEdgeWrapping
86
+ texture.flipY = false
87
+
88
+ return texture
89
+ }
90
+
91
+ /**
92
+ * Creates a THREE.Texture with a gradient pattern.
93
+ */
94
+ static createGradient(
95
+ size: number = 256,
96
+ startColor: Color = new Color(1.0, 0.0, 0.0),
97
+ endColor: Color = new Color(0.0, 0.0, 1.0),
98
+ direction: "horizontal" | "vertical" | "radial" = "vertical",
99
+ ): Texture {
100
+ const data = new Uint8ClampedArray(size * size * 4)
101
+
102
+ for (let y = 0; y < size; y++) {
103
+ for (let x = 0; x < size; x++) {
104
+ let t = 0
105
+
106
+ if (direction === "horizontal") {
107
+ t = x / (size - 1)
108
+ } else if (direction === "vertical") {
109
+ t = y / (size - 1)
110
+ } else if (direction === "radial") {
111
+ const dx = x - size / 2
112
+ const dy = y - size / 2
113
+ t = Math.min(1, Math.sqrt(dx * dx + dy * dy) / (size / 2))
114
+ }
115
+
116
+ const r = startColor.r * (1 - t) + endColor.r * t
117
+ const g = startColor.g * (1 - t) + endColor.g * t
118
+ const b = startColor.b * (1 - t) + endColor.b * t
119
+
120
+ const index = (y * size + x) * 4
121
+ data[index] = Math.floor(r * 255)
122
+ data[index + 1] = Math.floor(g * 255)
123
+ data[index + 2] = Math.floor(b * 255)
124
+ data[index + 3] = 255 // Alpha
125
+ }
126
+ }
127
+
128
+ const imageData: SimpleImageData = { data, width: size, height: size }
129
+ const texture = new DataTexture(data, size, size, RGBAFormat, UnsignedByteType)
130
+ texture.needsUpdate = true
131
+ texture.format = RGBAFormat
132
+ texture.magFilter = NearestFilter
133
+ texture.minFilter = NearestFilter
134
+ texture.wrapS = ClampToEdgeWrapping
135
+ texture.wrapT = ClampToEdgeWrapping
136
+ texture.flipY = false
137
+
138
+ return texture
139
+ }
140
+
141
+ /**
142
+ * Creates a THREE.Texture with a procedural noise pattern.
143
+ */
144
+ static createNoise(
145
+ size: number = 256,
146
+ scale: number = 1,
147
+ octaves: number = 1,
148
+ color1: Color = new Color(1.0, 1.0, 1.0),
149
+ color2: Color = new Color(0.0, 0.0, 0.0),
150
+ ): Texture {
151
+ const data = new Uint8ClampedArray(size * size * 4)
152
+
153
+ for (let y = 0; y < size; y++) {
154
+ for (let x = 0; x < size; x++) {
155
+ let noise = 0
156
+ let amplitude = 1
157
+ let frequency = 1
158
+
159
+ for (let o = 0; o < octaves; o++) {
160
+ const nx = (x * frequency * scale) / size
161
+ const ny = (y * frequency * scale) / size
162
+ const sampleX = Math.sin(nx * 12.9898) * 43758.5453
163
+ const sampleY = Math.cos(ny * 78.233) * 43758.5453
164
+ const sample = Math.sin(sampleX + sampleY) * 0.5 + 0.5
165
+ noise += sample * amplitude
166
+ amplitude *= 0.5
167
+ frequency *= 2
168
+ }
169
+
170
+ noise = Math.min(1, Math.max(0, noise)) // Normalize
171
+
172
+ const r = color1.r * noise + color2.r * (1 - noise)
173
+ const g = color1.g * noise + color2.g * (1 - noise)
174
+ const b = color1.b * noise + color2.b * (1 - noise)
175
+
176
+ const index = (y * size + x) * 4
177
+ data[index] = Math.floor(r * 255)
178
+ data[index + 1] = Math.floor(g * 255)
179
+ data[index + 2] = Math.floor(b * 255)
180
+ data[index + 3] = 255 // Alpha
181
+ }
182
+ }
183
+
184
+ const imageData: SimpleImageData = { data, width: size, height: size }
185
+ const texture = new DataTexture(data, size, size, RGBAFormat, UnsignedByteType)
186
+ texture.needsUpdate = true
187
+ texture.format = RGBAFormat
188
+ texture.magFilter = NearestFilter
189
+ texture.minFilter = NearestFilter
190
+ texture.wrapS = ClampToEdgeWrapping
191
+ texture.wrapT = ClampToEdgeWrapping
192
+ texture.flipY = false
193
+
194
+ return texture
195
+ }
196
+ }