@@ -64,9 +64,33 @@ export class ReactiveTUIContent {
6464 RedwoodStyling . redwood ( c ) ,
6565 ) ,
6666 }
67+
68+ // Validate spinner.characters if provided
69+ if (
70+ options . spinner ?. characters !== undefined &&
71+ ( ! Array . isArray ( options . spinner . characters ) ||
72+ options . spinner . characters . length < 2 )
73+ ) {
74+ throw new Error (
75+ 'tui: `spinner.characters` must be an array with at least 2 entries' ,
76+ )
77+ }
78+
6779 this . spinner = { ...defaultSpinner , ...options . spinner }
6880 this . boxen = { ...options . boxen }
69- this . frameInterval = options . frameInterval || 80
81+
82+ // Validate frameInterval if provided
83+ if ( options . frameInterval !== undefined ) {
84+ if (
85+ typeof options . frameInterval !== 'number' ||
86+ options . frameInterval <= 0
87+ ) {
88+ throw new Error ( 'tui: `frameInterval` must be a number > 0' )
89+ }
90+ this . frameInterval = options . frameInterval
91+ } else {
92+ this . frameInterval = 80
93+ }
7094
7195 if ( options . outStream ) {
7296 this . setOutStream ( options . outStream )
@@ -95,7 +119,16 @@ export class ReactiveTUIContent {
95119 this . content = options . content
96120 }
97121 if ( options . spinner ) {
98- // TODO: Validate characters array has at least two characters
122+ // Validate characters array has at least two characters (if provided)
123+ if (
124+ options . spinner . characters !== undefined &&
125+ ( ! Array . isArray ( options . spinner . characters ) ||
126+ options . spinner . characters . length < 2 )
127+ ) {
128+ throw new Error (
129+ 'tui: `spinner.characters` must be an array with at least 2 entries' ,
130+ )
131+ }
99132 this . spinner = { ...this . spinner , ...options . spinner }
100133 }
101134 if ( options . boxen ) {
@@ -104,8 +137,14 @@ export class ReactiveTUIContent {
104137 if ( options . outStream ) {
105138 this . setOutStream ( options . outStream )
106139 }
107- if ( options . frameInterval ) {
108- // TODO: Validate > 0
140+ if ( options . frameInterval !== undefined ) {
141+ // Validate > 0
142+ if (
143+ typeof options . frameInterval !== 'number' ||
144+ options . frameInterval <= 0
145+ ) {
146+ throw new Error ( 'tui: `frameInterval` must be a number > 0' )
147+ }
109148 this . frameInterval = options . frameInterval
110149 }
111150 }
@@ -169,7 +208,19 @@ export interface RedwoodTUIConfig {
169208}
170209
171210/**
172- * TODO: Documentation for this
211+ * RedwoodTUI
212+ *
213+ * A thin wrapper around stdout/stderr that renders static text and
214+ * "reactive" content (e.g., spinners) to the terminal. It coordinates a
215+ * shared UpdateManager, handles TTY/non-TTY output, and provides helpers
216+ * for prompting and boxed messages.
217+ *
218+ * Typical usage:
219+ * const tui = new RedwoodTUI()
220+ * const content = new ReactiveTUIContent({ spinner: { enabled: true } })
221+ * tui.startReactive(content)
222+ * // ...work...
223+ * tui.stopReactive(true)
173224 */
174225export class RedwoodTUI {
175226 private manager : UpdateManager
0 commit comments