@promptctl/rich-js 0.20.0 → 0.22.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.
@@ -3,7 +3,8 @@
3
3
  * long as they are drawn, and fade-in and dissolve-out, which run once and
4
4
  * are done. Each is an `Effect` for `Effected` (`./effect.ts`); the defaults
5
5
  * in `EFFECT_CURVES` are the ones signed off by eye in the effects-feel demo
6
- * (`npm run effects-feel`), at 30 fps and at one frame a second.
6
+ * (`npm run effects-feel`), at 30 fps and at one frame a second, and
7
+ * `EFFECT_CATALOGUE` makes every one of them at those, by name, one way.
7
8
  *
8
9
  * Each effect is something a first-time observer already knows from life —
9
10
  * a slow glow, sunlight moving on water, the colours of daylight, fireflies, ink
@@ -36,37 +37,35 @@
36
37
  * [LAW:no-ambient-temporal-coupling] No curve reads a clock; `t` is the
37
38
  * effect's argument, so the frame owner decides when to sample.
38
39
  *
39
- * Every import below names something the package exports, but for `noise`,
40
- * which the docs' effects playground page supplies itself: each of its
40
+ * Every import below names something the package exports, but for `noise`
41
+ * and `Memo`, which the docs' effects playground page supplies itself: each of its
41
42
  * cards runs this file's own declarations as the program a visitor edits
42
43
  * (`examples/effects-playground/programs.ts`), on the published library.
43
44
  */
44
45
  import { ColorRgba } from "../core/color.js";
45
46
  import { type Ease } from "../core/easing.js";
46
- import type { CellColors, Effect, EffectCell } from "./effect.js";
47
+ import { type Drawn, type Effect, type EffectCell } from "./effect.js";
47
48
  /** What a loop does to one colour at strength `w` in [0, 1]: at 0, nothing. */
48
49
  export type Touch = (color: ColorRgba, w: number) => ColorRgba;
49
- /** How strongly a loop acts on a cell at a moment, in [0, 1]; `onColors` holds a field outside it to it. */
50
- export type Field = (cell: EffectCell, t: number) => number;
50
+ /**
51
+ * How strongly a loop acts at a moment `t` on each cell, in [0, 1]; `onColors`
52
+ * holds a field outside it to it. Staged as `Effect` is: what holds for the
53
+ * whole moment is worked out once, then every cell is asked.
54
+ */
55
+ export type Field = (t: number) => (cell: EffectCell) => number;
51
56
  /** A looping effect: what it does to a colour, and where and when, how strongly. */
52
57
  export interface Loop {
53
58
  readonly touch: Touch;
54
59
  readonly field: Field;
55
60
  }
56
- /**
57
- * A cell's ink and ground as the screen shows them, and which of the two are
58
- * the terminal's: what an `Effect` is handed for that cell.
59
- */
60
- export interface Pair extends CellColors {
61
- readonly terminal: EffectCell["terminal"];
62
- }
63
61
  /**
64
62
  * How much of `touch` each of `colors` (hex) can take: the largest share in
65
- * [0, 1] at which every pair in `pairs` that shows it, touched at the same
63
+ * [0, 1] at which every pair `drawn` shows it in, touched at the same
66
64
  * strength, still reads at its resting contrast or `LEGIBLE`, whichever is
67
- * lower. A colour in a pair but not in `colors` takes none, and so does one
65
+ * lower, in the colours `Effected` writes it in at `drawn`'s depth and theme.
66
+ * A colour in a pair but not in `colors` takes none, and so does one
68
67
  * the terminal supplies, whatever its hex, as in `onColors`. One of `colors`
69
- * no pair writes has nothing to be measured against, and throws.
68
+ * no pair writes has nothing to be measured against, and takes it all.
70
69
  *
71
70
  * Colours are settled lightest first, each against every partner: one
72
71
  * already settled at its share, one not yet settled as it is. So the lighter
@@ -75,16 +74,30 @@ export interface Pair extends CellColors {
75
74
  * the fill room to glow — and a darker colour left as it is always holds,
76
75
  * because its lighter partner was settled against exactly that.
77
76
  */
