textmode.js 0.7.1 → 0.8.0-beta.2

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 (54) hide show
  1. package/dist/textmode.esm.js +2042 -2108
  2. package/dist/textmode.umd.js +16 -16
  3. package/dist/types/Textmode.d.ts +11 -11
  4. package/dist/types/errors/index.d.ts +1 -1
  5. package/dist/types/index.d.ts +11 -3
  6. package/dist/types/rendering/webgl/core/Framebuffer.d.ts +0 -6
  7. package/dist/types/rendering/webgl/core/Renderer.d.ts +7 -6
  8. package/dist/types/rendering/webgl/core/interfaces/IFramebuffer.d.ts +6 -6
  9. package/dist/types/rendering/webgl/core/interfaces/IRenderer.d.ts +3 -3
  10. package/dist/types/rendering/webgl/index.d.ts +2 -2
  11. package/dist/types/rendering/webgl/pipeline/MaterialBatchPipeline.d.ts +1 -1
  12. package/dist/types/textmode/Canvas.d.ts +2 -2
  13. package/dist/types/textmode/Grid.d.ts +32 -3
  14. package/dist/types/textmode/Textmodifier.d.ts +14 -72
  15. package/dist/types/textmode/conversion/ConversionManager.d.ts +73 -0
  16. package/dist/types/textmode/conversion/ConversionRegistry.d.ts +61 -18
  17. package/dist/types/textmode/conversion/index.d.ts +3 -1
  18. package/dist/types/textmode/filters/FilterManager.d.ts +0 -4
  19. package/dist/types/textmode/filters/index.d.ts +1 -1
  20. package/dist/types/textmode/interfaces/ITextmodifier.d.ts +165 -50
  21. package/dist/types/textmode/layers/Layer2DCompositor.d.ts +13 -20
  22. package/dist/types/textmode/layers/LayerManager.d.ts +31 -20
  23. package/dist/types/textmode/layers/TextmodeLayer.d.ts +58 -20
  24. package/dist/types/textmode/layers/interfaces/ILayerManager.d.ts +7 -0
  25. package/dist/types/textmode/layers/interfaces/ITextmodeLayer.d.ts +49 -28
  26. package/dist/types/textmode/layers/types.d.ts +16 -21
  27. package/dist/types/textmode/loadables/ITextmodeSource.d.ts +123 -0
  28. package/dist/types/textmode/loadables/TextmodeImage.d.ts +2 -2
  29. package/dist/types/textmode/loadables/TextmodeSource.d.ts +10 -118
  30. package/dist/types/textmode/loadables/font/CharacterExtractor.d.ts +1 -1
  31. package/dist/types/textmode/loadables/font/TextmodeFont.d.ts +3 -0
  32. package/dist/types/textmode/loadables/font/index.d.ts +2 -2
  33. package/dist/types/textmode/loadables/index.d.ts +0 -2
  34. package/dist/types/textmode/loadables/video/ITextmodeVideo.d.ts +75 -0
  35. package/dist/types/textmode/loadables/video/TextmodeVideo.d.ts +23 -126
  36. package/dist/types/textmode/loading/LoadingPhase.d.ts +26 -0
  37. package/dist/types/textmode/loading/LoadingScreenManager.d.ts +91 -93
  38. package/dist/types/textmode/loading/index.d.ts +3 -2
  39. package/dist/types/textmode/loading/types.d.ts +57 -57
  40. package/dist/types/textmode/managers/MouseManager.d.ts +24 -14
  41. package/dist/types/textmode/managers/TouchManager.d.ts +25 -13
  42. package/dist/types/textmode/mixins/index.d.ts +1 -2
  43. package/dist/types/textmode/mixins/interfaces/IAnimationMixin.d.ts +87 -87
  44. package/dist/types/textmode/mixins/interfaces/IKeyboardMixin.d.ts +128 -128
  45. package/dist/types/textmode/mixins/interfaces/IMouseMixin.d.ts +96 -105
  46. package/dist/types/textmode/mixins/interfaces/IRenderingMixin.d.ts +271 -370
  47. package/dist/types/textmode/mixins/interfaces/ITouchMixin.d.ts +1 -1
  48. package/dist/types/textmode/types.d.ts +2 -6
  49. package/package.json +5 -2
  50. package/dist/types/textmode/layers/filters/index.d.ts +0 -6
  51. package/dist/types/textmode/loadables/video/TextmodeVideoPreloader.d.ts +0 -29
  52. package/dist/types/textmode/loadables/video/types.d.ts +0 -43
  53. package/dist/types/textmode/mixins/FontMixin.d.ts +0 -8
  54. package/dist/types/textmode/mixins/interfaces/IFontMixin.d.ts +0 -46
