@fairyhunter13/opentui-core 0.1.112 → 0.1.114

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 (591) 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 +144 -0
  7. package/package.json +63 -51
  8. package/scripts/build.ts +400 -0
  9. package/scripts/publish.ts +60 -0
  10. package/src/3d/SpriteResourceManager.ts +286 -0
  11. package/src/3d/SpriteUtils.ts +70 -0
  12. package/src/3d/TextureUtils.ts +196 -0
  13. package/src/3d/ThreeRenderable.ts +197 -0
  14. package/src/3d/WGPURenderer.ts +294 -0
  15. package/src/3d/animation/ExplodingSpriteEffect.ts +513 -0
  16. package/src/3d/animation/PhysicsExplodingSpriteEffect.ts +429 -0
  17. package/src/3d/animation/SpriteAnimator.ts +633 -0
  18. package/src/3d/animation/SpriteParticleGenerator.ts +435 -0
  19. package/src/3d/canvas.ts +464 -0
  20. package/src/3d/index.ts +12 -0
  21. package/src/3d/physics/PlanckPhysicsAdapter.ts +72 -0
  22. package/src/3d/physics/RapierPhysicsAdapter.ts +66 -0
  23. package/src/3d/physics/physics-interface.ts +31 -0
  24. package/src/3d/shaders/supersampling.wgsl +201 -0
  25. package/src/3d.ts +3 -0
  26. package/src/NativeSpanFeed.ts +300 -0
  27. package/src/Renderable.ts +1704 -0
  28. package/src/__snapshots__/buffer.test.ts.snap +28 -0
  29. package/src/animation/Timeline.test.ts +2709 -0
  30. package/src/animation/Timeline.ts +598 -0
  31. package/src/ansi.ts +18 -0
  32. package/src/benchmark/attenuation-benchmark.ts +81 -0
  33. package/src/benchmark/colormatrix-benchmark.ts +128 -0
  34. package/src/benchmark/gain-benchmark.ts +80 -0
  35. package/src/benchmark/latest-all-bench-run.json +707 -0
  36. package/src/benchmark/latest-async-bench-run.json +336 -0
  37. package/src/benchmark/latest-default-bench-run.json +657 -0
  38. package/src/benchmark/latest-large-bench-run.json +707 -0
  39. package/src/benchmark/latest-quick-bench-run.json +207 -0
  40. package/src/benchmark/markdown-benchmark.ts +1796 -0
  41. package/src/benchmark/native-span-feed-async-benchmark.ts +355 -0
  42. package/src/benchmark/native-span-feed-benchmark.md +56 -0
  43. package/src/benchmark/native-span-feed-benchmark.ts +596 -0
  44. package/src/benchmark/native-span-feed-compare.ts +280 -0
  45. package/src/benchmark/renderer-benchmark.ts +754 -0
  46. package/src/benchmark/text-table-benchmark.ts +948 -0
  47. package/src/buffer.test.ts +291 -0
  48. package/src/buffer.ts +554 -0
  49. package/src/console.test.ts +612 -0
  50. package/src/console.ts +1254 -0
  51. package/src/edit-buffer.test.ts +1769 -0
  52. package/src/edit-buffer.ts +411 -0
  53. package/src/editor-view.test.ts +1032 -0
  54. package/src/editor-view.ts +284 -0
  55. package/src/examples/ascii-font-selection-demo.ts +245 -0
  56. package/src/examples/assets/Water_2_M_Normal.jpg +0 -0
  57. package/src/examples/assets/concrete.png +0 -0
  58. package/src/examples/assets/crate.png +0 -0
  59. package/src/examples/assets/crate_emissive.png +0 -0
  60. package/src/examples/assets/forrest_background.png +0 -0
  61. package/src/examples/assets/hast-example.json +1018 -0
  62. package/src/examples/assets/heart.png +0 -0
  63. package/src/examples/assets/main_char_heavy_attack.png +0 -0
  64. package/src/examples/assets/main_char_idle.png +0 -0
  65. package/src/examples/assets/main_char_jump_end.png +0 -0
  66. package/src/examples/assets/main_char_jump_landing.png +0 -0
  67. package/src/examples/assets/main_char_jump_start.png +0 -0
  68. package/src/examples/assets/main_char_run_loop.png +0 -0
  69. package/src/examples/assets/roughness_map.jpg +0 -0
  70. package/src/examples/build.ts +115 -0
  71. package/src/examples/code-demo.ts +924 -0
  72. package/src/examples/console-demo.ts +358 -0
  73. package/src/examples/core-plugin-slots-demo.ts +759 -0
  74. package/src/examples/diff-demo.ts +701 -0
  75. package/src/examples/draggable-three-demo.ts +259 -0
  76. package/src/examples/editor-demo.ts +322 -0
  77. package/src/examples/extmarks-demo.ts +196 -0
  78. package/src/examples/focus-restore-demo.ts +310 -0
  79. package/src/examples/fonts.ts +245 -0
  80. package/src/examples/fractal-shader-demo.ts +268 -0
  81. package/src/examples/framebuffer-demo.ts +674 -0
  82. package/src/examples/full-unicode-demo.ts +241 -0
  83. package/src/examples/golden-star-demo.ts +933 -0
  84. package/src/examples/grayscale-buffer-demo.ts +249 -0
  85. package/src/examples/hast-syntax-highlighting-demo.ts +129 -0
  86. package/src/examples/index.ts +926 -0
  87. package/src/examples/input-demo.ts +377 -0
  88. package/src/examples/input-select-layout-demo.ts +425 -0
  89. package/src/examples/install.sh +143 -0
  90. package/src/examples/keypress-debug-demo.ts +452 -0
  91. package/src/examples/lib/HexList.ts +122 -0
  92. package/src/examples/lib/PaletteGrid.ts +125 -0
  93. package/src/examples/lib/standalone-keys.ts +25 -0
  94. package/src/examples/lib/tab-controller.ts +243 -0
  95. package/src/examples/lights-phong-demo.ts +290 -0
  96. package/src/examples/link-demo.ts +220 -0
  97. package/src/examples/live-state-demo.ts +480 -0
  98. package/src/examples/markdown-demo.ts +725 -0
  99. package/src/examples/mouse-interaction-demo.ts +428 -0
  100. package/src/examples/nested-zindex-demo.ts +357 -0
  101. package/src/examples/opacity-example.ts +235 -0
  102. package/src/examples/opentui-demo.ts +1057 -0
  103. package/src/examples/physx-planck-2d-demo.ts +623 -0
  104. package/src/examples/physx-rapier-2d-demo.ts +655 -0
  105. package/src/examples/relative-positioning-demo.ts +323 -0
  106. package/src/examples/scroll-example.ts +214 -0
  107. package/src/examples/scrollbox-mouse-test.ts +112 -0
  108. package/src/examples/scrollbox-overlay-hit-test.ts +206 -0
  109. package/src/examples/select-demo.ts +237 -0
  110. package/src/examples/shader-cube-demo.ts +1015 -0
  111. package/src/examples/simple-layout-example.ts +591 -0
  112. package/src/examples/slider-demo.ts +617 -0
  113. package/src/examples/split-mode-demo.ts +453 -0
  114. package/src/examples/sprite-animation-demo.ts +443 -0
  115. package/src/examples/sprite-particle-generator-demo.ts +486 -0
  116. package/src/examples/static-sprite-demo.ts +193 -0
  117. package/src/examples/sticky-scroll-example.ts +308 -0
  118. package/src/examples/styled-text-demo.ts +282 -0
  119. package/src/examples/tab-select-demo.ts +219 -0
  120. package/src/examples/terminal-title.ts +29 -0
  121. package/src/examples/terminal.ts +305 -0
  122. package/src/examples/text-node-demo.ts +416 -0
  123. package/src/examples/text-selection-demo.ts +377 -0
  124. package/src/examples/text-table-demo.ts +503 -0
  125. package/src/examples/text-truncation-demo.ts +481 -0
  126. package/src/examples/text-wrap.ts +757 -0
  127. package/src/examples/texture-loading-demo.ts +259 -0
  128. package/src/examples/timeline-example.ts +670 -0
  129. package/src/examples/transparency-demo.ts +400 -0
  130. package/src/examples/vnode-composition-demo.ts +404 -0
  131. package/src/examples/wide-grapheme-overlay-demo.ts +280 -0
  132. package/src/index.ts +24 -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 +170 -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 +35 -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 +317 -0
  168. package/src/lib/keymapping.ts +115 -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 +2290 -0
  187. package/src/lib/stdin-parser.ts +1810 -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 +334 -0
  195. package/src/lib/tree-sitter/assets.d.ts +9 -0
  196. package/src/lib/tree-sitter/cache.test.ts +273 -0
  197. package/src/lib/tree-sitter/client.test.ts +1165 -0
  198. package/src/lib/tree-sitter/client.ts +607 -0
  199. package/src/lib/tree-sitter/default-parsers.ts +86 -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 +1042 -0
  203. package/src/lib/tree-sitter/parsers-config.ts +81 -0
  204. package/src/lib/tree-sitter/resolve-ft.test.ts +55 -0
  205. package/src/lib/tree-sitter/resolve-ft.ts +189 -0
  206. package/src/lib/tree-sitter/types.ts +82 -0
  207. package/src/lib/tree-sitter-styled-text.test.ts +1253 -0
  208. package/src/lib/tree-sitter-styled-text.ts +306 -0
  209. package/src/lib/validate-dir-name.ts +55 -0
  210. package/src/lib/yoga.options.test.ts +628 -0
  211. package/src/lib/yoga.options.ts +346 -0
  212. package/src/plugins/core-slot.ts +579 -0
  213. package/src/plugins/registry.ts +402 -0
  214. package/src/plugins/types.ts +46 -0
  215. package/src/post/effects.ts +930 -0
  216. package/src/post/filters.ts +489 -0
  217. package/src/post/matrices.ts +288 -0
  218. package/src/renderables/ASCIIFont.ts +219 -0
  219. package/src/renderables/Box.test.ts +205 -0
  220. package/src/renderables/Box.ts +326 -0
  221. package/src/renderables/Code.test.ts +2062 -0
  222. package/src/renderables/Code.ts +357 -0
  223. package/src/renderables/Diff.regression.test.ts +226 -0
  224. package/src/renderables/Diff.test.ts +3101 -0
  225. package/src/renderables/Diff.ts +1211 -0
  226. package/src/renderables/EditBufferRenderable.test.ts +288 -0
  227. package/src/renderables/EditBufferRenderable.ts +1166 -0
  228. package/src/renderables/FrameBuffer.ts +47 -0
  229. package/src/renderables/Input.test.ts +1228 -0
  230. package/src/renderables/Input.ts +247 -0
  231. package/src/renderables/LineNumberRenderable.ts +724 -0
  232. package/src/renderables/Markdown.ts +1393 -0
  233. package/src/renderables/ScrollBar.ts +422 -0
  234. package/src/renderables/ScrollBox.ts +883 -0
  235. package/src/renderables/Select.test.ts +1033 -0
  236. package/src/renderables/Select.ts +524 -0
  237. package/src/renderables/Slider.test.ts +456 -0
  238. package/src/renderables/Slider.ts +342 -0
  239. package/src/renderables/TabSelect.test.ts +197 -0
  240. package/src/renderables/TabSelect.ts +455 -0
  241. package/src/renderables/Text.selection-buffer.test.ts +123 -0
  242. package/src/renderables/Text.test.ts +2660 -0
  243. package/src/renderables/Text.ts +147 -0
  244. package/src/renderables/TextBufferRenderable.ts +518 -0
  245. package/src/renderables/TextNode.test.ts +1058 -0
  246. package/src/renderables/TextNode.ts +325 -0
  247. package/src/renderables/TextTable.test.ts +1421 -0
  248. package/src/renderables/TextTable.ts +1344 -0
  249. package/src/renderables/Textarea.ts +430 -0
  250. package/src/renderables/TimeToFirstDraw.ts +89 -0
  251. package/src/renderables/__snapshots__/Code.test.ts.snap +13 -0
  252. package/src/renderables/__snapshots__/Diff.test.ts.snap +785 -0
  253. package/src/renderables/__snapshots__/Text.test.ts.snap +421 -0
  254. package/src/renderables/__snapshots__/TextTable.test.ts.snap +215 -0
  255. package/src/renderables/__tests__/LineNumberRenderable.scrollbox-simple.test.ts +144 -0
  256. package/src/renderables/__tests__/LineNumberRenderable.scrollbox.test.ts +816 -0
  257. package/src/renderables/__tests__/LineNumberRenderable.test.ts +1865 -0
  258. package/src/renderables/__tests__/LineNumberRenderable.wrapping.test.ts +85 -0
  259. package/src/renderables/__tests__/Markdown.code-colors.test.ts +242 -0
  260. package/src/renderables/__tests__/Markdown.test.ts +2518 -0
  261. package/src/renderables/__tests__/MultiRenderable.selection.test.ts +87 -0
  262. package/src/renderables/__tests__/Textarea.buffer.test.ts +682 -0
  263. package/src/renderables/__tests__/Textarea.destroyed-events.test.ts +675 -0
  264. package/src/renderables/__tests__/Textarea.editing.test.ts +2041 -0
  265. package/src/renderables/__tests__/Textarea.error-handling.test.ts +35 -0
  266. package/src/renderables/__tests__/Textarea.events.test.ts +738 -0
  267. package/src/renderables/__tests__/Textarea.highlights.test.ts +590 -0
  268. package/src/renderables/__tests__/Textarea.keybinding.test.ts +3149 -0
  269. package/src/renderables/__tests__/Textarea.paste.test.ts +357 -0
  270. package/src/renderables/__tests__/Textarea.rendering.test.ts +1866 -0
  271. package/src/renderables/__tests__/Textarea.scroll.test.ts +733 -0
  272. package/src/renderables/__tests__/Textarea.selection.test.ts +1590 -0
  273. package/src/renderables/__tests__/Textarea.stress.test.ts +670 -0
  274. package/src/renderables/__tests__/Textarea.undo-redo.test.ts +383 -0
  275. package/src/renderables/__tests__/Textarea.visual-lines.test.ts +310 -0
  276. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.code.test.ts.snap +221 -0
  277. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox-simple.test.ts.snap +89 -0
  278. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox.test.ts.snap +457 -0
  279. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.test.ts.snap +158 -0
  280. package/src/renderables/__tests__/__snapshots__/Textarea.rendering.test.ts.snap +387 -0
  281. package/src/renderables/__tests__/markdown-parser.test.ts +217 -0
  282. package/src/renderables/__tests__/renderable-test-utils.ts +60 -0
  283. package/src/renderables/composition/README.md +8 -0
  284. package/src/renderables/composition/VRenderable.ts +32 -0
  285. package/src/renderables/composition/constructs.ts +127 -0
  286. package/src/renderables/composition/vnode.ts +289 -0
  287. package/src/renderables/index.ts +23 -0
  288. package/src/renderables/markdown-parser.ts +66 -0
  289. package/src/renderer.ts +2681 -0
  290. package/src/runtime-plugin-support.ts +39 -0
  291. package/src/runtime-plugin.ts +615 -0
  292. package/src/syntax-style.test.ts +841 -0
  293. package/src/syntax-style.ts +257 -0
  294. package/src/testing/README.md +210 -0
  295. package/src/testing/capture-spans.test.ts +194 -0
  296. package/src/testing/integration.test.ts +276 -0
  297. package/src/testing/manual-clock.ts +117 -0
  298. package/src/testing/mock-keys.test.ts +1378 -0
  299. package/src/testing/mock-keys.ts +457 -0
  300. package/src/testing/mock-mouse.test.ts +218 -0
  301. package/src/testing/mock-mouse.ts +247 -0
  302. package/src/testing/mock-tree-sitter-client.ts +73 -0
  303. package/src/testing/spy.ts +13 -0
  304. package/src/testing/test-recorder.test.ts +415 -0
  305. package/src/testing/test-recorder.ts +145 -0
  306. package/src/testing/test-renderer.ts +132 -0
  307. package/src/testing.ts +7 -0
  308. package/src/tests/__snapshots__/absolute-positioning.snapshot.test.ts.snap +481 -0
  309. package/src/tests/__snapshots__/renderable.snapshot.test.ts.snap +19 -0
  310. package/src/tests/__snapshots__/scrollbox.test.ts.snap +29 -0
  311. package/src/tests/absolute-positioning.snapshot.test.ts +638 -0
  312. package/src/tests/allocator-stats.test.ts +38 -0
  313. package/src/tests/destroy-during-render.test.ts +200 -0
  314. package/src/tests/destroy-on-exit.fixture.ts +36 -0
  315. package/src/tests/destroy-on-exit.test.ts +41 -0
  316. package/src/tests/hover-cursor.test.ts +98 -0
  317. package/src/tests/native-span-feed-async.test.ts +173 -0
  318. package/src/tests/native-span-feed-close.test.ts +120 -0
  319. package/src/tests/native-span-feed-coverage.test.ts +227 -0
  320. package/src/tests/native-span-feed-edge-cases.test.ts +352 -0
  321. package/src/tests/native-span-feed-use-after-free.test.ts +45 -0
  322. package/src/tests/opacity.test.ts +123 -0
  323. package/src/tests/renderable.snapshot.test.ts +524 -0
  324. package/src/tests/renderable.test.ts +1281 -0
  325. package/src/tests/renderer.clock.test.ts +158 -0
  326. package/src/tests/renderer.console-startup.test.ts +185 -0
  327. package/src/tests/renderer.control.test.ts +425 -0
  328. package/src/tests/renderer.core-slot-binding.test.ts +952 -0
  329. package/src/tests/renderer.cursor.test.ts +26 -0
  330. package/src/tests/renderer.destroy-during-render.test.ts +147 -0
  331. package/src/tests/renderer.focus-restore.test.ts +257 -0
  332. package/src/tests/renderer.focus.test.ts +294 -0
  333. package/src/tests/renderer.idle.test.ts +219 -0
  334. package/src/tests/renderer.input.test.ts +2237 -0
  335. package/src/tests/renderer.kitty-flags.test.ts +195 -0
  336. package/src/tests/renderer.mouse.test.ts +1274 -0
  337. package/src/tests/renderer.palette.test.ts +629 -0
  338. package/src/tests/renderer.selection.test.ts +49 -0
  339. package/src/tests/renderer.slot-registry.test.ts +684 -0
  340. package/src/tests/renderer.useMouse.test.ts +47 -0
  341. package/src/tests/runtime-plugin-node-modules-cycle.fixture.ts +76 -0
  342. package/src/tests/runtime-plugin-node-modules-mjs.fixture.ts +43 -0
  343. package/src/tests/runtime-plugin-node-modules-no-bare-rewrite.fixture.ts +67 -0
  344. package/src/tests/runtime-plugin-node-modules-package-type-cache.fixture.ts +72 -0
  345. package/src/tests/runtime-plugin-node-modules-runtime-specifier.fixture.ts +44 -0
  346. package/src/tests/runtime-plugin-node-modules-scoped-package-bare-rewrite.fixture.ts +85 -0
  347. package/src/tests/runtime-plugin-path-alias.fixture.ts +43 -0
  348. package/src/tests/runtime-plugin-resolve-roots.fixture.ts +65 -0
  349. package/src/tests/runtime-plugin-support.fixture.ts +11 -0
  350. package/src/tests/runtime-plugin-support.test.ts +19 -0
  351. package/src/tests/runtime-plugin-windows-file-url.fixture.ts +30 -0
  352. package/src/tests/runtime-plugin.fixture.ts +40 -0
  353. package/src/tests/runtime-plugin.test.ts +354 -0
  354. package/src/tests/scrollbox-culling-bug.test.ts +114 -0
  355. package/src/tests/scrollbox-hitgrid-resize.test.ts +136 -0
  356. package/src/tests/scrollbox-hitgrid.test.ts +909 -0
  357. package/src/tests/scrollbox.test.ts +1530 -0
  358. package/src/tests/wrap-resize-perf.test.ts +276 -0
  359. package/src/tests/yoga-setters.test.ts +921 -0
  360. package/src/text-buffer-view.test.ts +705 -0
  361. package/src/text-buffer-view.ts +189 -0
  362. package/src/text-buffer.test.ts +347 -0
  363. package/src/text-buffer.ts +250 -0
  364. package/src/types.ts +161 -0
  365. package/src/utils.ts +88 -0
  366. package/src/zig/ansi.zig +268 -0
  367. package/src/zig/bench/README.md +50 -0
  368. package/src/zig/bench/buffer-draw-text-buffer_bench.zig +887 -0
  369. package/src/zig/bench/edit-buffer_bench.zig +476 -0
  370. package/src/zig/bench/native-span-feed_bench.zig +100 -0
  371. package/src/zig/bench/rope-markers_bench.zig +713 -0
  372. package/src/zig/bench/rope_bench.zig +514 -0
  373. package/src/zig/bench/styled-text_bench.zig +470 -0
  374. package/src/zig/bench/text-buffer-coords_bench.zig +362 -0
  375. package/src/zig/bench/text-buffer-view_bench.zig +459 -0
  376. package/src/zig/bench/text-chunk-graphemes_bench.zig +273 -0
  377. package/src/zig/bench/utf8_bench.zig +799 -0
  378. package/src/zig/bench-utils.zig +431 -0
  379. package/src/zig/bench.zig +217 -0
  380. package/src/zig/buffer-methods.zig +211 -0
  381. package/src/zig/buffer.zig +2281 -0
  382. package/src/zig/build.zig +289 -0
  383. package/src/zig/build.zig.zon +16 -0
  384. package/src/zig/edit-buffer.zig +825 -0
  385. package/src/zig/editor-view.zig +802 -0
  386. package/src/zig/event-bus.zig +13 -0
  387. package/src/zig/event-emitter.zig +65 -0
  388. package/src/zig/file-logger.zig +92 -0
  389. package/src/zig/grapheme.zig +599 -0
  390. package/src/zig/lib.zig +1854 -0
  391. package/src/zig/link.zig +333 -0
  392. package/src/zig/logger.zig +43 -0
  393. package/src/zig/mem-registry.zig +125 -0
  394. package/src/zig/native-span-feed-bench-lib.zig +7 -0
  395. package/src/zig/native-span-feed.zig +708 -0
  396. package/src/zig/renderer.zig +1393 -0
  397. package/src/zig/rope.zig +1220 -0
  398. package/src/zig/syntax-style.zig +161 -0
  399. package/src/zig/terminal.zig +987 -0
  400. package/src/zig/test.zig +72 -0
  401. package/src/zig/tests/README.md +18 -0
  402. package/src/zig/tests/buffer-methods_test.zig +1109 -0
  403. package/src/zig/tests/buffer_test.zig +2557 -0
  404. package/src/zig/tests/edit-buffer-history_test.zig +271 -0
  405. package/src/zig/tests/edit-buffer_test.zig +1689 -0
  406. package/src/zig/tests/editor-view_test.zig +3299 -0
  407. package/src/zig/tests/event-emitter_test.zig +249 -0
  408. package/src/zig/tests/grapheme_test.zig +1304 -0
  409. package/src/zig/tests/link_test.zig +190 -0
  410. package/src/zig/tests/mem-registry_test.zig +473 -0
  411. package/src/zig/tests/memory_leak_regression_test.zig +159 -0
  412. package/src/zig/tests/native-span-feed_test.zig +1264 -0
  413. package/src/zig/tests/renderer_test.zig +1017 -0
  414. package/src/zig/tests/rope-nested_test.zig +712 -0
  415. package/src/zig/tests/rope_fuzz_test.zig +238 -0
  416. package/src/zig/tests/rope_test.zig +2362 -0
  417. package/src/zig/tests/segment-merge.test.zig +148 -0
  418. package/src/zig/tests/syntax-style_test.zig +557 -0
  419. package/src/zig/tests/terminal_test.zig +754 -0
  420. package/src/zig/tests/text-buffer-drawing_test.zig +3237 -0
  421. package/src/zig/tests/text-buffer-highlights_test.zig +666 -0
  422. package/src/zig/tests/text-buffer-iterators_test.zig +776 -0
  423. package/src/zig/tests/text-buffer-segment_test.zig +320 -0
  424. package/src/zig/tests/text-buffer-selection_test.zig +1035 -0
  425. package/src/zig/tests/text-buffer-selection_viewport_test.zig +358 -0
  426. package/src/zig/tests/text-buffer-view_test.zig +3649 -0
  427. package/src/zig/tests/text-buffer_test.zig +2191 -0
  428. package/src/zig/tests/unicode-width-map.zon +3909 -0
  429. package/src/zig/tests/utf8_no_zwj_test.zig +260 -0
  430. package/src/zig/tests/utf8_test.zig +4057 -0
  431. package/src/zig/tests/utf8_wcwidth_cursor_test.zig +267 -0
  432. package/src/zig/tests/utf8_wcwidth_test.zig +357 -0
  433. package/src/zig/tests/word-wrap-editing_test.zig +498 -0
  434. package/src/zig/tests/wrap-cache-perf_test.zig +113 -0
  435. package/src/zig/text-buffer-iterators.zig +499 -0
  436. package/src/zig/text-buffer-segment.zig +404 -0
  437. package/src/zig/text-buffer-view.zig +1371 -0
  438. package/src/zig/text-buffer.zig +1180 -0
  439. package/src/zig/utf8.zig +1948 -0
  440. package/src/zig/utils.zig +9 -0
  441. package/src/zig-structs.ts +261 -0
  442. package/src/zig.ts +3884 -0
  443. package/tsconfig.build.json +24 -0
  444. package/tsconfig.json +27 -0
  445. package/3d/SpriteResourceManager.d.ts +0 -74
  446. package/3d/SpriteUtils.d.ts +0 -13
  447. package/3d/TextureUtils.d.ts +0 -24
  448. package/3d/ThreeRenderable.d.ts +0 -40
  449. package/3d/WGPURenderer.d.ts +0 -61
  450. package/3d/animation/ExplodingSpriteEffect.d.ts +0 -71
  451. package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +0 -76
  452. package/3d/animation/SpriteAnimator.d.ts +0 -124
  453. package/3d/animation/SpriteParticleGenerator.d.ts +0 -62
  454. package/3d/canvas.d.ts +0 -44
  455. package/3d/index.d.ts +0 -12
  456. package/3d/physics/PlanckPhysicsAdapter.d.ts +0 -19
  457. package/3d/physics/RapierPhysicsAdapter.d.ts +0 -19
  458. package/3d/physics/physics-interface.d.ts +0 -27
  459. package/3d.d.ts +0 -2
  460. package/3d.js +0 -34041
  461. package/3d.js.map +0 -155
  462. package/LICENSE +0 -21
  463. package/NativeSpanFeed.d.ts +0 -41
  464. package/Renderable.d.ts +0 -334
  465. package/animation/Timeline.d.ts +0 -126
  466. package/ansi.d.ts +0 -13
  467. package/buffer.d.ts +0 -111
  468. package/console.d.ts +0 -144
  469. package/edit-buffer.d.ts +0 -98
  470. package/editor-view.d.ts +0 -73
  471. package/index-8fks7yv1.js +0 -411
  472. package/index-8fks7yv1.js.map +0 -10
  473. package/index-egy5e2rs.js +0 -12267
  474. package/index-egy5e2rs.js.map +0 -42
  475. package/index-tse8gzh0.js +0 -20614
  476. package/index-tse8gzh0.js.map +0 -67
  477. package/index.d.ts +0 -23
  478. package/index.js +0 -478
  479. package/index.js.map +0 -9
  480. package/lib/KeyHandler.d.ts +0 -61
  481. package/lib/RGBA.d.ts +0 -25
  482. package/lib/ascii.font.d.ts +0 -508
  483. package/lib/border.d.ts +0 -51
  484. package/lib/bunfs.d.ts +0 -7
  485. package/lib/clipboard.d.ts +0 -17
  486. package/lib/clock.d.ts +0 -15
  487. package/lib/data-paths.d.ts +0 -26
  488. package/lib/debounce.d.ts +0 -42
  489. package/lib/detect-links.d.ts +0 -6
  490. package/lib/env.d.ts +0 -42
  491. package/lib/extmarks-history.d.ts +0 -17
  492. package/lib/extmarks.d.ts +0 -89
  493. package/lib/hast-styled-text.d.ts +0 -17
  494. package/lib/index.d.ts +0 -21
  495. package/lib/keymapping.d.ts +0 -25
  496. package/lib/objects-in-viewport.d.ts +0 -24
  497. package/lib/output.capture.d.ts +0 -24
  498. package/lib/parse.keypress-kitty.d.ts +0 -2
  499. package/lib/parse.keypress.d.ts +0 -26
  500. package/lib/parse.mouse.d.ts +0 -30
  501. package/lib/paste.d.ts +0 -7
  502. package/lib/queue.d.ts +0 -15
  503. package/lib/renderable.validations.d.ts +0 -12
  504. package/lib/scroll-acceleration.d.ts +0 -43
  505. package/lib/selection.d.ts +0 -63
  506. package/lib/singleton.d.ts +0 -7
  507. package/lib/stdin-parser.d.ts +0 -87
  508. package/lib/styled-text.d.ts +0 -63
  509. package/lib/terminal-capability-detection.d.ts +0 -30
  510. package/lib/terminal-palette.d.ts +0 -50
  511. package/lib/tree-sitter/assets/update.d.ts +0 -11
  512. package/lib/tree-sitter/client.d.ts +0 -47
  513. package/lib/tree-sitter/default-parsers.d.ts +0 -2
  514. package/lib/tree-sitter/download-utils.d.ts +0 -21
  515. package/lib/tree-sitter/index.d.ts +0 -8
  516. package/lib/tree-sitter/parser.worker.d.ts +0 -1
  517. package/lib/tree-sitter/parsers-config.d.ts +0 -53
  518. package/lib/tree-sitter/resolve-ft.d.ts +0 -5
  519. package/lib/tree-sitter/types.d.ts +0 -82
  520. package/lib/tree-sitter-styled-text.d.ts +0 -14
  521. package/lib/validate-dir-name.d.ts +0 -1
  522. package/lib/yoga.options.d.ts +0 -32
  523. package/parser.worker.js +0 -899
  524. package/parser.worker.js.map +0 -12
  525. package/plugins/core-slot.d.ts +0 -72
  526. package/plugins/registry.d.ts +0 -42
  527. package/plugins/types.d.ts +0 -34
  528. package/post/effects.d.ts +0 -147
  529. package/post/filters.d.ts +0 -65
  530. package/post/matrices.d.ts +0 -20
  531. package/renderables/ASCIIFont.d.ts +0 -52
  532. package/renderables/Box.d.ts +0 -81
  533. package/renderables/Code.d.ts +0 -78
  534. package/renderables/Diff.d.ts +0 -142
  535. package/renderables/EditBufferRenderable.d.ts +0 -237
  536. package/renderables/FrameBuffer.d.ts +0 -16
  537. package/renderables/Input.d.ts +0 -67
  538. package/renderables/LineNumberRenderable.d.ts +0 -78
  539. package/renderables/Markdown.d.ts +0 -185
  540. package/renderables/ScrollBar.d.ts +0 -77
  541. package/renderables/ScrollBox.d.ts +0 -124
  542. package/renderables/Select.d.ts +0 -115
  543. package/renderables/Slider.d.ts +0 -47
  544. package/renderables/TabSelect.d.ts +0 -96
  545. package/renderables/Text.d.ts +0 -36
  546. package/renderables/TextBufferRenderable.d.ts +0 -105
  547. package/renderables/TextNode.d.ts +0 -91
  548. package/renderables/TextTable.d.ts +0 -140
  549. package/renderables/Textarea.d.ts +0 -63
  550. package/renderables/TimeToFirstDraw.d.ts +0 -24
  551. package/renderables/__tests__/renderable-test-utils.d.ts +0 -12
  552. package/renderables/composition/VRenderable.d.ts +0 -16
  553. package/renderables/composition/constructs.d.ts +0 -35
  554. package/renderables/composition/vnode.d.ts +0 -46
  555. package/renderables/index.d.ts +0 -23
  556. package/renderables/markdown-parser.d.ts +0 -10
  557. package/renderer.d.ts +0 -419
  558. package/runtime-plugin-support.d.ts +0 -3
  559. package/runtime-plugin-support.js +0 -29
  560. package/runtime-plugin-support.js.map +0 -10
  561. package/runtime-plugin.d.ts +0 -16
  562. package/runtime-plugin.js +0 -16
  563. package/runtime-plugin.js.map +0 -9
  564. package/syntax-style.d.ts +0 -54
  565. package/testing/manual-clock.d.ts +0 -17
  566. package/testing/mock-keys.d.ts +0 -81
  567. package/testing/mock-mouse.d.ts +0 -38
  568. package/testing/mock-tree-sitter-client.d.ts +0 -23
  569. package/testing/spy.d.ts +0 -7
  570. package/testing/test-recorder.d.ts +0 -61
  571. package/testing/test-renderer.d.ts +0 -23
  572. package/testing.d.ts +0 -6
  573. package/testing.js +0 -697
  574. package/testing.js.map +0 -15
  575. package/text-buffer-view.d.ts +0 -42
  576. package/text-buffer.d.ts +0 -67
  577. package/types.d.ts +0 -139
  578. package/utils.d.ts +0 -14
  579. package/zig-structs.d.ts +0 -155
  580. package/zig.d.ts +0 -353
  581. /package/{assets → src/lib/tree-sitter/assets}/javascript/highlights.scm +0 -0
  582. /package/{assets → src/lib/tree-sitter/assets}/javascript/tree-sitter-javascript.wasm +0 -0
  583. /package/{assets → src/lib/tree-sitter/assets}/markdown/highlights.scm +0 -0
  584. /package/{assets → src/lib/tree-sitter/assets}/markdown/injections.scm +0 -0
  585. /package/{assets → src/lib/tree-sitter/assets}/markdown/tree-sitter-markdown.wasm +0 -0
  586. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/highlights.scm +0 -0
  587. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
  588. /package/{assets → src/lib/tree-sitter/assets}/typescript/highlights.scm +0 -0
  589. /package/{assets → src/lib/tree-sitter/assets}/typescript/tree-sitter-typescript.wasm +0 -0
  590. /package/{assets → src/lib/tree-sitter/assets}/zig/highlights.scm +0 -0
  591. /package/{assets → src/lib/tree-sitter/assets}/zig/tree-sitter-zig.wasm +0 -0
