@effect-tui/react 0.1.0-alpha.1

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 (277) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -0
  3. package/dist/jsx-dev-runtime.d.ts +3 -0
  4. package/dist/jsx-dev-runtime.d.ts.map +1 -0
  5. package/dist/jsx-dev-runtime.js +3 -0
  6. package/dist/jsx-dev-runtime.js.map +1 -0
  7. package/dist/jsx-runtime.d.ts +47 -0
  8. package/dist/jsx-runtime.d.ts.map +1 -0
  9. package/dist/jsx-runtime.js +6 -0
  10. package/dist/jsx-runtime.js.map +1 -0
  11. package/dist/src/codeblock.d.ts +9 -0
  12. package/dist/src/codeblock.d.ts.map +1 -0
  13. package/dist/src/codeblock.js +24 -0
  14. package/dist/src/codeblock.js.map +1 -0
  15. package/dist/src/constants.d.ts +3 -0
  16. package/dist/src/constants.d.ts.map +1 -0
  17. package/dist/src/constants.js +3 -0
  18. package/dist/src/constants.js.map +1 -0
  19. package/dist/src/debug/DiagnosticsPanel.d.ts +7 -0
  20. package/dist/src/debug/DiagnosticsPanel.d.ts.map +1 -0
  21. package/dist/src/debug/DiagnosticsPanel.js +13 -0
  22. package/dist/src/debug/DiagnosticsPanel.js.map +1 -0
  23. package/dist/src/highlight.d.ts +20 -0
  24. package/dist/src/highlight.d.ts.map +1 -0
  25. package/dist/src/highlight.js +51 -0
  26. package/dist/src/highlight.js.map +1 -0
  27. package/dist/src/hooks/index.d.ts +4 -0
  28. package/dist/src/hooks/index.d.ts.map +1 -0
  29. package/dist/src/hooks/index.js +3 -0
  30. package/dist/src/hooks/index.js.map +1 -0
  31. package/dist/src/hooks/use-keyboard.d.ts +18 -0
  32. package/dist/src/hooks/use-keyboard.d.ts.map +1 -0
  33. package/dist/src/hooks/use-keyboard.js +26 -0
  34. package/dist/src/hooks/use-keyboard.js.map +1 -0
  35. package/dist/src/hooks/use-paste.d.ts +5 -0
  36. package/dist/src/hooks/use-paste.d.ts.map +1 -0
  37. package/dist/src/hooks/use-paste.js +14 -0
  38. package/dist/src/hooks/use-paste.js.map +1 -0
  39. package/dist/src/hooks/useFrameStats.d.ts +7 -0
  40. package/dist/src/hooks/useFrameStats.d.ts.map +1 -0
  41. package/dist/src/hooks/useFrameStats.js +28 -0
  42. package/dist/src/hooks/useFrameStats.js.map +1 -0
  43. package/dist/src/hosts/base.d.ts +22 -0
  44. package/dist/src/hosts/base.d.ts.map +1 -0
  45. package/dist/src/hosts/base.js +53 -0
  46. package/dist/src/hosts/base.js.map +1 -0
  47. package/dist/src/hosts/box.d.ts +26 -0
  48. package/dist/src/hosts/box.d.ts.map +1 -0
  49. package/dist/src/hosts/box.js +84 -0
  50. package/dist/src/hosts/box.js.map +1 -0
  51. package/dist/src/hosts/canvas.d.ts +48 -0
  52. package/dist/src/hosts/canvas.d.ts.map +1 -0
  53. package/dist/src/hosts/canvas.js +109 -0
  54. package/dist/src/hosts/canvas.js.map +1 -0
  55. package/dist/src/hosts/codeblock.d.ts +32 -0
  56. package/dist/src/hosts/codeblock.d.ts.map +1 -0
  57. package/dist/src/hosts/codeblock.js +118 -0
  58. package/dist/src/hosts/codeblock.js.map +1 -0
  59. package/dist/src/hosts/hstack.d.ts +18 -0
  60. package/dist/src/hosts/hstack.d.ts.map +1 -0
  61. package/dist/src/hosts/hstack.js +45 -0
  62. package/dist/src/hosts/hstack.js.map +1 -0
  63. package/dist/src/hosts/index.d.ts +16 -0
  64. package/dist/src/hosts/index.d.ts.map +1 -0
  65. package/dist/src/hosts/index.js +40 -0
  66. package/dist/src/hosts/index.js.map +1 -0
  67. package/dist/src/hosts/spacer.d.ts +19 -0
  68. package/dist/src/hosts/spacer.d.ts.map +1 -0
  69. package/dist/src/hosts/spacer.js +28 -0
  70. package/dist/src/hosts/spacer.js.map +1 -0
  71. package/dist/src/hosts/text.d.ts +43 -0
  72. package/dist/src/hosts/text.d.ts.map +1 -0
  73. package/dist/src/hosts/text.js +148 -0
  74. package/dist/src/hosts/text.js.map +1 -0
  75. package/dist/src/hosts/vstack.d.ts +18 -0
  76. package/dist/src/hosts/vstack.d.ts.map +1 -0
  77. package/dist/src/hosts/vstack.js +45 -0
  78. package/dist/src/hosts/vstack.js.map +1 -0
  79. package/dist/src/hosts/zstack.d.ts +20 -0
  80. package/dist/src/hosts/zstack.d.ts.map +1 -0
  81. package/dist/src/hosts/zstack.js +65 -0
  82. package/dist/src/hosts/zstack.js.map +1 -0
  83. package/dist/src/index.d.ts +20 -0
  84. package/dist/src/index.d.ts.map +1 -0
  85. package/dist/src/index.js +20 -0
  86. package/dist/src/index.js.map +1 -0
  87. package/dist/src/inline/index.d.ts +32 -0
  88. package/dist/src/inline/index.d.ts.map +1 -0
  89. package/dist/src/inline/index.js +111 -0
  90. package/dist/src/inline/index.js.map +1 -0
  91. package/dist/src/jsx.d.ts +2 -0
  92. package/dist/src/jsx.d.ts.map +1 -0
  93. package/dist/src/jsx.js +4 -0
  94. package/dist/src/jsx.js.map +1 -0
  95. package/dist/src/motion/color-motion-value.d.ts +32 -0
  96. package/dist/src/motion/color-motion-value.d.ts.map +1 -0
  97. package/dist/src/motion/color-motion-value.js +80 -0
  98. package/dist/src/motion/color-motion-value.js.map +1 -0
  99. package/dist/src/motion/color.d.ts +30 -0
  100. package/dist/src/motion/color.d.ts.map +1 -0
  101. package/dist/src/motion/color.js +172 -0
  102. package/dist/src/motion/color.js.map +1 -0
  103. package/dist/src/motion/color.test.d.ts +2 -0
  104. package/dist/src/motion/color.test.d.ts.map +1 -0
  105. package/dist/src/motion/color.test.js +97 -0
  106. package/dist/src/motion/color.test.js.map +1 -0
  107. package/dist/src/motion/event-emitter.d.ts +18 -0
  108. package/dist/src/motion/event-emitter.d.ts.map +1 -0
  109. package/dist/src/motion/event-emitter.js +30 -0
  110. package/dist/src/motion/event-emitter.js.map +1 -0
  111. package/dist/src/motion/frame.d.ts +9 -0
  112. package/dist/src/motion/frame.d.ts.map +1 -0
  113. package/dist/src/motion/frame.js +51 -0
  114. package/dist/src/motion/frame.js.map +1 -0
  115. package/dist/src/motion/hooks.d.ts +75 -0
  116. package/dist/src/motion/hooks.d.ts.map +1 -0
  117. package/dist/src/motion/hooks.js +190 -0
  118. package/dist/src/motion/hooks.js.map +1 -0
  119. package/dist/src/motion/index.d.ts +4 -0
  120. package/dist/src/motion/index.d.ts.map +1 -0
  121. package/dist/src/motion/index.js +7 -0
  122. package/dist/src/motion/index.js.map +1 -0
  123. package/dist/src/motion/motion-value.d.ts +40 -0
  124. package/dist/src/motion/motion-value.d.ts.map +1 -0
  125. package/dist/src/motion/motion-value.js +109 -0
  126. package/dist/src/motion/motion-value.js.map +1 -0
  127. package/dist/src/motion/motion-value.test.d.ts +2 -0
  128. package/dist/src/motion/motion-value.test.d.ts.map +1 -0
  129. package/dist/src/motion/motion-value.test.js +177 -0
  130. package/dist/src/motion/motion-value.test.js.map +1 -0
  131. package/dist/src/motion/spring-math.d.ts +28 -0
  132. package/dist/src/motion/spring-math.d.ts.map +1 -0
  133. package/dist/src/motion/spring-math.js +81 -0
  134. package/dist/src/motion/spring-math.js.map +1 -0
  135. package/dist/src/motion/types.d.ts +25 -0
  136. package/dist/src/motion/types.d.ts.map +1 -0
  137. package/dist/src/motion/types.js +13 -0
  138. package/dist/src/motion/types.js.map +1 -0
  139. package/dist/src/output.d.ts +47 -0
  140. package/dist/src/output.d.ts.map +1 -0
  141. package/dist/src/output.js +125 -0
  142. package/dist/src/output.js.map +1 -0
  143. package/dist/src/profiler.d.ts +6 -0
  144. package/dist/src/profiler.d.ts.map +1 -0
  145. package/dist/src/profiler.js +73 -0
  146. package/dist/src/profiler.js.map +1 -0
  147. package/dist/src/reconciler/host-config.d.ts +16 -0
  148. package/dist/src/reconciler/host-config.d.ts.map +1 -0
  149. package/dist/src/reconciler/host-config.js +174 -0
  150. package/dist/src/reconciler/host-config.js.map +1 -0
  151. package/dist/src/reconciler/types.d.ts +52 -0
  152. package/dist/src/reconciler/types.d.ts.map +1 -0
  153. package/dist/src/reconciler/types.js +2 -0
  154. package/dist/src/reconciler/types.js.map +1 -0
  155. package/dist/src/renderer.d.ts +101 -0
  156. package/dist/src/renderer.d.ts.map +1 -0
  157. package/dist/src/renderer.js +509 -0
  158. package/dist/src/renderer.js.map +1 -0
  159. package/dist/src/terminal.d.ts +37 -0
  160. package/dist/src/terminal.d.ts.map +1 -0
  161. package/dist/src/terminal.js +65 -0
  162. package/dist/src/terminal.js.map +1 -0
  163. package/dist/src/test/index.d.ts +3 -0
  164. package/dist/src/test/index.d.ts.map +1 -0
  165. package/dist/src/test/index.js +3 -0
  166. package/dist/src/test/index.js.map +1 -0
  167. package/dist/src/test/mock-streams.d.ts +44 -0
  168. package/dist/src/test/mock-streams.d.ts.map +1 -0
  169. package/dist/src/test/mock-streams.js +136 -0
  170. package/dist/src/test/mock-streams.js.map +1 -0
  171. package/dist/src/test/render-tui.d.ts +47 -0
  172. package/dist/src/test/render-tui.d.ts.map +1 -0
  173. package/dist/src/test/render-tui.js +76 -0
  174. package/dist/src/test/render-tui.js.map +1 -0
  175. package/dist/src/trace/SpanTree.d.ts +10 -0
  176. package/dist/src/trace/SpanTree.d.ts.map +1 -0
  177. package/dist/src/trace/SpanTree.js +104 -0
  178. package/dist/src/trace/SpanTree.js.map +1 -0
  179. package/dist/src/trace/index.d.ts +30 -0
  180. package/dist/src/trace/index.d.ts.map +1 -0
  181. package/dist/src/trace/index.js +142 -0
  182. package/dist/src/trace/index.js.map +1 -0
  183. package/dist/src/trace/location.d.ts +9 -0
  184. package/dist/src/trace/location.d.ts.map +1 -0
  185. package/dist/src/trace/location.js +88 -0
  186. package/dist/src/trace/location.js.map +1 -0
  187. package/dist/src/trace/span-processor.d.ts +16 -0
  188. package/dist/src/trace/span-processor.d.ts.map +1 -0
  189. package/dist/src/trace/span-processor.js +54 -0
  190. package/dist/src/trace/span-processor.js.map +1 -0
  191. package/dist/src/trace/span-state.d.ts +79 -0
  192. package/dist/src/trace/span-state.d.ts.map +1 -0
  193. package/dist/src/trace/span-state.js +229 -0
  194. package/dist/src/trace/span-state.js.map +1 -0
  195. package/dist/src/trace/tui-logger.d.ts +8 -0
  196. package/dist/src/trace/tui-logger.d.ts.map +1 -0
  197. package/dist/src/trace/tui-logger.js +70 -0
  198. package/dist/src/trace/tui-logger.js.map +1 -0
  199. package/dist/src/utils/border.d.ts +31 -0
  200. package/dist/src/utils/border.d.ts.map +1 -0
  201. package/dist/src/utils/border.js +81 -0
  202. package/dist/src/utils/border.js.map +1 -0
  203. package/dist/src/utils/flex-layout.d.ts +20 -0
  204. package/dist/src/utils/flex-layout.d.ts.map +1 -0
  205. package/dist/src/utils/flex-layout.js +85 -0
  206. package/dist/src/utils/flex-layout.js.map +1 -0
  207. package/dist/src/utils/index.d.ts +5 -0
  208. package/dist/src/utils/index.d.ts.map +1 -0
  209. package/dist/src/utils/index.js +5 -0
  210. package/dist/src/utils/index.js.map +1 -0
  211. package/dist/src/utils/padding.d.ts +26 -0
  212. package/dist/src/utils/padding.d.ts.map +1 -0
  213. package/dist/src/utils/padding.js +34 -0
  214. package/dist/src/utils/padding.js.map +1 -0
  215. package/dist/src/utils/styles.d.ts +13 -0
  216. package/dist/src/utils/styles.d.ts.map +1 -0
  217. package/dist/src/utils/styles.js +5 -0
  218. package/dist/src/utils/styles.js.map +1 -0
  219. package/dist/src/visualize/index.d.ts +50 -0
  220. package/dist/src/visualize/index.d.ts.map +1 -0
  221. package/dist/src/visualize/index.js +194 -0
  222. package/dist/src/visualize/index.js.map +1 -0
  223. package/dist/tsconfig.tsbuildinfo +1 -0
  224. package/package.json +94 -0
  225. package/src/codeblock.tsx +47 -0
  226. package/src/constants.ts +2 -0
  227. package/src/debug/DiagnosticsPanel.tsx +38 -0
  228. package/src/highlight.ts +76 -0
  229. package/src/hooks/index.ts +3 -0
  230. package/src/hooks/use-keyboard.ts +37 -0
  231. package/src/hooks/use-paste.ts +14 -0
  232. package/src/hooks/useFrameStats.ts +32 -0
  233. package/src/hosts/base.ts +65 -0
  234. package/src/hosts/box.ts +105 -0
  235. package/src/hosts/canvas.ts +155 -0
  236. package/src/hosts/codeblock.ts +145 -0
  237. package/src/hosts/hstack.ts +64 -0
  238. package/src/hosts/index.ts +45 -0
  239. package/src/hosts/spacer.ts +40 -0
  240. package/src/hosts/text.ts +175 -0
  241. package/src/hosts/vstack.ts +64 -0
  242. package/src/hosts/zstack.ts +77 -0
  243. package/src/index.ts +62 -0
  244. package/src/inline/index.tsx +181 -0
  245. package/src/jsx.ts +3 -0
  246. package/src/motion/color-motion-value.ts +90 -0
  247. package/src/motion/color.test.ts +115 -0
  248. package/src/motion/color.ts +191 -0
  249. package/src/motion/event-emitter.ts +35 -0
  250. package/src/motion/frame.ts +59 -0
  251. package/src/motion/hooks.ts +237 -0
  252. package/src/motion/index.ts +17 -0
  253. package/src/motion/motion-value.test.ts +222 -0
  254. package/src/motion/motion-value.ts +140 -0
  255. package/src/motion/spring-math.ts +114 -0
  256. package/src/motion/types.ts +34 -0
  257. package/src/output.ts +156 -0
  258. package/src/profiler.ts +88 -0
  259. package/src/reconciler/host-config.ts +277 -0
  260. package/src/reconciler/types.ts +66 -0
  261. package/src/renderer.ts +661 -0
  262. package/src/terminal.ts +67 -0
  263. package/src/test/index.ts +8 -0
  264. package/src/test/mock-streams.ts +149 -0
  265. package/src/test/render-tui.ts +118 -0
  266. package/src/trace/SpanTree.tsx +195 -0
  267. package/src/trace/index.tsx +205 -0
  268. package/src/trace/location.ts +90 -0
  269. package/src/trace/span-processor.ts +65 -0
  270. package/src/trace/span-state.ts +286 -0
  271. package/src/trace/tui-logger.ts +72 -0
  272. package/src/utils/border.ts +108 -0
  273. package/src/utils/flex-layout.ts +125 -0
  274. package/src/utils/index.ts +4 -0
  275. package/src/utils/padding.ts +45 -0
  276. package/src/utils/styles.ts +14 -0
  277. package/src/visualize/index.tsx +305 -0
