@promptctl/rich-js 0.24.1 → 0.25.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 (156) hide show
  1. package/README.md +7 -0
  2. package/dist/core/anchor.d.ts +5 -0
  3. package/dist/core/anchor.js +11 -4
  4. package/dist/core/animation.d.ts +175 -10
  5. package/dist/core/animation.js +283 -15
  6. package/dist/core/ansi.js +2 -2
  7. package/dist/core/box.d.ts +7 -7
  8. package/dist/core/cells.d.ts +23 -13
  9. package/dist/core/cells.js +58 -48
  10. package/dist/core/clock.d.ts +2 -2
  11. package/dist/core/clock.js +6 -4
  12. package/dist/core/color.d.ts +27 -10
  13. package/dist/core/color.js +21 -29
  14. package/dist/core/console.d.ts +28 -17
  15. package/dist/core/console.js +44 -39
  16. package/dist/core/easing.d.ts +30 -0
  17. package/dist/core/easing.js +65 -20
  18. package/dist/core/emoji.d.ts +1 -1
  19. package/dist/core/emoji.js +1 -2
  20. package/dist/core/export-html.js +2 -1
  21. package/dist/core/export-lines.js +3 -3
  22. package/dist/core/highlighter.d.ts +9 -8
  23. package/dist/core/highlighter.js +3 -2
  24. package/dist/core/json.js +2 -2
  25. package/dist/core/markup.js +16 -12
  26. package/dist/core/measure.js +2 -2
  27. package/dist/core/memo.d.ts +11 -2
  28. package/dist/core/memo.js +16 -0
  29. package/dist/core/oklch.js +17 -6
  30. package/dist/core/osc8.d.ts +1 -1
  31. package/dist/core/osc8.js +4 -5
  32. package/dist/core/paint.d.ts +2 -1
  33. package/dist/core/paint.js +4 -3
  34. package/dist/core/pattern.d.ts +21 -0
  35. package/dist/core/pattern.js +21 -0
  36. package/dist/core/pretty.js +9 -10
  37. package/dist/core/protocol.d.ts +100 -39
  38. package/dist/core/protocol.js +167 -21
  39. package/dist/core/render.d.ts +15 -2
  40. package/dist/core/render.js +25 -5
  41. package/dist/core/segment.d.ts +13 -5
  42. package/dist/core/segment.js +23 -9
  43. package/dist/core/spinnerData.d.ts +1 -1
  44. package/dist/core/state.d.ts +53 -0
  45. package/dist/core/state.js +82 -0
  46. package/dist/core/strip.d.ts +13 -16
  47. package/dist/core/strip.js +119 -110
  48. package/dist/core/style.d.ts +47 -14
  49. package/dist/core/style.js +57 -28
  50. package/dist/core/text.d.ts +5 -8
  51. package/dist/core/text.js +116 -124
  52. package/dist/core/timeline.d.ts +30 -5
  53. package/dist/core/timeline.js +43 -7
  54. package/dist/core/tween.d.ts +1 -1
  55. package/dist/core/tween.js +5 -3
  56. package/dist/core/view.d.ts +92 -0
  57. package/dist/core/view.js +83 -0
  58. package/dist/host/app.d.ts +49 -21
  59. package/dist/host/app.js +71 -37
  60. package/dist/host/input.js +3 -4
  61. package/dist/index.d.ts +24 -12
  62. package/dist/index.js +9 -4
  63. package/dist/node/traceback.js +4 -3
  64. package/dist/renderables/align.d.ts +2 -3
  65. package/dist/renderables/align.js +0 -3
  66. package/dist/renderables/change.d.ts +42 -0
  67. package/dist/renderables/change.js +112 -0
  68. package/dist/renderables/columns.d.ts +3 -4
  69. package/dist/renderables/columns.js +2 -7
  70. package/dist/renderables/constrain.d.ts +2 -3
  71. package/dist/renderables/constrain.js +0 -3
  72. package/dist/renderables/effect.d.ts +132 -54
  73. package/dist/renderables/effect.js +188 -115
  74. package/dist/renderables/effects.d.ts +122 -11
  75. package/dist/renderables/effects.js +238 -94
  76. package/dist/renderables/embed.d.ts +1 -1
  77. package/dist/renderables/embed.js +16 -8
  78. package/dist/renderables/flexStrip.d.ts +2 -3
  79. package/dist/renderables/flexStrip.js +0 -4
  80. package/dist/renderables/frames.d.ts +35 -54
  81. package/dist/renderables/frames.js +43 -58
  82. package/dist/renderables/glyph-effect.d.ts +158 -0
  83. package/dist/renderables/glyph-effect.js +237 -0
  84. package/dist/renderables/glyph-effects.d.ts +147 -0
  85. package/dist/renderables/glyph-effects.js +283 -0
  86. package/dist/renderables/group.d.ts +3 -4
  87. package/dist/renderables/group.js +0 -3
  88. package/dist/renderables/layout.d.ts +12 -12
  89. package/dist/renderables/layout.js +40 -46
  90. package/dist/renderables/lifecycle.d.ts +77 -0
  91. package/dist/renderables/lifecycle.js +132 -0
  92. package/dist/renderables/list-view.d.ts +4 -5
  93. package/dist/renderables/list-view.js +9 -13
  94. package/dist/renderables/live.d.ts +36 -21
  95. package/dist/renderables/live.js +88 -41
  96. package/dist/renderables/markdown-parse.d.ts +4 -4
  97. package/dist/renderables/markdown-parse.js +52 -46
  98. package/dist/renderables/markdown-url.js +11 -11
  99. package/dist/renderables/padding.d.ts +4 -5
  100. package/dist/renderables/padding.js +0 -3
  101. package/dist/renderables/panel.d.ts +14 -16
  102. package/dist/renderables/panel.js +6 -14
  103. package/dist/renderables/progress.d.ts +83 -34
  104. package/dist/renderables/progress.js +182 -95
  105. package/dist/renderables/progressBar.d.ts +22 -12
  106. package/dist/renderables/progressBar.js +32 -9
  107. package/dist/renderables/prompt.js +3 -2
  108. package/dist/renderables/python-space.js +2 -1
  109. package/dist/renderables/scroll.d.ts +50 -0
  110. package/dist/renderables/scroll.js +106 -0
  111. package/dist/renderables/spinner.d.ts +35 -14
  112. package/dist/renderables/spinner.js +65 -25
  113. package/dist/renderables/status.js +1 -1
  114. package/dist/renderables/syntax.d.ts +10 -9
  115. package/dist/renderables/syntax.js +3 -2
  116. package/dist/renderables/table.d.ts +34 -40
  117. package/dist/renderables/table.js +41 -63
  118. package/dist/renderables/traceback.d.ts +2 -2
  119. package/dist/renderables/traceback.js +6 -5
  120. package/dist/renderables/tree.d.ts +27 -25
  121. package/dist/renderables/tree.js +104 -58
  122. package/dist/renderables/viewport.d.ts +75 -44
  123. package/dist/renderables/viewport.js +145 -82
  124. package/dist/template-bindings/animation-funcs.d.ts +78 -9
  125. package/dist/template-bindings/animation-funcs.js +132 -14
  126. package/dist/template-bindings/index.d.ts +5 -5
  127. package/dist/template-bindings/index.js +5 -5
  128. package/dist/themes/ramp.d.ts +46 -3
  129. package/dist/themes/ramp.js +61 -4
  130. package/dist/themes/registry.js +5 -7
  131. package/dist/widgets/button.js +3 -2
  132. package/dist/widgets/checkbox.js +4 -3
  133. package/dist/widgets/dropdown.d.ts +3 -1
  134. package/dist/widgets/dropdown.js +20 -15
  135. package/dist/widgets/event-router.js +4 -2
  136. package/dist/widgets/focus-manager.d.ts +2 -0
  137. package/dist/widgets/focus-manager.js +6 -4
  138. package/dist/widgets/hit.d.ts +6 -0
  139. package/dist/widgets/hit.js +8 -1
  140. package/dist/widgets/observable.d.ts +23 -0
  141. package/dist/widgets/observable.js +43 -0
  142. package/dist/widgets/slider.d.ts +1 -1
  143. package/dist/widgets/slider.js +12 -3
  144. package/dist/widgets/static-item.d.ts +2 -3
  145. package/dist/widgets/static-item.js +0 -3
  146. package/dist/widgets/text-input.d.ts +28 -32
  147. package/dist/widgets/text-input.js +360 -346
  148. package/dist/widgets/themed-widget.js +2 -1
  149. package/dist/widgets/toggle.js +4 -3
  150. package/dist/widgets/types.d.ts +10 -4
  151. package/dist/widgets/types.js +8 -2
  152. package/dist/widgets/widget-app.d.ts +14 -4
  153. package/dist/widgets/widget-app.js +36 -7
  154. package/dist/widgets/widget-base.d.ts +2 -2
  155. package/dist/widgets/widget-base.js +29 -18
  156. package/package.json +8 -1
