@promptctl/rich-js 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/README.md +7 -7
  2. package/dist/core/animation.d.ts +37 -37
  3. package/dist/core/animation.js +61 -61
  4. package/dist/core/ansi.d.ts +4 -4
  5. package/dist/core/ansi.js +9 -9
  6. package/dist/core/bidi.js +6 -6
  7. package/dist/core/cells.d.ts +1 -1
  8. package/dist/core/cells.js +5 -5
  9. package/dist/core/clock.d.ts +1 -1
  10. package/dist/core/color.d.ts +50 -50
  11. package/dist/core/color.js +69 -69
  12. package/dist/core/console.d.ts +8 -8
  13. package/dist/core/console.js +5 -5
  14. package/dist/core/control-codes.d.ts +3 -3
  15. package/dist/core/control-codes.js +7 -7
  16. package/dist/core/easing.d.ts +40 -40
  17. package/dist/core/easing.js +40 -40
  18. package/dist/core/env.d.ts +1 -1
  19. package/dist/core/env.js +1 -1
  20. package/dist/core/export-html.js +1 -1
  21. package/dist/core/export-lines.d.ts +11 -11
  22. package/dist/core/export-lines.js +12 -12
  23. package/dist/core/export-svg.d.ts +3 -3
  24. package/dist/core/export-svg.js +4 -4
  25. package/dist/core/markup.js +1 -1
  26. package/dist/core/memo.d.ts +1 -1
  27. package/dist/core/memo.js +1 -1
  28. package/dist/core/oklch.d.ts +14 -14
  29. package/dist/core/oklch.js +10 -10
  30. package/dist/core/orient.d.ts +3 -3
  31. package/dist/core/orient.js +3 -3
  32. package/dist/core/paint.d.ts +9 -9
  33. package/dist/core/paint.js +3 -3
  34. package/dist/core/pretty.d.ts +1 -1
  35. package/dist/core/pretty.js +3 -3
  36. package/dist/core/protocol.d.ts +26 -26
  37. package/dist/core/protocol.js +22 -22
  38. package/dist/core/render.d.ts +11 -11
  39. package/dist/core/render.js +12 -12
  40. package/dist/core/segment.d.ts +3 -3
  41. package/dist/core/segment.js +5 -5
  42. package/dist/core/strip.d.ts +83 -83
  43. package/dist/core/strip.js +70 -70
  44. package/dist/core/style.d.ts +20 -20
  45. package/dist/core/style.js +55 -55
  46. package/dist/core/text.d.ts +2 -2
  47. package/dist/core/text.js +5 -5
  48. package/dist/core/timeline.d.ts +5 -5
  49. package/dist/core/timeline.js +9 -9
  50. package/dist/core/tween.d.ts +6 -6
  51. package/dist/core/tween.js +10 -10
  52. package/dist/core/view.d.ts +4 -4
  53. package/dist/core/view.js +12 -12
  54. package/dist/host/app.d.ts +9 -9
  55. package/dist/host/app.js +12 -12
  56. package/dist/host/host-environment.d.ts +2 -2
  57. package/dist/host/host-environment.js +2 -2
  58. package/dist/host/index.d.ts +2 -2
  59. package/dist/host/input.d.ts +7 -7
  60. package/dist/host/input.js +4 -4
  61. package/dist/host/terminal-colors.d.ts +2 -2
  62. package/dist/host/terminal-colors.js +4 -4
  63. package/dist/host/terminal-host.d.ts +2 -2
  64. package/dist/host/terminal-host.js +1 -1
  65. package/dist/index.d.ts +14 -14
  66. package/dist/index.js +10 -10
  67. package/dist/node/prompt.d.ts +1 -1
  68. package/dist/node/prompt.js +1 -1
  69. package/dist/node/terminal-host.d.ts +1 -1
  70. package/dist/node/traceback.js +2 -2
  71. package/dist/renderables/change.js +2 -2
  72. package/dist/renderables/effect.d.ts +39 -39
  73. package/dist/renderables/effect.js +45 -45
  74. package/dist/renderables/effects.d.ts +81 -81
  75. package/dist/renderables/effects.js +157 -157
  76. package/dist/renderables/embed.d.ts +1 -1
  77. package/dist/renderables/embed.js +2 -2
  78. package/dist/renderables/flexStrip.d.ts +7 -7
  79. package/dist/renderables/flexStrip.js +15 -15
  80. package/dist/renderables/frames.d.ts +6 -6
  81. package/dist/renderables/frames.js +11 -11
  82. package/dist/renderables/glyph-effect.d.ts +15 -15
  83. package/dist/renderables/glyph-effect.js +17 -17
  84. package/dist/renderables/glyph-effects.d.ts +7 -7
  85. package/dist/renderables/glyph-effects.js +16 -16
  86. package/dist/renderables/html-entities.d.ts +1 -1
  87. package/dist/renderables/html-entities.js +1 -1
  88. package/dist/renderables/lifecycle.d.ts +4 -4
  89. package/dist/renderables/lifecycle.js +12 -12
  90. package/dist/renderables/live.d.ts +2 -2
  91. package/dist/renderables/live.js +7 -7
  92. package/dist/renderables/markdown-parse.js +3 -3
  93. package/dist/renderables/panel.js +3 -3
  94. package/dist/renderables/progress.d.ts +1 -1
  95. package/dist/renderables/progress.js +1 -1
  96. package/dist/renderables/progressBar.d.ts +1 -1
  97. package/dist/renderables/progressBar.js +6 -6
  98. package/dist/renderables/prompt.d.ts +1 -1
  99. package/dist/renderables/scroll.d.ts +1 -1
  100. package/dist/renderables/scroll.js +3 -3
  101. package/dist/renderables/spinner.d.ts +4 -4
  102. package/dist/renderables/spinner.js +10 -10
  103. package/dist/renderables/syntax.d.ts +2 -2
  104. package/dist/renderables/syntax.js +2 -2
  105. package/dist/renderables/table.js +3 -3
  106. package/dist/renderables/traceback.d.ts +1 -1
  107. package/dist/renderables/traceback.js +1 -1
  108. package/dist/renderables/tree.js +3 -3
  109. package/dist/template-bindings/animation-funcs.d.ts +14 -14
  110. package/dist/template-bindings/animation-funcs.js +27 -27
  111. package/dist/template-bindings/color-funcs.d.ts +14 -14
  112. package/dist/template-bindings/color-funcs.js +25 -25
  113. package/dist/template-bindings/index.d.ts +9 -9
  114. package/dist/template-bindings/index.js +9 -9
  115. package/dist/template-bindings/palette-funcs.d.ts +1 -1
  116. package/dist/template-bindings/palette-funcs.js +3 -3
  117. package/dist/template-bindings/style-funcs.d.ts +5 -5
  118. package/dist/template-bindings/style-funcs.js +16 -16
  119. package/dist/themes/{transpose.d.ts → adjust.d.ts} +23 -23
  120. package/dist/themes/{transpose.js → adjust.js} +28 -28
  121. package/dist/themes/buildPalette.d.ts +3 -3
  122. package/dist/themes/buildPalette.js +20 -20
  123. package/dist/themes/colorMath.d.ts +16 -16
  124. package/dist/themes/colorMath.js +32 -32
  125. package/dist/themes/data/ansi-tables.d.ts +2 -2
  126. package/dist/themes/data/ansi-tables.js +2 -2
  127. package/dist/themes/data/types.d.ts +4 -4
  128. package/dist/themes/data/types.js +2 -2
  129. package/dist/themes/palette.d.ts +12 -12
  130. package/dist/themes/palette.js +16 -16
  131. package/dist/themes/ramp.d.ts +17 -17
  132. package/dist/themes/ramp.js +12 -12
  133. package/dist/themes/registry.js +4 -4
  134. package/dist/themes/terminalThemes.d.ts +1 -1
  135. package/dist/themes/terminalThemes.js +1 -1
  136. package/dist/widgets/button.d.ts +2 -2
  137. package/dist/widgets/button.js +4 -4
  138. package/dist/widgets/checkbox.d.ts +2 -2
  139. package/dist/widgets/checkbox.js +2 -2
  140. package/dist/widgets/dropdown.d.ts +2 -2
  141. package/dist/widgets/dropdown.js +3 -3
  142. package/dist/widgets/event-router.d.ts +6 -6
  143. package/dist/widgets/event-router.js +2 -2
  144. package/dist/widgets/focus-manager.d.ts +3 -3
  145. package/dist/widgets/focus-manager.js +3 -3
  146. package/dist/widgets/index.d.ts +2 -2
  147. package/dist/widgets/index.js +1 -1
  148. package/dist/widgets/ink.d.ts +3 -3
  149. package/dist/widgets/ink.js +4 -4
  150. package/dist/widgets/slider.d.ts +2 -2
  151. package/dist/widgets/static-item.d.ts +2 -2
  152. package/dist/widgets/text-input.d.ts +2 -2
  153. package/dist/widgets/text-input.js +5 -5
  154. package/dist/widgets/themed-widget.js +1 -1
  155. package/dist/widgets/toggle.d.ts +3 -3
  156. package/dist/widgets/toggle.js +3 -3
  157. package/dist/widgets/types.d.ts +6 -6
  158. package/dist/widgets/types.js +2 -2
  159. package/dist/widgets/widget-app.d.ts +10 -10
  160. package/dist/widgets/widget-app.js +8 -8
  161. package/dist/widgets/widget-base.d.ts +2 -2
  162. package/package.json +1 -1