@@ -1,9 +1,8 @@
1
1
  import type { GLRenderer } from '../../../rendering/webgl/core/Renderer';
2
2
  import type { Material } from '../../../rendering/webgl/materials/Material';
3
- import type { TextmodeFont } from '../font/TextmodeFont';
4
3
  import { TextmodeSource } from '../TextmodeSource';
5
- import type { TextmodeVideoOptions } from './types';
6
- export type { TextmodeVideoOptions, TextmodeVideoPreloadStrategy, TextmodeVideoPreloadProgress, TextmodeVideoPreloadComplete, } from './types';
4
+ import type { ITextmodeVideo } from './ITextmodeVideo';
5
+ import type { TextmodeConversionManager } from '../../conversion';
7
6
  /**
8
7
  * Represents a video element for textmode rendering via {@link Textmodifier.loadVideo}.
9
8
  *
@@ -11,7 +10,7 @@ export type { TextmodeVideoOptions, TextmodeVideoPreloadStrategy, TextmodeVideoP
11
10
  *
12
11
  * A video uploaded currently runs through an adjustable brightness-converter that converts
13
12
  * the video frames into a textmode representation using characters.
14
- * Those adjustable options are available via chainable methods on this class.
13
+ * Those adjustable options are available via chainable methods on this interface.
15
14
  * ```javascript
16
15
  * const t = textmode.create({
17
16
  * width: 800,
@@ -41,158 +40,56 @@ export type { TextmodeVideoOptions, TextmodeVideoPreloadStrategy, TextmodeVideoP
41
40
  * });
42
41
  * ```
43
42
  */