78
- export declare function shares(pairs: readonly Pair[], colors: ReadonlySet<string>, touch: Touch): Map<string, number>;
77
+ export declare function shares({ pairs, depth, theme }: Drawn, colors: ReadonlySet<string>, touch: Touch): Map<string, number>;
78
+ /**
79
+ * A loop as an `Effect` on the element's own colours, by hex, wherever a cell
80
+ * shows them, each touched at its share of the cell's strength: the share
81
+ * `shares` settles for it against the pairs the element draws its words in
82
+ * (`Drawn`), touched as `Effected` writes them at the frame's depth — below
83
+ * truecolor a touched colour lands on a colour the slot can write, and the
84
+ * contrast it spends is that colour's. `colors` are the ones lit, by default every colour the element
85
+ * sets itself. A powerline strip's fill is the ground of its cells and the
86
+ * ink of the seam glyphs between them, so the arrow moves with the cell it
87
+ * points out of. A colour the terminal supplies (`EffectCell.terminal`) is
88
+ * not the element's, whatever its hex, and takes no share.
89
+ *
90
+ * Settling shares is costly, so it is done once for each set of colours an
91
+ * element draws: make the effect once and draw it in every frame, and a frame
92
+ * drawing what an earlier one drew costs no settling.
93
+ */
94
+ export declare function onColors(loop: Loop, colors?: ReadonlySet<string>): Effect;
79
95
  /**
80
- * A loop as an `Effect` on a subject's own colours, by hex, wherever a cell
81
- * shows them, each touched at its share of the cell's strength. A powerline
82
- * strip's fill is the ground of its cells and the ink of the seam glyphs
83
- * between them, so the arrow moves with the cell it points out of. A colour
84
- * the terminal supplies (`EffectCell.terminal`) is not the subject's, whatever
85
- * its hex, and takes no share.
96
+ * A loop as an `Effect` on colours by hex, each touched at the share
97
+ * `share` gives it of the cell's strength in a frame drawing what `Drawn`
98
+ * says; a colour it gives none, and one the terminal supplies, stays as it is.
86
99
  */
87
- export declare function onColors(share: ReadonlyMap<string, number>, loop: Loop): Effect;
100
+ export declare function atShares(loop: Loop, share: (drawn: Drawn) => ReadonlyMap<string, number>): Effect;
88
101
  /** How the curves below are tuned: one period (or duration), ease and swing. */