@@ -0,0 +1,177 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { motionValue } from "./motion-value.js";
3
+ describe("MotionValue", () => {
4
+ describe("basic operations", () => {
5
+ it("initializes with correct value", () => {
6
+ const mv = motionValue(100);
7
+ expect(mv.get()).toBe(100);
8
+ });
9
+ it("jump() sets value immediately", () => {
10
+ const mv = motionValue(0);
11
+ mv.jump(50);
12
+ expect(mv.get()).toBe(50);
13
+ expect(mv.getVelocity()).toBe(0);
14
+ });
15
+ it("jump() stops any active animation", () => {
16
+ const mv = motionValue(0);
17
+ mv.set(100); // Start animation
18
+ expect(mv.isAnimating()).toBe(true);
19
+ mv.jump(50);
20
+ expect(mv.isAnimating()).toBe(false);
21
+ expect(mv.get()).toBe(50);
22
+ });
23
+ });
24
+ describe("spring animation", () => {
25
+ it("set() starts animation toward target", () => {
26
+ const mv = motionValue(0);
27
+ mv.set(100);
28
+ expect(mv.isAnimating()).toBe(true);
29
+ });
30
+ it("notifies on change", () => {
31
+ const mv = motionValue(0);
32
+ const values = [];
33
+ mv.on("change", (v) => values.push(v));
34
+ mv.jump(50);
35
+ expect(values).toContain(50);
36
+ });
37
+ it("notifies animationStart and animationComplete", async () => {
38
+ const mv = motionValue(0);
39
+ let started = false;
40
+ let completed = false;
41
+ mv.on("animationStart", () => {
42
+ started = true;
43
+ });
44
+ mv.on("animationComplete", () => {
45
+ completed = true;
46
+ });
47
+ mv.set(100, { stiffness: 1000, damping: 50 }); // Fast spring
48
+ expect(started).toBe(true);
49
+ // Wait for animation to complete
50
+ await new Promise((r) => setTimeout(r, 500));
51
+ expect(completed).toBe(true);
52
+ });
53
+ it("stop() halts animation", () => {
54
+ const mv = motionValue(0);
55
+ mv.set(100);
56
+ expect(mv.isAnimating()).toBe(true);
57
+ mv.stop();
58
+ expect(mv.isAnimating()).toBe(false);
59
+ });
60
+ });
61
+ describe("spring physics correctness", () => {
62
+ it("reaches target value when settled", async () => {
63
+ const mv = motionValue(0);
64
+ mv.set(100, { stiffness: 500, damping: 30 });
65
+ await new Promise((r) => setTimeout(r, 1000));
66
+ expect(mv.get()).toBeCloseTo(100, 1);
67
+ });
68
+ it("velocity is zero when settled", async () => {
69
+ const mv = motionValue(0);
70
+ mv.set(100, { stiffness: 500, damping: 30 });
71
+ await new Promise((r) => setTimeout(r, 1000));
72
+ expect(Math.abs(mv.getVelocity())).toBeLessThan(0.1);
73
+ });
74
+ });
75
+ describe("retargeting", () => {
76
+ it("preserves velocity when retargeting mid-animation", async () => {
77
+ const mv = motionValue(0);
78
+ mv.set(100, { stiffness: 100, damping: 10 });
79
+ // Wait a bit for velocity to build up
80
+ await new Promise((r) => setTimeout(r, 50));
81
+ const velocityBefore = mv.getVelocity();
82
+ const positionBefore = mv.get();
83
+ // Retarget to opposite direction
84
+ mv.set(0, { stiffness: 100, damping: 10 });
85
+ // Velocity should be preserved (same value, continuing momentum)
86
+ expect(mv.getVelocity()).toBeCloseTo(velocityBefore, 1);
87
+ expect(mv.get()).toBeCloseTo(positionBefore, 1);
88
+ });
89
+ it("curves smoothly when reversing direction", async () => {
90
+ const mv = motionValue(0);
91
+ mv.set(100, { stiffness: 100, damping: 15 });
92
+ // Wait for positive velocity
93
+ await new Promise((r) => setTimeout(r, 30));
94
+ const velBefore = mv.getVelocity();
95
+ expect(velBefore).toBeGreaterThan(0);
96
+ // Retarget back to 0
97
+ mv.set(0, { stiffness: 100, damping: 15 });
98
+ // Should still have positive velocity immediately after retarget
99
+ expect(mv.getVelocity()).toBeGreaterThan(0);
100
+ // Wait a bit - velocity should decrease and eventually reverse
101
+ await new Promise((r) => setTimeout(r, 100));
102
+ // Position should have moved past where it was (momentum carried it)
103
+ // or started moving back toward 0
104
+ });
105
+ });
106
+ describe("visualDuration/bounce API", () => {
107
+ it("visualDuration controls animation speed", async () => {
108
+ const fast = motionValue(0);
109
+ const slow = motionValue(0);
110
+ fast.set(100, { visualDuration: 0.1, bounce: 0 });
111
+ slow.set(100, { visualDuration: 0.5, bounce: 0 });
112
+ await new Promise((r) => setTimeout(r, 150));
113
+ // Fast should be closer to target
114
+ expect(Math.abs(100 - fast.get())).toBeLessThan(Math.abs(100 - slow.get()));
115
+ });
116
+ it("bounce: 0 means no overshoot (critically damped)", async () => {
117
+ const mv = motionValue(0);
118
+ mv.set(100, { visualDuration: 0.3, bounce: 0 });
119
+ const values = [];
120
+ mv.on("change", (v) => values.push(v));
121
+ await new Promise((r) => setTimeout(r, 500));
122
+ // Should never exceed target
123
+ const max = Math.max(...values);
124
+ expect(max).toBeLessThanOrEqual(100.5); // Small tolerance for numerical precision
125
+ });
126
+ it("bounce > 0 allows overshoot", async () => {
127
+ const mv = motionValue(0);
128
+ mv.set(100, { visualDuration: 0.3, bounce: 0.3 });
129
+ const values = [];
130
+ mv.on("change", (v) => values.push(v));
131
+ await new Promise((r) => setTimeout(r, 500));
132
+ // Should overshoot target
133
+ const max = Math.max(...values);
134
+ expect(max).toBeGreaterThan(100);
135
+ });
136
+ });
137
+ describe("cleanup", () => {
138
+ it("destroy() stops animation and clears subscribers", () => {
139
+ const mv = motionValue(0);
140
+ mv.on("change", () => {
141
+ // subscriber added
142
+ });
143
+ mv.set(100);
144
+ mv.destroy();
145
+ expect(mv.isAnimating()).toBe(false);
146
+ // After destroy, just verify it doesn't throw
147
+ mv.jump(50);
148
+ });
149
+ it("unsubscribe function works", () => {
150
+ const mv = motionValue(0);
151
+ const values = [];
152
+ const unsub = mv.on("change", (v) => values.push(v));
153
+ mv.jump(10);
154
+ expect(values).toContain(10);
155
+ unsub();
156
+ mv.jump(20);
157
+ expect(values).not.toContain(20);
158
+ });
159
+ });
160
+ });
161
+ describe("createSpringResolver", () => {
162
+ // Test the analytical spring formulas directly
163
+ // These are internal but critical for correctness
164
+ it("initial position equals from", () => {
165
+ const mv = motionValue(50);
166
+ mv.set(100, { stiffness: 100, damping: 10 });
167
+ // At t=0, should still be at initial position
168
+ expect(mv.get()).toBe(50);
169
+ });
170
+ it("initial velocity is preserved", () => {
171
+ const mv = motionValue(0);
172
+ mv.set(100, { stiffness: 100, damping: 10 });
173
+ // Initial velocity should be 0 (starting from rest)
174
+ expect(mv.getVelocity()).toBe(0);
175
+ });
176
+ });
177
+ //# sourceMappingURL=motion-value.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motion-value.test.js","sourceRoot":"","sources":["../../../src/motion/motion-value.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Spring physics calculations using analytical solutions.
3
+ * Matches framer-motion's formulas.
4
+ */
5
+ export interface SpringState {
6
+ value: number;
7
+ velocity: number;
8
+ done: boolean;
9
+ }
10
+ export type SpringResolver = (t: number) => SpringState;
11
+ /**
12
+ * Create a spring resolver function using analytical solution.
13
+ * Returns a function that computes position/velocity at any time t.
14
+ */
15
+ export declare function createSpringResolver(from: number, to: number, initialVelocity: number, stiffness: number, damping: number, mass: number, restSpeed?: number, restDelta?: number): SpringResolver;
16
+ /**
17
+ * Convert visualDuration/bounce to stiffness/damping.
18
+ * Uses Motion's formula from motion-dom.
19
+ */
20
+ export declare function springFromVisualDuration(visualDuration: number, bounce: number): {
21
+ stiffness: number;
22
+ damping: number;
23
+ };
24
+ /**
25
+ * Check if a spring has settled.
26
+ */
27
+ export declare function isSpringSettled(velocity: number, delta: number, restSpeed?: number, restDelta?: number): boolean;
28
+ //# sourceMappingURL=spring-math.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spring-math.d.ts","sourceRoot":"","sources":["../../../src/motion/spring-math.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;CACd;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,WAAW,CAAA;AAEvD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,SAAS,SAAO,EAChB,SAAS,SAAO,GACf,cAAc,CA+DhB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,GACb;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAQxC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,SAAO,EAAE,SAAS,SAAO,GAAG,OAAO,CAE5G"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Spring physics calculations using analytical solutions.
3
+ * Matches framer-motion's formulas.
4
+ */
5
+ /**
6
+ * Create a spring resolver function using analytical solution.
7
+ * Returns a function that computes position/velocity at any time t.
8
+ */
9
+ export function createSpringResolver(from, to, initialVelocity, stiffness, damping, mass, restSpeed = 0.01, restDelta = 0.01) {
10
+ // Use same convention as framer-motion: initialDelta = from - to
11
+ const initialDelta = from - to;
12
+ const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
13
+ const angularFreq = Math.sqrt(stiffness / mass);
14
+ const gamma = dampingRatio * angularFreq;
15
+ if (dampingRatio < 1) {
16
+ // Underdamped (oscillates)
17
+ const dampedFreq = angularFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
18
+ // Coefficients matching framer-motion's formula
19
+ const A = initialDelta;
20
+ const B = (initialVelocity + gamma * initialDelta) / dampedFreq;
21
+ return (t) => {
22
+ const envelope = Math.exp(-gamma * t);
23
+ const cos = Math.cos(dampedFreq * t);
24
+ const sin = Math.sin(dampedFreq * t);
25
+ // Position: to + envelope * (A*cos + B*sin)
26
+ const value = to + envelope * (A * cos + B * sin);
27
+ // Velocity: derivative of position
28
+ const velocity = envelope * ((B * dampedFreq - gamma * A) * cos + (-A * dampedFreq - gamma * B) * sin);
29
+ const done = Math.abs(velocity) < restSpeed && Math.abs(to - value) < restDelta;
30
+ return { value, velocity, done };
31
+ };
32
+ }
33
+ else if (dampingRatio === 1) {
34
+ // Critically damped (fastest without oscillation)
35
+ const A = initialDelta;
36
+ const B = initialVelocity + angularFreq * initialDelta;
37
+ return (t) => {
38
+ const envelope = Math.exp(-angularFreq * t);
39
+ const value = to + envelope * (A + B * t);
40
+ const velocity = envelope * (B - angularFreq * A - angularFreq * B * t);
41
+ const done = Math.abs(velocity) < restSpeed && Math.abs(to - value) < restDelta;
42
+ return { value, velocity, done };
43
+ };
44
+ }
45
+ else {
46
+ // Overdamped (slow, no oscillation)
47
+ const s = Math.sqrt(dampingRatio * dampingRatio - 1);
48
+ const r1 = -angularFreq * (dampingRatio - s);
49
+ const r2 = -angularFreq * (dampingRatio + s);
50
+ // Solve: A + B = initialDelta, A*r1 + B*r2 = initialVelocity
51
+ const A = (initialVelocity - r2 * initialDelta) / (r1 - r2);
52
+ const B = initialDelta - A;
53
+ return (t) => {
54
+ const e1 = Math.exp(r1 * t);
55
+ const e2 = Math.exp(r2 * t);
56
+ const value = to + A * e1 + B * e2;
57
+ const velocity = A * r1 * e1 + B * r2 * e2;
58
+ const done = Math.abs(velocity) < restSpeed && Math.abs(to - value) < restDelta;
59
+ return { value, velocity, done };
60
+ };
61
+ }
62
+ }
63
+ /**
64
+ * Convert visualDuration/bounce to stiffness/damping.
65
+ * Uses Motion's formula from motion-dom.
66
+ */
67
+ export function springFromVisualDuration(visualDuration, bounce) {
68
+ const root = (2 * Math.PI) / (visualDuration * 1.2);
69
+ const stiffness = root * root;
70
+ // Clamp bounce to [0.05, 1], then invert: 0 bounce = damping ratio 1, 1 bounce = 0.05
71
+ const clampedBounce = Math.max(0.05, Math.min(1, 1 - bounce));
72
+ const damping = 2 * clampedBounce * Math.sqrt(stiffness);
73
+ return { stiffness, damping };
74
+ }
75
+ /**
76
+ * Check if a spring has settled.
77
+ */
78
+ export function isSpringSettled(velocity, delta, restSpeed = 0.01, restDelta = 0.01) {
79
+ return Math.abs(velocity) < restSpeed && Math.abs(delta) < restDelta;
80
+ }
81
+ //# sourceMappingURL=spring-math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spring-math.js","sourceRoot":"","sources":["../../../src/motion/spring-math.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shared types for the motion system.
3
+ */
4
+ export interface SpringOptions {
5
+ /** Stiffness of the spring. Higher = snappier. Default: 100 */
6
+ stiffness?: number;
7
+ /** Damping of the spring. Higher = less oscillation. Default: 10 */
8
+ damping?: number;
9
+ /** Mass of the spring. Higher = more inertia. Default: 1 */
10
+ mass?: number;
11
+ /**
12
+ * Visual duration in seconds. This is the perceptual duration of the animation.
13
+ * The spring will feel like it completes in this time, though it may technically
14
+ * continue settling. Overrides stiffness/damping when provided.
15
+ */
16
+ visualDuration?: number;
17
+ /** Bounce amount 0-1 when using visualDuration. 0 = no bounce, 1 = full bounce. Default: 0 */
18
+ bounce?: number;
19
+ /** Velocity threshold to consider settled. Default: 0.01 */
20
+ restSpeed?: number;
21
+ /** Position threshold to consider settled. Default: 0.01 */
22
+ restDelta?: number;
23
+ }
24
+ export declare const DEFAULT_SPRING_OPTIONS: Required<SpringOptions>;
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/motion/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,aAAa,CAQ1D,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Shared types for the motion system.
3
+ */
4
+ export const DEFAULT_SPRING_OPTIONS = {
5
+ stiffness: 100,
6
+ damping: 10,
7
+ mass: 1,
8
+ visualDuration: 0,
9
+ bounce: 0,
10
+ restSpeed: 0.01,
11
+ restDelta: 0.01,
12
+ };
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/motion/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuBH,MAAM,CAAC,MAAM,sBAAsB,GAA4B;IAC7D,SAAS,EAAE,GAAG;IACd,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,CAAC;IACP,cAAc,EAAE,CAAC;IACjB,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;CAChB,CAAA"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Output helpers for rendering CellBuffer to ANSI strings.
3
+ * Extracts common logic from renderer.ts rendering paths.
4
+ */
5
+ import type { CellBuffer, Palette } from "@effect-tui/core";
6
+ /**
7
+ * Emit a row of cells as an ANSI string with run-length SGR encoding.
8
+ * Handles wide characters (cellWidth=0 continuations) and style changes.
9
+ *
10
+ * @param buffer - The cell buffer to read from
11
+ * @param palette - Palette for SGR code generation
12
+ * @param y - Row index
13
+ * @param width - Terminal width
14
+ * @param startX - Start column (default 0)
15
+ * @param endX - End column exclusive (default width)
16
+ * @returns ANSI string for the row (no cursor positioning, no trailing reset)
17
+ */
18
+ export declare function emitRow(buffer: CellBuffer, palette: Palette, y: number, width: number, startX?: number, endX?: number): {
19
+ output: string;
20
+ lastStyle: number;
21
+ };
22
+ /**
23
+ * Emit a row and reset style if needed.
24
+ */
25
+ export declare function emitRowWithReset(buffer: CellBuffer, palette: Palette, y: number, width: number, startX?: number, endX?: number): string;
26
+ /**
27
+ * Check if a row changed between two buffers.
28
+ */
29
+ export declare function rowChanged(prev: CellBuffer, next: CellBuffer, y: number, width: number): boolean;
30
+ /**
31
+ * Find the rightmost column with content (non-space or styled).
32
+ * Returns 0 if row is empty.
33
+ */
34
+ export declare function rowContentWidth(buffer: CellBuffer, y: number, width: number): number;
35
+ /**
36
+ * Find the change window between two buffers for a row.
37
+ * Returns the leftmost and rightmost changed columns, or null if no changes.
38
+ */
39
+ export declare function findChangeWindow(prev: CellBuffer, next: CellBuffer, y: number, width: number): {
40
+ left: number;
41
+ right: number;
42
+ } | null;
43
+ /**
44
+ * Find the last row with content in a buffer.
45
+ */
46
+ export declare function contentHeight(buffer: CellBuffer, width: number, height: number): number;
47
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAE3D;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CACtB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,EAChB,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,EACb,MAAM,SAAI,EACV,IAAI,SAAQ,GACV;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA6BvC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,EAChB,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,EACb,MAAM,SAAI,EACV,IAAI,SAAQ,GACV,MAAM,CAGR;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAShG;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAYpF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,UAAU,EAChB,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA2BxC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAUvF"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Output helpers for rendering CellBuffer to ANSI strings.
3
+ * Extracts common logic from renderer.ts rendering paths.
4
+ */
5
+ /**
6
+ * Emit a row of cells as an ANSI string with run-length SGR encoding.
7
+ * Handles wide characters (cellWidth=0 continuations) and style changes.
8
+ *
9
+ * @param buffer - The cell buffer to read from
10
+ * @param palette - Palette for SGR code generation
11
+ * @param y - Row index
12
+ * @param width - Terminal width
13
+ * @param startX - Start column (default 0)
14
+ * @param endX - End column exclusive (default width)
15
+ * @returns ANSI string for the row (no cursor positioning, no trailing reset)
16
+ */
17
+ export function emitRow(buffer, palette, y, width, startX = 0, endX = width) {
18
+ const row = y * width;
19
+ let output = "";
20
+ let visualCol = startX;
21
+ let currentStyle = -1;
22
+ for (let x = startX; x < endX && visualCol < width; x++) {
23
+ const idx = row + x;
24
+ const glyph = buffer.g[idx];
25
+ const styleId = buffer.s[idx];
26
+ const cellWidth = buffer.cw[idx] || 1;
27
+ // Skip continuation cells (wide char second half)
28
+ if (cellWidth === 0)
29
+ continue;
30
+ // Stop if this char would overflow
31
+ if (visualCol + cellWidth > width)
32
+ break;
33
+ // Emit SGR only when style changes (run-length encoding)
34
+ if (styleId !== currentStyle) {
35
+ output += palette.sgr(styleId);
36
+ currentStyle = styleId;
37
+ }
38
+ output += glyph === 32 ? " " : String.fromCodePoint(glyph);
39
+ visualCol += cellWidth;
40
+ }
41
+ return { output, lastStyle: currentStyle };
42
+ }
43
+ /**
44
+ * Emit a row and reset style if needed.
45
+ */
46
+ export function emitRowWithReset(buffer, palette, y, width, startX = 0, endX = width) {
47
+ const { output, lastStyle } = emitRow(buffer, palette, y, width, startX, endX);
48
+ return lastStyle !== 0 ? output + palette.sgr(0) : output;
49
+ }
50
+ /**
51
+ * Check if a row changed between two buffers.
52
+ */
53
+ export function rowChanged(prev, next, y, width) {
54
+ const row = y * width;
55
+ for (let x = 0; x < width; x++) {
56
+ const idx = row + x;
57
+ if (next.g[idx] !== prev.g[idx] || next.s[idx] !== prev.s[idx] || next.cw[idx] !== prev.cw[idx]) {
58
+ return true;
59
+ }
60
+ }
61
+ return false;
62
+ }
63
+ /**
64
+ * Find the rightmost column with content (non-space or styled).
65
+ * Returns 0 if row is empty.
66
+ */
67
+ export function rowContentWidth(buffer, y, width) {
68
+ const row = y * width;
69
+ for (let x = width - 1; x >= 0; x--) {
70
+ const idx = row + x;
71
+ // Skip continuation cells
72
+ if (buffer.cw[idx] === 0)
73
+ continue;
74
+ // Found content if non-space or has style
75
+ if (buffer.g[idx] !== 32 || buffer.s[idx] !== 0) {
76
+ return x + 1;
77
+ }
78
+ }
79
+ return 0;
80
+ }
81
+ /**
82
+ * Find the change window between two buffers for a row.
83
+ * Returns the leftmost and rightmost changed columns, or null if no changes.
84
+ */
85
+ export function findChangeWindow(prev, next, y, width) {
86
+ const row = y * width;
87
+ let left = 0;
88
+ let right = width - 1;
89
+ // Find leftmost change
90
+ while (left <= right) {
91
+ const i = row + left;
92
+ if (next.g[i] !== prev.g[i] || next.s[i] !== prev.s[i] || next.cw[i] !== prev.cw[i]) {
93
+ break;
94
+ }
95
+ left++;
96
+ }
97
+ // No changes found
98
+ if (left > right)
99
+ return null;
100
+ // Find rightmost change
101
+ while (right >= left) {
102
+ const i = row + right;
103
+ if (next.g[i] !== prev.g[i] || next.s[i] !== prev.s[i] || next.cw[i] !== prev.cw[i]) {
104
+ break;
105
+ }
106
+ right--;
107
+ }
108
+ return { left, right };
109
+ }
110
+ /**
111
+ * Find the last row with content in a buffer.
112
+ */
113
+ export function contentHeight(buffer, width, height) {
114
+ for (let y = height - 1; y >= 0; y--) {
115
+ const row = y * width;
116
+ for (let x = 0; x < width; x++) {
117
+ const glyph = buffer.g[row + x];
118
+ const style = buffer.s[row + x];
119
+ if (glyph !== 32 || style !== 0)
120
+ return y + 1;
121
+ }
122
+ }
123
+ return 0;
124
+ }
125
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function startFrame(): number;
2
+ export declare function endFrame(start: number): void;
3
+ export declare function startPhase(): number;
4
+ export declare function endPhase(name: string, start: number): void;
5
+ export declare function dumpStats(): void;
6
+ //# sourceMappingURL=profiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiler.d.ts","sourceRoot":"","sources":["../../src/profiler.ts"],"names":[],"mappings":"AAoBA,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK5C;AAED,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAY1D;AAED,wBAAgB,SAAS,IAAI,IAAI,CA2BhC"}
@@ -0,0 +1,73 @@
1
+ // Simple render profiler - accumulates timing stats per phase
2
+ // Enable with: PROFILE_TUI=1
3
+ // Output goes to ./tui-profile.txt
4
+ import { writeFileSync } from "node:fs";
5
+ const ENABLED = process.env.PROFILE_TUI === "1";
6
+ const OUTPUT_FILE = "tui-profile.txt";
7
+ const phases = new Map();
8
+ let frameCount = 0;
9
+ let frameTotal = 0;
10
+ export function startFrame() {
11
+ if (!ENABLED)
12
+ return 0;
13
+ return performance.now();
14
+ }
15
+ export function endFrame(start) {
16
+ if (!ENABLED)
17
+ return;
18
+ const elapsed = performance.now() - start;
19
+ frameCount++;
20
+ frameTotal += elapsed;
21
+ }
22
+ export function startPhase() {
23
+ if (!ENABLED)
24
+ return 0;
25
+ return performance.now();
26
+ }
27
+ export function endPhase(name, start) {
28
+ if (!ENABLED)
29
+ return;
30
+ const elapsed = performance.now() - start;
31
+ let stats = phases.get(name);
32
+ if (!stats) {
33
+ stats = { total: 0, count: 0, min: Infinity, max: 0 };
34
+ phases.set(name, stats);
35
+ }
36
+ stats.total += elapsed;
37
+ stats.count++;
38
+ stats.min = Math.min(stats.min, elapsed);
39
+ stats.max = Math.max(stats.max, elapsed);
40
+ }
41
+ export function dumpStats() {
42
+ if (!ENABLED || frameCount === 0)
43
+ return;
44
+ const lines = [];
45
+ const avgFrame = frameTotal / frameCount;
46
+ lines.push(`=== TUI Profile (${frameCount} frames, avg ${avgFrame.toFixed(2)}ms) ===`);
47
+ // Sort by total time descending
48
+ const sorted = [...phases.entries()].sort((a, b) => b[1].total - a[1].total);
49
+ for (const [name, stats] of sorted) {
50
+ const avg = stats.total / stats.count;
51
+ const pct = ((stats.total / frameTotal) * 100).toFixed(1);
52
+ lines.push(` ${name.padEnd(12)} ${avg.toFixed(3)}ms avg ${stats.min.toFixed(3)}-${stats.max.toFixed(3)}ms ${pct}%`);
53
+ }
54
+ lines.push("");
55
+ try {
56
+ writeFileSync(OUTPUT_FILE, lines.join("\n"));
57
+ // Also print path after alt buffer exit
58
+ setTimeout(() => console.log(`Profile written to ${OUTPUT_FILE}`), 50);
59
+ }
60
+ catch {
61
+ // Fallback to stderr if file write fails
62
+ console.error(lines.join("\n"));
63
+ }
64
+ }
65
+ // Auto-dump on exit
66
+ if (ENABLED) {
67
+ process.on("exit", dumpStats);
68
+ process.on("SIGINT", () => {
69
+ dumpStats();
70
+ process.exit(0);
71
+ });
72
+ }
73
+ //# sourceMappingURL=profiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiler.js","sourceRoot":"","sources":["../../src/profiler.ts"],"names":[],"mappings":"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"}