@ranker/raxflow 0.2.1 → 0.2.3

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 (214) hide show
  1. package/dist/benchmark.d.ts +10 -0
  2. package/dist/bin.d.ts +3 -0
  3. package/dist/bootstrap.d.ts +8 -0
  4. package/dist/bridge-adapter-templates.d.ts +4 -0
  5. package/dist/bridge-test.d.ts +7 -0
  6. package/dist/dashboard.d.ts +4 -0
  7. package/dist/doctor.d.ts +6 -0
  8. package/dist/evolve.d.ts +7 -0
  9. package/dist/host-init-templates.d.ts +16 -0
  10. package/dist/hub/__tests__/commands.test.d.ts +2 -0
  11. package/dist/hub/__tests__/history.test.d.ts +2 -0
  12. package/dist/hub/__tests__/parser.test.d.ts +2 -0
  13. package/dist/hub/commands/agents.d.ts +3 -0
  14. package/dist/hub/commands/index.d.ts +4 -0
  15. package/dist/hub/commands/logs.d.ts +3 -0
  16. package/dist/hub/commands/memory.d.ts +3 -0
  17. package/dist/hub/commands/metrics.d.ts +3 -0
  18. package/dist/hub/commands/providers.d.ts +3 -0
  19. package/dist/hub/commands/run.d.ts +3 -0
  20. package/dist/hub/commands/status.d.ts +3 -0
  21. package/dist/hub/commands/workflows.d.ts +3 -0
  22. package/dist/hub/config-loader.d.ts +4 -0
  23. package/dist/hub/history.d.ts +13 -0
  24. package/dist/hub/index.d.ts +4 -0
  25. package/dist/hub/parser.d.ts +4 -0
  26. package/dist/hub/styles/borders.d.ts +23 -0
  27. package/dist/hub/styles/colors.d.ts +63 -0
  28. package/dist/hub/styles/typography.d.ts +34 -0
  29. package/dist/hub/types.d.ts +27 -0
  30. package/{src/index.ts → dist/index.d.ts} +1 -0
  31. package/dist/init-host.d.ts +10 -0
  32. package/dist/install.d.ts +8 -0
  33. package/dist/run.d.ts +16 -0
  34. package/dist/setup/components/ProviderSelector.d.ts.map +1 -1
  35. package/dist/setup/components/ProviderSelector.js +8 -7
  36. package/dist/setup/components/ProviderSelector.js.map +1 -1
  37. package/dist/styles.d.ts +12 -0
  38. package/dist/tui/App.d.ts.map +1 -1
  39. package/dist/tui/App.js +7 -2
  40. package/dist/tui/App.js.map +1 -1
  41. package/dist/tui/components/ChatPanel.d.ts +1 -0
  42. package/dist/tui/components/ChatPanel.d.ts.map +1 -1
  43. package/dist/tui/components/ChatPanel.js +4 -3
  44. package/dist/tui/components/ChatPanel.js.map +1 -1
  45. package/dist/tui/components/DAGPanel.d.ts +1 -0
  46. package/dist/tui/components/DAGPanel.d.ts.map +1 -1
  47. package/dist/tui/components/DAGPanel.js +4 -3
  48. package/dist/tui/components/DAGPanel.js.map +1 -1
  49. package/dist/tui/components/Header.d.ts.map +1 -1
  50. package/dist/tui/components/Header.js +1 -1
  51. package/dist/tui/components/Header.js.map +1 -1
  52. package/dist/tui/components/InputBar.d.ts.map +1 -1
  53. package/dist/tui/components/InputBar.js +1 -1
  54. package/dist/tui/components/InputBar.js.map +1 -1
  55. package/dist/tui/components/LogsPanel.d.ts +1 -0
  56. package/dist/tui/components/LogsPanel.d.ts.map +1 -1
  57. package/dist/tui/components/LogsPanel.js +4 -3
  58. package/dist/tui/components/LogsPanel.js.map +1 -1
  59. package/dist/tui/components/MemoryPanel.d.ts +1 -0
  60. package/dist/tui/components/MemoryPanel.d.ts.map +1 -1
  61. package/dist/tui/components/MemoryPanel.js +2 -2
  62. package/dist/tui/components/MemoryPanel.js.map +1 -1
  63. package/dist/tui/components/MetricsPanel.d.ts +1 -0
  64. package/dist/tui/components/MetricsPanel.d.ts.map +1 -1
  65. package/dist/tui/components/MetricsPanel.js +2 -2
  66. package/dist/tui/components/MetricsPanel.js.map +1 -1
  67. package/dist/tui/components/StatusPanel.d.ts +1 -0
  68. package/dist/tui/components/StatusPanel.d.ts.map +1 -1
  69. package/dist/tui/components/StatusPanel.js +4 -3
  70. package/dist/tui/components/StatusPanel.js.map +1 -1
  71. package/dist/vendor-manifests.d.ts +22 -0
  72. package/package.json +5 -1
  73. package/dashboard/index.html +0 -420
  74. package/dist/hub/chat/ChatApp.d.ts +0 -2
  75. package/dist/hub/chat/ChatApp.d.ts.map +0 -1
  76. package/dist/hub/chat/ChatApp.js +0 -146
  77. package/dist/hub/chat/ChatApp.js.map +0 -1
  78. package/dist/hub/chat/components/ChatInput.d.ts +0 -9
  79. package/dist/hub/chat/components/ChatInput.d.ts.map +0 -1
  80. package/dist/hub/chat/components/ChatInput.js +0 -19
  81. package/dist/hub/chat/components/ChatInput.js.map +0 -1
  82. package/dist/hub/chat/components/MessageList.d.ts +0 -7
  83. package/dist/hub/chat/components/MessageList.d.ts.map +0 -1
  84. package/dist/hub/chat/components/MessageList.js +0 -6
  85. package/dist/hub/chat/components/MessageList.js.map +0 -1
  86. package/dist/hub/chat/context.d.ts.map +0 -1
  87. package/dist/hub/chat/context.js +0 -42
  88. package/dist/hub/chat/context.js.map +0 -1
  89. package/dist/hub/chat/hooks/useChatHistory.d.ts +0 -7
  90. package/dist/hub/chat/hooks/useChatHistory.d.ts.map +0 -1
  91. package/dist/hub/chat/hooks/useChatHistory.js +0 -31
  92. package/dist/hub/chat/hooks/useChatHistory.js.map +0 -1
  93. package/dist/hub/chat/index.d.ts.map +0 -1
  94. package/dist/hub/chat/index.js +0 -7
  95. package/dist/hub/chat/index.js.map +0 -1
  96. package/dist/hub/chat/intent-parser.d.ts.map +0 -1
  97. package/dist/hub/chat/intent-parser.js +0 -48
  98. package/dist/hub/chat/intent-parser.js.map +0 -1
  99. package/dist/hub/chat/types.d.ts.map +0 -1
  100. package/dist/hub/chat/types.js +0 -2
  101. package/dist/hub/chat/types.js.map +0 -1
  102. package/dist/hub/tui/App.d.ts +0 -2
  103. package/dist/hub/tui/App.d.ts.map +0 -1
  104. package/dist/hub/tui/App.js +0 -53
  105. package/dist/hub/tui/App.js.map +0 -1
  106. package/dist/hub/tui/components/AgentQueue.d.ts +0 -6
  107. package/dist/hub/tui/components/AgentQueue.d.ts.map +0 -1
  108. package/dist/hub/tui/components/AgentQueue.js +0 -20
  109. package/dist/hub/tui/components/AgentQueue.js.map +0 -1
  110. package/dist/hub/tui/components/DAGPanel.d.ts +0 -16
  111. package/dist/hub/tui/components/DAGPanel.d.ts.map +0 -1
  112. package/dist/hub/tui/components/DAGPanel.js +0 -51
  113. package/dist/hub/tui/components/DAGPanel.js.map +0 -1
  114. package/dist/hub/tui/components/Header.d.ts +0 -7
  115. package/dist/hub/tui/components/Header.d.ts.map +0 -1
  116. package/dist/hub/tui/components/Header.js +0 -17
  117. package/dist/hub/tui/components/Header.js.map +0 -1
  118. package/dist/hub/tui/components/LogsPanel.d.ts +0 -6
  119. package/dist/hub/tui/components/LogsPanel.d.ts.map +0 -1
  120. package/dist/hub/tui/components/LogsPanel.js +0 -26
  121. package/dist/hub/tui/components/LogsPanel.js.map +0 -1
  122. package/dist/hub/tui/components/StatusBar.d.ts +0 -8
  123. package/dist/hub/tui/components/StatusBar.d.ts.map +0 -1
  124. package/dist/hub/tui/components/StatusBar.js +0 -7
  125. package/dist/hub/tui/components/StatusBar.js.map +0 -1
  126. package/dist/hub/tui/hooks/useEvents.d.ts +0 -2
  127. package/dist/hub/tui/hooks/useEvents.d.ts.map +0 -1
  128. package/dist/hub/tui/hooks/useEvents.js +0 -13
  129. package/dist/hub/tui/hooks/useEvents.js.map +0 -1
  130. package/dist/hub/tui/index.d.ts.map +0 -1
  131. package/dist/hub/tui/index.js +0 -7
  132. package/dist/hub/tui/index.js.map +0 -1
  133. package/dist/hub/tui/types.d.ts.map +0 -1
  134. package/dist/hub/tui/types.js +0 -2
  135. package/dist/hub/tui/types.js.map +0 -1
  136. package/src/benchmark.ts +0 -156
  137. package/src/bin.ts +0 -156
  138. package/src/bootstrap.ts +0 -36
  139. package/src/bridge-adapter-templates.ts +0 -181
  140. package/src/bridge-test.ts +0 -107
  141. package/src/dashboard.ts +0 -51
  142. package/src/doctor.ts +0 -92
  143. package/src/evolve.ts +0 -74
  144. package/src/host-init-templates.ts +0 -134
  145. package/src/hub/__tests__/commands.test.ts +0 -84
  146. package/src/hub/__tests__/history.test.ts +0 -137
  147. package/src/hub/__tests__/parser.test.ts +0 -105
  148. package/src/hub/commands/agents.ts +0 -53
  149. package/src/hub/commands/index.ts +0 -140
  150. package/src/hub/commands/logs.ts +0 -70
  151. package/src/hub/commands/memory.ts +0 -47
  152. package/src/hub/commands/metrics.ts +0 -49
  153. package/src/hub/commands/providers.ts +0 -39
  154. package/src/hub/commands/run.ts +0 -37
  155. package/src/hub/commands/status.ts +0 -69
  156. package/src/hub/commands/workflows.ts +0 -64
  157. package/src/hub/config-loader.ts +0 -37
  158. package/src/hub/event-listener.ts +0 -17
  159. package/src/hub/history.ts +0 -66
  160. package/src/hub/index.ts +0 -132
  161. package/src/hub/parser.ts +0 -107
  162. package/src/hub/styles/borders.ts +0 -74
  163. package/src/hub/styles/colors.ts +0 -129
  164. package/src/hub/styles/typography.ts +0 -68
  165. package/src/hub/types.ts +0 -31
  166. package/src/init-host.ts +0 -285
  167. package/src/install.ts +0 -118
  168. package/src/run.ts +0 -317
  169. package/src/setup/components/ApiKeyInput.tsx +0 -158
  170. package/src/setup/components/AsciiBanner.tsx +0 -125
  171. package/src/setup/components/CliDetector.tsx +0 -230
  172. package/src/setup/components/ModeSelector.tsx +0 -137
  173. package/src/setup/components/ProviderSelector.tsx +0 -174
  174. package/src/setup/components/SetupWizard.tsx +0 -368
  175. package/src/setup/components/StepIndicator.tsx +0 -74
  176. package/src/setup/components/SuccessScreen.tsx +0 -229
  177. package/src/setup/index.ts +0 -34
  178. package/src/setup/utils/cli-detection.ts +0 -99
  179. package/src/setup/utils/config-writer.ts +0 -249
  180. package/src/styles.ts +0 -12
  181. package/src/tui/App.tsx +0 -177
  182. package/src/tui/components/AgentStateIcon.tsx +0 -84
  183. package/src/tui/components/AnimatedBranch.tsx +0 -134
  184. package/src/tui/components/ChatPanel.tsx +0 -125
  185. package/src/tui/components/DAGPanel.tsx +0 -208
  186. package/src/tui/components/ExecutionTimeline.tsx +0 -225
  187. package/src/tui/components/Header.tsx +0 -109
  188. package/src/tui/components/HelpOverlay.tsx +0 -140
  189. package/src/tui/components/InputBar.tsx +0 -69
  190. package/src/tui/components/LogsPanel.tsx +0 -129
  191. package/src/tui/components/MemoryPanel.tsx +0 -163
  192. package/src/tui/components/MetricsPanel.tsx +0 -149
  193. package/src/tui/components/StatusPanel.tsx +0 -137
  194. package/src/tui/components/TaskTree.tsx +0 -159
  195. package/src/tui/components/animations/ProgressBar.tsx +0 -160
  196. package/src/tui/components/animations/Pulse.tsx +0 -73
  197. package/src/tui/components/animations/Spinner.tsx +0 -54
  198. package/src/tui/components/animations/StatusAnimator.tsx +0 -153
  199. package/src/tui/components/animations/TypingEffect.tsx +0 -119
  200. package/src/tui/components/animations/index.ts +0 -16
  201. package/src/tui/hooks/useAnimation.ts +0 -290
  202. package/src/tui/hooks/useAppState.ts +0 -403
  203. package/src/tui/index.ts +0 -9
  204. package/src/tui/services/orchestrator.ts +0 -195
  205. package/src/tui/styles/borders.ts +0 -51
  206. package/src/tui/styles/colors.ts +0 -19
  207. package/src/tui/styles/index.ts +0 -20
  208. package/src/tui/styles/indicators.ts +0 -54
  209. package/src/tui/styles/layout.ts +0 -44
  210. package/src/tui/styles/providers.ts +0 -32
  211. package/src/tui/utils/animation.ts +0 -124
  212. package/src/vendor-manifests.ts +0 -113
  213. package/src/ws-relay.ts +0 -156
  214. package/tsconfig.json +0 -28