44
- export declare class TextmodeVideo extends TextmodeSource {
43
+ export declare class TextmodeVideo extends TextmodeSource implements ITextmodeVideo {
45
44
  private _videoElement;
46
- private _currentFrameIndex;
47
- private _preloader;
48
45
  /**
49
- * Create a new TextmodeVideo instance.
50
- * @param gl WebGL2 rendering context
46
+ * Create a TextmodeVideo from an HTML video element.
47
+ * @param gl WebGL context
51
48
  * @param renderer GLRenderer instance
52
- * @param texture WebGL texture for video frames
53
- * @param videoElement The HTML video element
54
- * @param originalWidth Original video width in pixels
55
- * @param originalHeight Original video height in pixels
56
- * @param gridCols Number of columns in the grid (for auto-sizing)
57
- * @param gridRows Number of rows in the grid (for auto-sizing)
58
- *
59
- * @ignore
49
+ * @param texture WebGL texture
50
+ * @param conversionManager Conversion manager
51
+ * @param videoElement HTMLVideoElement source
52
+ * @param originalWidth Original width of the video
53
+ * @param originalHeight Original height of the video
54
+ * @param gridCols Grid columns
55
+ * @param gridRows Grid rows
60
56
  */
61
- constructor(gl: WebGL2RenderingContext, renderer: GLRenderer, texture: WebGLTexture, font: TextmodeFont, videoElement: HTMLVideoElement, originalWidth: number, originalHeight: number, gridCols: number, gridRows: number);
57
+ private constructor();
62
58
  /**
63
- * Dispose of GPU resources and cleanup video element.
59
+ * Dispose of this TextmodeVideo and free its resources.
64
60
  * @ignore
65
61
  */
66
62
  $dispose(): void;
67
- /**
68
- * Update the texture with the current video frame if needed.
69
- * For preloaded videos, this returns the appropriate frame texture.
70
- * For live videos, this updates the texture with current video data.
71
- * @ignore
72
- */
73
63
  $updateTexture(): void;
74
- /**
75
- * Get the active texture for the current frame.
76
- * For preloaded videos, returns the texture at the current frame index.
77
- * For live videos, returns the live texture.
78
- * @ignore
79
- */
80
64
  protected $getActiveTexture(): WebGLTexture;
81
65
  /**
82
66
  * Get or create the material for rendering this video.
83
67
  * Always updates the material to ensure the latest video frame is used.
68
+ * @returns Material
84
69
  * @ignore
85
70
  */
86
71
  $getMaterial(): Material;
87
72
  protected $beforeMaterialUpdate(): void;
88
73
  /**
89
- * For preloaded videos, set or get the current frame index.
90
- * When called without arguments, returns this video instance for use with t.image().
91
- * When called with an index, sets the frame and returns this instance.
92
- *
93
- * The frame index automatically wraps using modulo, so you can pass t.frameCount directly
94
- * and it will loop through the video frames seamlessly.
95
- *
96
- * For non-preloaded videos, this method does nothing and returns the instance.
97
- *
98
- * @param index Optional frame index to set (0-based, automatically wraps)
99
- * @returns This instance for chaining.
100
- *
101
- * @example
102
- * ```javascript
103
- * // Draw specific frame
104
- * t.image(video.frame(0), x, y);
105
- *
106
- * // Draw frame based on frameCount (automatically wraps)
107
- * t.image(video.frame(t.frameCount), x, y);
108
- *
109
- * video.frame(t.frameCount);
110
- * t.image(video, x, y);
111
- * ```
112
- */
113
- frame(index?: number): this;
114
- /**
115
- * Create a TextmodeVideo instance from a video source (URL or HTMLVideoElement).
74
+ * Create a TextmodeVideo from a video URL.
116
75
  * @param renderer GLRenderer instance
117
- * @param source Video URL string or HTMLVideoElement
118
- * @param gridCols Number of columns in the grid
119
- * @param gridRows Number of rows in the grid
120
- * @param options Optional preload configuration (frameRate, onProgress, onComplete, onError).
121
- * @returns Promise resolving to TextmodeVideo instance
76
+ * @param conversionManager Conversion manager
77
+ * @param source Video URL
78
+ * @param gridCols Number of grid columns
79
+ * @param gridRows Number of grid rows
80
+ * @returns Promise resolving to a TextmodeVideo instance
122
81
  * @ignore
123
82
  */
124
- static $fromSource(renderer: GLRenderer, font: TextmodeFont, source: string, gridCols: number, gridRows: number, options?: TextmodeVideoOptions): Promise<TextmodeVideo>;
125
- /**
126
- * Play the video.
127
- * @returns Promise that resolves when playback starts
128
- */
83
+ static $fromSource(renderer: GLRenderer, conversionManager: TextmodeConversionManager, source: string, gridCols: number, gridRows: number): Promise<TextmodeVideo>;
129
84
  play(): Promise<void>;
130
- /**
131
- * Pause the video.
132
- */
133
85
  pause(): void;
134
- /**
135
- * Stop the video and reset to beginning.
136
- */
137
86
  stop(): void;
138
- /**
139
- * Set the playback speed.
140
- * @param rate Playback rate (1.0 = normal speed)
141
- */
142
87
  speed(rate: number): this;
143
- /**
144
- * Set whether the video should loop.
145
- * @param shouldLoop Whether to loop (defaults to true)
146
- */
147
88
  loop(shouldLoop?: boolean): this;
148
- /**
149
- * Set the current time position in the video.
150
- * @param seconds Time in seconds
151
- */
152
89
  time(seconds: number): this;
153
- /**
154
- * Set the volume.
155
- * @param level Volume level (0.0-1.0)
156
- */
157
90
  volume(level: number): this;
158
- /**
159
- * WebGL texture handle containing the current video frame.
160
- */
161
- get texture(): WebGLTexture;
162
- /**
163
- * Ideal width to draw the video at (in grid cells), calculated to fit the grid while preserving aspect ratio.
164
- */
165
- get width(): number;
166
- /**
167
- * Ideal height to draw the video at (in grid cells), calculated to fit the grid while preserving aspect ratio.
168
- */
169
- get height(): number;
170
- /**
171
- * Original pixel width of the video.
172
- */
173
- get originalWidth(): number;
174
- /**
175
- * Original pixel height of the video.
176
- */
177
- get originalHeight(): number;
178
- /**
179
- * The underlying HTML video element.
180
- */
181
91
  get videoElement(): HTMLVideoElement;
182
- /**
183
- * Current playback time in seconds.
184
- */
185
92
  get currentTime(): number;
186
- /**
187
- * Total duration of the video in seconds.
188
- */
189
93
  get duration(): number;
190
- /**
191
- * Whether the video is currently playing.
192
- */
193
94
  get isPlaying(): boolean;
194
- /**
195
- * Total number of preloaded frames. Returns 0 for non-preloaded videos.
196
- */
197
- get totalFrames(): number;
198
95
  }
@@ -0,0 +1,26 @@
1
+ import type { LoadingPhaseTracker } from "./LoadingPhaseTracker";
2
+ import type { ILoadingPhase } from "./types";
3
+ /**
4
+ * Represents a loading phase tracked by a LoadingPhaseTracker.
5
+ *
6
+ * Allows reporting progress, completion, and failure of the phase.
7
+ *
8
+ * Also provides a method to track asynchronous tasks within the phase.
9
+ */
10
+ export declare class LoadingPhase implements ILoadingPhase {
11
+ private readonly _phaseTracker;
12
+ readonly id: string;
13
+ readonly label: string;
14
+ /**
15
+ * Creates a new LoadingPhase.
16
+ * @param _phaseTracker The LoadingPhaseTracker managing this phase
17
+ * @param id The unique identifier for this loading phase
18
+ * @param label The human-readable label for this loading phase
19
+ * @ignore
20
+ */
21
+ constructor(_phaseTracker: LoadingPhaseTracker, id: string, label: string);
22
+ report(progress: number): void;
23
+ complete(): void;
24
+ fail(_error?: Error): void;
25
+ track<T>(task: Promise<T> | (() => Promise<T> | T)): Promise<T>;
26
+ }
@@ -1,6 +1,7 @@
1
1
  import type { Textmodifier } from '../Textmodifier';
2
2
  import type { RGBA } from '../utils/cssColor';
3
- import type { LoadingPhaseHandle, LoadingScreenOptions } from './types';
3
+ import { LoadingPhase } from './LoadingPhase';
4
+ import type { LoadingScreenOptions } from './types';
4
5
  /**
5
6
  * Manages the loading screen display and state. Can be accessed via {@link Textmodifier.loading}.
6
7
  */
@@ -11,11 +12,8 @@ export declare class LoadingScreenManager {
11
12
  private readonly _phaseTracker;
12
13
  private readonly _transition;
13
14
  private readonly _loadingAnimationController;
14
- private _loadingFont;
15
- private _loadingGrid;
16
- private _loadingDrawFramebuffer;
17
- private _loadingFramebuffer;
18
- private _renderer;
15
+ private _loadingLayer;
16
+ private _customRenderer;
19
17
  private _palette;
20
18
  private _theme;
21
19
  private _startTime;
@@ -31,12 +29,12 @@ export declare class LoadingScreenManager {
31
29
  */
32
30
  constructor(textmodifier: Textmodifier, opts: LoadingScreenOptions | undefined, canvasBackground: RGBA | null);
33
31
  /**
34
- * Initialize loading screen resources (font, grid, framebuffers).
32
+ * Initialize loading screen resources using a TextmodeLayer.
35
33
  * Must be called after the renderer is ready.
36
34
  * @param fontSource Optional font source for the loading screen
37
35
  * @ignore
38
36
  */
39
- $initialize(fontSource?: string): Promise<void>;
37
+ $initialize(): Promise<void>;
40
38
  /**
41
39
  * Indicates whether the loading screen should render this frame.
42
40
  * @ignore
@@ -55,7 +53,7 @@ export declare class LoadingScreenManager {
55
53
  $stop(): void;
56
54
  /**
57
55
  * Handle canvas resize during loading.
58
- * Updates grid and framebuffers to match new canvas dimensions.
56
+ * Delegates to the loading layer which handles grid and framebuffer resizing.
59
57
  * @ignore
60
58
  */
61
59
  $resize(): void;
@@ -66,84 +64,84 @@ export declare class LoadingScreenManager {
66
64
  $dispose(): void;
67
65
  /**
68
66
  * Get the current overall loading progress (0-1).
69
- *
70
- * @example
71
- * ```javascript
72
- * const t = textmode.create({
73
- * width: 800,
74
- * height: 600,
75
- * loadingScreen: { message: 'starting...' }
76
- * });
77
- *
78
- * // In setup we can start a phase and read the overall progress
79
- * t.setup(async () => {
80
- * const phase = t.loading.beginPhase('assets', 1);
81
- * phase.report(0.5); // half complete for the phase
82
- *
83
- * // The `progress` accessor reports the global progress across all phases
84
- * console.log(`Loading: ${Math.round(t.loading.progress * 100)}%`);
85
- * });
86
- * ```
67
+ *
68
+ * @example
69
+ * ```javascript
70
+ * const t = textmode.create({
71
+ * width: 800,
72
+ * height: 600,
73
+ * loadingScreen: { message: 'starting...' }
74
+ * });
75
+ *
76
+ * // In setup we can start a phase and read the overall progress
77
+ * t.setup(async () => {
78
+ * const phase = t.loading.beginPhase('assets', 1);
79
+ * phase.report(0.5); // half complete for the phase
80
+ *
81
+ * // The `progress` accessor reports the global progress across all phases
82
+ * console.log(`Loading: ${Math.round(t.loading.progress * 100)}%`);
83
+ * });
84
+ * ```
87
85
  */
88
86
  get progress(): number;
89
87
  /**
90
88
  * Get or set the loading screen message.
91
89
  * @param next Optional new message to set.
92
90
  * @returns The current loading screen message.
93
- *
94
- * @example
95
- * ```javascript
96
- * const t = textmode.create({
97
- * width: 800,
98
- * height: 600,
99
- * loadingScreen: { message: 'loading...' }
100
- * });
101
- *
102
- * t.setup(() => {
103
- * // Update the message visible on the loading screen
104
- * t.loading.message('preloading video...');
105
- *
106
- * // Read the current message (useful in custom renderers)
107
- * const msg = t.loading.message();
108
- * console.log(msg);
109
- * });
110
- * ```
91
+ *
92
+ * @example
93
+ * ```javascript
94
+ * const t = textmode.create({
95
+ * width: 800,
96
+ * height: 600,
97
+ * loadingScreen: { message: 'loading...' }
98
+ * });
99
+ *
100
+ * t.setup(() => {
101
+ * // Update the message visible on the loading screen
102
+ * t.loading.message('preloading video...');
103
+ *
104
+ * // Read the current message (useful in custom renderers)
105
+ * const msg = t.loading.message();
106
+ * console.log(msg);
107
+ * });
108
+ * ```
111
109
  */
112
110
  message(next?: string): string | undefined;
113
111
  /**
114
112
  * Begin a new loading phase.
115
113
  *
116
- * With the returned {@link LoadingPhaseHandle} you can report progress,
114
+ * With the returned {@link LoadingPhase} you can report progress,
117
115
  * track asynchronous work, and manage the phase lifecycle.
118
116
  *
119
117
  * @param label Label for the loading phase.
120
118
  * @param weight Weight of the loading phase (default is 1).
121
119
  * @returns A handle to the created loading phase.
122
- *
123
- * @example
124
- * ```javascript
125
- * const t = textmode.create({
126
- * width: 800,
127
- * height: 600,
128
- * loadingScreen: { message: 'preparing...' }
129
- * });
130
- *
131
- * // In setup we start a phase and then track work in that phase
132
- * t.setup(async () => {
133
- * const phase = t.loading.beginPhase('video preload', 2);
134
- *
135
- * // Example: report progress from a loader callback
136
- * await phase.track(async () => {
137
- * // Simulated work
138
- * for (let i = 0; i <= 10; i++) {
139
- * phase.report(i / 10);
140
- * await new Promise((r) => setTimeout(r, 30));
141
- * }
142
- * });
143
- * });
144
- * ```
145
- */
146
- addPhase(label: string, weight?: number): LoadingPhaseHandle;
120
+ *
121
+ * @example
122
+ * ```javascript
123
+ * const t = textmode.create({
124
+ * width: 800,
125
+ * height: 600,
126
+ * loadingScreen: { message: 'preparing...' }
127
+ * });
128
+ *
129
+ * // In setup we start a phase and then track work in that phase
130
+ * t.setup(async () => {
131
+ * const phase = t.loading.beginPhase('video preload', 2);
132
+ *
133
+ * // Example: report progress from a loader callback
134
+ * await phase.track(async () => {
135
+ * // Simulated work
136
+ * for (let i = 0; i <= 10; i++) {
137
+ * phase.report(i / 10);
138
+ * await new Promise((r) => setTimeout(r, 30));
139
+ * }
140
+ * });
141
+ * });
142
+ * ```
143
+ */
144
+ addPhase(label: string, weight?: number): LoadingPhase;
147
145
  /**
148
146
  * Finish the loading process.
149
147
  * @ignore
@@ -160,28 +158,28 @@ export declare class LoadingScreenManager {
160
158
  /**
161
159
  * Report an error that occurred during loading.
162
160
  * @param error The error message or `Error` object.
163
- *
164
- * @example
165
- * ```javascript
166
- * const t = textmode.create({
167
- * width: 800,
168
- * height: 600,
169
- * loadingScreen: { message: 'starting...' }
170
- * });
171
- *
172
- * t.setup(async () => {
173
- * const phase = t.loading.beginPhase('remote fetch', 1);
174
- * try {
175
- * await phase.track(async () => {
176
- * // Failing call
177
- * throw new Error('server down');
178
- * });
179
- * } catch (err) {
180
- * // This will put the loading manager into an error state
181
- * t.loading.error(err instanceof Error ? err : String(err));
182
- * }
183
- * });
184
- * ```
161
+ *
162
+ * @example
163
+ * ```javascript
164
+ * const t = textmode.create({
165
+ * width: 800,
166
+ * height: 600,
167
+ * loadingScreen: { message: 'starting...' }
168
+ * });
169
+ *
170
+ * t.setup(async () => {
171
+ * const phase = t.loading.beginPhase('remote fetch', 1);
172
+ * try {
173
+ * await phase.track(async () => {
174
+ * // Failing call
175
+ * throw new Error('server down');
176
+ * });
177
+ * } catch (err) {
178
+ * // This will put the loading manager into an error state
179
+ * t.loading.error(err instanceof Error ? err : String(err));
180
+ * }
181
+ * });
182
+ * ```
185
183
  */
186
184
  error(error: Error | string): void;
187
185
  /**
@@ -2,5 +2,6 @@ export { LoadingScreenManager } from './LoadingScreenManager';
2
2
  export { LoadingPhaseTracker } from './LoadingPhaseTracker';
3
3
  export { LoadingScreenStateMachine } from './LoadingScreenState';
4
4
  export { LoadingScreenTransition } from './LoadingScreenTransition';
5
- export { $resolveTheme as resolveTheme, $resolveDefaultPalette as resolveDefaultPalette, $resolveColorInputs as resolveColorInputs } from './LoadingScreenTheme';
6
- export type { LoadingPhaseSnapshot, LoadingScreenOptions, LoadingScreenRendererContext, LoadingPhaseHandle, LoadingScreenTheme, LoadingScreenState } from './types';
5
+ export { $resolveTheme as resolveTheme, $resolveDefaultPalette as resolveDefaultPalette, $resolveColorInputs as resolveColorInputs, } from './LoadingScreenTheme';
6
+ export { LoadingPhase } from './LoadingPhase';
7
+ export type { LoadingPhaseSnapshot, LoadingScreenOptions, LoadingScreenRendererContext, LoadingScreenTheme, LoadingScreenState, } from './types';
@@ -145,7 +145,7 @@ export type LoadingScreenRenderer = (context: LoadingScreenRendererContext) => v
145
145
  /**
146
146
  * Handle for managing a loading phase.
147
147
  */
148
- export interface LoadingPhaseHandle {
148
+ export interface ILoadingPhase {
149
149
  /**
150
150
  * The unique identifier of the loading phase.
151
151
  */
@@ -157,77 +157,77 @@ export interface LoadingPhaseHandle {
157
157
  /**
158
158
  * Update the progress of the loading phase.
159
159
  * @param progress A number between 0 and 1 representing the phase's progress.
160
- *
161
- * @example
162
- * ```ts
163
- * const t = textmode.create({ width: 800, height: 600, loadingScreen: { message: 'prepping...' } });
164
- *
165
- * // Create a phase and report progress as work proceeds
166
- * t.setup(async () => {
167
- * const phase = t.loading.beginPhase('assets', 1);
168
- * phase.report(0.25);
169
- * // ...load assets...
170
- * phase.report(0.75);
171
- * phase.complete();
172
- * });
173
- * ```
160
+ *
161
+ * @example
162
+ * ```ts
163
+ * const t = textmode.create({ width: 800, height: 600, loadingScreen: { message: 'prepping...' } });
164
+ *
165
+ * // Create a phase and report progress as work proceeds
166
+ * t.setup(async () => {
167
+ * const phase = t.loading.beginPhase('assets', 1);
168
+ * phase.report(0.25);
169
+ * // ...load assets...
170
+ * phase.report(0.75);
171
+ * phase.complete();
172
+ * });
173
+ * ```
174
174
  */
175
175
  report(progress: number): void;
176
176
  /**
177
177
  * Mark the loading phase as complete.
178
- *
179
- * @example
180
- * ```ts
181
- * const t = textmode.create({ width: 800, height: 600, loadingScreen: { message: 'prepping...' } });
182
- *
183
- * t.setup(() => {
184
- * const phase = t.loading.beginPhase('init', 1);
185
- * // Finish phase when work is done
186
- * phase.complete();
187
- * });
188
- * ```
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * const t = textmode.create({ width: 800, height: 600, loadingScreen: { message: 'prepping...' } });
182
+ *
183
+ * t.setup(() => {
184
+ * const phase = t.loading.beginPhase('init', 1);
185
+ * // Finish phase when work is done
186
+ * phase.complete();
187
+ * });
188
+ * ```
189
189
  */
190
190
  complete(): void;
191
191
  /**
192
192
  * Mark the loading phase as failed.
193
193
  * @param error An optional error object describing the failure.
194
- *
195
- * @example
196
- * ```ts
197
- * const t = textmode.create({ width: 800, height: 600 });
198
- *
199
- * t.setup(async () => {
200
- * const phase = t.loading.beginPhase('fetch', 1);
201
- * try {
202
- * // simulate failure
203
- * throw new Error('network error');
204
- * } catch (err) {
205
- * phase.fail(err instanceof Error ? err : String(err));
206
- * }
207
- * });
208
- * ```
194
+ *
195
+ * @example
196
+ * ```ts
197
+ * const t = textmode.create({ width: 800, height: 600 });
198
+ *
199
+ * t.setup(async () => {
200
+ * const phase = t.loading.beginPhase('fetch', 1);
201
+ * try {
202
+ * // simulate failure
203
+ * throw new Error('network error');
204
+ * } catch (err) {
205
+ * phase.fail(err instanceof Error ? err : String(err));
206
+ * }
207
+ * });
208
+ * ```
209
209
  */
210
210
  fail(error?: Error): void;
211
211
  /**
212
212
  * Track a task within this loading phase.
213
213
  * @param task A promise or function representing the task to track.
214
214
  * @returns A promise that resolves with the task's result.
215
- *
216
- * @example
217
- * ```ts
218
- * const t = textmode.create({ width: 800, height: 600, loadingScreen: { message: 'loading...' } });
219
- *
220
- * t.setup(async () => {
221
- * const phase = t.loading.beginPhase('video', 2);
222
- * await phase.track(async () => {
223
- * // do async work and report updates
224
- * for (let i = 0; i <= 10; i++) {
225
- * phase.report(i / 10);
226
- * await new Promise((r) => setTimeout(r, 30));
227
- * }
228
- * });
229
- * });
230
- * ```
215
+ *
216
+ * @example
217
+ * ```ts
218
+ * const t = textmode.create({ width: 800, height: 600, loadingScreen: { message: 'loading...' } });
219
+ *
220
+ * t.setup(async () => {
221
+ * const phase = t.loading.beginPhase('video', 2);
222
+ * await phase.track(async () => {
223
+ * // do async work and report updates
224
+ * for (let i = 0; i <= 10; i++) {
225
+ * phase.report(i / 10);
226
+ * await new Promise((r) => setTimeout(r, 30));
227
+ * }
228
+ * });
229
+ * });
230
+ * ```
231
231
  */
232
232
  track<T>(task: Promise<T> | (() => Promise<T> | T)): Promise<T>;
233
233
  }