89
102
  export interface Curve {
90
103
  /** Seconds: a looping effect's period, a transition's duration. */
@@ -192,46 +205,46 @@ export declare function shimmer(curve: Curve, span: number, width: number, glow:
192
205
  */
193
206
  export declare function sparkle(curve: Curve, span: number, glow: ColorRgba, z: number): Loop;
194
207
  /**
195
- * How much of a cell shows at `t`: 1 is the cell as drawn, 0 is the cell gone
196
- * to the terminal's ground. Read per cell, so cells can arrive or leave apart. One
197
- * outside [0, 1] is held to it.
208
+ * How much of each cell shows at `t`: 1 is the cell as drawn, 0 is the cell
209
+ * gone to the terminal's ground. Read per cell, so cells can arrive or leave
210
+ * apart, and staged as `Field` is. One outside [0, 1] is held to it.
198
211
  */
199
- export type Visibility = (cell: EffectCell, t: number) => number;
212
+ export type Visibility = (t: number) => (cell: EffectCell) => number;
200
213
  /**
201
- * A cell mixed toward the terminal's `ground` by how hidden it is: its fill
202
- * toward the ground, and its ink toward that fill, so an element with fills
203
- * of its own — a powerline strip — arrives and leaves whole, fill and words
204
- * together, never as bare coloured blocks. Invisible is ink and fill equal
205
- * to the ground. `swing` scales the hiding — 1 reaches fully invisible. A
206
- * cell wholly shown is returned as it was.
214
+ * A cell mixed toward the ground of the terminal the frame is drawn on
215
+ * (`Drawn.theme`) by how hidden it is: its fill toward the ground, and its ink
216
+ * toward that fill, so an element with fills of its own — a powerline strip —
217
+ * arrives and leaves whole, fill and words together, never as bare coloured
218
+ * blocks. Invisible is ink and fill equal to the ground. `swing` scales the
219
+ * hiding — 1 reaches fully invisible. A cell wholly shown is returned as it was.
207
220
  */
208
- export declare function veiled(visibility: Visibility, swing: number, ground: ColorRgba): Effect;
221
+ export declare function veiled(visibility: Visibility, swing: number): Effect;
209
222
  /**
210
- * An effect that runs once: a fade-in or a dissolve-out from its start time
211
- * over its curve's `seconds`. `done(t)` is true from the moment every cell
212
- * has arrived or gone, so the caller knows when to stop drawing an element
213
- * that is leaving, or to drop the effect from one that has arrived.
223
+ * An effect that runs once: a fade-in or a dissolve-out over its curve's
224
+ * `seconds` from `t = 0`, its own clock as every effect's is — the caller
225
+ * draws it at the time since it began. `done(t)` is true from the moment
226
+ * every cell has arrived or gone, so the caller knows when to stop drawing an
227
+ * element that is leaving, or to drop the effect from one that has arrived.
214
228
  */
215
229
  export interface Transition {
216
230
  readonly effect: Effect;
217
231
  done(t: number): boolean;
218
232
  }
219
233
  /**
220
- * Fade-in starting at `start`, as ink blooming in water: patches of the
221
- * element surface first and the rest follows outward from them, each cell
222
- * rising smoothly over its own part of the duration. Whole at
223
- * `start + seconds`.
234
+ * Fade-in, as ink blooming in water: patches of the element surface first
235
+ * and the rest follows outward from them, each cell rising smoothly over its
236
+ * own part of the duration. Whole at `seconds`.
224
237
  */
225
- export declare function fadeIn(curve: Curve, start: number, z: number, ground: ColorRgba): Transition;
238
+ export declare function fadeIn(curve: Curve, z: number): Transition;
226
239
  /**
227
- * Dissolve-out starting at `start`, as mist lifting: the element thins in
228
- * drifting patches, each cell fading smoothly over its own part of the
229
- * duration, until nothing is left at `start + seconds`. Mist does not lift
240
+ * Dissolve-out, as mist lifting: the element thins in drifting patches, each
241
+ * cell fading smoothly over its own part of the duration, until nothing is
242
+ * left at `seconds`. Mist does not lift
230
243
  * in one breath: towards the end, patches of what is left — the later a cell
231
244
  * goes, the likelier — rise back part way, as the last of it eddies, before
232
245
  * they thin away for good.
233
246
  */
234
- export declare function dissolveOut(curve: Curve, start: number, z: number, ground: ColorRgba): Transition;
247
+ export declare function dissolveOut(curve: Curve, z: number): Transition;
235
248
  /**
236
249
  * Wheel, as the colour of daylight going round: every hue turning the whole
237
250
  * way round once a period — far too slowly to be seen moving, so a glance
@@ -247,6 +260,36 @@ export declare function dissolveOut(curve: Curve, start: number, z: number, grou
247
260
  * its own. A segment's stray is slow noise of its own, at `STRAY_PERIODS`,
248
261
  * so no two keep step, and the row never shows one spread of hues twice.
249
262
  * Lightness and chroma are kept, so the words read as they did; the turn
250
- * only happens to `colors`, the element's own, never the terminal's.
263
+ * only happens to the element's own colours (`Drawn.colors`), never the
264
+ * terminal's.
265
+ */
266
+ export declare function wheel(curve: Curve, z: number): Effect;
267
+ /**
268
+ * What a catalogue effect is made for: the element it is drawn on, as wide as
269
+ * `span` columns — how far a shimmer crosses, how many fireflies keep to it —
270
+ * and at `z` in the noise, so two elements under one effect do not move in
271
+ * lockstep.
251
272
  */
252
- export declare function wheel(curve: Curve, colors: ReadonlySet<string>, fills: ReadonlySet<string>, z: number): Effect;
273
+ export interface EffectTarget {
274
+ readonly span: number;
275
+ readonly z: number;
276
+ }
277
+ /** The names of the effects that loop. */
278
+ export type LoopName = "shimmer" | "pulse" | "sparkle" | "wheel";
279
+ /** The names of the effects that run once. */
280
+ export type TransitionName = "fade" | "dissolve";
281
+ /**
282
+ * Every effect in the catalogue by its name in `EFFECT_CURVES`, each made the
283
+ * one way: for an element, at its signed-off curve unless handed another,
284
+ * with the light and the width it was signed off with. A loop comes lit on
285
+ * the element's own colours (`onColors`); a transition comes as itself, to
286
+ * be told when it is done. [LAW:types-are-the-program] Keyed by the two
287
+ * name types, which `EFFECT_CURVES` is held to as well: a curve signed off
288
+ * does not compile until it is named a loop or a transition, and then not
289
+ * until it has an entry here making one. A picker walking a section's names
290
+ * offers an effect added here with no change of its own.
291
+ */
292
+ export declare const EFFECT_CATALOGUE: {
293
+ readonly loops: Readonly<Record<LoopName, (element: EffectTarget, curve?: Curve) => Effect>>;
294
+ readonly transitions: Readonly<Record<TransitionName, (element: EffectTarget, curve?: Curve) => Transition>>;
295
+ };