@promptctl/rich-js 0.18.1 → 0.20.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 (169) hide show
  1. package/README.md +11 -8
  2. package/dist/core/box.d.ts +3 -1
  3. package/dist/core/box.js +6 -13
  4. package/dist/core/cells.d.ts +61 -28
  5. package/dist/core/cells.js +171 -124
  6. package/dist/core/clock.d.ts +48 -0
  7. package/dist/core/clock.js +42 -0
  8. package/dist/core/color.d.ts +99 -18
  9. package/dist/core/color.js +334 -146
  10. package/dist/core/console.d.ts +38 -7
  11. package/dist/core/console.js +159 -90
  12. package/dist/core/easing.d.ts +86 -0
  13. package/dist/core/easing.js +171 -0
  14. package/dist/core/env.d.ts +16 -0
  15. package/dist/core/env.js +16 -0
  16. package/dist/core/export-html.js +1 -4
  17. package/dist/core/export-lines.d.ts +22 -13
  18. package/dist/core/export-lines.js +37 -19
  19. package/dist/core/export-svg.d.ts +49 -0
  20. package/dist/core/export-svg.js +213 -0
  21. package/dist/core/fnv1a.d.ts +10 -0
  22. package/dist/core/fnv1a.js +17 -0
  23. package/dist/core/highlighter.d.ts +2 -2
  24. package/dist/core/highlighter.js +113 -47
  25. package/dist/core/json.js +1 -1
  26. package/dist/core/markup.d.ts +28 -7
  27. package/dist/core/markup.js +235 -312
  28. package/dist/core/measure.d.ts +3 -3
  29. package/dist/core/measure.js +12 -7
  30. package/dist/core/memo.d.ts +19 -0
  31. package/dist/core/memo.js +34 -0
  32. package/dist/core/noise.d.ts +31 -0
  33. package/dist/core/noise.js +94 -0
  34. package/dist/core/osc8.d.ts +6 -6
  35. package/dist/core/osc8.js +9 -21
  36. package/dist/core/paint.d.ts +107 -0
  37. package/dist/core/paint.js +161 -0
  38. package/dist/core/place.d.ts +1 -1
  39. package/dist/core/place.js +4 -6
  40. package/dist/core/pretty.d.ts +126 -2
  41. package/dist/core/pretty.js +571 -105
  42. package/dist/core/protocol.d.ts +43 -3
  43. package/dist/core/protocol.js +23 -2
  44. package/dist/core/render.d.ts +33 -30
  45. package/dist/core/render.js +43 -83
  46. package/dist/core/segment.d.ts +6 -5
  47. package/dist/core/segment.js +11 -15
  48. package/dist/core/selection.d.ts +12 -0
  49. package/dist/core/selection.js +14 -0
  50. package/dist/core/strip.d.ts +116 -74
  51. package/dist/core/strip.js +266 -217
  52. package/dist/core/style.d.ts +27 -7
  53. package/dist/core/style.js +106 -41
  54. package/dist/core/text.d.ts +43 -16
  55. package/dist/core/text.js +180 -59
  56. package/dist/core/wrap.d.ts +5 -0
  57. package/dist/core/wrap.js +16 -3
  58. package/dist/host/app.d.ts +95 -17
  59. package/dist/host/app.js +201 -61
  60. package/dist/host/index.d.ts +4 -1
  61. package/dist/host/index.js +1 -0
  62. package/dist/host/input.d.ts +84 -0
  63. package/dist/host/input.js +498 -0
  64. package/dist/host/terminal-host.d.ts +15 -2
  65. package/dist/host/terminal-host.js +2 -0
  66. package/dist/index.d.ts +26 -14
  67. package/dist/index.js +17 -7
  68. package/dist/node/prompt.d.ts +13 -0
  69. package/dist/node/prompt.js +30 -9
  70. package/dist/node/save.d.ts +4 -3
  71. package/dist/node/save.js +6 -3
  72. package/dist/node/terminal-host.d.ts +10 -2
  73. package/dist/node/terminal-host.js +7 -0
  74. package/dist/node/traceback.d.ts +2 -1
  75. package/dist/node/traceback.js +3 -39
  76. package/dist/renderables/align.js +2 -9
  77. package/dist/renderables/columns.d.ts +45 -29
  78. package/dist/renderables/columns.js +142 -103
  79. package/dist/renderables/constrain.js +6 -12
  80. package/dist/renderables/effect.d.ts +113 -0
  81. package/dist/renderables/effect.js +182 -0
  82. package/dist/renderables/effects.d.ts +252 -0
  83. package/dist/renderables/effects.js +565 -0
  84. package/dist/renderables/embed.d.ts +94 -31
  85. package/dist/renderables/embed.js +141 -45
  86. package/dist/renderables/group.d.ts +6 -3
  87. package/dist/renderables/group.js +5 -0
  88. package/dist/renderables/layout.d.ts +6 -23
  89. package/dist/renderables/layout.js +24 -113
  90. package/dist/renderables/list-view.d.ts +42 -0
  91. package/dist/renderables/list-view.js +78 -0
  92. package/dist/renderables/live.d.ts +40 -16
  93. package/dist/renderables/live.js +96 -83
  94. package/dist/renderables/markdown.d.ts +16 -2
  95. package/dist/renderables/markdown.js +521 -118
  96. package/dist/renderables/padding.d.ts +22 -1
  97. package/dist/renderables/padding.js +30 -24
  98. package/dist/renderables/panel.d.ts +31 -33
  99. package/dist/renderables/panel.js +137 -141
  100. package/dist/renderables/progress.d.ts +110 -16
  101. package/dist/renderables/progress.js +212 -81
  102. package/dist/renderables/progressBar.d.ts +24 -4
  103. package/dist/renderables/progressBar.js +78 -23
  104. package/dist/renderables/prompt.d.ts +37 -15
  105. package/dist/renderables/prompt.js +125 -85
  106. package/dist/renderables/ratio.d.ts +123 -0
  107. package/dist/renderables/ratio.js +213 -0
  108. package/dist/renderables/rule.d.ts +3 -2
  109. package/dist/renderables/rule.js +50 -52
  110. package/dist/renderables/spinner.d.ts +28 -2
  111. package/dist/renderables/spinner.js +52 -19
  112. package/dist/renderables/status.d.ts +13 -7
  113. package/dist/renderables/status.js +15 -29
  114. package/dist/renderables/syntax.d.ts +37 -7
  115. package/dist/renderables/syntax.js +134 -83
  116. package/dist/renderables/table.d.ts +58 -20
  117. package/dist/renderables/table.js +373 -197
  118. package/dist/renderables/traceback.d.ts +5 -4
  119. package/dist/renderables/traceback.js +239 -68
  120. package/dist/renderables/tree.d.ts +10 -2
  121. package/dist/renderables/tree.js +61 -34
  122. package/dist/renderables/viewport.d.ts +30 -0
  123. package/dist/renderables/viewport.js +61 -7
  124. package/dist/template-bindings/color-funcs.d.ts +31 -9
  125. package/dist/template-bindings/color-funcs.js +40 -14
  126. package/dist/template-bindings/helpers.d.ts +4 -2
  127. package/dist/template-bindings/helpers.js +5 -20
  128. package/dist/template-bindings/index.d.ts +29 -17
  129. package/dist/template-bindings/index.js +36 -20
  130. package/dist/template-bindings/palette-funcs.d.ts +3 -1
  131. package/dist/template-bindings/palette-funcs.js +11 -7
  132. package/dist/template-bindings/style-funcs.js +4 -2
  133. package/dist/themes/buildPalette.d.ts +24 -3
  134. package/dist/themes/buildPalette.js +52 -8
  135. package/dist/themes/colorMath.d.ts +29 -17
  136. package/dist/themes/colorMath.js +74 -48
  137. package/dist/themes/colorRef.d.ts +2 -17
  138. package/dist/themes/colorRef.js +13 -31
  139. package/dist/themes/palette.d.ts +24 -0
  140. package/dist/themes/palette.js +46 -3
  141. package/dist/themes/ramp.d.ts +21 -34
  142. package/dist/themes/ramp.js +23 -42
  143. package/dist/themes/registry.js +39 -28
  144. package/dist/widgets/button.d.ts +2 -6
  145. package/dist/widgets/button.js +9 -40
  146. package/dist/widgets/checkbox.d.ts +2 -5
  147. package/dist/widgets/checkbox.js +9 -31
  148. package/dist/widgets/dropdown.d.ts +2 -5
  149. package/dist/widgets/dropdown.js +17 -51
  150. package/dist/widgets/event-router.d.ts +31 -40
  151. package/dist/widgets/event-router.js +52 -483
  152. package/dist/widgets/index.d.ts +2 -1
  153. package/dist/widgets/ink.d.ts +22 -0
  154. package/dist/widgets/ink.js +31 -0
  155. package/dist/widgets/slider.d.ts +2 -5
  156. package/dist/widgets/slider.js +11 -34
  157. package/dist/widgets/text-input.d.ts +19 -10
  158. package/dist/widgets/text-input.js +156 -147
  159. package/dist/widgets/themed-widget.d.ts +20 -0
  160. package/dist/widgets/themed-widget.js +89 -0
  161. package/dist/widgets/toggle.d.ts +2 -5
  162. package/dist/widgets/toggle.js +8 -31
  163. package/dist/widgets/types.d.ts +8 -25
  164. package/dist/widgets/types.js +8 -0
  165. package/dist/widgets/widget-app.d.ts +24 -7
  166. package/dist/widgets/widget-app.js +35 -18
  167. package/dist/widgets/widget-base.d.ts +2 -0
  168. package/dist/widgets/widget-base.js +9 -2
  169. package/package.json +31 -17
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Clock — the time source and timer whoever draws frames is handed, and the
3
+ * frame rate it ticks at.
4
+ *
5
+ * [LAW:no-ambient-temporal-coupling] Frame rate belongs to whoever draws the
6
+ * frames — an `App`, a `Live` — never to what is drawn, and each ticks on the
7
+ * `Clock` it was given. An `App` reads the frame's time through that clock and
8
+ * hands it to its view as data, so nothing rendered reads a clock, and an
9
+ * effect sampled thirty times a second or once every two seconds runs the
10
+ * same code.
11
+ *
12
+ * [LAW:effects-at-boundaries] The clock is a capability passed in, like the
13
+ * `TerminalHost`: a test hands over a clock whose time it moves by hand and
14
+ * counts frames with no real timer, and nothing it starts can outlive the
15
+ * thing that started it. `systemClock` is the one place the library reads the
16
+ * platform's clock and timers, and it reads them only when called.
17
+ */
18
+ // The longest delay a platform timer holds, in seconds: setInterval clamps a
19
+ // longer one to a millisecond, which would turn the slowest rate into the
20
+ // fastest.
21
+ const LONGEST_INTERVAL = (2 ** 31 - 1) / 1000;
22
+ /**
23
+ * `perSecond` as a `FrameRate`; anything but a positive, finite number throws,
24
+ * and so does a rate whose frames are further apart than a timer can wait —
25
+ * about 24.8 days.
26
+ */
27
+ export function frameRate(perSecond) {
28
+ if (!(Number.isFinite(perSecond) && perSecond > 0 && 1 / perSecond <= LONGEST_INTERVAL)) {
29
+ throw new RangeError(`a frame rate is a positive, finite number of frames a second, at most ${LONGEST_INTERVAL} s apart, not ${perSecond}`);
30
+ }
31
+ return { perSecond, interval: 1 / perSecond };
32
+ }
33
+ /** The platform's monotonic clock and its interval timer. */
34
+ export function systemClock() {
35
+ return {
36
+ now: () => performance.now() / 1000,
37
+ every: (rate, tick) => {
38
+ const timer = setInterval(tick, rate.interval * 1000);
39
+ return () => clearInterval(timer);
40
+ },
41
+ };
42
+ }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Terminal color representation, parsing, downgrading, and ANSI code generation.
3
3
  */