@@ -4,6 +4,7 @@
4
4
  import { COLOR_NAMES, ColorSpec, SURFACE_BLACK, } from "./color.js";
5
5
  import { shiftAnchor } from "./anchor.js";
6
6
  import { Memo } from "./memo.js";
7
+ import { pattern } from "./pattern.js";
7
8
  // [LAW:one-way-deps] `core/style` depends only on `core/color`. The substrate
8
9
  // a translucent colour is flattened over is `SURFACE_BLACK`, defined beside
9
10
  // `compositeOver`.
@@ -61,6 +62,8 @@ export const ATTRIBUTE_SHORT_ALIASES = {
61
62
  o: "overline",
62
63
  uu: "underline2",
63
64
  };
65
+ /** The hold of a cell that never changes: always was, and always will be. */
66
+ const NEVER_CHANGES = { lastChange: Number.NEGATIVE_INFINITY, nextChange: Number.POSITIVE_INFINITY };
64
67
  export class StyleSyntaxError extends Error {
65
68
  constructor(message, options) {
66
69
  super(message, options);
@@ -95,25 +98,31 @@ export class Style {
95
98
  */
96
99
  anchor;
97
100
  /**
98
- * When what this style's cells show next changes, in seconds on the
99
- * timeline of whoever drew the frame — `t` itself for a cell drawn by
100
- * something that moves every frame, and `Infinity`, the default, for one
101
+ * The hold this style's cells are in, on the timeline of whoever drew the
102
+ * frame: since when what they show has been what it is (`lastChange`), and
103
+ * when it next changes (`nextChange`) — both `t` for a cell drawn by
104
+ * something that moves every frame, and `-Infinity`/`Infinity` for one
101
105
  * that never changes. It draws nothing. Whatever draws for a handed time
102
- * stamps its cells with it (`Frames`, `Effected`), the stamp rides up
103
- * through every container as the anchor does (`./anchor.ts`), and
104
- * whoever holds the composed frame reads the soonest off it
105
- * (`Segment.nextChange`), so a host knows when to draw again without
106
- * asking each container. Two styles laid together change at the sooner.
106
+ * stamps its cells with it (`placedRender`, `Effected`), the stamp rides up
107
+ * through every container as the anchor does (`./anchor.ts`), and whoever
108
+ * holds the composed frame reads it off (`Segment.nextChange`, and
109
+ * `Segment.lastChange` for a host running its timeline backwards), so a
110
+ * host knows when to draw again without asking each container. Two styles
111
+ * laid together are in the intersection of their holds.
107
112
  */
108
- nextChange;
113
+ hold;
109
114
  constructor(options = {}) {
110
- const nextChange = options.nextChange ?? Number.POSITIVE_INFINITY;
115
+ const hold = options.hold ?? NEVER_CHANGES;
116
+ const { lastChange, nextChange } = hold;
111
117
  // [LAW:parse-dont-validate] A time or never, settled where the style is
112
- // made: NaN and -Infinity fail here, so no reader of a frame meets one.
118
+ // made: NaN and the far infinity fail here, so no reader of a frame meets one.
113
119
  if (!(nextChange > Number.NEGATIVE_INFINITY)) {
114
120
  throw new RangeError(`Style nextChange must be a time in seconds or Infinity, got ${nextChange}`);
115
121
  }
116
- this.nextChange = nextChange;
122
+ if (!(lastChange < Number.POSITIVE_INFINITY)) {
123
+ throw new RangeError(`Style lastChange must be a time in seconds or -Infinity, got ${lastChange}`);
124
+ }
125
+ this.hold = hold;
117
126
  this.color = resolveColor(options.color);
118
127
  this.bgcolor = resolveBackground(options.bgcolor);
119
128
  this.bold = options.bold;
@@ -153,7 +162,8 @@ export class Style {
153
162
  this.link === undefined &&
154
163
  this.meta === undefined &&
155
164
  this.anchor === undefined &&
156
- this.nextChange === Number.POSITIVE_INFINITY);
165
+ this.hold.nextChange === Number.POSITIVE_INFINITY &&
166
+ this.hold.lastChange === Number.NEGATIVE_INFINITY);
157
167
  }
158
168
  get transparentBackground() {
159
169
  return this.bgcolor === undefined || this.bgcolor.isDefault;
@@ -189,6 +199,28 @@ export class Style {
189
199
  withAnchor(anchor) {
190
200
  return this.with({ anchor });
191
201
  }
202
+ /** The style's text attributes, each as it sets it. */
203
+ get attributes() {
204
+ // [LAW:one-source-of-truth] Keyed by `ATTRIBUTE_NAMES`, whose every name is a key here: the cast is that list's own claim.
205
+ return Object.fromEntries(ATTRIBUTE_NAMES.map((name) => [name, this[name]]));
206
+ }
207
+ /**
208
+ * The same style with each attribute `attributes` names set as it says —
209
+ * on, off, or unset — and every other field as it was.
210
+ */
211
+ withAttributes(attributes) {
212
+ // Only the attribute names are read: a wider object — a `Style`, say —
213
+ // satisfies the type and must not carry its colours or anchor in with it.
214
+ return this.with(Object.fromEntries(ATTRIBUTE_NAMES.filter((name) => name in attributes).map((name) => [name, attributes[name]])));
215
+ }
216
+ /**
217
+ * This style with its motion taken out, what reduced motion draws: `blink`
218
+ * and `blink2`, the motion a terminal makes on its own, unset, and every
219
+ * other field as it was. A style that does not blink is its own.
220
+ */
221
+ reduced() {
222
+ return this.blink || this.blink2 ? this.withAttributes({ blink: undefined, blink2: undefined }) : this;
223
+ }
192
224
  /**
193
225
  * This style on the cell `cells` to the right: its anchor shifted along its
194
226
  * row, or the style itself when it has no anchor.
@@ -225,8 +257,9 @@ export class Style {
225
257
  ? { ...this.meta, ...other.meta }
226
258
  : other.meta ?? this.meta,
227
259
  anchor: other.anchor ?? this.anchor,
228
- // Cells under both change when either does: the sooner.
229
- nextChange: Math.min(this.nextChange, other.nextChange),
260
+ // Cells under both change when either does: the sooner, and have been
261
+ // what they are since the later — the intersection of the two holds.
262
+ hold: { lastChange: Math.max(this.hold.lastChange, other.hold.lastChange), nextChange: Math.min(this.hold.nextChange, other.hold.nextChange) },
230
263
  });
231
264
  }
232
265
  equals(other) {
@@ -249,7 +282,8 @@ export class Style {
249
282
  this.overline === other.overline &&
250
283
  this.link === other.link &&
251
284
  anchorsEqual(this.anchor, other.anchor) &&
252
- this.nextChange === other.nextChange);
285
+ this.hold.nextChange === other.hold.nextChange &&
286
+ this.hold.lastChange === other.hold.lastChange);
253
287
  }
254
288
  /**
255
289
  * The colours this style puts on screen at `colorSystem`: each flattened
@@ -299,7 +333,7 @@ export class Style {
299
333
  /**
300
334
  * The look as a canonical string that round-trips through `Style.parse()`:
301
335
  * colours, attributes and the link, which is all a style string can spell.
302
- * What a style carries beyond its look — `meta`, `anchor`, `nextChange` —
336
+ * What a style carries beyond its look — `meta`, `anchor`, `hold` —
303
337
  * has no spelling and is not here, so two styles that differ only there
304
338
  * read alike; `equals` tells them apart.
305
339
  */
@@ -390,7 +424,7 @@ export class StyleStack {
390
424
  }
391
425
  }
392
426
  // --- Theme ---
393
- const STYLE_NAME_RE = /^[a-z][a-z0-9._-]*$/;
427
+ const STYLE_NAME_RE = pattern(/^[a-z][a-z0-9._-]*$/);
394
428
  /**
395
429
  * `over` added to `base`, the outer style winning as `Style.add` has it. A
396
430
  * `Style` base takes the addition now, and so does `""`, the definition that
@@ -409,19 +443,14 @@ export function layerStyle(base, over) {
409
443
  export class Theme {
410
444
  styles;
411
445
  constructor(definitions = {}, options) {
412
- this.styles = new Map();
413
- const inherit = options?.inherit !== false;
414
- if (inherit) {
415
- for (const [name, style] of Object.entries(DEFAULT_STYLES)) {
416
- this.styles.set(name, style);
417
- }
418
- }
419
- for (const [name, def] of Object.entries(definitions)) {
446
+ const inherited = options?.inherit !== false ? Object.entries(DEFAULT_STYLES) : [];
447
+ const defined = Object.entries(definitions).map(([name, def]) => {
420
448
  if (!STYLE_NAME_RE.test(name)) {
421
449
  throw new Error(`Invalid style name: "${name}" (must be lowercase, start with letter, contain only letters, digits, ".", "-", "_")`);
422
450
  }
423
- this.styles.set(name, Style.parse(def));
424
- }
451
+ return [name, Style.parse(def)];
452
+ });
453
+ this.styles = new Map([...inherited, ...defined]);
425
454
  }
426
455
  get(name) {
427
456
  return this.styles.get(name);
@@ -33,15 +33,12 @@ export interface RichTextOptions {
33
33
  noWrap?: boolean;
34
34
  }
35
35
  export declare class RichText implements Renderable, Measurable {
36
- private _text;
37
- private _spans;
38
- private _style;
39
- private _justify;
40
- private _overflow;
41
- private _end;
42
- private _tabSize;
43
- private _noWrap;
36
+ private readonly _text;
37
+ private readonly _spans;
38
+ private readonly _format;
39
+ private readonly _tabSize;
44
40
  constructor(text?: string, options?: RichTextOptions);
41
+ private _reformat;
45
42
  get plain(): string;
46
43
  set plain(value: string);
47
44
  get length(): number;