linecraft 0.1.0 → 0.2.0

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 (283) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +313 -64
  3. package/lib/api/color.d.ts +6 -0
  4. package/lib/api/color.d.ts.map +1 -0
  5. package/lib/api/color.js +9 -0
  6. package/lib/api/color.js.map +1 -0
  7. package/lib/api/color.test.d.ts +2 -0
  8. package/lib/api/color.test.d.ts.map +1 -0
  9. package/lib/api/color.test.js +23 -0
  10. package/lib/api/color.test.js.map +1 -0
  11. package/lib/api/flex.d.ts +55 -0
  12. package/lib/api/flex.d.ts.map +1 -0
  13. package/lib/api/flex.js +86 -0
  14. package/lib/api/flex.js.map +1 -0
  15. package/lib/api/flex.test.d.ts +2 -0
  16. package/lib/api/flex.test.d.ts.map +1 -0
  17. package/lib/api/flex.test.js +82 -0
  18. package/lib/api/flex.test.js.map +1 -0
  19. package/lib/api/grid.d.ts +22 -0
  20. package/lib/api/grid.d.ts.map +1 -0
  21. package/lib/api/grid.js +65 -0
  22. package/lib/api/grid.js.map +1 -0
  23. package/lib/api/grid.test.d.ts +2 -0
  24. package/lib/api/grid.test.d.ts.map +1 -0
  25. package/lib/api/grid.test.js +48 -0
  26. package/lib/api/grid.test.js.map +1 -0
  27. package/lib/components/base.d.ts +53 -0
  28. package/lib/components/base.d.ts.map +1 -0
  29. package/lib/components/base.js +47 -0
  30. package/lib/components/base.js.map +1 -0
  31. package/lib/components/col.d.ts +35 -0
  32. package/lib/components/col.d.ts.map +1 -0
  33. package/lib/components/col.js +168 -0
  34. package/lib/components/col.js.map +1 -0
  35. package/lib/components/col.test.d.ts +2 -0
  36. package/lib/components/col.test.d.ts.map +1 -0
  37. package/lib/components/col.test.js +96 -0
  38. package/lib/components/col.test.js.map +1 -0
  39. package/lib/components/index.d.ts +3 -0
  40. package/lib/components/index.d.ts.map +1 -0
  41. package/lib/components/index.js +5 -0
  42. package/lib/components/index.js.map +1 -0
  43. package/lib/components/progress-bar-grid.d.ts +20 -0
  44. package/lib/components/progress-bar-grid.d.ts.map +1 -0
  45. package/lib/components/progress-bar-grid.js +44 -0
  46. package/lib/components/progress-bar-grid.js.map +1 -0
  47. package/lib/components/progress-bar-grid.test.d.ts +2 -0
  48. package/lib/components/progress-bar-grid.test.d.ts.map +1 -0
  49. package/lib/components/progress-bar-grid.test.js +101 -0
  50. package/lib/components/progress-bar-grid.test.js.map +1 -0
  51. package/lib/components/progress-bar.d.ts +26 -3
  52. package/lib/components/progress-bar.d.ts.map +1 -1
  53. package/lib/components/progress-bar.js +62 -6
  54. package/lib/components/progress-bar.js.map +1 -1
  55. package/lib/components/progress-bar.test.d.ts +2 -0
  56. package/lib/components/progress-bar.test.d.ts.map +1 -0
  57. package/lib/components/progress-bar.test.js +153 -0
  58. package/lib/components/progress-bar.test.js.map +1 -0
  59. package/lib/components/prompt.d.ts +14 -0
  60. package/lib/components/prompt.d.ts.map +1 -0
  61. package/lib/components/prompt.js +77 -0
  62. package/lib/components/prompt.js.map +1 -0
  63. package/lib/components/renderable.d.ts +42 -0
  64. package/lib/components/renderable.d.ts.map +1 -0
  65. package/lib/components/renderable.js +225 -0
  66. package/lib/components/renderable.js.map +1 -0
  67. package/lib/components/spinner.d.ts +2 -2
  68. package/lib/components/spinner.d.ts.map +1 -1
  69. package/lib/components/spinner.js +3 -1
  70. package/lib/components/spinner.js.map +1 -1
  71. package/lib/components/spinner.test.d.ts +2 -0
  72. package/lib/components/spinner.test.d.ts.map +1 -0
  73. package/lib/components/spinner.test.js +168 -0
  74. package/lib/components/spinner.test.js.map +1 -0
  75. package/lib/components/style.d.ts +16 -0
  76. package/lib/components/style.d.ts.map +1 -0
  77. package/lib/components/style.js +72 -0
  78. package/lib/components/style.js.map +1 -0
  79. package/lib/components/style.test.d.ts +2 -0
  80. package/lib/components/style.test.d.ts.map +1 -0
  81. package/lib/components/style.test.js +135 -0
  82. package/lib/components/style.test.js.map +1 -0
  83. package/lib/components/text.d.ts +24 -0
  84. package/lib/components/text.d.ts.map +1 -0
  85. package/lib/components/text.js +65 -0
  86. package/lib/components/text.js.map +1 -0
  87. package/lib/drawing/boxes.d.ts +33 -0
  88. package/lib/drawing/boxes.d.ts.map +1 -0
  89. package/lib/drawing/boxes.js +76 -0
  90. package/lib/drawing/boxes.js.map +1 -0
  91. package/lib/index.d.ts +18 -11
  92. package/lib/index.d.ts.map +1 -1
  93. package/lib/index.js +21 -10
  94. package/lib/index.js.map +1 -1
  95. package/lib/index.test.d.ts +2 -0
  96. package/lib/index.test.d.ts.map +1 -0
  97. package/lib/index.test.js +80 -0
  98. package/lib/index.test.js.map +1 -0
  99. package/lib/layout/flex.d.ts +39 -0
  100. package/lib/layout/flex.d.ts.map +1 -0
  101. package/lib/layout/flex.js +300 -0
  102. package/lib/layout/flex.js.map +1 -0
  103. package/lib/layout/flex.test.d.ts +2 -0
  104. package/lib/layout/flex.test.d.ts.map +1 -0
  105. package/lib/layout/flex.test.js +206 -0
  106. package/lib/layout/flex.test.js.map +1 -0
  107. package/lib/layout/grid.d.ts +53 -0
  108. package/lib/layout/grid.d.ts.map +1 -0
  109. package/lib/layout/grid.js +421 -0
  110. package/lib/layout/grid.js.map +1 -0
  111. package/lib/layout/grid.test.d.ts +2 -0
  112. package/lib/layout/grid.test.d.ts.map +1 -0
  113. package/lib/layout/grid.test.js +139 -0
  114. package/lib/layout/grid.test.js.map +1 -0
  115. package/lib/native/ansi.d.ts +104 -0
  116. package/lib/native/ansi.d.ts.map +1 -0
  117. package/lib/native/ansi.js +120 -0
  118. package/lib/native/ansi.js.map +1 -0
  119. package/lib/native/ansi.test.d.ts +2 -0
  120. package/lib/native/ansi.test.d.ts.map +1 -0
  121. package/lib/native/ansi.test.js +57 -0
  122. package/lib/native/ansi.test.js.map +1 -0
  123. package/lib/native/buffer.d.ts +32 -0
  124. package/lib/native/buffer.d.ts.map +1 -0
  125. package/lib/native/buffer.js +49 -0
  126. package/lib/native/buffer.js.map +1 -0
  127. package/lib/native/buffer.test.d.ts +2 -0
  128. package/lib/native/buffer.test.d.ts.map +1 -0
  129. package/lib/native/buffer.test.js +64 -0
  130. package/lib/native/buffer.test.js.map +1 -0
  131. package/lib/native/diff.d.ts +20 -0
  132. package/lib/native/diff.d.ts.map +1 -0
  133. package/lib/native/diff.js +33 -0
  134. package/lib/native/diff.js.map +1 -0
  135. package/lib/native/diff.test.d.ts +2 -0
  136. package/lib/native/diff.test.d.ts.map +1 -0
  137. package/lib/native/diff.test.js +106 -0
  138. package/lib/native/diff.test.js.map +1 -0
  139. package/lib/native/region-old.d.ts +117 -0
  140. package/lib/native/region-old.d.ts.map +1 -0
  141. package/lib/native/region-old.js +539 -0
  142. package/lib/native/region-old.js.map +1 -0
  143. package/lib/native/region-renderer.d.ts +167 -0
  144. package/lib/native/region-renderer.d.ts.map +1 -0
  145. package/lib/native/region-renderer.js +1238 -0
  146. package/lib/native/region-renderer.js.map +1 -0
  147. package/lib/native/region-simple.d.ts +44 -0
  148. package/lib/native/region-simple.d.ts.map +1 -0
  149. package/lib/native/region-simple.js +290 -0
  150. package/lib/native/region-simple.js.map +1 -0
  151. package/lib/native/region.d.ts +53 -0
  152. package/lib/native/region.d.ts.map +1 -0
  153. package/lib/native/region.js +426 -0
  154. package/lib/native/region.js.map +1 -0
  155. package/lib/native/region.test.d.ts +2 -0
  156. package/lib/native/region.test.d.ts.map +1 -0
  157. package/lib/native/region.test.js +248 -0
  158. package/lib/native/region.test.js.map +1 -0
  159. package/lib/native/throttle.d.ts +29 -0
  160. package/lib/native/throttle.d.ts.map +1 -0
  161. package/lib/native/throttle.js +57 -0
  162. package/lib/native/throttle.js.map +1 -0
  163. package/lib/native/throttle.test.d.ts +2 -0
  164. package/lib/native/throttle.test.d.ts.map +1 -0
  165. package/lib/native/throttle.test.js +86 -0
  166. package/lib/native/throttle.test.js.map +1 -0
  167. package/lib/native.d.ts +5 -11
  168. package/lib/native.d.ts.map +1 -1
  169. package/lib/native.js +8 -64
  170. package/lib/native.js.map +1 -1
  171. package/lib/region.d.ts +48 -5
  172. package/lib/region.d.ts.map +1 -1
  173. package/lib/region.js +474 -36
  174. package/lib/region.js.map +1 -1
  175. package/lib/region.test.d.ts +2 -0
  176. package/lib/region.test.d.ts.map +1 -0
  177. package/lib/region.test.js +227 -0
  178. package/lib/region.test.js.map +1 -0
  179. package/lib/region.visual.test.d.ts +2 -0
  180. package/lib/region.visual.test.d.ts.map +1 -0
  181. package/lib/region.visual.test.js +55 -0
  182. package/lib/region.visual.test.js.map +1 -0
  183. package/lib/test-helpers/capturable-terminal.d.ts +61 -0
  184. package/lib/test-helpers/capturable-terminal.d.ts.map +1 -0
  185. package/lib/test-helpers/capturable-terminal.js +113 -0
  186. package/lib/test-helpers/capturable-terminal.js.map +1 -0
  187. package/lib/test-helpers/capturable-terminal.test.d.ts +2 -0
  188. package/lib/test-helpers/capturable-terminal.test.d.ts.map +1 -0
  189. package/lib/test-helpers/capturable-terminal.test.js +45 -0
  190. package/lib/test-helpers/capturable-terminal.test.js.map +1 -0
  191. package/lib/test-helpers/mock-region.d.ts +21 -0
  192. package/lib/test-helpers/mock-region.d.ts.map +1 -0
  193. package/lib/test-helpers/mock-region.js +37 -0
  194. package/lib/test-helpers/mock-region.js.map +1 -0
  195. package/lib/test-helpers/virtual-terminal-diff-reflow.test.d.ts +2 -0
  196. package/lib/test-helpers/virtual-terminal-diff-reflow.test.d.ts.map +1 -0
  197. package/lib/test-helpers/virtual-terminal-diff-reflow.test.js +256 -0
  198. package/lib/test-helpers/virtual-terminal-diff-reflow.test.js.map +1 -0
  199. package/lib/test-helpers/virtual-terminal-flex-resize.test.d.ts +2 -0
  200. package/lib/test-helpers/virtual-terminal-flex-resize.test.d.ts.map +1 -0
  201. package/lib/test-helpers/virtual-terminal-flex-resize.test.js +438 -0
  202. package/lib/test-helpers/virtual-terminal-flex-resize.test.js.map +1 -0
  203. package/lib/test-helpers/virtual-terminal.d.ts +176 -0
  204. package/lib/test-helpers/virtual-terminal.d.ts.map +1 -0
  205. package/lib/test-helpers/virtual-terminal.js +492 -0
  206. package/lib/test-helpers/virtual-terminal.js.map +1 -0
  207. package/lib/test-helpers/virtual-terminal.test.d.ts +2 -0
  208. package/lib/test-helpers/virtual-terminal.test.d.ts.map +1 -0
  209. package/lib/test-helpers/virtual-terminal.test.js +219 -0
  210. package/lib/test-helpers/virtual-terminal.test.js.map +1 -0
  211. package/lib/ts/components/spinner.test.d.ts +2 -0
  212. package/lib/ts/components/spinner.test.d.ts.map +1 -0
  213. package/lib/ts/components/spinner.test.js +168 -0
  214. package/lib/ts/components/spinner.test.js.map +1 -0
  215. package/lib/ts/utils/colors.test.d.ts +2 -0
  216. package/lib/ts/utils/colors.test.d.ts.map +1 -0
  217. package/lib/ts/utils/colors.test.js +87 -0
  218. package/lib/ts/utils/colors.test.js.map +1 -0
  219. package/lib/types.d.ts +8 -2
  220. package/lib/types.d.ts.map +1 -1
  221. package/lib/types.js.map +1 -1
  222. package/lib/utils/colors-simple.d.ts +51 -0
  223. package/lib/utils/colors-simple.d.ts.map +1 -0
  224. package/lib/utils/colors-simple.js +59 -0
  225. package/lib/utils/colors-simple.js.map +1 -0
  226. package/lib/utils/colors.d.ts +1 -1
  227. package/lib/utils/colors.d.ts.map +1 -1
  228. package/lib/utils/colors.js.map +1 -1
  229. package/lib/utils/colors.test.d.ts +2 -0
  230. package/lib/utils/colors.test.d.ts.map +1 -0
  231. package/lib/utils/colors.test.js +87 -0
  232. package/lib/utils/colors.test.js.map +1 -0
  233. package/lib/utils/cursor-position.d.ts +22 -0
  234. package/lib/utils/cursor-position.d.ts.map +1 -0
  235. package/lib/utils/cursor-position.js +139 -0
  236. package/lib/utils/cursor-position.js.map +1 -0
  237. package/lib/utils/debug-log.d.ts +2 -0
  238. package/lib/utils/debug-log.d.ts.map +1 -0
  239. package/lib/utils/debug-log.js +36 -0
  240. package/lib/utils/debug-log.js.map +1 -0
  241. package/lib/utils/terminal.d.ts +27 -0
  242. package/lib/utils/terminal.d.ts.map +1 -0
  243. package/lib/utils/terminal.js +116 -0
  244. package/lib/utils/terminal.js.map +1 -0
  245. package/lib/utils/text.d.ts +21 -0
  246. package/lib/utils/text.d.ts.map +1 -0
  247. package/lib/utils/text.js +82 -0
  248. package/lib/utils/text.js.map +1 -0
  249. package/lib/utils/wait-for-spacebar.d.ts +10 -0
  250. package/lib/utils/wait-for-spacebar.d.ts.map +1 -0
  251. package/lib/utils/wait-for-spacebar.js +71 -0
  252. package/lib/utils/wait-for-spacebar.js.map +1 -0
  253. package/package.json +31 -28
  254. package/.cursor/plan.md +0 -952
  255. package/TESTING.md +0 -102
  256. package/build.zig +0 -100
  257. package/examples/basic-progress.ts +0 -21
  258. package/examples/multi-lane.ts +0 -29
  259. package/examples/spinner.ts +0 -20
  260. package/examples/test-basic.ts +0 -23
  261. package/src/ts/components/progress-bar.ts +0 -53
  262. package/src/ts/components/spinner.ts +0 -56
  263. package/src/ts/index.ts +0 -37
  264. package/src/ts/native.ts +0 -86
  265. package/src/ts/region.ts +0 -89
  266. package/src/ts/types/ffi-napi.d.ts +0 -11
  267. package/src/ts/types/ref-napi.d.ts +0 -5
  268. package/src/ts/types.ts +0 -53
  269. package/src/ts/utils/colors.ts +0 -72
  270. package/src/zig/ansi.zig +0 -21
  271. package/src/zig/buffer.zig +0 -37
  272. package/src/zig/diff.zig +0 -43
  273. package/src/zig/region.zig +0 -292
  274. package/src/zig/renderer.zig +0 -92
  275. package/src/zig/test_ansi.zig +0 -66
  276. package/src/zig/test_buffer.zig +0 -82
  277. package/src/zig/test_diff.zig +0 -220
  278. package/src/zig/test_integration.zig +0 -76
  279. package/src/zig/test_region.zig +0 -191
  280. package/src/zig/test_runner.zig +0 -27
  281. package/src/zig/test_throttle.zig +0 -59
  282. package/src/zig/throttle.zig +0 -38
  283. package/tsconfig.json +0 -21