@@ -14,7 +14,7 @@
14
14
  * sRGB is the wire format terminals consume (what ANSI escape codes
15
15
  * carry); OKLCH is the perceptual manipulation space (where equal
16
16
  * numerical deltas mean equal perceptual deltas, which is the property
17
- * "transposition" requires). Two types, mutual conversion, no hybrid.
17
+ * "adjustment" requires). Two types, mutual conversion, no hybrid.
18
18
  *
19
19
  * [LAW:one-way-deps] This module imports `ColorRgba` from core/color and
20
20
  * nothing else from inside the project. Nothing in core/ depends back on
@@ -25,13 +25,13 @@ import { ColorRgba } from "./color.js";
25
25
  * A perceptually-uniform color transform.
26
26
  *
27
27
  * [LAW:dataflow-not-control-flow] Identity is *data* (`IDENTITY`), not a
28
- * special case. Every transposition runs the same code path — the values
28
+ * special case. Every adjustment runs the same code path — the values
29
29
  * decide whether the operation is a no-op or a 180° rotation.
30
30
  *
31
31
  * Lightness is parameterized as `L' = clamp01(L * scale + shift)` to make
32
32
  * "invert" expressible as `{scale: -1, shift: 1}` without a boolean knob.
33
33
  */
34
- export interface ThemeKey {
34
+ export interface ColorAdjustment {
35
35
  /** Hue offset in degrees; positive rotates toward warmer→cooler→back. */
36
36
  readonly hueShift: number;
37
37
  /** Multiplier on chroma. 0 = grayscale, 1 = identity, >1 = more saturated. */
@@ -48,22 +48,22 @@ export interface OklchWeights {
48
48
  readonly h: number;
49
49
  readonly alpha: number;
50
50
  }
51
- export declare const IDENTITY: ThemeKey;
51
+ export declare const IDENTITY: ColorAdjustment;
52
52
  /**
53
53
  * Flip lightness around the midpoint (`L' = 1 - L`) with hue and chroma
54
- * untouched. Combined with the anchor logic in `transposePalette`, this
54
+ * untouched. Combined with the anchor logic in `adjustPalette`, this
55
55
  * converts a dark theme to its light "octave": semantic anchors
56
56
  * (error/success/warning) still lightness-invert — only their *hue* is
57
57
  * preserved — so errors stay red and dark-on-light becomes light-on-dark.
58
58
  */
59
- export declare const INVERT_LIGHTNESS: ThemeKey;
59
+ export declare const INVERT_LIGHTNESS: ColorAdjustment;
60
60
  /**
61
61
  * Whether a key is the no-op transform. Exported so that callers
62
- * (`transposePalette`) can fast-path byte-exact identity without going
62
+ * (`adjustPalette`) can fast-path byte-exact identity without going
63
63
  * through the lossy sRGB↔OKLCH round-trip. [LAW:one-source-of-truth] —
64
64
  * the predicate lives once, here.
65
65
  */
66
- export declare function isIdentityKey(k: ThemeKey): boolean;
66
+ export declare function isIdentityKey(k: ColorAdjustment): boolean;
67
67
  export declare function srgbToLinear(v: number): number;
68
68
  export declare function linearToSrgb(v: number): number;
69
69
  /**
@@ -96,13 +96,13 @@ export declare class Oklch {
96
96
  */
97
97
  toRgba(): ColorRgba;
98
98
  /**
99
- * Apply a `ThemeKey`. Returns a new `Oklch`; pure.
99
+ * Apply a `ColorAdjustment`. Returns a new `Oklch`; pure.
100
100
  *
101
101
  * [LAW:dataflow-not-control-flow] Identity short-circuits to `this` —
102
102
  * same shape as `ColorRgba.compositeOver(bg)` returning `this` when
103
103
  * `alpha === 1`. Callers invoke unconditionally; the data decides.
104
104
  */
105
- applyKey(k: ThemeKey): Oklch;
105
+ applyKey(k: ColorAdjustment): Oklch;
106
106
  /**
107
107
  * The color `t` of the way from this one toward `toward`, in OKLCH.
108
108
  * `t = 0` is this color, `t = 1` is `toward`; pure.
@@ -115,7 +115,7 @@ export declare class Oklch {
115
115
  * that gains chroma, instead of rotating through the wheel from 0°.
116
116
  *
117
117
  * `t` must lie in [0, 1]: this is interpolation, not extrapolation, and a
118
- * `t` outside it (NaN included) is a RangeError, never a colour off the
118
+ * `t` outside it (NaN included) is a RangeError, never a color off the
119
119
  * far end of the segment. [LAW:no-silent-failure]
120
120
  *
121
121
  * [LAW:one-source-of-truth] Achromatic means the same `ACHROMATIC_EPS`
@@ -133,19 +133,19 @@ export declare class Oklch {
133
133
  * whichever is called.
134
134
  *
135
135
  * It exists because perceptual axes are independent: a tint can take most of
136
- * a hue's colourfulness while keeping close to the lightness it started at,
136
+ * a hue's colorfulness while keeping close to the lightness it started at,
137
137
  * which a single `t` cannot say — raising `t` for chroma drags lightness with
138
138
  * it. Every weight is required: an axis left out would need a default, and
139
139
  * "unchanged" (0) and "same as the others" are both plausible readings.
140
140
  *
141
- * A weak `h` beside a strong `c` shows the starting colour's hue at high
141
+ * A weak `h` beside a strong `c` shows the starting color's hue at high
142
142
  * chroma. The powerless rule covers only a truly achromatic start, so a
143
143
  * near-grey whose hue is noise (a theme surface at c ≈ 0.004) keeps that
144
144
  * noise in proportion. To land on the target's hue, pass `h: 1`.
145
145
  */
146
146
  mixAxes(toward: Oklch, weights: OklchWeights): Oklch;
147
147
  /**
148
- * ΔE_OK — the Euclidean distance between this colour and `other` in OKLab
148
+ * ΔE_OK — the Euclidean distance between this color and `other` in OKLab
149
149
  * (CSS Color 4's `deltaEOK`), where ~0.02 is the smallest difference the eye
150
150
  * resolves. Alpha is not a coordinate of the space and does not count.
151
151
  * Symmetric and pure.
@@ -14,7 +14,7 @@
14
14
  * sRGB is the wire format terminals consume (what ANSI escape codes
15
15
  * carry); OKLCH is the perceptual manipulation space (where equal
16
16
  * numerical deltas mean equal perceptual deltas, which is the property
17
- * "transposition" requires). Two types, mutual conversion, no hybrid.
17
+ * "adjustment" requires). Two types, mutual conversion, no hybrid.
18
18
  *
19
19
  * [LAW:one-way-deps] This module imports `ColorRgba` from core/color and
20
20
  * nothing else from inside the project. Nothing in core/ depends back on
@@ -33,7 +33,7 @@ export const IDENTITY = Object.freeze({
33
33
  });
34
34
  /**
35
35
  * Flip lightness around the midpoint (`L' = 1 - L`) with hue and chroma
36
- * untouched. Combined with the anchor logic in `transposePalette`, this
36
+ * untouched. Combined with the anchor logic in `adjustPalette`, this
37
37
  * converts a dark theme to its light "octave": semantic anchors
38
38
  * (error/success/warning) still lightness-invert — only their *hue* is
39
39
  * preserved — so errors stay red and dark-on-light becomes light-on-dark.
@@ -46,7 +46,7 @@ export const INVERT_LIGHTNESS = Object.freeze({
46
46
  });
47
47
  /**
48
48
  * Whether a key is the no-op transform. Exported so that callers
49
- * (`transposePalette`) can fast-path byte-exact identity without going
49
+ * (`adjustPalette`) can fast-path byte-exact identity without going
50
50
  * through the lossy sRGB↔OKLCH round-trip. [LAW:one-source-of-truth] —
51
51
  * the predicate lives once, here.
52
52
  */
@@ -179,7 +179,7 @@ export class Oklch {
179
179
  return new ColorRgba(sR, sG, sB, this.alpha);
180
180
  }
181
181
  /**
182
- * Apply a `ThemeKey`. Returns a new `Oklch`; pure.
182
+ * Apply a `ColorAdjustment`. Returns a new `Oklch`; pure.
183
183
  *
184
184
  * [LAW:dataflow-not-control-flow] Identity short-circuits to `this` —
185
185
  * same shape as `ColorRgba.compositeOver(bg)` returning `this` when
@@ -205,7 +205,7 @@ export class Oklch {
205
205
  * that gains chroma, instead of rotating through the wheel from 0°.
206
206
  *
207
207
  * `t` must lie in [0, 1]: this is interpolation, not extrapolation, and a
208
- * `t` outside it (NaN included) is a RangeError, never a colour off the
208
+ * `t` outside it (NaN included) is a RangeError, never a color off the
209
209
  * far end of the segment. [LAW:no-silent-failure]
210
210
  *
211
211
  * [LAW:one-source-of-truth] Achromatic means the same `ACHROMATIC_EPS`
@@ -228,12 +228,12 @@ export class Oklch {
228
228
  * whichever is called.
229
229
  *
230
230
  * It exists because perceptual axes are independent: a tint can take most of
231
- * a hue's colourfulness while keeping close to the lightness it started at,
231
+ * a hue's colorfulness while keeping close to the lightness it started at,
232
232
  * which a single `t` cannot say — raising `t` for chroma drags lightness with
233
233
  * it. Every weight is required: an axis left out would need a default, and
234
234
  * "unchanged" (0) and "same as the others" are both plausible readings.
235
235
  *
236
- * A weak `h` beside a strong `c` shows the starting colour's hue at high
236
+ * A weak `h` beside a strong `c` shows the starting color's hue at high
237
237
  * chroma. The powerless rule covers only a truly achromatic start, so a
238
238
  * near-grey whose hue is noise (a theme surface at c ≈ 0.004) keeps that
239
239
  * noise in proportion. To land on the target's hue, pass `h: 1`.
@@ -265,7 +265,7 @@ export class Oklch {
265
265
  return new _a(lerp(this.l, toward.l, wl), c, hueOf(c, wrapHue(lerp(fromU, toU, wh))), lerp(this.alpha, toward.alpha, walpha));
266
266
  }
267
267
  /**
268
- * ΔE_OK — the Euclidean distance between this colour and `other` in OKLab
268
+ * ΔE_OK — the Euclidean distance between this color and `other` in OKLab
269
269
  * (CSS Color 4's `deltaEOK`), where ~0.02 is the smallest difference the eye
270
270
  * resolves. Alpha is not a coordinate of the space and does not count.
271
271
  * Symmetric and pure.
@@ -276,9 +276,9 @@ export class Oklch {
276
276
  return Math.hypot(this.l - other.l, a - otherA, b - otherB);
277
277
  }
278
278
  /**
279
- * This colour's OKLab a and b, kept with it: a colour matched against a
279
+ * This color's OKLab a and b, kept with it: a color matched against a
280
280
  * palette is measured against every entry, and each entry against every
281
- * colour it is matched with, so the trigonometry is paid once a colour
281
+ * color it is matched with, so the trigonometry is paid once a color
282
282
  * rather than once a comparison.
283
283
  */
284
284
  #lab;
@@ -42,7 +42,7 @@ export declare function drawnTail(text: string): string;
42
42
  */
43
43
  export declare function hangingWhitespace(line: Segment[]): number;
44
44
  /** What a row of a directed line is, given the text it started as and its offset in the line. */
45
- export interface Directed {
45
+ export interface ReorderedLine {
46
46
  /** The line to cut: X9's removals gone where the terminal will not need them. */
47
47
  readonly line: readonly Segment[];
48
48
  /** Whether a row's cells may not be merged with the padding beside them. */
@@ -51,7 +51,7 @@ export interface Directed {
51
51
  orient(shown: readonly Segment[], start: number, source: string): Segment[];
52
52
  }
53
53
  /** What `order` does with `line`, one logical line of drawn segments. */
54
- export declare function directed(line: readonly Segment[], order: TextOrder): Directed;
54
+ export declare function reorder(line: readonly Segment[], order: TextOrder): ReorderedLine;
55
55
  /** `text` as `order` measures it: what `directed` removes ahead of wrapping is no word. */
56
56
  export declare function measured(text: string, order: TextOrder): string;
57
57
  /** The offsets in `text`, one row, of the characters `order` shows at its left and right edges. */
@@ -65,4 +65,4 @@ export declare function edges(text: string, order: TextOrder): {
65
65
  * button's brackets would be mirrored around it. A label `directed` leaves alone
66
66
  * is one segment with its frame, as it always was.
67
67
  */
68
- export declare function labelled(before: string, label: string, after: string, style: Style | undefined, order: TextOrder | undefined): Segment[];
68
+ export declare function labeled(before: string, label: string, after: string, style: Style | undefined, order: TextOrder | undefined): Segment[];
@@ -147,7 +147,7 @@ const REMOVALS = {
147
147
  visual: (text) => withoutMarks(withoutExplicit(text)),
148
148
  };
149
149
  /** What `order` does with `line`, one logical line of drawn segments. */
150
- export function directed(line, order) {
150
+ export function reorder(line, order) {
151
151
  if (!isBidi(Segment.plainOf(line)))
152
152
  return UNTOUCHED(line);
153
153
  if (order === "plain")
@@ -215,8 +215,8 @@ function ordered(text) {
215
215
  * button's brackets would be mirrored around it. A label `directed` leaves alone
216
216
  * is one segment with its frame, as it always was.
217
217
  */
218
- export function labelled(before, label, after, style, order) {
219
- const { line, oriented, orient } = directed([new Segment(label, style)], order ?? "plain");
218
+ export function labeled(before, label, after, style, order) {
219
+ const { line, oriented, orient } = reorder([new Segment(label, style)], order ?? "plain");
220
220
  const text = Segment.plainOf(line);
221
221
  if (!oriented)
222
222
  return [new Segment(before + text + after, style)];
@@ -5,7 +5,7 @@
5
5
  * back.
6
6
  *
7
7
  * [LAW:one-source-of-truth] Where the cursor rests between frames, and how
8
- * many rows the next paint goes back over, is one fact, and a `SurfacePainter`
8
+ * many rows the next paint goes back over, is one fact, and a `SurfaceRenderer`
9
9
  * is its only owner: `App` holds one, and so does `Live` on a terminal, so
10
10
  * they cannot disagree about it. They once did: `Live` wrote a newline after its last row, and on a
11
11
  * frame as tall as the terminal that newline scrolled the screen, so every
@@ -13,7 +13,7 @@
13
13
  * the last row, and the newline that ends it is written once, when the frame
14
14
  * is handed back.
15
15
  */
16
- import type { Destination } from "./color.js";
16
+ import type { OutputTarget } from "./color.js";
17
17
  import type { Height } from "./protocol.js";
18
18
  import { Segment } from "./segment.js";
19
19
  /**
@@ -36,7 +36,7 @@ export type FrameSource = () => Segment[][];
36
36
  /**
37
37
  * What paints a run of frames on an output, from `take` to `handBack`.
38
38
  */
39
- export interface Painter {
39
+ export interface Renderer {
40
40
  /** The budget a frame renders under, on a screen `screenRows` tall. */
41
41
  height(screenRows: number): Height;
42
42
  /** Take the output. */
@@ -45,12 +45,12 @@ export interface Painter {
45
45
  * Paint `frame` over the last frame. `frame` is already shaped to its
46
46
  * height by whoever set its budget. An empty frame erases the last one.
47
47
  */
48
- paint(frame: FrameSource, screen: Screen, destination: Destination): void;
48
+ paint(frame: FrameSource, screen: Screen, destination: OutputTarget): void;
49
49
  /**
50
50
  * The bytes that write `text` while `frame` is the frame standing on the
51
51
  * output, for the caller to write in one piece.
52
52
  */
53
- around(text: string, frame: FrameSource, screen: Screen, destination: Destination): string;
53
+ around(text: string, frame: FrameSource, screen: Screen, destination: OutputTarget): string;
54
54
  /** Hand the output back. The next `take` starts from wherever it then is. */
55
55
  handBack(): void;
56
56
  }
@@ -59,7 +59,7 @@ export interface Painter {
59
59
  * rows on the terminal — what the next paint goes back over — from `take` to
60
60
  * `handBack`.
61
61
  */
62
- export declare class SurfacePainter implements Painter {
62
+ export declare class SurfaceRenderer implements Renderer {
63
63
  private readonly write;
64
64
  private readonly geometry;
65
65
  private rows;
@@ -74,13 +74,13 @@ export declare class SurfacePainter implements Painter {
74
74
  * not go back over. The rows returned are what `destination` shows
75
75
  * (`shownOn`): under reduced motion, nothing in them blinks.
76
76
  */
77
- paint(frame: FrameSource, screen: Screen, destination: Destination): Segment[][];
77
+ paint(frame: FrameSource, screen: Screen, destination: OutputTarget): Segment[][];
78
78
  /**
79
79
  * The frame erased, `text` written, and `frame` painted again on the line
80
80
  * under it — in one string, so no terminal ever shows the frame gone. The
81
81
  * frame fills whole lines, so text that stops mid-line is ended before it.
82
82
  */
83
- around(text: string, frame: FrameSource, screen: Screen, destination: Destination): string;
83
+ around(text: string, frame: FrameSource, screen: Screen, destination: OutputTarget): string;
84
84
  private over;
85
85
  /**
86
86
  * Hand the terminal back: style reset, then the cursor shown on the
@@ -96,7 +96,7 @@ export declare class SurfacePainter implements Painter {
96
96
  * the output is handed back. What is written around the frame goes out as it
97
97
  * was given. No frame is drawn but the one handed back.
98
98
  */
99
- export declare class FinalFramePainter implements Painter {
99
+ export declare class FinalFrameRenderer implements Renderer {
100
100
  private readonly print;
101
101
  private last;
102
102
  constructor(print: (frame: Segment[][]) => void);
@@ -5,7 +5,7 @@
5
5
  * back.
6
6
  *
7
7
  * [LAW:one-source-of-truth] Where the cursor rests between frames, and how
8
- * many rows the next paint goes back over, is one fact, and a `SurfacePainter`
8
+ * many rows the next paint goes back over, is one fact, and a `SurfaceRenderer`
9
9
  * is its only owner: `App` holds one, and so does `Live` on a terminal, so
10
10
  * they cannot disagree about it. They once did: `Live` wrote a newline after its last row, and on a
11
11
  * frame as tall as the terminal that newline scrolled the screen, so every
@@ -65,7 +65,7 @@ const fitRows = (frame, screen) => frame.map((line) => Segment.adjustLineLength(
65
65
  * rows on the terminal — what the next paint goes back over — from `take` to
66
66
  * `handBack`.
67
67
  */
68
- export class SurfacePainter {
68
+ export class SurfaceRenderer {
69
69
  write;
70
70
  geometry;
71
71
  rows = 0;
@@ -138,7 +138,7 @@ export class SurfacePainter {
138
138
  * the output is handed back. What is written around the frame goes out as it
139
139
  * was given. No frame is drawn but the one handed back.
140
140
  */
141
- export class FinalFramePainter {
141
+ export class FinalFrameRenderer {
142
142
  print;
143
143
  last = () => [];
144
144
  constructor(print) {
@@ -46,7 +46,7 @@ export interface PrettyOptions {
46
46
  */
47
47
  indentGuides?: boolean;
48
48
  /**
49
- * Who colours the formatted text. Defaults to a `ReprHighlighter`.
49
+ * Who colors the formatted text. Defaults to a `ReprHighlighter`.
50
50
  *
51
51
  * Passed rather than imported so a caller's choice survives. `Console.print`
52
52
  * routes data arguments through here, and its `highlight` flag and custom
@@ -16,7 +16,7 @@
16
16
  * once to probe it and again to place it, so a node at depth d was visited 2^d
17
17
  * times.
18
18
  */
19
- import { asCellCol, cellColToCodeUnitOffset, cellLen, graphemes, replaceWithheld, splitAtCells, unicodeEscape, wireText } from "./cells.js";
19
+ import { asCellCol, cellColToCodeUnitOffset, cellLen, graphemes, replaceZeroWidth, splitAtCells, unicodeEscape, wireText } from "./cells.js";
20
20
  import { divideLine } from "./wrap.js";
21
21
  import { Memo } from "./memo.js";
22
22
  import { Segment } from "./segment.js";
@@ -233,7 +233,7 @@ function fitOneLine(lines, budget) {
233
233
  * A typed array is an array with a fixed element type, and neither of the two
234
234
  * questions asked elsewhere in this file recognises it: `Array.isArray` says
235
235
  * false, and its own `toString` answers the bare `1,2,3` — no brackets, nothing
236
- * for the highlighter to colour per element. Both spellings reach the one arm
236
+ * for the highlighter to color per element. Both spellings reach the one arm
237
237
  * that knows what a sequence looks like. `DataView` is excluded because it is a
238
238
  * window onto bytes, not a sequence of values.
239
239
  *
@@ -472,7 +472,7 @@ const BARE_KEY = pattern(/^(?![^]*\p{Default_Ignorable_Code_Point})(?:[\p{ID_Sta
472
472
  */
473
473
  const unprintable = () => /(?! )[\p{Cc}\p{Cf}\p{Co}\p{Cn}\p{Zl}\p{Zp}\p{Zs}]/gu;
474
474
  /** `value` in double quotes, every character that does not print or that the wire would withhold escaped. */
475
- const quoted = (value) => replaceWithheld(JSON.stringify(value), unicodeEscape).replace(unprintable(), unicodeEscape);
475
+ const quoted = (value) => replaceZeroWidth(JSON.stringify(value), unicodeEscape).replace(unprintable(), unicodeEscape);
476
476
  export class Pretty {
477
477
  data;
478
478
  indent;
@@ -3,7 +3,7 @@
3
3
  * [LAW:one-source-of-truth] These interfaces are the single authority for the rendering contract.
4
4
  */
5
5
  import type { Segment } from "./segment.js";
6
- import { Style, type Hold, type StyleSyntaxError, type Theme } from "./style.js";
6
+ import { Style, type ValidityInterval, type StyleSyntaxError, type Theme } from "./style.js";
7
7
  import { ColorDepth, type TerminalColors } from "./color.js";
8
8
  import type { TextOrder } from "./text-order.js";
9
9
  import type { Highlighter } from "./highlighter.js";
@@ -20,7 +20,7 @@ import type { Highlighter } from "./highlighter.js";
20
20
  export type OverflowMethod = "fold" | "crop" | "ellipsis" | "ignore";
21
21
  /**
22
22
  * The frame being drawn, as a value: `time`, the moment it is drawn for, in
23
- * seconds, on the clock its cells' `nextChange` stamps are read on, and
23
+ * seconds, on the clock its cells' `validUntil` stamps are read on, and
24
24
  * `host`, the identity of what drew it — nothing to read, so what draws in
25
25
  * the frame has one time, this one, and cannot ask the host for another.
26
26
  * [LAW:types-are-the-program] A `Progress` keeps the identity to refuse a
@@ -91,18 +91,18 @@ export interface RenderOptions {
91
91
  */
92
92
  highlighter?: Highlighter;
93
93
  /**
94
- * The depth the output will be encoded at, `null` when it carries no colour.
94
+ * The depth the output will be encoded at, `null` when it carries no color.
95
95
  * A renderable that measures what it draws — the strip's joiner, holding a
96
- * seam's ink off its ground — measures the colours the terminal will draw at
97
- * this depth, which at 256 colours or fewer are not the colours it was
96
+ * seam's ink off its ground — measures the colors the terminal will draw at
97
+ * this depth, which at 256 colors or fewer are not the colors it was
98
98
  * handed. Absent means truecolor.
99
99
  */
100
100
  colorSystem?: ColorDepth | null;
101
101
  /** What the output's destination does with direction. Absent is `"plain"`. */
102
102
  textOrder?: TextOrder;
103
103
  /**
104
- * The terminal the output is drawn on: the colours a cell that sets none is
105
- * drawn in, and the sixteen an ANSI colour names. The terminal's own palette
104
+ * The terminal the output is drawn on: the colors a cell that sets none is
105
+ * drawn in, and the sixteen an ANSI color names. The terminal's own palette
106
106
  * is never queried, so the program says what it is, once, where the output
107
107
  * is decided; a renderable reads it here (`Effected`, `ProgressBar`) and
108
108
  * nothing hands it down to one. Absent is the terminal the depth assumes
@@ -125,7 +125,7 @@ export interface RenderOptions {
125
125
  * The reader asked for reduced motion — CSS's `prefers-reduced-motion`,
126
126
  * which a terminal has no way to report, so a host is told. Every placed
127
127
  * animation is drawn reduced, its motion taken out and its content kept on
128
- * time (`shownAt`, `Animation.reduced`, `./animation.ts`), and a `Destination`
128
+ * time (`shownAt`, `Animation.reduced`, `./animation.ts`), and an `OutputTarget`
129
129
  * told the same writes no blink (`shownOn`, `./render.ts`). Absent, everything
130
130
  * moves. Nothing here reads it from the environment.
131
131
  */
@@ -142,13 +142,13 @@ export interface RenderOptions {
142
142
  /**
143
143
  * Told of every renderable `render` is asked for, as it is asked, so the
144
144
  * calls arrive in document order: a container before what it holds, what
145
- * it holds in the order it renders it. `"drawn"` is a renderable drawn at
146
- * the width it was handed; `"held"` is one handed no column, which is still
145
+ * it holds in the order it renders it. `"visible"` is a renderable drawn at
146
+ * the width it was handed; `"hidden"` is one handed no column, which is still
147
147
  * in the view but has nothing drawn for it (`render`). A renderable rendered
148
148
  * twice is told twice. A render made to measure is not drawing and is not
149
149
  * told (`measuring`).
150
150
  */
151
- onPresent?: (renderable: Renderable, presence: Presence) => void;
151
+ onVisibility?: (renderable: Renderable, visibility: Visibility) => void;
152
152
  /**
153
153
  * Told of a hold the frame is in that no cell of it may carry: an animation
154
154
  * placed in the view reports its own, whether or not it drew a cell — one
@@ -159,16 +159,16 @@ export interface RenderOptions {
159
159
  * (`measuring`) and a held render (`holding`) tell too: what they find
160
160
  * decides the frame's layout, so when it changes, the frame may.
161
161
  */
162
- onHold?: (hold: Hold) => void;
162
+ onValidity?: (validity: ValidityInterval) => void;
163
163
  /**
164
164
  * Told of the hold the element `key` names, drawn for a time on its own
165
165
  * clock, is in: an effect's frame, which alone knows, since the answer
166
- * depends on what it drew. `t` is that clock's, not the frame's, so this cannot be `onHold`:
166
+ * depends on what it drew. `t` is that clock's, not the frame's, so this cannot be `onValidity`:
167
167
  * the animation placed around the value carries the answer back through the
168
- * combinators that remapped the time (`Moves`, `./animation.ts`). It reaches
168
+ * combinators that remapped the time (`Reads`, `./animation.ts`). It reaches
169
169
  * whatever `frame` reaches.
170
170
  */
171
- onMoved?: (t: number, key: string, hold: Hold) => void;
171
+ onReads?: (t: number, key: string, validity: ValidityInterval) => void;
172
172
  }
173
173
  /** The one field of the render options that says whether the reader wants motion. */
174
174
  export type Motion = Pick<RenderOptions, "reducedMotion">;
@@ -176,7 +176,7 @@ export type Motion = Pick<RenderOptions, "reducedMotion">;
176
176
  * Whether a renderable the view holds was drawn, or held: in the view, handed
177
177
  * no column, and so not drawn (`render`).
178
178
  */
179
- export type Presence = "drawn" | "held";
179
+ export type Visibility = "visible" | "hidden";
180
180
  /** Whether `text` is all ASCII — what an `asciiOnly` output can draw. */
181
181
  export declare const isAscii: (text: string) => boolean;
182
182
  /**
@@ -285,19 +285,19 @@ export type StyleErrorHandler = (error: StyleSyntaxError, style: string) => void
285
285
  export declare function getStyle(options: RenderOptions, style: string | Style): Style;
286
286
  /**
287
287
  * `style` as the depth the render is encoded at can draw it. A style that
288
- * paints its own ground in fixed colours chose its ink and ground as a pair;
289
- * at sixteen colours the writer rounds a fixed colour to an ANSI slot, which
290
- * the terminal paints in its own theme's colour, and no pair of slots reads in
291
- * every bundled theme. So where the depth would turn a fixed colour of the
288
+ * paints its own ground in fixed colors chose its ink and ground as a pair;
289
+ * at sixteen colors the writer rounds a fixed color to an ANSI slot, which
290
+ * the terminal paints in its own theme's color, and no pair of slots reads in
291
+ * every bundled theme. So where the depth would turn a fixed color of the
292
292
  * pair into a slot, the pair is dropped and the run is drawn on the
293
293
  * terminal's own foreground and background, which its theme does make
294
294
  * readable; its attributes still set it apart. Both are named, not left
295
- * unset, so the colour of whatever the run sits in — a quote, a link — does
296
- * not show through: Rich's code keeps its own colours inside a quote, and the
297
- * terminal's are the ones it keeps here. A style whose colours are
295
+ * unset, so the color of whatever the run sits in — a quote, a link — does
296
+ * not show through: Rich's code keeps its own colors inside a quote, and the
297
+ * terminal's are the ones it keeps here. A style whose colors are
298
298
  * slots already (`white on blue`), or that paints no ground (`bold magenta`),
299
- * was written for the terminal's own colours and is drawn as written. Rich
300
- * draws a highlighted line number the same way below 256 colours
299
+ * was written for the terminal's own colors and is drawn as written. Rich
300
+ * draws a highlighted line number the same way below 256 colors
301
301
  * (`Syntax._get_number_styles`).
302
302
  */
303
303
  export declare function groundedStyle(options: RenderOptions, style: Style): Style;
@@ -374,7 +374,7 @@ export declare function afterPass(effect: () => void): void;
374
374
  * write during render is refused at: a `State` set in a pass that did not make
375
375
  * it throws (`./state.ts`).
376
376
  *
377
- * It is also the one reporter of what the view holds (`onPresent`). Under one
377
+ * It is also the one reporter of what the view holds (`onVisibility`). Under one
378
378
  * column a renderable is held: in the view, with nothing of it on the frame.
379
379
  * It is drawn all the same and what it drew dropped (`holding`), so what a held
380
380
  * container is reported holding is what it draws, under the options it hands
@@ -65,19 +65,19 @@ export function getStyle(options, style) {
65
65
  const TERMINAL_GROUND = Style.parse("default on default");
66
66
  /**
67
67
  * `style` as the depth the render is encoded at can draw it. A style that
68
- * paints its own ground in fixed colours chose its ink and ground as a pair;
69
- * at sixteen colours the writer rounds a fixed colour to an ANSI slot, which
70
- * the terminal paints in its own theme's colour, and no pair of slots reads in
71
- * every bundled theme. So where the depth would turn a fixed colour of the
68
+ * paints its own ground in fixed colors chose its ink and ground as a pair;
69
+ * at sixteen colors the writer rounds a fixed color to an ANSI slot, which
70
+ * the terminal paints in its own theme's color, and no pair of slots reads in
71
+ * every bundled theme. So where the depth would turn a fixed color of the
72
72
  * pair into a slot, the pair is dropped and the run is drawn on the
73
73
  * terminal's own foreground and background, which its theme does make
74
74
  * readable; its attributes still set it apart. Both are named, not left
75
- * unset, so the colour of whatever the run sits in — a quote, a link — does
76
- * not show through: Rich's code keeps its own colours inside a quote, and the
77
- * terminal's are the ones it keeps here. A style whose colours are
75
+ * unset, so the color of whatever the run sits in — a quote, a link — does
76
+ * not show through: Rich's code keeps its own colors inside a quote, and the
77
+ * terminal's are the ones it keeps here. A style whose colors are
78
78
  * slots already (`white on blue`), or that paints no ground (`bold magenta`),
79
- * was written for the terminal's own colours and is drawn as written. Rich
80
- * draws a highlighted line number the same way below 256 colours
79
+ * was written for the terminal's own colors and is drawn as written. Rich
80
+ * draws a highlighted line number the same way below 256 colors
81
81
  * (`Syntax._get_number_styles`).
82
82
  */
83
83
  export function groundedStyle(options, style) {
@@ -230,7 +230,7 @@ const ITERATOR_PROTOTYPE = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol
230
230
  * write during render is refused at: a `State` set in a pass that did not make
231
231
  * it throws (`./state.ts`).
232
232
  *
233
- * It is also the one reporter of what the view holds (`onPresent`). Under one
233
+ * It is also the one reporter of what the view holds (`onVisibility`). Under one
234
234
  * column a renderable is held: in the view, with nothing of it on the frame.
235
235
  * It is drawn all the same and what it drew dropped (`holding`), so what a held
236
236
  * container is reported holding is what it draws, under the options it hands
@@ -239,13 +239,13 @@ const ITERATOR_PROTOTYPE = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol
239
239
  */
240
240
  export function render(renderable, options) {
241
241
  const opens = active === undefined;
242
- const presence = drawsNothing(options) ? "held" : "drawn";
243
- const { phase, drawing } = presence === "drawn" ? { phase: phaseHere(), drawing: options } : holding(options);
242
+ const visibility = drawsNothing(options) ? "hidden" : "visible";
243
+ const { phase, drawing } = visibility === "visible" ? { phase: phaseHere(), drawing: options } : holding(options);
244
244
  const drawn = runIn(phase, () => {
245
- options.onPresent?.(renderable, presence);
245
+ options.onVisibility?.(renderable, visibility);
246
246
  return renderable.render(drawing);
247
247
  });
248
- if (presence === "held") {
248
+ if (visibility === "hidden") {
249
249
  runIn(phase, () => {
250
250
  for (const _ of drawn)
251
251
  ;
@@ -257,7 +257,7 @@ export function render(renderable, options) {
257
257
  /**
258
258
  * Where a held renderable is drawn, and the options it is drawn under: what
259
259
  * it draws is dropped, and everything it draws is reported held, whatever
260
- * width it hands it. What it tells of its hold (`onHold`) still reaches the
260
+ * width it hands it. What it tells of its hold (`onValidity`) still reaches the
261
261
  * frame: an element not yet entered is held at no width, and must say when it
262
262
  * enters and takes some. A motion held at no width therefore wakes its host
263
263
  * for frames that look the same: when it next takes room is not a moment its
@@ -275,14 +275,14 @@ export function render(renderable, options) {
275
275
  * can repeat.
276
276
  */
277
277
  function holding(options) {
278
- const { onPresent, onMoved } = options;
278
+ const { onVisibility, onReads } = options;
279
279
  return {
280
280
  phase: { pass: phaseHere().pass, effects: [] },
281
281
  drawing: {
282
282
  ...options,
283
283
  maxWidth: 0,
284
- onPresent: onPresent && ((content) => onPresent(content, "held")),
285
- onMoved: onMoved && ((t, key) => onMoved(t, key, NEVER_CHANGES)),
284
+ onVisibility: onVisibility && ((content) => onVisibility(content, "hidden")),
285
+ onReads: onReads && ((t, key) => onReads(t, key, NEVER_CHANGES)),
286
286
  },
287
287
  };
288
288
  }
@@ -300,16 +300,16 @@ export function measure(measurable, options) {
300
300
  }
301
301
  /**
302
302
  * `options` as a measurement is asked with. A `measure` that renders to learn
303
- * its shape draws nothing on the frame, so it reports nothing to `onPresent` —
303
+ * its shape draws nothing on the frame, so it reports nothing to `onVisibility` —
304
304
  * one that did would put a widget in the view at the moment a container
305
305
  * measured it, and keep one the frame then cropped away — and nothing to
306
- * `onMoved`, which speaks only for what the frame shows. It still tells its
307
- * hold (`onHold`): a layout decided by a measurement changes when it does.
306
+ * `onReads`, which speaks only for what the frame shows. It still tells its
307
+ * hold (`onValidity`): a layout decided by a measurement changes when it does.
308
308
  *
309
309
  * [LAW:single-enforcer] Every measurement starts here: `measure` asks with it.
310
310
  */
311
311
  function measuring(options) {
312
- return { ...options, onPresent: undefined, onMoved: undefined };
312
+ return { ...options, onVisibility: undefined, onReads: undefined };
313
313
  }
314
314
  /**
315
315
  * The options a renderable should *lay out against*: `withCellWidth`, with an