@@ -1,54 +0,0 @@
1
- import React, { memo, useMemo } from "react";
2
- import { Text } from "ink";
3
- import { useAnimation } from "../../hooks/useAnimation.js";
4
- import { tuiColors } from "../../styles/index.js";
5
-
6
- export type SpinnerType = "dots" | "circle" | "pulse" | "brackets" | "arrows" | "hamburger" | "grow";
7
-
8
- const SPINNER_FRAMES: Record<SpinnerType, string[]> = {
9
- dots: ["⠋", "⠙", "⠹", "⠸", "⼸", "⠴", "⠦", "⠧", "⠇", "⠏"],
10
- circle: ["◐", "◓", "◑", "◒"],
11
- pulse: ["●", "◐", "○", "◐"],
12
- brackets: ["[ ]", "[= ]", "[== ]", "[=== ]", "[==== ]", "[===== ]", "[====== ]", "[======= ]", "[======== ]", "[========= ]", "[==========]", "[ =========]", "[ ========]", "[ =======]", "[ ======]", "[ =====]", "[ ====]", "[ ===]", "[ ==]", "[ =]"],
13
- arrows: ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"],
14
- hamburger: ["☰", "☱", "ěr", "☳", "☴", "pě", "☲", "☶"],
15
- grow: ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "▇", "▆", "▅", "▄", "▃", "▂"],
16
- };
17
-
18
- const DEFAULT_INTERVALS: Record<SpinnerType, number> = {
19
- dots: 100,
20
- circle: 120,
21
- pulse: 200,
22
- brackets: 80,
23
- arrows: 100,
24
- hamburger: 150,
25
- grow: 100,
26
- };
27
-
28
- interface SpinnerProps {
29
- type?: SpinnerType;
30
- interval?: number;
31
- color?: string;
32
- isAnimating?: boolean;
33
- }
34
-
35
- export const Spinner = memo(function Spinner({
36
- type = "dots",
37
- interval,
38
- color = tuiColors.primary,
39
- isAnimating = true
40
- }: SpinnerProps) {
41
- const frames = SPINNER_FRAMES[type];
42
- const actualInterval = interval ?? DEFAULT_INTERVALS[type];
43
- const { frame } = useAnimation({ interval: actualInterval, loop: true, autoStart: isAnimating, maxFps: 20 });
44
- const currentFrame = frames[frame % frames.length];
45
-
46
- return <Text color={color}>{currentFrame}</Text>;
47
- });
48
-
49
- export function useSpinnerFrame(type: SpinnerType = "dots", tick: number): string {
50
- const frames = SPINNER_FRAMES[type];
51
- return frames[tick % frames.length];
52
- }
53
-
54
- export const spinnerTypes = Object.keys(SPINNER_FRAMES) as SpinnerType[];
@@ -1,153 +0,0 @@
1
- import React, { useState, useEffect, memo, useRef } from "react";
2
- import { Box, Text } from "ink";
3
- import { tuiColors, getStatusIndicator } from "../../styles/index.js";
4
- import { useAnimation } from "../../hooks/useAnimation.js";
5
-
6
- export type TransitionStatus = "entering" | "active" | "exiting" | "hidden";
7
-
8
- interface StatusAnimatorProps {
9
- status: "pending" | "running" | "done" | "error" | "idle" | "queued";
10
- label?: string;
11
- showLabel?: boolean;
12
- transitionDuration?: number;
13
- }
14
-
15
- const STATUS_COLORS: Record<string, string> = {
16
- pending: tuiColors.textTertiary,
17
- queued: tuiColors.warning,
18
- running: tuiColors.primary,
19
- done: tuiColors.success,
20
- error: tuiColors.error,
21
- idle: tuiColors.textQuaternary,
22
- };
23
-
24
- const RUNNING_FRAMES = ["◐", "◓", "◑", "◒"];
25
- const TRANSITION_FRAMES = ["○", "◐", "◓", "●"];
26
- const EXIT_FRAMES = ["●", "◑", "◒", "○"];
27
-
28
- const STATUS_ORDER = ["pending", "queued", "running", "done", "error", "idle"];
29
-
30
- function getStatusColor(status: string): string {
31
- return STATUS_COLORS[status] || tuiColors.textTertiary;
32
- }
33
-
34
- export const StatusAnimator = memo(function StatusAnimator({
35
- status,
36
- label,
37
- showLabel = true,
38
- transitionDuration = 500,
39
- }: StatusAnimatorProps) {
40
- const [displayStatus, setDisplayStatus] = useState(status);
41
- const [isTransitioning, setIsTransitioning] = useState(false);
42
- const [transitionFrame, setTransitionFrame] = useState(0);
43
- const timeoutRef = useRef<NodeJS.Timeout | null>(null);
44
-
45
- const { frame } = useAnimation({ interval: 100, loop: true, maxFps: 15 });
46
-
47
- useEffect(() => {
48
- if (status !== displayStatus) {
49
- setIsTransitioning(true);
50
- timeoutRef.current = setTimeout(() => {
51
- setDisplayStatus(status);
52
- setIsTransitioning(false);
53
- }, transitionDuration);
54
- return () => {
55
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
56
- };
57
- }
58
- }, [status, displayStatus, transitionDuration]);
59
-
60
- const getAnimatedIcon = (): string => {
61
- if (status === "running") {
62
- return RUNNING_FRAMES[frame % RUNNING_FRAMES.length];
63
- }
64
-
65
- if (isTransitioning) {
66
- const frames = STATUS_ORDER.indexOf(status) > STATUS_ORDER.indexOf(displayStatus)
67
- ? TRANSITION_FRAMES
68
- : EXIT_FRAMES;
69
- return frames[transitionFrame % frames.length];
70
- }
71
-
72
- const statusInfo = getStatusIndicator(displayStatus);
73
- return statusInfo.icon;
74
- };
75
-
76
- const color = getStatusColor(status);
77
-
78
- return (
79
- <Box flexDirection="row">
80
- <Text color={color}>{getAnimatedIcon()}</Text>
81
- {showLabel && label && (
82
- <Text color={color}> {label}</Text>
83
- )}
84
- {showLabel && !label && (
85
- <Text color={tuiColors.textSecondary}> [{status.toUpperCase()}]</Text>
86
- )}
87
- </Box>
88
- );
89
- });
90
-
91
- interface MetricPulseProps {
92
- value: number | string;
93
- label: string;
94
- unit?: string;
95
- threshold?: { warning: number; critical: number };
96
- isHighlighted?: boolean;
97
- }
98
-
99
- export const MetricPulse = memo(function MetricPulse({
100
- value,
101
- label,
102
- unit,
103
- threshold,
104
- isHighlighted
105
- }: MetricPulseProps) {
106
- const { frame } = useAnimation({ interval: 200, loop: true, maxFps: 10 });
107
- const numValue = typeof value === "number" ? value : parseFloat(value) || 0;
108
-
109
- let color = tuiColors.success;
110
- if (threshold) {
111
- if (numValue >= threshold.critical) color = tuiColors.error;
112
- else if (numValue >= threshold.warning) color = tuiColors.warning;
113
- }
114
-
115
- return (
116
- <Box flexDirection="row">
117
- <Text color={tuiColors.textTertiary}>{label}:</Text>
118
- <Text color={color} bold={isHighlighted}> {value}{unit || ""}</Text>
119
- </Box>
120
- );
121
- });
122
-
123
- interface FitnessAnimatorProps {
124
- value: number;
125
- previousValue?: number;
126
- }
127
-
128
- export const FitnessAnimator = memo(function FitnessAnimator({ value, previousValue }: FitnessAnimatorProps) {
129
- const { frame } = useAnimation({ interval: 150, loop: true, maxFps: 12 });
130
- const diff = previousValue !== undefined ? value - previousValue : 0;
131
- const isImproving = diff > 0;
132
- const isDeclining = diff < 0;
133
-
134
- let color = tuiColors.success;
135
- if (value >= 0.9) color = tuiColors.success;
136
- else if (value >= 0.7) color = tuiColors.warning;
137
- else color = tuiColors.error;
138
-
139
- const frames = ["●", "◐", "●", "◐"];
140
- const animFrame = (isImproving || isDeclining) ? frames[frame % frames.length] : "●";
141
-
142
- const statusLabel = value >= 0.9 ? "OPTIMAL" : value >= 0.7 ? "GOOD" : "IMPROVING";
143
-
144
- return (
145
- <Box flexDirection="row">
146
- <Text color={tuiColors.textTertiary}>Fitness:</Text>
147
- <Text color={color} bold> {value.toFixed(2)}</Text>
148
- <Text color={tuiColors.textTertiary}> [{statusLabel}]</Text>
149
- {isImproving && <Text color={tuiColors.success}> ↑</Text>}
150
- {isDeclining && <Text color={tuiColors.error}> ↓</Text>}
151
- </Box>
152
- );
153
- });
@@ -1,119 +0,0 @@
1
- import React, { useState, useEffect, memo, useRef } from "react";
2
- import { Box, Text } from "ink";
3
- import { tuiColors } from "../../styles/index.js";
4
- import { Spinner } from "./Spinner.js";
5
-
6
- interface TypingEffectProps {
7
- text: string;
8
- speed?: number;
9
- color?: string;
10
- showCursor?: boolean;
11
- cursorChar?: string;
12
- onComplete?: () => void;
13
- isAnimating?: boolean;
14
- prefix?: string;
15
- }
16
-
17
- export const TypingEffect = memo(function TypingEffect({
18
- text,
19
- speed = 30,
20
- color = tuiColors.textPrimary,
21
- showCursor = true,
22
- cursorChar = "█",
23
- onComplete,
24
- isAnimating = true,
25
- prefix,
26
- }: TypingEffectProps) {
27
- const [displayedChars, setDisplayedChars] = useState(0);
28
- const [isComplete, setIsComplete] = useState(false);
29
- const timeoutRef = useRef<NodeJS.Timeout | null>(null);
30
- const onCompleteRef = useRef(onComplete);
31
- onCompleteRef.current = onComplete;
32
-
33
- useEffect(() => {
34
- if (!isAnimating) {
35
- setDisplayedChars(text.length);
36
- setIsComplete(true);
37
- return;
38
- }
39
-
40
- if (displayedChars >= text.length) {
41
- if (!isComplete) {
42
- setIsComplete(true);
43
- onCompleteRef.current?.();
44
- }
45
- return;
46
- }
47
-
48
- timeoutRef.current = setTimeout(() => {
49
- setDisplayedChars((prev) => prev + 1);
50
- }, speed);
51
-
52
- return () => {
53
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
54
- };
55
- }, [displayedChars, text.length, speed, isComplete, isAnimating]);
56
-
57
- const displayedText = text.slice(0, displayedChars);
58
-
59
- return (
60
- <Box flexDirection="row">
61
- {prefix && <Text color={tuiColors.textTertiary}>{prefix}</Text>}
62
- <Text color={color}>{displayedText}</Text>
63
- {showCursor && !isComplete && <Text color={tuiColors.primary}>{cursorChar}</Text>}
64
- </Box>
65
- );
66
- });
67
-
68
- interface TypewriterMessageProps {
69
- text: string;
70
- speed?: number;
71
- color?: string;
72
- isComplete?: boolean;
73
- }
74
-
75
- export const TypewriterMessage = memo(function TypewriterMessage({
76
- text,
77
- speed = 20,
78
- color = tuiColors.textPrimary,
79
- isComplete
80
- }: TypewriterMessageProps) {
81
- const [displayedChars, setDisplayedChars] = useState(0);
82
- const timeoutRef = useRef<NodeJS.Timeout | null>(null);
83
-
84
- useEffect(() => {
85
- if (isComplete) {
86
- setDisplayedChars(text.length);
87
- return;
88
- }
89
-
90
- if (displayedChars >= text.length) return;
91
-
92
- timeoutRef.current = setTimeout(() => {
93
- setDisplayedChars((prev) => prev + 1);
94
- }, speed);
95
-
96
- return () => {
97
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
98
- };
99
- }, [displayedChars, text.length, speed, isComplete]);
100
-
101
- return <Text color={color}>{text.slice(0, displayedChars)}</Text>;
102
- });
103
-
104
- interface ProcessingIndicatorProps {
105
- text?: string;
106
- color?: string;
107
- }
108
-
109
- export const ProcessingIndicator = memo(function ProcessingIndicator({
110
- text = "Processing",
111
- color = tuiColors.warning
112
- }: ProcessingIndicatorProps) {
113
- return (
114
- <Box flexDirection="row">
115
- <Spinner type="dots" color={color} />
116
- <Text color={color}> {text}...</Text>
117
- </Box>
118
- );
119
- });
@@ -1,16 +0,0 @@
1
- export { Spinner, useSpinnerFrame, spinnerTypes } from "./Spinner.js";
2
- export type { SpinnerType } from "./Spinner.js";
3
-
4
- export { Pulse, StatusPulse, usePulseFrame, usePulseIntensity } from "./Pulse.js";
5
-
6
- export { TypingEffect, TypewriterMessage, ProcessingIndicator } from "./TypingEffect.js";
7
-
8
- export { StatusAnimator, MetricPulse, FitnessAnimator } from "./StatusAnimator.js";
9
- export type { TransitionStatus } from "./StatusAnimator.js";
10
-
11
- export {
12
- AnimatedProgressBar,
13
- ProgressWithLabel,
14
- SegmentedProgress,
15
- WorkflowProgress
16
- } from "./ProgressBar.js";
@@ -1,290 +0,0 @@
1
- import { useState, useEffect, useCallback, useRef } from "react";
2
-
3
- export interface AnimationOptions {
4
- interval?: number;
5
- loop?: boolean;
6
- autoStart?: boolean;
7
- totalFrames?: number;
8
- maxFps?: number;
9
- pauseOnHidden?: boolean;
10
- }
11
-
12
- export interface AnimationState {
13
- frame: number;
14
- tick: number;
15
- isAnimating: boolean;
16
- progress: number;
17
- start: () => void;
18
- stop: () => void;
19
- reset: () => void;
20
- toggle: () => void;
21
- }
22
-
23
- const DEFAULT_FPS_LIMIT = 24;
24
- const FRAME_SKIP_THRESHOLD = 2;
25
-
26
- export function useAnimation(options: AnimationOptions = {}): AnimationState {
27
- const {
28
- interval = 100,
29
- loop = true,
30
- autoStart = true,
31
- totalFrames = 100,
32
- maxFps = DEFAULT_FPS_LIMIT,
33
- pauseOnHidden = true,
34
- } = options;
35
-
36
- const [frame, setFrame] = useState(0);
37
- const [isAnimating, setIsAnimating] = useState(autoStart);
38
- const intervalRef = useRef<NodeJS.Timeout | null>(null);
39
- const lastFrameTimeRef = useRef<number>(0);
40
- const frameCountRef = useRef<number>(0);
41
- const isHiddenRef = useRef<boolean>(false);
42
-
43
- useEffect(() => {
44
- if (!pauseOnHidden || typeof document === "undefined") return;
45
-
46
- const handleVisibility = () => {
47
- isHiddenRef.current = document.hidden;
48
- };
49
-
50
- document.addEventListener("visibilitychange", handleVisibility);
51
- return () => document.removeEventListener("visibilitychange", handleVisibility);
52
- }, [pauseOnHidden]);
53
-
54
- const start = useCallback(() => {
55
- setIsAnimating(true);
56
- }, []);
57
-
58
- const stop = useCallback(() => {
59
- setIsAnimating(false);
60
- }, []);
61
-
62
- const reset = useCallback(() => {
63
- setFrame(0);
64
- frameCountRef.current = 0;
65
- lastFrameTimeRef.current = 0;
66
- }, []);
67
-
68
- const toggle = useCallback(() => {
69
- setIsAnimating((prev) => !prev);
70
- }, []);
71
-
72
- useEffect(() => {
73
- if (!isAnimating) {
74
- if (intervalRef.current) {
75
- clearInterval(intervalRef.current);
76
- intervalRef.current = null;
77
- }
78
- return;
79
- }
80
-
81
- const minFrameTime = 1000 / maxFps;
82
-
83
- intervalRef.current = setInterval(() => {
84
- if (pauseOnHidden && isHiddenRef.current) return;
85
-
86
- const now = performance.now();
87
- const elapsed = now - lastFrameTimeRef.current;
88
-
89
- if (elapsed < minFrameTime) return;
90
-
91
- const framesToSkip = Math.floor(elapsed / interval) - 1;
92
- const shouldSkipFrame = framesToSkip > FRAME_SKIP_THRESHOLD;
93
-
94
- if (shouldSkipFrame) {
95
- frameCountRef.current += framesToSkip;
96
- }
97
-
98
- lastFrameTimeRef.current = now;
99
- frameCountRef.current++;
100
-
101
- setFrame((prev) => {
102
- if (loop) {
103
- return prev + 1;
104
- }
105
- return prev >= totalFrames - 1 ? prev : prev + 1;
106
- });
107
- }, interval);
108
-
109
- return () => {
110
- if (intervalRef.current) {
111
- clearInterval(intervalRef.current);
112
- intervalRef.current = null;
113
- }
114
- };
115
- }, [isAnimating, interval, loop, totalFrames, maxFps, pauseOnHidden]);
116
-
117
- const progress = totalFrames > 0 ? (frame % totalFrames) / totalFrames : 0;
118
-
119
- return {
120
- frame,
121
- tick: frame,
122
- isAnimating,
123
- progress,
124
- start,
125
- stop,
126
- reset,
127
- toggle,
128
- };
129
- }
130
-
131
- export function usePulse(interval: number = 2000): { intensity: number; frame: number } {
132
- const { frame } = useAnimation({ interval: 100, loop: true, maxFps: 15 });
133
- const intensity = 0.5 + Math.sin((frame * 100 / interval) * Math.PI * 2) * 0.5;
134
- return { intensity, frame };
135
- }
136
-
137
- export function useTypewriter(
138
- text: string,
139
- speed: number = 50,
140
- startDelay: number = 0
141
- ): { displayedText: string; isComplete: boolean; restart: () => void } {
142
- const [displayedChars, setDisplayedChars] = useState(0);
143
- const [isStarted, setIsStarted] = useState(false);
144
- const [isComplete, setIsComplete] = useState(false);
145
- const timeoutRef = useRef<NodeJS.Timeout | null>(null);
146
-
147
- const restart = useCallback(() => {
148
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
149
- setDisplayedChars(0);
150
- setIsStarted(false);
151
- setIsComplete(false);
152
- }, []);
153
-
154
- useEffect(() => {
155
- restart();
156
- }, [text, restart]);
157
-
158
- useEffect(() => {
159
- if (startDelay > 0 && !isStarted) {
160
- const timeout = setTimeout(() => setIsStarted(true), startDelay);
161
- return () => clearTimeout(timeout);
162
- } else if (startDelay === 0) {
163
- setIsStarted(true);
164
- }
165
- }, [startDelay, isStarted]);
166
-
167
- useEffect(() => {
168
- if (!isStarted || isComplete) return;
169
-
170
- if (displayedChars >= text.length) {
171
- setIsComplete(true);
172
- return;
173
- }
174
-
175
- timeoutRef.current = setTimeout(() => {
176
- setDisplayedChars((prev) => prev + 1);
177
- }, speed);
178
-
179
- return () => {
180
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
181
- };
182
- }, [isStarted, displayedChars, text.length, speed, isComplete]);
183
-
184
- return {
185
- displayedText: text.slice(0, displayedChars),
186
- isComplete,
187
- restart,
188
- };
189
- }
190
-
191
- export function useCountdown(
192
- initialSeconds: number,
193
- options: { autoStart?: boolean; onComplete?: () => void } = {}
194
- ): { seconds: number; isRunning: boolean; start: () => void; pause: () => void; reset: () => void } {
195
- const { autoStart = false, onComplete } = options;
196
- const [seconds, setSeconds] = useState(initialSeconds);
197
- const [isRunning, setIsRunning] = useState(autoStart);
198
- const onCompleteRef = useRef(onComplete);
199
- const intervalRef = useRef<NodeJS.Timeout | null>(null);
200
- onCompleteRef.current = onComplete;
201
-
202
- const start = useCallback(() => setIsRunning(true), []);
203
- const pause = useCallback(() => setIsRunning(false), []);
204
- const reset = useCallback(() => {
205
- setSeconds(initialSeconds);
206
- setIsRunning(false);
207
- }, [initialSeconds]);
208
-
209
- useEffect(() => {
210
- if (!isRunning || seconds <= 0) {
211
- if (seconds <= 0 && isRunning) {
212
- setIsRunning(false);
213
- onCompleteRef.current?.();
214
- }
215
- return;
216
- }
217
-
218
- intervalRef.current = setInterval(() => {
219
- setSeconds((prev) => prev - 1);
220
- }, 1000);
221
-
222
- return () => {
223
- if (intervalRef.current) clearInterval(intervalRef.current);
224
- };
225
- }, [isRunning, seconds]);
226
-
227
- return { seconds, isRunning, start, pause, reset };
228
- }
229
-
230
- export function useFps(targetFps: number = 24): number {
231
- const [frame, setFrame] = useState(0);
232
- const frameRef = useRef(0);
233
- const lastTimeRef = useRef(performance.now());
234
- const rafIdRef = useRef<number | null>(null);
235
-
236
- useEffect(() => {
237
- const interval = 1000 / targetFps;
238
-
239
- const tick = () => {
240
- const now = performance.now();
241
- const delta = now - lastTimeRef.current;
242
-
243
- if (delta >= interval) {
244
- lastTimeRef.current = now - (delta % interval);
245
- frameRef.current++;
246
- setFrame(frameRef.current);
247
- }
248
-
249
- rafIdRef.current = requestAnimationFrame(tick);
250
- };
251
-
252
- rafIdRef.current = requestAnimationFrame(tick);
253
- return () => {
254
- if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);
255
- };
256
- }, [targetFps]);
257
-
258
- return frame;
259
- }
260
-
261
- export function useDebouncedCallback<T extends (...args: unknown[]) => void>(
262
- callback: T,
263
- delay: number
264
- ): T {
265
- const timeoutRef = useRef<NodeJS.Timeout | null>(null);
266
- const callbackRef = useRef(callback);
267
- callbackRef.current = callback;
268
-
269
- return useCallback(((...args: Parameters<T>) => {
270
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
271
- timeoutRef.current = setTimeout(() => callbackRef.current(...args), delay);
272
- }) as T, [delay]);
273
- }
274
-
275
- export function useThrottledCallback<T extends (...args: unknown[]) => void>(
276
- callback: T,
277
- delay: number
278
- ): T {
279
- const lastCallRef = useRef<number>(0);
280
- const callbackRef = useRef(callback);
281
- callbackRef.current = callback;
282
-
283
- return useCallback(((...args: Parameters<T>) => {
284
- const now = performance.now();
285
- if (now - lastCallRef.current >= delay) {
286
- lastCallRef.current = now;
287
- callbackRef.current(...args);
288
- }
289
- }) as T, [delay]);
290
- }