package/TESTING.md DELETED
@@ -1,102 +0,0 @@
1
- # Testing EchoKit
2
-
3
- ## Running Tests
4
-
5
- ### All Tests
6
- ```bash
7
- zig build test
8
- # or
9
- pnpm test
10
- ```
11
-
12
- ### Individual Test Modules
13
- ```bash
14
- # ANSI tests only
15
- zig build test:ansi
16
-
17
- # Throttle tests only
18
- zig build test:throttle
19
-
20
- # Buffer tests only
21
- zig build test:buffer
22
-
23
- # Diff tests only
24
- zig build test:diff
25
-
26
- # Region tests only
27
- zig build test:region
28
- ```
29
-
30
- ## Test Coverage
31
-
32
- ### ANSI Module (`test_ansi.zig`)
33
- - ✅ `move_cursor_to` - Generates correct cursor positioning ANSI
34
- - ✅ `move_cursor_up` - Generates correct up movement ANSI
35
- - ✅ `move_cursor_down` - Generates correct down movement ANSI
36
- - ✅ ANSI constants - All constants verified
37
- - ✅ `move_cursor_to` with zero coordinates
38
- - ✅ `move_cursor_to` with large coordinates
39
- - ✅ `move_cursor_up` with zero
40
-
41
- ### Throttle Module (`test_throttle.zig`)
42
- - ✅ Initialization - Creates throttle with correct FPS
43
- - ✅ `set_fps` - Changes FPS correctly
44
- - ✅ `should_render` - Allows first frame
45
- - ✅ `should_render` - Respects interval (blocks immediate second frame)
46
- - ✅ `time_until_next_frame` - Calculates remaining time correctly
47
- - ✅ Very high FPS (1000 FPS)
48
- - ✅ Very low FPS (1 FPS)
49
-
50
- ### Buffer Module (`test_buffer.zig`)
51
- - ✅ Initialization - Creates empty buffer
52
- - ✅ `write` - Appends data correctly
53
- - ✅ `clear` - Clears buffer
54
- - ✅ `flush` - Writes to stdout and clears
55
- - ✅ Large content handling
56
- - ✅ Multiple writes and flush
57
-
58
- ### Diff Module (`test_diff.zig`)
59
- - ✅ Identical frames - Returns no_change ops
60
- - ✅ Changed line - Detects line updates
61
- - ✅ Inserted line - Detects new lines
62
- - ✅ Deleted line - Detects removed lines
63
- - ✅ Multiple changes - Handles complex diffs
64
- - ✅ Empty frames
65
- - ✅ Completely different frames
66
-
67
- ### Region Module (`test_region.zig`)
68
- - ✅ Initialization - Creates region with correct dimensions
69
- - ✅ `set_line` - Expands automatically when needed
70
- - ✅ `set_line` - Rejects line 0 (1-based indexing)
71
- - ✅ `set` - Splits content by newlines correctly
72
- - ✅ `expand_to` - Expands region height
73
- - ✅ `clear_line` - Clears individual lines
74
- - ✅ Throttle configuration - Sets FPS correctly
75
- - ✅ `set_line` with empty string
76
- - ✅ `set` with empty content
77
- - ✅ `set` with single line (no newline)
78
- - ✅ Multiple `set_line` calls
79
- - ✅ `clear` all lines
80
-
81
- ### Integration Tests (`test_integration.zig`)
82
- - ✅ Region with diff and throttle together
83
- - ✅ Region expansion with multiple operations
84
- - ✅ `set` then `set_line` interaction
85
-
86
- ## Test Output
87
-
88
- All tests print visible output to the console using `std.debug.print()`. Each test shows:
89
- - ✓ Checkmark for passed assertions
90
- - Test name and module
91
- - Relevant values being tested
92
-
93
- Example output:
94
- ```
95
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
96
- Testing: ANSI Module
97
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
98
- ✓ move_cursor_to(10, 5): [1b[5;10H
99
- ✓ move_cursor_up(3): [1b[3A
100
- ✓ All ANSI constants verified
101
- ```
102
-
package/build.zig DELETED
@@ -1,100 +0,0 @@
1
- const std = @import("std");
2
-
3
- pub fn build(b: *std.Build) void {
4
- const target = b.standardTargetOptions(.{});
5
- const optimize = b.standardOptimizeOption(.{});
6
-
7
- // Create shared library for Node.js addon
8
- // In Zig 0.15.x, target and optimize must be set in createModule
9
- const lib = b.addLibrary(.{
10
- .name = "echokit",
11
- .root_module = b.createModule(.{
12
- .root_source_file = b.path("src/zig/renderer.zig"),
13
- .target = target,
14
- .optimize = optimize,
15
- }),
16
- .linkage = .dynamic, // Shared library for Node.js addon
17
- });
18
-
19
- // Link with libc (needed for N-API)
20
- lib.linkLibC();
21
-
22
- // Install the library (defaults to zig-out/lib/)
23
- b.installArtifact(lib);
24
-
25
- // Test all modules together
26
- // Using addTest automatically discovers all test functions
27
- const test_exe = b.addTest(.{
28
- .root_module = b.createModule(.{
29
- .root_source_file = b.path("src/zig/test_runner.zig"),
30
- .target = target,
31
- .optimize = optimize,
32
- }),
33
- });
34
-
35
- const run_tests = b.addRunArtifact(test_exe);
36
- run_tests.has_side_effects = true;
37
- const test_step = b.step("test", "Run all Zig tests with visible console output");
38
- test_step.dependOn(&run_tests.step);
39
-
40
- // Individual test modules (can be run separately for focused testing)
41
- const test_ansi = b.addTest(.{
42
- .root_module = b.createModule(.{
43
- .root_source_file = b.path("src/zig/test_ansi.zig"),
44
- .target = target,
45
- .optimize = optimize,
46
- }),
47
- });
48
- const run_test_ansi = b.addRunArtifact(test_ansi);
49
- run_test_ansi.has_side_effects = true;
50
- const test_ansi_step = b.step("test:ansi", "Run ANSI tests only");
51
- test_ansi_step.dependOn(&run_test_ansi.step);
52
-
53
- const test_throttle = b.addTest(.{
54
- .root_module = b.createModule(.{
55
- .root_source_file = b.path("src/zig/test_throttle.zig"),
56
- .target = target,
57
- .optimize = optimize,
58
- }),
59
- });
60
- const run_test_throttle = b.addRunArtifact(test_throttle);
61
- run_test_throttle.has_side_effects = true;
62
- const test_throttle_step = b.step("test:throttle", "Run Throttle tests only");
63
- test_throttle_step.dependOn(&run_test_throttle.step);
64
-
65
- const test_buffer = b.addTest(.{
66
- .root_module = b.createModule(.{
67
- .root_source_file = b.path("src/zig/test_buffer.zig"),
68
- .target = target,
69
- .optimize = optimize,
70
- }),
71
- });
72
- const run_test_buffer = b.addRunArtifact(test_buffer);
73
- run_test_buffer.has_side_effects = true;
74
- const test_buffer_step = b.step("test:buffer", "Run Buffer tests only");
75
- test_buffer_step.dependOn(&run_test_buffer.step);
76
-
77
- const test_diff = b.addTest(.{
78
- .root_module = b.createModule(.{
79
- .root_source_file = b.path("src/zig/test_diff.zig"),
80
- .target = target,
81
- .optimize = optimize,
82
- }),
83
- });
84
- const run_test_diff = b.addRunArtifact(test_diff);
85
- run_test_diff.has_side_effects = true;
86
- const test_diff_step = b.step("test:diff", "Run Diff tests only");
87
- test_diff_step.dependOn(&run_test_diff.step);
88
-
89
- const test_region = b.addTest(.{
90
- .root_module = b.createModule(.{
91
- .root_source_file = b.path("src/zig/test_region.zig"),
92
- .target = target,
93
- .optimize = optimize,
94
- }),
95
- });
96
- const run_test_region = b.addRunArtifact(test_region);
97
- run_test_region.has_side_effects = true;
98
- const test_region_step = b.step("test:region", "Run Region tests only");
99
- test_region_step.dependOn(&run_test_region.step);
100
- }
@@ -1,21 +0,0 @@
1
- import { createRegion, createProgressBar } from '../src/ts';
2
-
3
- async function main() {
4
- const region = createRegion({ width: 80 });
5
- const progress = createProgressBar(region, 1, {
6
- label: 'Installing packages',
7
- width: 50,
8
- });
9
-
10
- for (let i = 0; i <= 100; i++) {
11
- progress.update(i, 100);
12
- await new Promise(resolve => setTimeout(resolve, 50));
13
- }
14
-
15
- progress.finish();
16
- await new Promise(resolve => setTimeout(resolve, 1000));
17
- region.destroy();
18
- }
19
-
20
- main().catch(console.error);
21
-
@@ -1,29 +0,0 @@
1
- import { createRegion, createProgressBar } from '../src/ts/index.js';
2
-
3
- async function updateProgress(progress: ReturnType<typeof createProgressBar>, total: number) {
4
- for (let i = 0; i <= total; i++) {
5
- progress.update(i, total);
6
- await new Promise(resolve => setTimeout(resolve, 20 + Math.random() * 30));
7
- }
8
- }
9
-
10
- async function main() {
11
- const region = createRegion({ width: 80 });
12
-
13
- const download = createProgressBar(region, 1, { label: 'Downloading' });
14
- const extract = createProgressBar(region, 2, { label: 'Extracting' });
15
- const install = createProgressBar(region, 3, { label: 'Installing' });
16
-
17
- // Update lanes concurrently
18
- await Promise.all([
19
- updateProgress(download, 100),
20
- updateProgress(extract, 100),
21
- updateProgress(install, 100),
22
- ]);
23
-
24
- await new Promise(resolve => setTimeout(resolve, 1000));
25
- region.destroy();
26
- }
27
-
28
- main().catch(console.error);
29
-
@@ -1,20 +0,0 @@
1
- import { createRegion, createSpinner } from '../src/ts/index.js';
2
-
3
- async function main() {
4
- const region = createRegion({ width: 80 });
5
- const spinner = createSpinner(region, 1);
6
-
7
- spinner.setText('Processing...');
8
- spinner.start();
9
-
10
- // Simulate work
11
- await new Promise(resolve => setTimeout(resolve, 3000));
12
-
13
- spinner.stop();
14
- region.setLine(1, '✓ Done!');
15
- await new Promise(resolve => setTimeout(resolve, 1000));
16
- region.destroy();
17
- }
18
-
19
- main().catch(console.error);
20
-
@@ -1,23 +0,0 @@
1
- // Simple test to verify the Node.js API works
2
- import { createRegion } from '../src/ts/index.js';
3
-
4
- console.log('Creating region...');
5
- const region = createRegion({ x: 0, y: 0, width: 80, height: 1 });
6
-
7
- console.log('Setting line 1...');
8
- region.setLine(1, 'Hello from EchoKit!');
9
-
10
- console.log('Setting line 2 (should expand)...');
11
- region.setLine(2, 'This is line 2');
12
-
13
- console.log('Setting multiple lines...');
14
- region.set('Line 1\nLine 2\nLine 3');
15
-
16
- console.log('Flushing...');
17
- region.flush();
18
-
19
- console.log('Cleaning up...');
20
- region.destroy();
21
-
22
- console.log('Test complete!');
23
-
@@ -1,53 +0,0 @@
1
- import { TerminalRegion } from '../region.js';
2
- import type { ProgressBarOptions } from '../types.js';
3
-
4
- export class ProgressBar {
5
- private region: TerminalRegion;
6
- private lineNumber: number; // 1-based
7
- private current: number = 0;
8
- private total: number = 100;
9
- private label: string;
10
- private width: number;
11
- private completeChar: string;
12
- private incompleteChar: string;
13
- private brackets: [string, string];
14
-
15
- constructor(region: TerminalRegion, lineNumber: number, options: ProgressBarOptions = {}) {
16
- this.region = region;
17
- this.lineNumber = lineNumber;
18
- this.label = options.label || '';
19
- this.width = options.width ?? 40;
20
- this.completeChar = options.style?.complete ?? '█';
21
- this.incompleteChar = options.style?.incomplete ?? '░';
22
- this.brackets = options.style?.brackets ?? ['[', ']'];
23
- }
24
-
25
- update(current: number, total: number): void {
26
- this.current = current;
27
- this.total = total;
28
- this.render();
29
- }
30
-
31
- setLabel(label: string): void {
32
- this.label = label;
33
- this.render();
34
- }
35
-
36
- private render(): void {
37
- const percentage = Math.min(100, Math.max(0, (this.current / this.total) * 100));
38
- const filled = Math.floor((percentage / 100) * this.width);
39
- const empty = this.width - filled;
40
-
41
- const bar = this.completeChar.repeat(filled) + this.incompleteChar.repeat(empty);
42
- const text = `${this.label} ${this.brackets[0]}${bar}${this.brackets[1]} ${percentage.toFixed(1)}%`;
43
-
44
- // Just update the line - Zig handles batching and rendering
45
- this.region.setLine(this.lineNumber, text);
46
- // Optional: call flush() if you need immediate rendering
47
- }
48
-
49
- finish(): void {
50
- this.update(this.total, this.total);
51
- }
52
- }
53
-
@@ -1,56 +0,0 @@
1
- import { TerminalRegion } from '../region.js';
2
- import type { SpinnerOptions } from '../types.js';
3
-
4
- const DEFAULT_SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
5
-
6
- export class Spinner {
7
- private region: TerminalRegion;
8
- private lineNumber: number; // 1-based
9
- private frameIndex: number = 0;
10
- private text: string = '';
11
- private interval?: NodeJS.Timeout;
12
- private isRunning: boolean = false;
13
- private frames: string[];
14
- private intervalMs: number;
15
-
16
- constructor(region: TerminalRegion, lineNumber: number, options: SpinnerOptions = {}) {
17
- this.region = region;
18
- this.lineNumber = lineNumber;
19
- this.frames = options.frames ?? DEFAULT_SPINNER_FRAMES;
20
- this.intervalMs = options.interval ?? 100;
21
- }
22
-
23
- start(): void {
24
- if (this.isRunning) return;
25
- this.isRunning = true;
26
- this.interval = setInterval(() => {
27
- this.render();
28
- this.frameIndex = (this.frameIndex + 1) % this.frames.length;
29
- }, this.intervalMs);
30
- }
31
-
32
- stop(): void {
33
- if (!this.isRunning) return;
34
- this.isRunning = false;
35
- if (this.interval) {
36
- clearInterval(this.interval);
37
- }
38
- // Clear the spinner line
39
- this.region.setLine(this.lineNumber, '');
40
- }
41
-
42
- setText(text: string): void {
43
- this.text = text;
44
- this.render();
45
- }
46
-
47
- private render(): void {
48
- const frame = this.frames[this.frameIndex];
49
- const line = `${frame} ${this.text}`;
50
-
51
- // Just update the line - Zig handles batching and rendering
52
- this.region.setLine(this.lineNumber, line);
53
- // Spinner updates frequently, so Zig's throttling will handle smooth animation
54
- }
55
- }
56
-
package/src/ts/index.ts DELETED
@@ -1,37 +0,0 @@
1
- export { TerminalRegion } from './region.js';
2
- export { ProgressBar } from './components/progress-bar.js';
3
- export { Spinner } from './components/spinner.js';
4
- export type {
5
- RegionOptions,
6
- LineContent,
7
- TextStyle,
8
- Color,
9
- ProgressBarOptions,
10
- SpinnerOptions,
11
- } from './types.js';
12
-
13
- import { TerminalRegion } from './region.js';
14
- import { ProgressBar } from './components/progress-bar.js';
15
- import { Spinner } from './components/spinner.js';
16
- import type { RegionOptions, ProgressBarOptions, SpinnerOptions } from './types.js';
17
-
18
- export function createRegion(options?: RegionOptions): TerminalRegion {
19
- return new TerminalRegion(options);
20
- }
21
-
22
- export function createProgressBar(
23
- region: TerminalRegion,
24
- lineNumber: number,
25
- options?: ProgressBarOptions
26
- ): ProgressBar {
27
- return new ProgressBar(region, lineNumber, options);
28
- }
29
-
30
- export function createSpinner(
31
- region: TerminalRegion,
32
- lineNumber: number,
33
- options?: SpinnerOptions
34
- ): Spinner {
35
- return new Spinner(region, lineNumber, options);
36
- }
37
-
package/src/ts/native.ts DELETED
@@ -1,86 +0,0 @@
1
- import { fileURLToPath } from 'url';
2
- import { dirname, join } from 'path';
3
- import { Library } from 'ffi-napi';
4
- import ref from 'ref-napi';
5
-
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = dirname(__filename);
8
-
9
- // Determine the library path based on platform
10
- function getLibraryPath(): string {
11
- const platform = process.platform;
12
-
13
- if (platform === 'darwin') {
14
- return join(__dirname, '../../zig-out/lib/libechokit.dylib');
15
- } else if (platform === 'win32') {
16
- return join(__dirname, '../../zig-out/lib/echokit.dll');
17
- } else {
18
- return join(__dirname, '../../zig-out/lib/libechokit.so');
19
- }
20
- }
21
-
22
- // Load the Zig library using FFI
23
- const lib = Library(getLibraryPath(), {
24
- create_region: ['uint64', ['uint32', 'uint32', 'uint32', 'uint32']],
25
- destroy_region: ['void', ['uint64']],
26
- set_line: ['void', ['uint64', 'uint32', 'pointer', 'size_t']],
27
- set: ['void', ['uint64', 'pointer', 'size_t']],
28
- clear_line: ['void', ['uint64', 'uint32']],
29
- clear_region: ['void', ['uint64']],
30
- flush: ['void', ['uint64']],
31
- set_throttle_fps: ['void', ['uint64', 'uint32']],
32
- });
33
-
34
- export interface NativeRegion {
35
- createRegion(x: number, y: number, width: number, height: number): number;
36
- destroyRegion(handle: number): void;
37
- setLine(handle: number, lineNumber: number, content: string): void; // 1-based
38
- set(handle: number, content: string): void;
39
- clearLine(handle: number, lineNumber: number): void; // 1-based
40
- clearRegion(handle: number): void;
41
- flush(handle: number): void;
42
- setThrottleFps(handle: number, fps: number): void;
43
- }
44
-
45
- export const native: NativeRegion = {
46
- createRegion: (x: number, y: number, width: number, height: number): number => {
47
- return Number(lib.create_region(x, y, width, height));
48
- },
49
-
50
- destroyRegion: (handle: number): void => {
51
- lib.destroy_region(BigInt(handle));
52
- },
53
-
54
- setLine: (handle: number, lineNumber: number, content: string): void => {
55
- const buf = Buffer.from(content, 'utf8');
56
- // Allocate a buffer and copy the string data
57
- const ptr = ref.alloc(buf.length);
58
- buf.copy(ptr);
59
- lib.set_line(BigInt(handle), lineNumber, ptr, buf.length);
60
- },
61
-
62
- set: (handle: number, content: string): void => {
63
- const buf = Buffer.from(content, 'utf8');
64
- // Allocate a buffer and copy the string data
65
- const ptr = ref.alloc(buf.length);
66
- buf.copy(ptr);
67
- lib.set(BigInt(handle), ptr, buf.length);
68
- },
69
-
70
- clearLine: (handle: number, lineNumber: number): void => {
71
- lib.clear_line(BigInt(handle), lineNumber);
72
- },
73
-
74
- clearRegion: (handle: number): void => {
75
- lib.clear_region(BigInt(handle));
76
- },
77
-
78
- flush: (handle: number): void => {
79
- lib.flush(BigInt(handle));
80
- },
81
-
82
- setThrottleFps: (handle: number, fps: number): void => {
83
- lib.set_throttle_fps(BigInt(handle), fps);
84
- },
85
- };
86
-
package/src/ts/region.ts DELETED
@@ -1,89 +0,0 @@
1
- import { native } from './native.js';
2
- import { applyStyle } from './utils/colors.js';
3
- import type { RegionOptions, LineContent, TextStyle } from './types.js';
4
-
5
- export class TerminalRegion {
6
- private handle: number;
7
- private _width: number;
8
- private _height: number; // Current height (may expand)
9
-
10
- constructor(options: RegionOptions = {}) {
11
- const x = options.x ?? 0;
12
- const y = options.y ?? 0;
13
- this._width = options.width ?? (process.stdout.columns ?? 80);
14
- this._height = options.height ?? 1; // Default to 1 line, expands as needed
15
- this.handle = native.createRegion(x, y, this._width, this._height);
16
- }
17
-
18
- get width(): number {
19
- return this._width;
20
- }
21
-
22
- get height(): number {
23
- return this._height;
24
- }
25
-
26
- setLine(lineNumber: number, content: string | LineContent): void {
27
- if (lineNumber < 1) {
28
- throw new Error('Line numbers start at 1');
29
- }
30
-
31
- // Zig handles batching and expansion automatically
32
- const text = typeof content === 'string' ? content : content.text;
33
- // Apply styling if provided
34
- const styled = applyStyle(text, typeof content === 'object' ? content.style : undefined);
35
- native.setLine(this.handle, lineNumber, styled);
36
- // Zig will:
37
- // - Convert to 0-based internally
38
- // - Expand region if lineNumber > current height
39
- // - Buffer this update in pending_frame
40
- // - Check throttle
41
- // - Schedule render if needed (or render immediately if throttle allows)
42
-
43
- // Update our height tracking if Zig expanded
44
- if (lineNumber > this._height) {
45
- this._height = lineNumber;
46
- }
47
- }
48
-
49
- set(content: string | LineContent[]): void {
50
- if (typeof content === 'string') {
51
- // Single string with \n line breaks
52
- native.set(this.handle, content);
53
- // Update height based on line count
54
- this._height = content.split('\n').length;
55
- } else {
56
- // Array of LineContent
57
- const lines = content.map(c =>
58
- applyStyle(c.text, c.style)
59
- ).join('\n');
60
- native.set(this.handle, lines);
61
- this._height = content.length;
62
- }
63
- }
64
-
65
- clearLine(lineNumber: number): void {
66
- if (lineNumber < 1) {
67
- throw new Error('Line numbers start at 1');
68
- }
69
- native.clearLine(this.handle, lineNumber);
70
- }
71
-
72
- clear(): void {
73
- native.clearRegion(this.handle);
74
- }
75
-
76
- flush(): void {
77
- // Force immediate render of any pending updates (bypasses throttle)
78
- native.flush(this.handle);
79
- }
80
-
81
- setThrottle(fps: number): void {
82
- native.setThrottleFps(this.handle, fps);
83
- }
84
-
85
- destroy(): void {
86
- native.destroyRegion(this.handle);
87
- }
88
- }
89
-
@@ -1,11 +0,0 @@
1
- declare module 'ffi-napi' {
2
- export interface Library {
3
- [key: string]: (...args: any[]) => any;
4
- }
5
-
6
- export function Library(
7
- path: string,
8
- functions: Record<string, [string, string[]]>
9
- ): Library;
10
- }
11
-
@@ -1,5 +0,0 @@
1
- declare module 'ref-napi' {
2
- export function alloc(size: number): Buffer;
3
- export function alloc(type: string, size: number): Buffer;
4
- }
5
-