4
+ import type { Env } from "./env.js";
4
5
  /**
5
6
  * Immutable RGBA color value. Alpha defaults to 1 (fully opaque).
6
7
  *
@@ -34,8 +35,9 @@ export declare class ColorRgba {
34
35
  /**
35
36
  * The surface a terminal draws a translucent colour over. A terminal cannot
36
37
  * know what lies under its cells, so the SGR writer (`Style.toSgrCodes`), the
37
- * strip's seam test and the contrast choosers (`themes/colorMath`) all
38
- * composite over this one colour. [LAW:one-source-of-truth] One constant, so
38
+ * exports that picture its output (`resolveLook`), the strip's seam test and
39
+ * the contrast choosers (`themes/colorMath`) all composite over this one
40
+ * colour. [LAW:one-source-of-truth] One constant, so
39
41
  * the colour text is chosen against is the colour the writer draws.
40
42
  */
41
43
  export declare const SURFACE_BLACK: ColorRgba;
@@ -56,11 +58,18 @@ export declare function relativeLuminance(c: ColorRgba): number;
56
58
  * foreground, flatten it first (or use `ensureContrast`, which does).
57
59
  */
58
60
  export declare function contrastRatio(a: ColorRgba, b: ColorRgba): number;
61
+ export declare function rgbDistance(a: ColorRgba, b: ColorRgba): number;
62
+ /**
63
+ * An indexed palette: entry `i` of `colors` is terminal index `firstIndex + i`.
64
+ * `firstIndex` lets a table hold only the part of a palette a downgrade may
65
+ * choose (the 256-colour cube and grey ramp start at 16) while every index it
66
+ * reports is the terminal's own.
67
+ */
59
68
  export declare class ColorTable {
60
69
  private readonly colors;
61
- private readonly firstIndex;
62
- private readonly matchCache;
63
- private readonly readableCache;
70
+ readonly firstIndex: number;
71
+ private readonly matchMemo;
72
+ private readonly readableMemo;
64
73
  constructor(colors: ColorRgba[], firstIndex?: number);
65
74
  get(index: number): ColorRgba;
66
75
  private luminanceCache;
@@ -74,6 +83,7 @@ export declare class ColorTable {
74
83
  * don't collide, but is not used in the distance metric.
75
84
  */
76
85
  match(value: ColorRgba): number;
86
+ private nearest;
77
87
  /**
78
88
  * The nearest entry to `value` (the distance `match` uses) among those that
79
89
  * clear `minRatio` against `on`; when none does, the entry with the most
@@ -84,6 +94,7 @@ export declare class ColorTable {
84
94
  * the ratio decides which one wins.
85
95
  */
86
96
  matchReadable(value: ColorRgba, on: ColorRgba, minRatio: number): number;
97
+ private nearestReadable;
87
98
  /**
88
99
  * The nearest entry to `value` (the distance `match` uses) among those
89
100
  * `accept` takes, given each entry's colour and terminal index; `undefined`
@@ -103,10 +114,22 @@ export declare enum ColorDepth {
103
114
  }
104
115
  export interface DetectColorOptions {
105
116
  /** Environment to probe. Defaults to `process.env`. */
106
- env?: NodeJS.ProcessEnv;
117
+ env?: Env;
107
118
  /** Whether output is going to a real terminal. Defaults to `process.stdout?.isTTY`. */
108
119
  isTTY?: boolean;
109
120
  }
121
+ declare const COLOR_SYSTEM_DEPTHS: {
122
+ readonly truecolor: ColorDepth.TRUECOLOR;
123
+ readonly "256": ColorDepth.EIGHT_BIT;
124
+ readonly ansi: ColorDepth.STANDARD;
125
+ readonly none: null;
126
+ };
127
+ /**
128
+ * A colour system by name: `"auto"` detects it from the environment, and each
129
+ * other name is a fixed depth — `"none"` no colour. `ColorDepth.WINDOWS` has
130
+ * no name; pass the enum value where a `ColorDepth` is accepted.
131
+ */
132
+ export type ColorSystemName = "auto" | keyof typeof COLOR_SYSTEM_DEPTHS;
110
133
  /**
111
134
  * Detect the terminal's color capability from env + TTY state.
112
135
  *
@@ -119,6 +142,12 @@ export interface DetectColorOptions {
119
142
  * in the env values, not in which checks execute.
120
143
  */
121
144
  export declare function detectColorSystem(options?: DetectColorOptions): ColorDepth | null;
145
+ /**
146
+ * A terminal that says it cannot be drawn on: `TERM` is `dumb` or `unknown`,
147
+ * as Emacs' shell mode sets it. It takes no colour and nothing that moves the
148
+ * cursor.
149
+ */
150
+ export declare function isDumbTerminal(env: Env): boolean;
122
151
  /**
123
152
  * Where segments are written, as everything the serializer (`segmentsToString`)
124
153
  * needs to know about it: the colour depth SGR is drawn at, and whether OSC 8
@@ -139,17 +168,17 @@ export interface Destination {
139
168
  * colour preferences, leave them alone. A FORCE_COLOR that forces colour on
140
169
  * declares the destination takes escapes, so it keeps links on a pipe too.
141
170
  */
142
- export declare function resolveDestination(spec: string | ColorDepth | null, options?: DetectColorOptions): Destination;
171
+ export declare function resolveDestination(spec: ColorSystemName | ColorDepth | null, options?: DetectColorOptions): Destination;
143
172
  /**
144
- * Resolve a string spec into a `ColorDepth` (or `null` for no color).
173
+ * Resolve a colour system name into a `ColorDepth` (or `null` for no color).
145
174
  *
146
- * `"auto"` triggers env-based detection; all other recognized specs are
147
- * direct table lookups against `STRING_TO_DEPTH`. Throws on unknown specs
148
- * — silent fallback would mask user typos.
175
+ * `"auto"` triggers env-based detection; every other name is a fixed depth.
176
+ * A name outside the vocabulary — reachable only from untyped JavaScript —
177
+ * throws: silent fallback would mask a typo.
149
178
  *
150
- * [LAW:single-enforcer] All string→ColorDepth resolution flows through here.
179
+ * [LAW:single-enforcer] All name→ColorDepth resolution flows through here.
151
180
  */
152
- export declare function resolveColorSystem(spec: string, options?: DetectColorOptions): ColorDepth | null;
181
+ export declare function resolveColorSystem(spec: ColorSystemName, options?: DetectColorOptions): ColorDepth | null;
153
182
  export declare class ColorParseError extends Error {
154
183
  constructor(message: string);
155
184
  }
@@ -166,8 +195,9 @@ export declare class ColorSpec {
166
195
  * any alpha is flattened, so a translucent value is drawn composited over
167
196
  * its ground (`flattenAlpha`) and should be measured that way: a
168
197
  * truecolor value, or a 256-colour cube or grey-ramp entry (xterm fixes
169
- * indices 16–255, and `fromAnsi` types only those as EIGHT_BIT). ANSI 0–15
170
- * and the default colour are the terminal theme's own, so they have none.
198
+ * indices 16–255, and `fromAnsi` types only those as EIGHT_BIT). ANSI 0–15,
199
+ * the default colour and a blend reaching either are the terminal theme's
200
+ * own, so they have none.
171
201
  */
172
202
  get fixedValue(): ColorRgba | undefined;
173
203
  get isSystemDefined(): boolean;
@@ -203,17 +233,52 @@ export declare class ColorSpec {
203
233
  static fromRgba(value: ColorRgba): ColorSpec;
204
234
  static fromRgb(r: number, g: number, b: number): ColorSpec;
205
235
  /**
206
- * Parse a color string. Cached — identical strings return the same instance.
236
+ * The colour `t` of the way from `from` to `to`: what `blend(from,to,t)`
237
+ * parses to. Two fixed colours mix to a fixed colour. A mix reaching a
238
+ * theme's own colour stays a mix until it is drawn, so whatever theme draws
239
+ * an end draws the mix from it: exported under a theme whose `blue` is
240
+ * #61afef, a mix with `blue` starts from #61afef. A terminal is told its RGB
241
+ * under the standard table, the only one a render has.
242
+ *
243
+ * Each end is one opaque colour: `default` is no colour to mix, and a
244
+ * translucent end has no one shade until it is laid on a ground.
245
+ */
246
+ static blend(from: ColorSpec, to: ColorSpec, t: number): ColorSpec;
247
+ /**
248
+ * The spec that draws `value` nearest to it at `depth` on a terminal known
249
+ * to show `theme`, as the colour of the glyph (`foreground`) or of the
250
+ * ground. Where `downgrade` knows no terminal, and so rounds only against
251
+ * colours every terminal fixes (or, at sixteen colours, the stock
252
+ * sixteen), this rounds against every colour the depth can write whose
253
+ * look `theme` fixes: the default colour, the theme's sixteen, and at 256
254
+ * colours the cube and grey ramp too. A colour read off any of those and
255
+ * moved a little is drawn as the colour it came from — or, where the theme
256
+ * gives two slots one colour, as the lower slot, which looks the same.
257
+ *
258
+ * `value` is opaque: a translucent colour has no one look until it is laid
259
+ * on a ground (`flattenAlpha`).
260
+ */
261
+ static matchOn(value: ColorRgba, depth: ColorDepth, theme: TerminalTheme, foreground: boolean): ColorSpec;
262
+ /**
263
+ * Parse a color string. Memoized (`Memo`): a string parsed again while
264
+ * remembered returns the same instance.
207
265
  */
208
266
  static parse(colorString: string): ColorSpec;
209
267
  private performDowngrade;
210
268
  }
269
+ /** Six hex digits, no `#`, as an opaque colour. @throws {ColorParseError} on anything else. */
211
270
  export declare function parseRgbHex(hex: string): ColorRgba;
271
+ /** Eight hex digits, no `#`, the last pair alpha. @throws {ColorParseError} on anything else. */
212
272
  export declare function parseRgbaHex(hex: string): ColorRgba;
273
+ /**
274
+ * A `#RRGGBB` or `#RRGGBBAA` literal, exactly — no surrounding whitespace.
275
+ * @throws {ColorParseError} on anything else.
276
+ */
277
+ export declare function parseHexColor(literal: string): ColorRgba;
213
278
  export declare function blendRgb(color1: ColorRgba, color2: ColorRgba, crossFade?: number): ColorRgba;
214
279
  /**
215
- * A terminal theme — surface/foreground baseline, the ANSI 16/256 LUT, and a
216
- * semantic palette.
280
+ * A terminal theme — surface/foreground baseline, the sixteen ANSI colours,
281
+ * and a semantic palette.
217
282
  *
218
283
  * **`ansiColors` is the theme's own sixteen colours**, the shades a terminal
219
284
  * showing this theme draws `red`, `blue` and the rest in. `ColorSpec.parse("red")`
@@ -237,6 +302,21 @@ export declare const EIGHT_BIT_TABLE: ColorTable;
237
302
  */
238
303
  export declare const EIGHT_BIT_DOWNGRADE_TABLE: ColorTable;
239
304
  export declare const WINDOWS_TABLE: ColorTable;
305
+ /**
306
+ * The terminal a colour at `depth` is drawn by: `theme`, or when a caller names
307
+ * none, the one the depth assumes — the Windows console at WINDOWS, the VGA
308
+ * sixteen otherwise — for `ColorSpec.getTruecolor` and the contrast measurement
309
+ * that reads it. (Widgets fall back to `DEFAULT_TERMINAL_THEME`, which carries a
310
+ * palette this does not.)
311
+ */
312
+ export declare function resolveTerminal(theme: TerminalTheme | undefined, depth: ColorDepth): TerminalTheme;
313
+ /**
314
+ * The table a downgrade to `depth` rounds a fixed colour against.
315
+ * [LAW:one-source-of-truth] `ColorSpec.downgrade` picks the index a colour is
316
+ * written as from it, and colorMath hands back its entries as colours the
317
+ * writer rounds to those same indices.
318
+ */
319
+ export declare function downgradeTable(depth: ColorDepth.EIGHT_BIT | ColorDepth.STANDARD | ColorDepth.WINDOWS): ColorTable;
240
320
  export declare const ANSI_COLOR_NAMES: Record<string, number>;
241
321
  /**
242
322
  * Every word `ColorSpec.parse` accepts as a name rather than a `#hex`,
@@ -244,3 +324,4 @@ export declare const ANSI_COLOR_NAMES: Record<string, number>;
244
324
  * are exactly the two name checks `parseSingle` makes.
245
325
  */
246
326
  export declare const COLOR_NAMES: readonly string[];
327
+ export {};