@@ -0,0 +1,638 @@
1
+ import { test, expect, beforeEach, afterEach, describe } from "bun:test"
2
+ import { createTestRenderer, type TestRenderer } from "../testing/test-renderer.js"
3
+ import { BoxRenderable } from "../renderables/Box.js"
4
+ import { TextRenderable } from "../renderables/Text.js"
5
+
6
+ let testRenderer: TestRenderer
7
+ let renderOnce: () => Promise<void>
8
+ let captureFrame: () => string
9
+ let resize: (width: number, height: number) => void
10
+
11
+ beforeEach(async () => {
12
+ ;({
13
+ renderer: testRenderer,
14
+ renderOnce,
15
+ captureCharFrame: captureFrame,
16
+ resize,
17
+ } = await createTestRenderer({
18
+ width: 40,
19
+ height: 20,
20
+ }))
21
+ })
22
+
23
+ afterEach(() => {
24
+ testRenderer.destroy()
25
+ })
26
+
27
+ describe("Absolute Positioning - Snapshot Tests", () => {
28
+ describe("Basic absolute positioning", () => {
29
+ test("absolute positioned box at top-left", async () => {
30
+ const box = new BoxRenderable(testRenderer, {
31
+ position: "absolute",
32
+ left: 0,
33
+ top: 0,
34
+ width: 15,
35
+ height: 5,
36
+ border: true,
37
+ })
38
+
39
+ const text = new TextRenderable(testRenderer, { content: "Top Left" })
40
+ box.add(text)
41
+ testRenderer.root.add(box)
42
+
43
+ await renderOnce()
44
+ expect(captureFrame()).toMatchSnapshot("absolute positioned box at top-left")
45
+ })
46
+
47
+ test("absolute positioned box at bottom-right using right/bottom", async () => {
48
+ const box = new BoxRenderable(testRenderer, {
49
+ position: "absolute",
50
+ right: 0,
51
+ bottom: 0,
52
+ width: 15,
53
+ height: 5,
54
+ border: true,
55
+ })
56
+
57
+ const text = new TextRenderable(testRenderer, { content: "Bottom Right" })
58
+ box.add(text)
59
+ testRenderer.root.add(box)
60
+
61
+ await renderOnce()
62
+ expect(captureFrame()).toMatchSnapshot("absolute positioned box at bottom-right")
63
+ })
64
+
65
+ test("absolute positioned box centered with left/top", async () => {
66
+ const box = new BoxRenderable(testRenderer, {
67
+ position: "absolute",
68
+ left: 10,
69
+ top: 5,
70
+ width: 20,
71
+ height: 8,
72
+ border: true,
73
+ })
74
+
75
+ const text = new TextRenderable(testRenderer, { content: "Centered" })
76
+ box.add(text)
77
+ testRenderer.root.add(box)
78
+
79
+ await renderOnce()
80
+ expect(captureFrame()).toMatchSnapshot("absolute positioned box centered")
81
+ })
82
+ })
83
+
84
+ describe("Nested absolute positioning", () => {
85
+ test("absolute child inside absolute parent - basic", async () => {
86
+ const parent = new BoxRenderable(testRenderer, {
87
+ position: "absolute",
88
+ left: 5,
89
+ top: 3,
90
+ width: 30,
91
+ height: 12,
92
+ border: true,
93
+ })
94
+
95
+ const child = new BoxRenderable(testRenderer, {
96
+ position: "absolute",
97
+ left: 2,
98
+ top: 1,
99
+ width: 12,
100
+ height: 4,
101
+ border: true,
102
+ })
103
+
104
+ const text = new TextRenderable(testRenderer, { content: "Nested" })
105
+ child.add(text)
106
+ parent.add(child)
107
+ testRenderer.root.add(parent)
108
+
109
+ await renderOnce()
110
+ expect(captureFrame()).toMatchSnapshot("nested absolute - child inside parent at left/top")
111
+ })
112
+
113
+ test("absolute child at bottom:0 inside absolute parent (issue #406 fix)", async () => {
114
+ const parent = new BoxRenderable(testRenderer, {
115
+ position: "absolute",
116
+ left: 5,
117
+ top: 2,
118
+ width: 30,
119
+ height: 14,
120
+ border: true,
121
+ })
122
+
123
+ const child = new BoxRenderable(testRenderer, {
124
+ position: "absolute",
125
+ bottom: 0,
126
+ left: 2,
127
+ width: 15,
128
+ height: 3,
129
+ border: true,
130
+ })
131
+
132
+ const text = new TextRenderable(testRenderer, { content: "At Bottom" })
133
+ child.add(text)
134
+ parent.add(child)
135
+ testRenderer.root.add(parent)
136
+
137
+ await renderOnce()
138
+ expect(captureFrame()).toMatchSnapshot("nested absolute - child at bottom:0 of parent")
139
+ })
140
+
141
+ test("absolute child at right:0 inside absolute parent", async () => {
142
+ const parent = new BoxRenderable(testRenderer, {
143
+ position: "absolute",
144
+ left: 2,
145
+ top: 2,
146
+ width: 35,
147
+ height: 12,
148
+ border: true,
149
+ })
150
+
151
+ const child = new BoxRenderable(testRenderer, {
152
+ position: "absolute",
153
+ right: 0,
154
+ top: 1,
155
+ width: 12,
156
+ height: 4,
157
+ border: true,
158
+ })
159
+
160
+ const text = new TextRenderable(testRenderer, { content: "At Right" })
161
+ child.add(text)
162
+ parent.add(child)
163
+ testRenderer.root.add(parent)
164
+
165
+ await renderOnce()
166
+ expect(captureFrame()).toMatchSnapshot("nested absolute - child at right:0 of parent")
167
+ })
168
+
169
+ test("absolute child at bottom-right corner inside absolute parent", async () => {
170
+ const parent = new BoxRenderable(testRenderer, {
171
+ position: "absolute",
172
+ left: 3,
173
+ top: 1,
174
+ width: 34,
175
+ height: 16,
176
+ border: true,
177
+ })
178
+
179
+ const child = new BoxRenderable(testRenderer, {
180
+ position: "absolute",
181
+ right: 1,
182
+ bottom: 1,
183
+ width: 14,
184
+ height: 4,
185
+ border: true,
186
+ })
187
+
188
+ const text = new TextRenderable(testRenderer, { content: "Corner" })
189
+ child.add(text)
190
+ parent.add(child)
191
+ testRenderer.root.add(parent)
192
+
193
+ await renderOnce()
194
+ expect(captureFrame()).toMatchSnapshot("nested absolute - child at bottom-right corner")
195
+ })
196
+
197
+ test("multiple absolute children inside absolute parent at different positions", async () => {
198
+ const parent = new BoxRenderable(testRenderer, {
199
+ position: "absolute",
200
+ left: 2,
201
+ top: 1,
202
+ width: 36,
203
+ height: 17,
204
+ border: true,
205
+ })
206
+
207
+ const topLeftChild = new BoxRenderable(testRenderer, {
208
+ position: "absolute",
209
+ left: 1,
210
+ top: 1,
211
+ width: 10,
212
+ height: 3,
213
+ border: true,
214
+ })
215
+
216
+ const topRightChild = new BoxRenderable(testRenderer, {
217
+ position: "absolute",
218
+ right: 1,
219
+ top: 1,
220
+ width: 10,
221
+ height: 3,
222
+ border: true,
223
+ })
224
+
225
+ const bottomLeftChild = new BoxRenderable(testRenderer, {
226
+ position: "absolute",
227
+ left: 1,
228
+ bottom: 1,
229
+ width: 10,
230
+ height: 3,
231
+ border: true,
232
+ })
233
+
234
+ const bottomRightChild = new BoxRenderable(testRenderer, {
235
+ position: "absolute",
236
+ right: 1,
237
+ bottom: 1,
238
+ width: 10,
239
+ height: 3,
240
+ border: true,
241
+ })
242
+
243
+ topLeftChild.add(new TextRenderable(testRenderer, { content: "TL" }))
244
+ topRightChild.add(new TextRenderable(testRenderer, { content: "TR" }))
245
+ bottomLeftChild.add(new TextRenderable(testRenderer, { content: "BL" }))
246
+ bottomRightChild.add(new TextRenderable(testRenderer, { content: "BR" }))
247
+
248
+ parent.add(topLeftChild)
249
+ parent.add(topRightChild)
250
+ parent.add(bottomLeftChild)
251
+ parent.add(bottomRightChild)
252
+ testRenderer.root.add(parent)
253
+
254
+ await renderOnce()
255
+ expect(captureFrame()).toMatchSnapshot("nested absolute - four corners inside parent")
256
+ })
257
+ })
258
+
259
+ describe("Three-level nesting", () => {
260
+ test("deeply nested absolute positioning - grandchild at bottom", async () => {
261
+ const grandparent = new BoxRenderable(testRenderer, {
262
+ position: "absolute",
263
+ left: 1,
264
+ top: 1,
265
+ width: 38,
266
+ height: 18,
267
+ border: true,
268
+ })
269
+
270
+ const parent = new BoxRenderable(testRenderer, {
271
+ position: "absolute",
272
+ left: 2,
273
+ top: 2,
274
+ width: 32,
275
+ height: 12,
276
+ border: true,
277
+ })
278
+
279
+ const child = new BoxRenderable(testRenderer, {
280
+ position: "absolute",
281
+ bottom: 1,
282
+ left: 2,
283
+ width: 15,
284
+ height: 3,
285
+ border: true,
286
+ })
287
+
288
+ child.add(new TextRenderable(testRenderer, { content: "Deep" }))
289
+ parent.add(child)
290
+ grandparent.add(parent)
291
+ testRenderer.root.add(grandparent)
292
+
293
+ await renderOnce()
294
+ expect(captureFrame()).toMatchSnapshot("three-level nested absolute - grandchild at bottom")
295
+ })
296
+ })
297
+
298
+ describe("Mixed positioning", () => {
299
+ test("absolute child inside relative parent", async () => {
300
+ const container = new BoxRenderable(testRenderer, {
301
+ width: 40,
302
+ height: 20,
303
+ paddingTop: 2,
304
+ paddingLeft: 3,
305
+ })
306
+
307
+ const parent = new BoxRenderable(testRenderer, {
308
+ position: "relative",
309
+ width: 30,
310
+ height: 14,
311
+ border: true,
312
+ })
313
+
314
+ const absoluteChild = new BoxRenderable(testRenderer, {
315
+ position: "absolute",
316
+ bottom: 1,
317
+ right: 1,
318
+ width: 12,
319
+ height: 4,
320
+ border: true,
321
+ })
322
+
323
+ absoluteChild.add(new TextRenderable(testRenderer, { content: "Absolute" }))
324
+ parent.add(absoluteChild)
325
+ container.add(parent)
326
+ testRenderer.root.add(container)
327
+
328
+ await renderOnce()
329
+ expect(captureFrame()).toMatchSnapshot("absolute child inside relative parent")
330
+ })
331
+
332
+ test("sibling absolute elements at same level", async () => {
333
+ const box1 = new BoxRenderable(testRenderer, {
334
+ position: "absolute",
335
+ left: 0,
336
+ top: 0,
337
+ width: 15,
338
+ height: 6,
339
+ border: true,
340
+ })
341
+
342
+ const box2 = new BoxRenderable(testRenderer, {
343
+ position: "absolute",
344
+ left: 12,
345
+ top: 4,
346
+ width: 15,
347
+ height: 6,
348
+ border: true,
349
+ })
350
+
351
+ const box3 = new BoxRenderable(testRenderer, {
352
+ position: "absolute",
353
+ left: 24,
354
+ top: 8,
355
+ width: 15,
356
+ height: 6,
357
+ border: true,
358
+ })
359
+
360
+ box1.add(new TextRenderable(testRenderer, { content: "Box 1" }))
361
+ box2.add(new TextRenderable(testRenderer, { content: "Box 2" }))
362
+ box3.add(new TextRenderable(testRenderer, { content: "Box 3" }))
363
+
364
+ testRenderer.root.add(box1)
365
+ testRenderer.root.add(box2)
366
+ testRenderer.root.add(box3)
367
+
368
+ await renderOnce()
369
+ expect(captureFrame()).toMatchSnapshot("sibling absolute elements overlapping")
370
+ })
371
+ })
372
+
373
+ describe("Edge cases", () => {
374
+ test("absolute positioned box with negative coordinates (partially off-screen)", async () => {
375
+ const box = new BoxRenderable(testRenderer, {
376
+ position: "absolute",
377
+ left: -5,
378
+ top: -2,
379
+ width: 20,
380
+ height: 8,
381
+ border: true,
382
+ })
383
+
384
+ const text = new TextRenderable(testRenderer, { content: "Partial" })
385
+ box.add(text)
386
+ testRenderer.root.add(box)
387
+
388
+ await renderOnce()
389
+ expect(captureFrame()).toMatchSnapshot("absolute box with negative coordinates")
390
+ })
391
+
392
+ test("absolute positioned box extending beyond viewport", async () => {
393
+ const box = new BoxRenderable(testRenderer, {
394
+ position: "absolute",
395
+ left: 30,
396
+ top: 15,
397
+ width: 20,
398
+ height: 10,
399
+ border: true,
400
+ })
401
+
402
+ const text = new TextRenderable(testRenderer, { content: "Overflow" })
403
+ box.add(text)
404
+ testRenderer.root.add(box)
405
+
406
+ await renderOnce()
407
+ expect(captureFrame()).toMatchSnapshot("absolute box extending beyond viewport")
408
+ })
409
+
410
+ test("absolute child fills parent completely", async () => {
411
+ const parent = new BoxRenderable(testRenderer, {
412
+ position: "absolute",
413
+ left: 5,
414
+ top: 3,
415
+ width: 30,
416
+ height: 12,
417
+ border: true,
418
+ })
419
+
420
+ const child = new BoxRenderable(testRenderer, {
421
+ position: "absolute",
422
+ left: 0,
423
+ top: 0,
424
+ right: 0,
425
+ bottom: 0,
426
+ border: true,
427
+ borderStyle: "double",
428
+ })
429
+
430
+ child.add(new TextRenderable(testRenderer, { content: "Full" }))
431
+ parent.add(child)
432
+ testRenderer.root.add(parent)
433
+
434
+ await renderOnce()
435
+ expect(captureFrame()).toMatchSnapshot("absolute child fills parent with inset 0")
436
+ })
437
+
438
+ test("absolute positioned box with percentage width inside absolute parent", async () => {
439
+ resize(50, 20)
440
+
441
+ const parent = new BoxRenderable(testRenderer, {
442
+ position: "absolute",
443
+ left: 5,
444
+ top: 2,
445
+ width: 40,
446
+ height: 15,
447
+ border: true,
448
+ })
449
+
450
+ const child = new BoxRenderable(testRenderer, {
451
+ position: "absolute",
452
+ left: 2,
453
+ bottom: 1,
454
+ width: "50%",
455
+ height: 4,
456
+ border: true,
457
+ })
458
+
459
+ child.add(new TextRenderable(testRenderer, { content: "50%" }))
460
+ parent.add(child)
461
+ testRenderer.root.add(parent)
462
+
463
+ await renderOnce()
464
+ expect(captureFrame()).toMatchSnapshot("absolute child with percentage width")
465
+ })
466
+
467
+ test("absolute positioned box with percentage height inside absolute parent", async () => {
468
+ const parent = new BoxRenderable(testRenderer, {
469
+ position: "absolute",
470
+ left: 5,
471
+ top: 2,
472
+ width: 30,
473
+ height: 16,
474
+ border: true,
475
+ })
476
+
477
+ const child = new BoxRenderable(testRenderer, {
478
+ position: "absolute",
479
+ left: 2,
480
+ top: 1,
481
+ width: 15,
482
+ height: "50%",
483
+ border: true,
484
+ })
485
+
486
+ child.add(new TextRenderable(testRenderer, { content: "50% H" }))
487
+ parent.add(child)
488
+ testRenderer.root.add(parent)
489
+
490
+ await renderOnce()
491
+ expect(captureFrame()).toMatchSnapshot("absolute child with percentage height")
492
+ })
493
+
494
+ test("absolute child with conflicting insets (left and right without explicit width)", async () => {
495
+ const parent = new BoxRenderable(testRenderer, {
496
+ position: "absolute",
497
+ left: 3,
498
+ top: 2,
499
+ width: 34,
500
+ height: 14,
501
+ border: true,
502
+ })
503
+
504
+ const child = new BoxRenderable(testRenderer, {
505
+ position: "absolute",
506
+ left: 2,
507
+ right: 2,
508
+ top: 2,
509
+ height: 5,
510
+ border: true,
511
+ })
512
+
513
+ child.add(new TextRenderable(testRenderer, { content: "Stretch" }))
514
+ parent.add(child)
515
+ testRenderer.root.add(parent)
516
+
517
+ await renderOnce()
518
+ expect(captureFrame()).toMatchSnapshot("absolute child with left and right insets (no explicit width)")
519
+ })
520
+
521
+ test("absolute child with conflicting insets (top and bottom without explicit height)", async () => {
522
+ const parent = new BoxRenderable(testRenderer, {
523
+ position: "absolute",
524
+ left: 5,
525
+ top: 1,
526
+ width: 30,
527
+ height: 16,
528
+ border: true,
529
+ })
530
+
531
+ const child = new BoxRenderable(testRenderer, {
532
+ position: "absolute",
533
+ top: 1,
534
+ bottom: 1,
535
+ left: 2,
536
+ width: 15,
537
+ border: true,
538
+ })
539
+
540
+ child.add(new TextRenderable(testRenderer, { content: "VStretch" }))
541
+ parent.add(child)
542
+ testRenderer.root.add(parent)
543
+
544
+ await renderOnce()
545
+ expect(captureFrame()).toMatchSnapshot("absolute child with top and bottom insets (no explicit height)")
546
+ })
547
+ })
548
+
549
+ describe("Complex hierarchies", () => {
550
+ test("relative parent with absolute child containing absolute grandchild", async () => {
551
+ const container = new BoxRenderable(testRenderer, {
552
+ width: 40,
553
+ height: 20,
554
+ paddingTop: 1,
555
+ paddingLeft: 2,
556
+ })
557
+
558
+ const relativeParent = new BoxRenderable(testRenderer, {
559
+ position: "relative",
560
+ width: 35,
561
+ height: 16,
562
+ border: true,
563
+ })
564
+
565
+ const absoluteChild = new BoxRenderable(testRenderer, {
566
+ position: "absolute",
567
+ left: 2,
568
+ top: 1,
569
+ width: 28,
570
+ height: 12,
571
+ border: true,
572
+ })
573
+
574
+ const absoluteGrandchild = new BoxRenderable(testRenderer, {
575
+ position: "absolute",
576
+ right: 1,
577
+ bottom: 1,
578
+ width: 12,
579
+ height: 4,
580
+ border: true,
581
+ })
582
+
583
+ absoluteGrandchild.add(new TextRenderable(testRenderer, { content: "Grand" }))
584
+ absoluteChild.add(absoluteGrandchild)
585
+ relativeParent.add(absoluteChild)
586
+ container.add(relativeParent)
587
+ testRenderer.root.add(container)
588
+
589
+ await renderOnce()
590
+ expect(captureFrame()).toMatchSnapshot("relative -> absolute -> absolute hierarchy")
591
+ })
592
+
593
+ test("multiple nested relative and absolute layers", async () => {
594
+ const root = new BoxRenderable(testRenderer, {
595
+ position: "relative",
596
+ width: 38,
597
+ height: 18,
598
+ border: true,
599
+ })
600
+
601
+ const absoluteLayer1 = new BoxRenderable(testRenderer, {
602
+ position: "absolute",
603
+ left: 2,
604
+ top: 1,
605
+ width: 32,
606
+ height: 14,
607
+ border: true,
608
+ })
609
+
610
+ const relativeLayer2 = new BoxRenderable(testRenderer, {
611
+ position: "relative",
612
+ width: 28,
613
+ height: 10,
614
+ marginLeft: 1,
615
+ marginTop: 1,
616
+ border: true,
617
+ })
618
+
619
+ const absoluteLayer3 = new BoxRenderable(testRenderer, {
620
+ position: "absolute",
621
+ right: 1,
622
+ bottom: 1,
623
+ width: 10,
624
+ height: 3,
625
+ border: true,
626
+ })
627
+
628
+ absoluteLayer3.add(new TextRenderable(testRenderer, { content: "Deep" }))
629
+ relativeLayer2.add(absoluteLayer3)
630
+ absoluteLayer1.add(relativeLayer2)
631
+ root.add(absoluteLayer1)
632
+ testRenderer.root.add(root)
633
+
634
+ await renderOnce()
635
+ expect(captureFrame()).toMatchSnapshot("relative -> absolute -> relative -> absolute hierarchy")
636
+ })
637
+ })
638
+ })
@@ -0,0 +1,38 @@
1
+ import { test, expect } from "bun:test"
2
+ import { resolveRenderLib } from "../zig.js"
3
+
4
+ const lib = resolveRenderLib()
5
+
6
+ function expectValidAllocatorStats(stats: ReturnType<typeof lib.getAllocatorStats>): void {
7
+ expect(Number.isFinite(stats.totalRequestedBytes)).toBe(true)
8
+ expect(Number.isFinite(stats.activeAllocations)).toBe(true)
9
+ expect(Number.isFinite(stats.smallAllocations)).toBe(true)
10
+ expect(Number.isFinite(stats.largeAllocations)).toBe(true)
11
+ expect(typeof stats.requestedBytesValid).toBe("boolean")
12
+
13
+ expect(stats.totalRequestedBytes).toBeGreaterThanOrEqual(0)
14
+ expect(stats.activeAllocations).toBeGreaterThanOrEqual(0)
15
+ expect(stats.smallAllocations).toBeGreaterThanOrEqual(0)
16
+ expect(stats.largeAllocations).toBeGreaterThanOrEqual(0)
17
+ expect(stats.activeAllocations).toBe(stats.smallAllocations + stats.largeAllocations)
18
+ }
19
+
20
+ test("getBuildOptions exposes native build flags", () => {
21
+ const buildOptions = lib.getBuildOptions()
22
+ expect(typeof buildOptions.gpaSafeStats).toBe("boolean")
23
+ expect(typeof buildOptions.gpaMemoryLimitTracking).toBe("boolean")
24
+ expect(buildOptions.gpaMemoryLimitTracking).toBe(buildOptions.gpaSafeStats)
25
+ })
26
+
27
+ test("getAllocatorStats returns allocator stats", () => {
28
+ const before = lib.getAllocatorStats()
29
+ expectValidAllocatorStats(before)
30
+
31
+ const textBuffer = lib.createTextBuffer("unicode")
32
+ textBuffer.append("allocator stats smoke test")
33
+
34
+ const after = lib.getAllocatorStats()
35
+ expectValidAllocatorStats(after)
36
+
37
+ textBuffer.destroy()
38
+ })