@promptctl/rich-js 0.18.0 → 0.18.1

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 (221) hide show
  1. package/dist/core/anchor.d.ts +45 -0
  2. package/dist/core/anchor.js +39 -0
  3. package/dist/core/ansi.d.ts +65 -0
  4. package/dist/core/ansi.js +231 -0
  5. package/dist/core/box.d.ts +143 -0
  6. package/dist/core/box.js +379 -0
  7. package/dist/core/cells.d.ts +159 -0
  8. package/dist/core/cells.js +287 -0
  9. package/dist/core/color.d.ts +246 -0
  10. package/dist/core/color.js +1038 -0
  11. package/dist/core/console.d.ts +165 -0
  12. package/dist/core/console.js +527 -0
  13. package/dist/core/emoji.d.ts +24 -0
  14. package/dist/core/emoji.js +391 -0
  15. package/dist/core/export-html.d.ts +59 -0
  16. package/dist/core/export-html.js +200 -0
  17. package/dist/core/export-lines.d.ts +121 -0
  18. package/dist/core/export-lines.js +141 -0
  19. package/dist/core/highlighter.d.ts +33 -0
  20. package/dist/core/highlighter.js +124 -0
  21. package/dist/core/json.d.ts +27 -0
  22. package/dist/core/json.js +53 -0
  23. package/dist/core/markup.d.ts +119 -0
  24. package/dist/core/markup.js +731 -0
  25. package/dist/core/measure.d.ts +27 -0
  26. package/dist/core/measure.js +62 -0
  27. package/dist/core/oklch.d.ts +161 -0
  28. package/dist/core/oklch.js +312 -0
  29. package/dist/core/osc8.d.ts +68 -0
  30. package/dist/core/osc8.js +90 -0
  31. package/dist/core/place.d.ts +30 -0
  32. package/dist/core/place.js +51 -0
  33. package/dist/core/pretty.d.ts +144 -0
  34. package/dist/core/pretty.js +476 -0
  35. package/dist/core/protocol.d.ts +267 -0
  36. package/dist/core/protocol.js +163 -0
  37. package/dist/core/render.d.ts +84 -0
  38. package/dist/core/render.js +145 -0
  39. package/dist/core/segment.d.ts +161 -0
  40. package/dist/core/segment.js +492 -0
  41. package/dist/core/spinnerData.d.ts +12 -0
  42. package/dist/core/spinnerData.js +117 -0
  43. package/dist/core/strip.d.ts +141 -0
  44. package/dist/core/strip.js +305 -0
  45. package/dist/core/style.d.ts +169 -0
  46. package/dist/core/style.js +695 -0
  47. package/dist/core/subscription.d.ts +12 -0
  48. package/dist/core/subscription.js +12 -0
  49. package/dist/core/text.d.ts +256 -0
  50. package/dist/core/text.js +976 -0
  51. package/dist/core/wrap.d.ts +41 -0
  52. package/dist/core/wrap.js +127 -0
  53. package/dist/host/app.d.ts +121 -0
  54. package/dist/host/app.js +255 -0
  55. package/dist/host/host-environment.d.ts +26 -0
  56. package/dist/host/host-environment.js +44 -0
  57. package/dist/host/index.d.ts +5 -0
  58. package/dist/host/index.js +3 -0
  59. package/dist/host/terminal-host.d.ts +179 -0
  60. package/dist/host/terminal-host.js +186 -0
  61. package/dist/index.d.ts +91 -0
  62. package/dist/index.js +107 -0
  63. package/dist/node/prompt.d.ts +21 -0
  64. package/dist/node/prompt.js +30 -0
  65. package/dist/node/save.d.ts +17 -0
  66. package/dist/node/save.js +21 -0
  67. package/dist/node/terminal-host.d.ts +113 -0
  68. package/dist/node/terminal-host.js +227 -0
  69. package/dist/node/traceback.d.ts +37 -0
  70. package/dist/node/traceback.js +134 -0
  71. package/dist/renderables/align.d.ts +16 -0
  72. package/dist/renderables/align.js +33 -0
  73. package/dist/renderables/columns.d.ts +61 -0
  74. package/dist/renderables/columns.js +152 -0
  75. package/dist/renderables/constrain.d.ts +15 -0
  76. package/dist/renderables/constrain.js +37 -0
  77. package/dist/renderables/embed.d.ts +50 -0
  78. package/dist/renderables/embed.js +71 -0
  79. package/dist/renderables/flexStrip.d.ts +41 -0
  80. package/dist/renderables/flexStrip.js +200 -0
  81. package/dist/renderables/group.d.ts +11 -0
  82. package/dist/renderables/group.js +17 -0
  83. package/dist/renderables/layout.d.ts +92 -0
  84. package/dist/renderables/layout.js +312 -0
  85. package/dist/renderables/live.d.ts +50 -0
  86. package/dist/renderables/live.js +175 -0
  87. package/dist/renderables/markdown.d.ts +24 -0
  88. package/dist/renderables/markdown.js +184 -0
  89. package/dist/renderables/padding.d.ts +38 -0
  90. package/dist/renderables/padding.js +141 -0
  91. package/dist/renderables/panel.d.ts +116 -0
  92. package/dist/renderables/panel.js +307 -0
  93. package/dist/renderables/progress.d.ts +90 -0
  94. package/dist/renderables/progress.js +238 -0
  95. package/dist/renderables/progressBar.d.ts +31 -0
  96. package/dist/renderables/progressBar.js +53 -0
  97. package/dist/renderables/prompt.d.ts +49 -0
  98. package/dist/renderables/prompt.js +125 -0
  99. package/dist/renderables/rule.d.ts +25 -0
  100. package/dist/renderables/rule.js +90 -0
  101. package/dist/renderables/spinner.d.ts +31 -0
  102. package/dist/renderables/spinner.js +70 -0
  103. package/dist/renderables/status.d.ts +23 -0
  104. package/dist/renderables/status.js +60 -0
  105. package/dist/renderables/syntax.d.ts +35 -0
  106. package/dist/renderables/syntax.js +115 -0
  107. package/dist/renderables/table.d.ts +194 -0
  108. package/dist/renderables/table.js +795 -0
  109. package/dist/renderables/traceback.d.ts +31 -0
  110. package/dist/renderables/traceback.js +108 -0
  111. package/dist/renderables/tree.d.ts +68 -0
  112. package/dist/renderables/tree.js +150 -0
  113. package/dist/renderables/viewport.d.ts +114 -0
  114. package/dist/renderables/viewport.js +198 -0
  115. package/dist/template-bindings/color-funcs.d.ts +87 -0
  116. package/dist/template-bindings/color-funcs.js +217 -0
  117. package/dist/template-bindings/helpers.d.ts +24 -0
  118. package/dist/template-bindings/helpers.js +48 -0
  119. package/dist/template-bindings/index.d.ts +107 -0
  120. package/dist/template-bindings/index.js +146 -0
  121. package/dist/template-bindings/palette-funcs.d.ts +94 -0
  122. package/dist/template-bindings/palette-funcs.js +141 -0
  123. package/dist/template-bindings/style-funcs.d.ts +28 -0
  124. package/dist/template-bindings/style-funcs.js +155 -0
  125. package/dist/themes/buildPalette.d.ts +36 -0
  126. package/dist/themes/buildPalette.js +56 -0
  127. package/dist/themes/colorMath.d.ts +82 -0
  128. package/dist/themes/colorMath.js +254 -0
  129. package/dist/themes/colorRef.d.ts +51 -0
  130. package/dist/themes/colorRef.js +96 -0
  131. package/dist/themes/data/ansi-tables.d.ts +14 -0
  132. package/dist/themes/data/ansi-tables.js +49 -0
  133. package/dist/themes/data/atom-one-dark.d.ts +3 -0
  134. package/dist/themes/data/atom-one-dark.js +177 -0
  135. package/dist/themes/data/atom-one-light.d.ts +3 -0
  136. package/dist/themes/data/atom-one-light.js +177 -0
  137. package/dist/themes/data/catppuccin-frappe.d.ts +3 -0
  138. package/dist/themes/data/catppuccin-frappe.js +177 -0
  139. package/dist/themes/data/catppuccin-latte.d.ts +3 -0
  140. package/dist/themes/data/catppuccin-latte.js +177 -0
  141. package/dist/themes/data/catppuccin-macchiato.d.ts +3 -0
  142. package/dist/themes/data/catppuccin-macchiato.js +177 -0
  143. package/dist/themes/data/catppuccin-mocha.d.ts +3 -0
  144. package/dist/themes/data/catppuccin-mocha.js +177 -0
  145. package/dist/themes/data/cyberpunk.d.ts +17 -0
  146. package/dist/themes/data/cyberpunk.js +193 -0
  147. package/dist/themes/data/default.d.ts +3 -0
  148. package/dist/themes/data/default.js +160 -0
  149. package/dist/themes/data/dracula.d.ts +3 -0
  150. package/dist/themes/data/dracula.js +177 -0
  151. package/dist/themes/data/flexoki.d.ts +3 -0
  152. package/dist/themes/data/flexoki.js +177 -0
  153. package/dist/themes/data/gruvbox.d.ts +3 -0
  154. package/dist/themes/data/gruvbox.js +177 -0
  155. package/dist/themes/data/index.d.ts +35 -0
  156. package/dist/themes/data/index.js +64 -0
  157. package/dist/themes/data/monokai.d.ts +3 -0
  158. package/dist/themes/data/monokai.js +177 -0
  159. package/dist/themes/data/nord.d.ts +3 -0
  160. package/dist/themes/data/nord.js +177 -0
  161. package/dist/themes/data/rose-pine-dawn.d.ts +3 -0
  162. package/dist/themes/data/rose-pine-dawn.js +177 -0
  163. package/dist/themes/data/rose-pine-moon.d.ts +3 -0
  164. package/dist/themes/data/rose-pine-moon.js +177 -0
  165. package/dist/themes/data/rose-pine.d.ts +3 -0
  166. package/dist/themes/data/rose-pine.js +177 -0
  167. package/dist/themes/data/solarized-dark.d.ts +3 -0
  168. package/dist/themes/data/solarized-dark.js +177 -0
  169. package/dist/themes/data/solarized-light.d.ts +3 -0
  170. package/dist/themes/data/solarized-light.js +177 -0
  171. package/dist/themes/data/svg-export.d.ts +3 -0
  172. package/dist/themes/data/svg-export.js +177 -0
  173. package/dist/themes/data/textual-ansi.d.ts +3 -0
  174. package/dist/themes/data/textual-ansi.js +160 -0
  175. package/dist/themes/data/textual-dark.d.ts +3 -0
  176. package/dist/themes/data/textual-dark.js +160 -0
  177. package/dist/themes/data/textual-light.d.ts +3 -0
  178. package/dist/themes/data/textual-light.js +160 -0
  179. package/dist/themes/data/tokyo-night.d.ts +3 -0
  180. package/dist/themes/data/tokyo-night.js +177 -0
  181. package/dist/themes/data/types.d.ts +31 -0
  182. package/dist/themes/data/types.js +10 -0
  183. package/dist/themes/palette.d.ts +21 -0
  184. package/dist/themes/palette.js +28 -0
  185. package/dist/themes/ramp.d.ts +83 -0
  186. package/dist/themes/ramp.js +122 -0
  187. package/dist/themes/registry.d.ts +44 -0
  188. package/dist/themes/registry.js +94 -0
  189. package/dist/themes/terminalThemes.d.ts +49 -0
  190. package/dist/themes/terminalThemes.js +63 -0
  191. package/dist/themes/transpose.d.ts +87 -0
  192. package/dist/themes/transpose.js +138 -0
  193. package/dist/widgets/button.d.ts +49 -0
  194. package/dist/widgets/button.js +208 -0
  195. package/dist/widgets/checkbox.d.ts +41 -0
  196. package/dist/widgets/checkbox.js +157 -0
  197. package/dist/widgets/dropdown.d.ts +67 -0
  198. package/dist/widgets/dropdown.js +450 -0
  199. package/dist/widgets/event-router.d.ts +71 -0
  200. package/dist/widgets/event-router.js +629 -0
  201. package/dist/widgets/focus-manager.d.ts +45 -0
  202. package/dist/widgets/focus-manager.js +191 -0
  203. package/dist/widgets/hit.d.ts +64 -0
  204. package/dist/widgets/hit.js +113 -0
  205. package/dist/widgets/index.d.ts +20 -0
  206. package/dist/widgets/index.js +14 -0
  207. package/dist/widgets/slider.d.ts +57 -0
  208. package/dist/widgets/slider.js +270 -0
  209. package/dist/widgets/static-item.d.ts +34 -0
  210. package/dist/widgets/static-item.js +54 -0
  211. package/dist/widgets/text-input.d.ts +274 -0
  212. package/dist/widgets/text-input.js +1165 -0
  213. package/dist/widgets/toggle.d.ts +44 -0
  214. package/dist/widgets/toggle.js +180 -0
  215. package/dist/widgets/types.d.ts +87 -0
  216. package/dist/widgets/types.js +30 -0
  217. package/dist/widgets/widget-app.d.ts +63 -0
  218. package/dist/widgets/widget-app.js +199 -0
  219. package/dist/widgets/widget-base.d.ts +40 -0
  220. package/dist/widgets/widget-base.js +165 -0
  221. package/package.json +6 -2
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The OSC 8 hyperlink wire grammar — which bytes may not appear inside a
3
+ * link, how a link becomes bytes, and how bytes are read back as a link.
4
+ *
5
+ * [LAW:one-source-of-truth] The producer (`segmentsToString`, the one encoder
6
+ * every link reaches the wire through) opens a link with `osc8Open` and closes
7
+ * it with `OSC8_CLOSE`; every consumer that reads rendered bytes (a width measure, a
8
+ * test extracting URLs) matches them with `OSC8`; the data-model boundary
9
+ * (RichText) cleans URLs with `stripOscTerminators`. All four read the one
10
+ * terminator set below, so the bytes a sanitizer removes and the bytes a
11
+ * reader stops at cannot disagree.
12
+ *
13
+ * [LAW:locality-or-seam] This module depends on nothing; every consumer
14
+ * imports downward.
15
+ *
16
+ * The `id=` parameter is what makes one link hover as one link. A terminal
17
+ * treats cells as the same hyperlink when they share BOTH the URI and the id
18
+ * (the OSC 8 spec, and VTE / iTerm2 / kitty / WezTerm alike); without an id,
19
+ * each open sequence is its own link. The coalescer can only share one OSC 8
20
+ * pair across a run of identical SGR, so a link whose text changes style
21
+ * mid-span — a bold glyph beside plain text, a padded cell — is emitted as
22
+ * several pairs, and would highlight piecewise on hover.
23
+ *
24
+ * [LAW:types-are-the-program] The id is a pure function of the URI, so the
25
+ * byte stream stays a pure function of (style, text, destination): no counter,
26
+ * no construction-order dependence. The consequence is deliberate: two spans
27
+ * with the same URI hover as one link wherever they sit on screen, adjacent
28
+ * or not — a click on either does the same thing, so they ARE one link.
29
+ * Because terminals key on the (id, URI) PAIR, a hash collision between two
30
+ * different URIs merges nothing — the URIs still differ — so a 32-bit hash is
31
+ * exact, not approximate.
32
+ */
33
+ /**
34
+ * The bytes that prematurely terminate an OSC 8 sequence: ESC (`\x1b`, which
35
+ * begins ST `ESC \`), BEL (`\x07`), and the 8-bit ST (`\x9c`).
36
+ */
37
+ const TERMINATORS = "\\x1b\\x07\\x9c";
38
+ const TERMINATOR_RE = new RegExp(`[${TERMINATORS}]`, "g");
39
+ /** Remove every byte that could break a URL out of its OSC 8 wrap. */
40
+ export function stripOscTerminators(url) {
41
+ return url.replace(TERMINATOR_RE, "");
42
+ }
43
+ const utf8 = new TextEncoder();
44
+ /**
45
+ * FNV-1a, 32-bit, over the URL's UTF-8 bytes, as 8 lowercase hex digits — a
46
+ * legal `id=` value (no `:`/`;`). UTF-8 rather than UTF-16 code units, so any
47
+ * other runtime computing standard FNV-1a over the same URL gets the same id.
48
+ */
49
+ function linkId(url) {
50
+ let h = 0x811c9dc5;
51
+ for (const byte of utf8.encode(url)) {
52
+ h ^= byte;
53
+ h = Math.imul(h, 0x01000193);
54
+ }
55
+ return (h >>> 0).toString(16).padStart(8, "0");
56
+ }
57
+ /**
58
+ * The bytes that open a hyperlink to `url`.
59
+ *
60
+ * [LAW:single-enforcer] Wire-byte trust boundary — the URL is sanitized at
61
+ * the one place it becomes an OSC 8 sequence, whichever upstream API attached
62
+ * it to the Style (RichText sanitizes at its data-model boundary too; a Style
63
+ * built directly with `new Style({ link })` reaches here unsanitized).
64
+ */
65
+ export function osc8Open(url) {
66
+ const clean = stripOscTerminators(url);
67
+ return `\x1b]8;id=${linkId(clean)};${clean}\x1b\\`;
68
+ }
69
+ /** The bytes that close the current hyperlink. */
70
+ export const OSC8_CLOSE = "\x1b]8;;\x1b\\";
71
+ /**
72
+ * Matches one OSC 8 sequence — an open or a close — terminated by `ESC \`,
73
+ * BEL, or the 8-bit ST. Group 1 is the params, group 2 the URI; both are empty
74
+ * on a close. To read bytes back use `osc8Sequences`; this pattern is exported
75
+ * for composing into a larger one (a width measure's zero-width alternation).
76
+ */
77
+ export const OSC8 = new RegExp(`\\x1b\\]8;([^;${TERMINATORS}]*);([^${TERMINATORS}]*)(?:\\x1b\\\\|\\x07|\\x9c)`);
78
+ const OSC8_SCAN = new RegExp(OSC8.source, "g");
79
+ /**
80
+ * Every OSC 8 sequence in `text`, in order — the typed way to read rendered
81
+ * bytes back.
82
+ */
83
+ export function osc8Sequences(text) {
84
+ return [...text.matchAll(OSC8_SCAN)].map((m) => ({
85
+ index: m.index,
86
+ length: m[0].length,
87
+ params: m[1],
88
+ uri: m[2],
89
+ }));
90
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * place — a renderable's output set down as one block inside a wider width.
3
+ *
4
+ * The block is placed, not its lines. The renderable is measured, drawn at the
5
+ * width it asked for and at its own height — a region's height is dropped, as
6
+ * the reference's `Align` drops it — and every line is padded to the widest, so the block is a
7
+ * rectangle; only then is the rectangle padded to the offered width. A
8
+ * multi-line paragraph keeps its own shape under `"center"` — `hi` over `hello`
9
+ * stays a 5-cell block, centred as one — where padding each line to the full
10
+ * width on its own would centre `hi` against the whole terminal. That is
11
+ * Rich's `Align`, and `test/core/console.test.ts` pins it against the
12
+ * reference's bytes.
13
+ *
14
+ * It lives in `core/` because `Console.print` places with it: Rich's `print`
15
+ * wraps what it prints in `Align` for the three alignments, and `console.ts`
16
+ * reaching for `renderables/align.ts` would be a third upward edge out of this
17
+ * layer. [LAW:one-way-deps] `Align` is this function behind the `Renderable`
18
+ * interface. [LAW:one-source-of-truth]
19
+ */
20
+ import { Segment } from "./segment.js";
21
+ import { type Renderable, type RenderOptions } from "./protocol.js";
22
+ export type Alignment = "left" | "center" | "right";
23
+ /**
24
+ * `renderable`'s lines, the block they form placed by `align` in
25
+ * `options.maxWidth`. `options.maxWidth` must be finite: the spare cells are
26
+ * written out as spaces. A block wider than the offer — a line with nowhere to
27
+ * break, drawn by a renderable that does not cut its own — is left unpadded at
28
+ * its full width, for whatever holds it to crop or keep.
29
+ */
30
+ export declare function placeBlock(renderable: Renderable, align: Alignment, options: RenderOptions): Segment[][];
@@ -0,0 +1,51 @@
1
+ /**
2
+ * place — a renderable's output set down as one block inside a wider width.
3
+ *
4
+ * The block is placed, not its lines. The renderable is measured, drawn at the
5
+ * width it asked for and at its own height — a region's height is dropped, as
6
+ * the reference's `Align` drops it — and every line is padded to the widest, so the block is a
7
+ * rectangle; only then is the rectangle padded to the offered width. A
8
+ * multi-line paragraph keeps its own shape under `"center"` — `hi` over `hello`
9
+ * stays a 5-cell block, centred as one — where padding each line to the full
10
+ * width on its own would centre `hi` against the whole terminal. That is
11
+ * Rich's `Align`, and `test/core/console.test.ts` pins it against the
12
+ * reference's bytes.
13
+ *
14
+ * It lives in `core/` because `Console.print` places with it: Rich's `print`
15
+ * wraps what it prints in `Align` for the three alignments, and `console.ts`
16
+ * reaching for `renderables/align.ts` would be a third upward edge out of this
17
+ * layer. [LAW:one-way-deps] `Align` is this function behind the `Renderable`
18
+ * interface. [LAW:one-source-of-truth]
19
+ */
20
+ import { Segment } from "./segment.js";
21
+ import { Measurement } from "./measure.js";
22
+ import { isMeasurable } from "./protocol.js";
23
+ // The share of the spare cells that goes on the left; the rest go on the right.
24
+ // Right-alignment pads no right side at all, which is the reference's choice
25
+ // and not a zero: a line that ends at the edge carries no trailing blanks.
26
+ const PADS = {
27
+ left: (spare) => [0, spare],
28
+ center: (spare) => [Math.floor(spare / 2), spare - Math.floor(spare / 2)],
29
+ right: (spare) => [spare, 0],
30
+ };
31
+ /**
32
+ * `renderable`'s lines, the block they form placed by `align` in
33
+ * `options.maxWidth`. `options.maxWidth` must be finite: the spare cells are
34
+ * written out as spaces. A block wider than the offer — a line with nowhere to
35
+ * break, drawn by a renderable that does not cut its own — is left unpadded at
36
+ * its full width, for whatever holds it to crop or keep.
37
+ */
38
+ export function placeBlock(renderable, align, options) {
39
+ // A renderable that cannot say how wide it wants to be is offered all of it,
40
+ // and the block is then only as wide as what it actually drew.
41
+ const width = isMeasurable(renderable)
42
+ ? Measurement.get(options, renderable).maximum
43
+ : options.maxWidth;
44
+ const drawn = Segment.splitLines(renderable.render({ ...options, maxWidth: width, height: undefined }));
45
+ const [blockWidth, height] = Segment.getShape(drawn);
46
+ const [left, right] = PADS[align](Math.max(0, options.maxWidth - blockWidth));
47
+ return Segment.setShape(drawn, blockWidth, height).map((line) => [...pad(left), ...line, ...pad(right)]);
48
+ }
49
+ // [LAW:dataflow-not-control-flow] no spare room is a pad of no segments, not a
50
+ // step skipped.
51
+ const pad = (cells) => (cells > 0 ? [new Segment(" ".repeat(cells))] : []);
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Pretty — formats JavaScript data structures with highlighting.
3
+ *
4
+ * Lives in `core/` beside `markup` and `emoji` because it does their job: turn
5
+ * foreign input into `RichText`. It composes no other renderable — the trait
6
+ * every file in `renderables/` shares and this one does not — and its imports
7
+ * are core primitives only. `Console.print` accepts `unknown` and must turn any
8
+ * of it into something renderable, so the formatter has to sit where `console`
9
+ * can reach it without an upward edge. [LAW:one-way-deps]
10
+ *
11
+ * Two traversals share this file, and the split is the whole design. `_format`
12
+ * lays a value out across lines; `_oneLine` answers only "does this fit on one
13
+ * line, and if so what is it?". They meet at `_shape`, which describes a
14
+ * container without committing to either layout. One traversal answering both
15
+ * questions is what made this formatter exponential: every child was rendered
16
+ * once to probe it and again to place it, so a node at depth d was visited 2^d
17
+ * times.
18
+ */
19
+ import { Segment } from "./segment.js";
20
+ import { RichText } from "./text.js";
21
+ import type { Highlighter } from "./highlighter.js";
22
+ import type { Renderable, Measurable, RenderOptions } from "./protocol.js";
23
+ export interface PrettyOptions {
24
+ indent?: number;
25
+ expandAll?: boolean;
26
+ maxLength?: number;
27
+ maxString?: number;
28
+ /**
29
+ * How many levels of nesting to descend before eliding. Unbounded by default.
30
+ *
31
+ * `Console.print` supplies a bound because it formats whatever it is handed;
32
+ * a caller constructing a `Pretty` has seen their data and can say what they
33
+ * want. Past the cap a container renders as `[...]`, `{...}`, `Map {...}` or
34
+ * `Set {...}` — visible, so the reader knows the value continues.
35
+ */
36
+ maxDepth?: number;
37
+ indentGuides?: boolean;
38
+ /**
39
+ * Who colours the formatted text. Defaults to a `ReprHighlighter`.
40
+ *
41
+ * Passed rather than imported so a caller's choice survives. `Console.print`
42
+ * routes data arguments through here, and its `highlight` flag and custom
43
+ * `highlighter` have to reach the output the same way they reach a printed
44
+ * string — a `Pretty` reaching for its own singleton would silently outrank
45
+ * both. `NullHighlighter` is the "none" case.
46
+ */
47
+ highlighter?: Highlighter;
48
+ }
49
+ export declare class Pretty implements Renderable, Measurable {
50
+ readonly data: unknown;
51
+ readonly indent: number;
52
+ readonly expandAll: boolean;
53
+ readonly maxLength: number | undefined;
54
+ readonly maxString: number | undefined;
55
+ readonly maxDepth: number;
56
+ readonly indentGuides: boolean;
57
+ readonly highlighter: Highlighter;
58
+ constructor(data: unknown, options?: PrettyOptions);
59
+ render(options: RenderOptions): Iterable<Segment>;
60
+ /** The value laid out for `options.maxWidth` and highlighted: the text this renders. */
61
+ toText(options: RenderOptions): RichText;
62
+ measure(_options: RenderOptions): {
63
+ minimum: number;
64
+ maximum: number;
65
+ };
66
+ /**
67
+ * The text a value shows without being reflected on, or `null` when it is an
68
+ * object and the shape arms own it.
69
+ *
70
+ * Every kind answered here renders the same wherever it sits — no
71
+ * indentation, no width to fit — which is why one method serves both
72
+ * traversals.
73
+ */
74
+ private _scalar;
75
+ /**
76
+ * A container, or the text standing in for one that is empty or past the
77
+ * depth cap.
78
+ *
79
+ * `positions` is a thunk because both of those answers are reachable from
80
+ * `size` alone, and reaching a position is not free: a `Map` or `Set` reaches
81
+ * its own through an iterator, so enumerating one only to elide it drains a
82
+ * container to print `Set {...}`. `size` also says how many positions were
83
+ * dropped, which is where the elision marker comes from — one derivation, so
84
+ * the count and the bound cannot disagree.
85
+ */
86
+ private _container;
87
+ /**
88
+ * The brackets and positions of an object, layout-free. See `Shape`.
89
+ *
90
+ * `bound` is the most positions the caller could ever use. Laying out passes
91
+ * `Infinity`, because it prints every position it is handed. A probe passes
92
+ * what is left of its line, which is already more positions than a fitting
93
+ * one could hold — `SEPARATOR` charges two cells apiece, so a container with
94
+ * more positions than `budget` overruns however narrow its contents are.
95
+ * Reaching past it only ever feeds a join that returns `null`, and reaching a
96
+ * position is what drains a `Map` or `Set`.
97
+ */
98
+ private _shape;
99
+ /** The laid-out form of a value, expanded across lines wherever one line will not do. */
100
+ private _format;
101
+ /** The arms for a non-null object, with `value` already on the open path. */
102
+ private _formatObject;
103
+ /**
104
+ * One position, with every value in it laid out.
105
+ *
106
+ * `at.column` is where `slot.head` begins. Rather than hand-tracking a
107
+ * second, parallel "column so far" alongside `out` — two values a future
108
+ * edit could update out of step, silently reintroducing a stale-budget bug
109
+ * of the same shape this file just fixed — each hole derives its own
110
+ * column fresh from `out` via `lineColumn`, the one place "text just
111
+ * emitted" becomes "column now". [LAW:one-source-of-truth] `out` is
112
+ * already the complete record; `column` is a read of it, not a second copy
113
+ * of the same fact. `_joinOneLine`'s probe sibling tracks the analogous
114
+ * thing via `budget` shrinking instead, because a probe already discards
115
+ * anything that overruns and so never needs to know where a multi-line
116
+ * insert's last line ends.
117
+ *
118
+ * Each hole's `reserve` is its own `tail` plus, only for the slot's last
119
+ * hole, whatever `at.reserve` already asked this whole slot to leave room
120
+ * for (`_formatObject`'s trailing `,`). An earlier hole's tail is never
121
+ * folded into a later hole's reserve — it is spent, not carried, the moment
122
+ * `out` grows past it.
123
+ */
124
+ private _expandSlot;
125
+ /** The one-line form of a value, or `null` when it will not fit `at.budget`. */
126
+ private _oneLine;
127
+ /**
128
+ * A container's positions on one line, or `null` as soon as they overrun.
129
+ *
130
+ * The budget is spent as it goes and each position is asked for only what is
131
+ * left, so a subtree that has already outgrown the line is abandoned where it
132
+ * outgrew it rather than formatted in full and then measured.
133
+ *
134
+ * The brackets are charged before anything is read, and that ordering is what
135
+ * bounds the traversal: a budget checked only against the finished text still
136
+ * reads the whole subtree to produce text it then throws away. Charged first,
137
+ * every level costs at least the two cells of its own brackets, so a probe
138
+ * descends at most `budget / 2` levels however deep the data goes.
139
+ */
140
+ private _joinOneLine;
141
+ /** One position on one line, or `null` when any value in it will not fit. */
142
+ private _slotOneLine;
143
+ private _addIndentGuides;
144
+ }