@promptctl/rich-js 0.27.0 → 0.28.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.
- package/README.md +1 -0
- package/THIRD-PARTY-NOTICES +42 -0
- package/dist/core/animation.d.ts +36 -17
- package/dist/core/animation.js +61 -37
- package/dist/core/ansi.d.ts +15 -8
- package/dist/core/ansi.js +106 -28
- package/dist/core/bidi-data.d.ts +14 -0
- package/dist/core/bidi-data.js +385 -0
- package/dist/core/bidi.d.ts +89 -0
- package/dist/core/bidi.js +615 -0
- package/dist/core/box.d.ts +9 -1
- package/dist/core/box.js +11 -0
- package/dist/core/cell-widths.d.ts +3 -2
- package/dist/core/cell-widths.js +93 -93
- package/dist/core/cells.d.ts +20 -0
- package/dist/core/cells.js +93 -5
- package/dist/core/color.d.ts +6 -7
- package/dist/core/color.js +11 -13
- package/dist/core/console.d.ts +18 -1
- package/dist/core/console.js +24 -5
- package/dist/core/control-codes.d.ts +61 -0
- package/dist/core/control-codes.js +157 -0
- package/dist/core/env.d.ts +6 -0
- package/dist/core/env.js +9 -1
- package/dist/core/export-html.js +4 -3
- package/dist/core/export-lines.d.ts +2 -0
- package/dist/core/export-lines.js +7 -3
- package/dist/core/export-svg.js +6 -5
- package/dist/core/json.js +9 -2
- package/dist/core/markup.js +4 -3
- package/dist/core/orient.d.ts +68 -0
- package/dist/core/orient.js +224 -0
- package/dist/core/osc8.d.ts +12 -5
- package/dist/core/osc8.js +14 -7
- package/dist/core/pretty.js +22 -18
- package/dist/core/protocol.d.ts +27 -6
- package/dist/core/protocol.js +14 -6
- package/dist/core/render.d.ts +8 -3
- package/dist/core/render.js +18 -5
- package/dist/core/seal.d.ts +26 -0
- package/dist/core/seal.js +75 -0
- package/dist/core/segment.d.ts +9 -1
- package/dist/core/segment.js +11 -1
- package/dist/core/style.d.ts +29 -1
- package/dist/core/style.js +41 -5
- package/dist/core/text-order.d.ts +51 -0
- package/dist/core/text-order.js +50 -0
- package/dist/core/text.d.ts +10 -0
- package/dist/core/text.js +133 -87
- package/dist/core/timeline.js +6 -6
- package/dist/core/view.d.ts +1 -1
- package/dist/core/view.js +5 -4
- package/dist/core/wrap.d.ts +24 -6
- package/dist/core/wrap.js +82 -16
- package/dist/host/app.d.ts +44 -3
- package/dist/host/app.js +111 -6
- package/dist/host/index.d.ts +3 -2
- package/dist/host/index.js +1 -0
- package/dist/host/input.d.ts +35 -2
- package/dist/host/input.js +88 -4
- package/dist/host/terminal-colors.d.ts +18 -0
- package/dist/host/terminal-colors.js +46 -0
- package/dist/host/terminal-host.d.ts +2 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +2 -2
- package/dist/renderables/change.d.ts +1 -3
- package/dist/renderables/change.js +4 -6
- package/dist/renderables/effect.d.ts +60 -59
- package/dist/renderables/effect.js +91 -81
- package/dist/renderables/effects.d.ts +37 -8
- package/dist/renderables/effects.js +185 -52
- package/dist/renderables/frames.d.ts +1 -10
- package/dist/renderables/frames.js +1 -16
- package/dist/renderables/glyph-effect.d.ts +12 -13
- package/dist/renderables/glyph-effect.js +34 -32
- package/dist/renderables/glyph-effects.d.ts +27 -8
- package/dist/renderables/glyph-effects.js +75 -7
- package/dist/renderables/lifecycle.d.ts +5 -7
- package/dist/renderables/lifecycle.js +6 -7
- package/dist/renderables/markdown.js +4 -2
- package/dist/renderables/panel.js +6 -4
- package/dist/renderables/progressBar.d.ts +3 -3
- package/dist/renderables/progressBar.js +16 -13
- package/dist/renderables/syntax.js +7 -2
- package/dist/renderables/table.js +2 -1
- package/dist/template-bindings/animation-funcs.d.ts +49 -18
- package/dist/template-bindings/animation-funcs.js +115 -32
- package/dist/template-bindings/index.d.ts +7 -5
- package/dist/template-bindings/index.js +8 -5
- package/dist/template-bindings/palette-funcs.d.ts +1 -1
- package/dist/template-bindings/palette-funcs.js +1 -1
- package/dist/themes/buildPalette.d.ts +3 -2
- package/dist/themes/buildPalette.js +2 -2
- package/dist/themes/data/index.js +1 -4
- package/dist/themes/data/textual-ansi.js +0 -143
- package/dist/themes/ramp.d.ts +1 -1
- package/dist/themes/ramp.js +1 -1
- package/dist/themes/registry.d.ts +6 -8
- package/dist/themes/registry.js +2 -4
- package/dist/themes/terminalThemes.d.ts +4 -11
- package/dist/themes/terminalThemes.js +31 -47
- package/dist/widgets/button.d.ts +1 -1
- package/dist/widgets/button.js +6 -6
- package/dist/widgets/checkbox.js +4 -4
- package/dist/widgets/dropdown.d.ts +1 -1
- package/dist/widgets/dropdown.js +7 -5
- package/dist/widgets/themed-widget.js +3 -3
- package/dist/widgets/toggle.d.ts +1 -1
- package/dist/widgets/toggle.js +5 -5
- package/package.json +5 -4
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* number the time is turned into first: a frame's stamp says when it changes
|
|
21
21
|
* on the host's clock, which only `Timeline.run` can carry it back onto —
|
|
22
22
|
* paused, never; backwards, at the hold it is about to drop under.
|
|
23
|
-
* [LAW:single-enforcer] `
|
|
23
|
+
* [LAW:single-enforcer] `drawn` is the one place the time, the timeline
|
|
24
24
|
* and the reader's preference for motion are read, for every function.
|
|
25
25
|
*
|
|
26
26
|
* `frames <seconds> <frame> <seconds> <frame> …` is a `FrameSequence`
|
|
@@ -57,31 +57,52 @@
|
|
|
57
57
|
* exact arity of typed slots, so a slot of the wrong kind fails at the gate.
|
|
58
58
|
*
|
|
59
59
|
* Every function says when what it drew changes, so a host paints a
|
|
60
|
-
* template while it moves and not after
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
60
|
+
* template while it moves and not after — and says it only for what the
|
|
61
|
+
* output depends on. A number or a colour has no cells to carry a hold, and
|
|
62
|
+
* a fragment's cells lose theirs the moment it is flattened (`printf "%s"`),
|
|
63
|
+
* so no function stamps cells or tells the frame itself. Each marks its
|
|
64
|
+
* return with the hold its value is in (`marked`, the engine's evaluation
|
|
65
|
+
* provenance), and the engine carries the mark beside the value into every
|
|
66
|
+
* variable, dot and function the value passes through, reporting it where
|
|
67
|
+
* the output depends on it. `emitted` is where a template's cells take a
|
|
68
|
+
* hold: every fragment the template emits, stamped with the holds of the
|
|
69
|
+
* marked values its action read. `decided` is the route for a hold no cell
|
|
70
|
+
* can carry, told to the frame (`TemplateFrame.onHold`): a mark an
|
|
71
|
+
* `if`/`with`/`range` consumed, whichever arm it took, because the frame may
|
|
72
|
+
* show cells for it later and must say when without a cell to say it on, as
|
|
73
|
+
* a placed animation of no cells does (`placed`) — and, by the same rule, a
|
|
74
|
+
* mark a writing function or a throwing action read; `EngineConfig.decided`
|
|
75
|
+
* is the authority on when it is called. A mark bound somewhere nobody reads
|
|
76
|
+
* is reported nowhere, so a value a template computes and never draws or
|
|
77
|
+
* decides on tells the frame nothing (rich-animation-27tq.0gd). Early, never
|
|
78
|
+
* late: an emission may carry a hold it did not strictly need, and a hold
|
|
79
|
+
* the output depends on is never dropped. [LAW:single-enforcer]
|
|
80
|
+
*
|
|
81
|
+
* The functions and the two hooks go into the host's engine config together,
|
|
82
|
+
* by `withAnimation`: the functions wired without the hooks would compile,
|
|
83
|
+
* draw and never say they move. [LAW:no-silent-failure]
|
|
66
84
|
*/
|
|
67
|
-
import type
|
|
85
|
+
import { type EngineConfig } from "@promptctl/go-template-js";
|
|
68
86
|
import type { RenderOptions } from "../core/protocol.js";
|
|
87
|
+
import type { RichText } from "../core/text.js";
|
|
69
88
|
import { Timeline } from "../core/timeline.js";
|
|
70
|
-
/** What
|
|
71
|
-
export interface
|
|
89
|
+
/** What the animation functions are drawn on, beside the frame each evaluation is handed. */
|
|
90
|
+
export interface AnimationOptions {
|
|
72
91
|
/** The timeline to draw on, read once per call; the frame's own time when omitted. */
|
|
73
92
|
readonly timeline?: () => Timeline;
|
|
74
93
|
}
|
|
75
94
|
/**
|
|
76
95
|
* The frame a template is evaluated for, in the fields a render's options
|
|
77
|
-
* carry under the same names: `time` in seconds, `onHold`, told
|
|
78
|
-
*
|
|
96
|
+
* carry under the same names: `time` in seconds, `onHold`, told the hold of
|
|
97
|
+
* an animated value the output may depend on with no cell to carry it — one
|
|
98
|
+
* a decision read, whichever arm it took, a writing function's input, a
|
|
99
|
+
* throwing action's (the engine's `decided`) — and the reader's preferences,
|
|
79
100
|
* `reducedMotion`, and `asciiOnly`, which the glyphs an effect picks for
|
|
80
101
|
* itself go through. They arrive with every frame and nowhere else, so a
|
|
81
102
|
* template drawn in an `App` is drawn as the app's preferences say.
|
|
82
103
|
* [LAW:one-source-of-truth]
|
|
83
104
|
*
|
|
84
|
-
* `time` is on the clock `
|
|
105
|
+
* `time` is on the clock `AnimationOptions.timeline` maps from, and
|
|
85
106
|
* `onHold` hears on that clock. A host outside rich-js hands its own clock's
|
|
86
107
|
* time. Inside a rich-js frame the time is the frame's, which its host's
|
|
87
108
|
* timeline has already mapped, so a template drawn there registers no
|
|
@@ -93,14 +114,24 @@ export interface TemplateFrame extends Pick<RenderOptions, "onHold" | "reducedMo
|
|
|
93
114
|
/** The frame a renderable is drawn in, as the frame a template it evaluates there is drawn for. */
|
|
94
115
|
export declare function templateFrame(options: RenderOptions): TemplateFrame;
|
|
95
116
|
/**
|
|
96
|
-
*
|
|
97
|
-
* the frame `frame` reports when
|
|
98
|
-
* seconds, from whatever zero the
|
|
99
|
-
* `options.timeline`, and each
|
|
117
|
+
* `config` with `frames`, `stepped`, `tween`, `loop` and `glyphs` registered
|
|
118
|
+
* beside its own functions, each drawn for the frame `frame` reports when
|
|
119
|
+
* the template is evaluated — its time in seconds, from whatever zero the
|
|
120
|
+
* host counts from — through `options.timeline`, and each marking its
|
|
121
|
+
* return with the hold it is in there; and with the two hooks that carry
|
|
122
|
+
* those holds to the cells (`emitted`) and the frame (`decided`) installed
|
|
123
|
+
* over any `config` already has, which still hear everything they did. One
|
|
124
|
+
* call, so the functions and the hooks that report for them cannot be wired
|
|
125
|
+
* apart: the functions alone would compile, draw, and never say they move.
|
|
126
|
+
* [LAW:types-are-the-program] [LAW:no-silent-failure] [LAW:composability]
|
|
127
|
+
* A `config` that already has one of the five names is refused, which is
|
|
128
|
+
* also what a second `withAnimation` over its own result meets: its template
|
|
129
|
+
* calls would otherwise reach these with no word said.
|
|
130
|
+
*
|
|
100
131
|
* The functions exist whatever `frame` returns, so a template compiles once
|
|
101
132
|
* and is evaluated at every moment the host draws. In a frame that says
|
|
102
133
|
* `reducedMotion` each draws its animation reduced (`Animation.reduced`): a
|
|
103
134
|
* loop at its start, a one-shot cut from where it starts to where it arrives
|
|
104
135
|
* when it starts.
|
|
105
136
|
*/
|
|
106
|
-
export declare function
|
|
137
|
+
export declare function withAnimation(config: EngineConfig<RichText>, frame: () => TemplateFrame, options?: AnimationOptions): EngineConfig<RichText>;
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* number the time is turned into first: a frame's stamp says when it changes
|
|
21
21
|
* on the host's clock, which only `Timeline.run` can carry it back onto —
|
|
22
22
|
* paused, never; backwards, at the hold it is about to drop under.
|
|
23
|
-
* [LAW:single-enforcer] `
|
|
23
|
+
* [LAW:single-enforcer] `drawn` is the one place the time, the timeline
|
|
24
24
|
* and the reader's preference for motion are read, for every function.
|
|
25
25
|
*
|
|
26
26
|
* `frames <seconds> <frame> <seconds> <frame> …` is a `FrameSequence`
|
|
@@ -57,27 +57,62 @@
|
|
|
57
57
|
* exact arity of typed slots, so a slot of the wrong kind fails at the gate.
|
|
58
58
|
*
|
|
59
59
|
* Every function says when what it drew changes, so a host paints a
|
|
60
|
-
* template while it moves and not after
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
60
|
+
* template while it moves and not after — and says it only for what the
|
|
61
|
+
* output depends on. A number or a colour has no cells to carry a hold, and
|
|
62
|
+
* a fragment's cells lose theirs the moment it is flattened (`printf "%s"`),
|
|
63
|
+
* so no function stamps cells or tells the frame itself. Each marks its
|
|
64
|
+
* return with the hold its value is in (`marked`, the engine's evaluation
|
|
65
|
+
* provenance), and the engine carries the mark beside the value into every
|
|
66
|
+
* variable, dot and function the value passes through, reporting it where
|
|
67
|
+
* the output depends on it. `emitted` is where a template's cells take a
|
|
68
|
+
* hold: every fragment the template emits, stamped with the holds of the
|
|
69
|
+
* marked values its action read. `decided` is the route for a hold no cell
|
|
70
|
+
* can carry, told to the frame (`TemplateFrame.onHold`): a mark an
|
|
71
|
+
* `if`/`with`/`range` consumed, whichever arm it took, because the frame may
|
|
72
|
+
* show cells for it later and must say when without a cell to say it on, as
|
|
73
|
+
* a placed animation of no cells does (`placed`) — and, by the same rule, a
|
|
74
|
+
* mark a writing function or a throwing action read; `EngineConfig.decided`
|
|
75
|
+
* is the authority on when it is called. A mark bound somewhere nobody reads
|
|
76
|
+
* is reported nowhere, so a value a template computes and never draws or
|
|
77
|
+
* decides on tells the frame nothing (rich-animation-27tq.0gd). Early, never
|
|
78
|
+
* late: an emission may carry a hold it did not strictly need, and a hold
|
|
79
|
+
* the output depends on is never dropped. [LAW:single-enforcer]
|
|
80
|
+
*
|
|
81
|
+
* The functions and the two hooks go into the host's engine config together,
|
|
82
|
+
* by `withAnimation`: the functions wired without the hooks would compile,
|
|
83
|
+
* draw and never say they move. [LAW:no-silent-failure]
|
|
66
84
|
*/
|
|
67
|
-
import {
|
|
85
|
+
import { marked } from "@promptctl/go-template-js";
|
|
86
|
+
import { Animation, frameTimeOf, holdOf, shownAt, stamp } from "../core/animation.js";
|
|
68
87
|
import { Phase, beat, finiteTime, parseEase } from "../core/easing.js";
|
|
88
|
+
import { layerStyle } from "../core/style.js";
|
|
69
89
|
import { Timeline } from "../core/timeline.js";
|
|
70
90
|
import { tween } from "../core/tween.js";
|
|
71
91
|
import { cellSeed } from "../renderables/effect.js";
|
|
72
92
|
import { reglyphText } from "../renderables/glyph-effect.js";
|
|
73
93
|
import { GLYPH_EFFECT_CATALOGUE } from "../renderables/glyph-effects.js";
|
|
74
|
-
import { FrameSequence
|
|
94
|
+
import { FrameSequence } from "../renderables/frames.js";
|
|
75
95
|
import { asColor } from "./color-funcs.js";
|
|
76
96
|
import { asFragment } from "./helpers.js";
|
|
77
97
|
/** The frame a renderable is drawn in, as the frame a template it evaluates there is drawn for. */
|
|
78
98
|
export function templateFrame(options) {
|
|
79
99
|
return { time: frameTimeOf(options), onHold: options.onHold, reducedMotion: options.reducedMotion, asciiOnly: options.asciiOnly };
|
|
80
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* The mark a function puts on its return: the hold its value is in, and the
|
|
103
|
+
* frame it was drawn for, which is the one `decided` tells. Only the two
|
|
104
|
+
* hooks here read one; a consumer's own marks pass through them untouched,
|
|
105
|
+
* and a foreign token shaped like a `Hold` is not one.
|
|
106
|
+
* [LAW:types-are-the-program]
|
|
107
|
+
*/
|
|
108
|
+
class HoldMark {
|
|
109
|
+
hold;
|
|
110
|
+
frame;
|
|
111
|
+
constructor(hold, frame) {
|
|
112
|
+
this.hold = hold;
|
|
113
|
+
this.frame = frame;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
81
116
|
/** The host's own clock as a timeline: host time 0 at animation time 0, at rate 1. */
|
|
82
117
|
const HOST_CLOCK = Timeline.play(0);
|
|
83
118
|
/**
|
|
@@ -127,36 +162,41 @@ function glyphEffect(name) {
|
|
|
127
162
|
return GLYPH_EFFECTS[name];
|
|
128
163
|
}
|
|
129
164
|
/**
|
|
130
|
-
*
|
|
131
|
-
* the frame `frame` reports when
|
|
132
|
-
* seconds, from whatever zero the
|
|
133
|
-
* `options.timeline`, and each
|
|
165
|
+
* `config` with `frames`, `stepped`, `tween`, `loop` and `glyphs` registered
|
|
166
|
+
* beside its own functions, each drawn for the frame `frame` reports when
|
|
167
|
+
* the template is evaluated — its time in seconds, from whatever zero the
|
|
168
|
+
* host counts from — through `options.timeline`, and each marking its
|
|
169
|
+
* return with the hold it is in there; and with the two hooks that carry
|
|
170
|
+
* those holds to the cells (`emitted`) and the frame (`decided`) installed
|
|
171
|
+
* over any `config` already has, which still hear everything they did. One
|
|
172
|
+
* call, so the functions and the hooks that report for them cannot be wired
|
|
173
|
+
* apart: the functions alone would compile, draw, and never say they move.
|
|
174
|
+
* [LAW:types-are-the-program] [LAW:no-silent-failure] [LAW:composability]
|
|
175
|
+
* A `config` that already has one of the five names is refused, which is
|
|
176
|
+
* also what a second `withAnimation` over its own result meets: its template
|
|
177
|
+
* calls would otherwise reach these with no word said.
|
|
178
|
+
*
|
|
134
179
|
* The functions exist whatever `frame` returns, so a template compiles once
|
|
135
180
|
* and is evaluated at every moment the host draws. In a frame that says
|
|
136
181
|
* `reducedMotion` each draws its animation reduced (`Animation.reduced`): a
|
|
137
182
|
* loop at its start, a one-shot cut from where it starts to where it arrives
|
|
138
183
|
* when it starts.
|
|
139
184
|
*/
|
|
140
|
-
export function
|
|
185
|
+
export function withAnimation(config, frame, options = {}) {
|
|
141
186
|
const timeline = options.timeline ?? (() => HOST_CLOCK);
|
|
142
|
-
// `animation
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const [drawn, t] = drawing(what, animation, at);
|
|
150
|
-
const shown = shownAt(drawn, t, at);
|
|
151
|
-
at.onHold?.(holdOf(shown, t));
|
|
152
|
-
return shown.value;
|
|
187
|
+
// What `animation`, on this call's timeline, shows in the frame `at`,
|
|
188
|
+
// under the reader's preference, marked with how long for: the time is
|
|
189
|
+
// read once a call so a value and its hold are one frame's.
|
|
190
|
+
const drawn = (what, animation, at) => {
|
|
191
|
+
const t = finiteTime(what, at.time);
|
|
192
|
+
const shown = shownAt(Timeline.run(timeline(), animation), t, at);
|
|
193
|
+
return marked(shown.value, new HoldMark(holdOf(shown, t), at));
|
|
153
194
|
};
|
|
154
195
|
const startedAt = (start, animation) => Timeline.run(Timeline.play(start), animation);
|
|
155
196
|
const framesFunc = {
|
|
156
197
|
fn: ((...tail) => {
|
|
157
198
|
const frames = pairs("frame", tail, asFragment).map(({ seconds, value }) => ({ seconds, text: value }));
|
|
158
|
-
|
|
159
|
-
return textFrameAt(...drawing("frames", new FrameSequence(frames), at), at);
|
|
199
|
+
return drawn("frames", new FrameSequence(frames), frame());
|
|
160
200
|
}),
|
|
161
201
|
argTypes: ["float", "liftable"],
|
|
162
202
|
arity: { kind: "alternating", minimum: 2 },
|
|
@@ -165,20 +205,20 @@ export function animationFuncs(frame, options = {}) {
|
|
|
165
205
|
const steppedFunc = {
|
|
166
206
|
fn: ((...tail) => {
|
|
167
207
|
const steps = pairs("color", tail, (v) => asColor(v, "stepped"));
|
|
168
|
-
return
|
|
208
|
+
return drawn("stepped", Animation.map(beat(steps.map((s) => s.seconds)), (step) => steps[step].value.hex), frame());
|
|
169
209
|
}),
|
|
170
210
|
argTypes: ["float", "string"],
|
|
171
211
|
arity: { kind: "alternating", minimum: 2 },
|
|
172
212
|
returnType: "string",
|
|
173
213
|
};
|
|
174
214
|
const tweenFunc = {
|
|
175
|
-
fn: ((seconds, ease, start, from, to) =>
|
|
215
|
+
fn: ((seconds, ease, start, from, to) => drawn("tween", startedAt(start, tween(from, to, { seconds, ease: parseEase(ease) })), frame())),
|
|
176
216
|
argTypes: ["float", "string", "float", "float", "float"],
|
|
177
217
|
arity: { kind: "exact" },
|
|
178
218
|
returnType: "float",
|
|
179
219
|
};
|
|
180
220
|
const loopFunc = {
|
|
181
|
-
fn: ((seconds, start) =>
|
|
221
|
+
fn: ((seconds, start) => drawn("loop", startedAt(start, Animation.continuous(Phase.loop(seconds))), frame())),
|
|
182
222
|
argTypes: ["float", "float"],
|
|
183
223
|
arity: { kind: "exact" },
|
|
184
224
|
returnType: "float",
|
|
@@ -191,11 +231,54 @@ export function animationFuncs(frame, options = {}) {
|
|
|
191
231
|
const key = fragment.plain;
|
|
192
232
|
const at = frame();
|
|
193
233
|
const reglyphed = reglyphText(fragment, make({ z: cellSeed(key, 0, 0) }), { key, asciiOnly: at.asciiOnly === true });
|
|
194
|
-
return
|
|
234
|
+
return drawn("glyphs", startedAt(start, reglyphed), at);
|
|
195
235
|
}),
|
|
196
236
|
argTypes: ["string", "float", "liftable"],
|
|
197
237
|
arity: { kind: "exact" },
|
|
198
238
|
returnType: "T",
|
|
199
239
|
};
|
|
200
|
-
|
|
240
|
+
const funcs = { frames: framesFunc, stepped: steppedFunc, tween: tweenFunc, loop: loopFunc, glyphs: glyphsFunc };
|
|
241
|
+
const taken = Object.keys(funcs).filter((name) => Object.hasOwn(config.funcs ?? {}, name));
|
|
242
|
+
if (taken.length > 0) {
|
|
243
|
+
throw new RangeError(`withAnimation registers ${taken.join(", ")}, already in config.funcs`);
|
|
244
|
+
}
|
|
245
|
+
const holdMarks = (marks) => [...marks].filter((mark) => mark instanceof HoldMark);
|
|
246
|
+
// The holds among `marks` layered onto the fragment's base style, which an
|
|
247
|
+
// empty text still draws as its one piece of no width: `Style.add` keeps
|
|
248
|
+
// the later `lastChange` and the sooner `nextChange`, so cells that read
|
|
249
|
+
// two animated values are in the intersection of their holds, as two
|
|
250
|
+
// styles laid together are anywhere. A fragment no hold reaches is handed
|
|
251
|
+
// back as it came — the engine calls this for every emission — and one a
|
|
252
|
+
// hold reaches is a copy, since the engine may hand the one fragment a
|
|
253
|
+
// scope holds to more than one emission.
|
|
254
|
+
const held = (fragment, marks) => {
|
|
255
|
+
const holds = holdMarks(marks);
|
|
256
|
+
if (holds.length === 0)
|
|
257
|
+
return fragment;
|
|
258
|
+
const result = fragment.copy();
|
|
259
|
+
result.style = holds.reduce((style, mark) => layerStyle(style, stamp(mark.hold)), fragment.style);
|
|
260
|
+
return result;
|
|
261
|
+
};
|
|
262
|
+
const told = (marks) => {
|
|
263
|
+
for (const mark of holdMarks(marks))
|
|
264
|
+
mark.frame.onHold?.(mark.hold);
|
|
265
|
+
};
|
|
266
|
+
// The hooks `config` brought run first and hear everything they did; a
|
|
267
|
+
// consumer that stamps or listens on its own loses nothing to this binding.
|
|
268
|
+
const emitted = config.emitted ?? ((fragment) => fragment);
|
|
269
|
+
const decided = config.decided ?? (() => { });
|
|
270
|
+
return {
|
|
271
|
+
...config,
|
|
272
|
+
funcs: { ...config.funcs, ...funcs },
|
|
273
|
+
emitted: (fragment, marks) => held(emitted(fragment, marks), marks),
|
|
274
|
+
// `finally`: a consumer hook that throws still leaves the frame told its holds.
|
|
275
|
+
decided: (marks) => {
|
|
276
|
+
try {
|
|
277
|
+
decided(marks);
|
|
278
|
+
}
|
|
279
|
+
finally {
|
|
280
|
+
told(marks);
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
};
|
|
201
284
|
}
|
|
@@ -14,10 +14,12 @@
|
|
|
14
14
|
* - `paletteFuncs(getPalette)` — `color` and `ramp`, the two functions that
|
|
15
15
|
* resolve a palette name. This is the *only* registration that knows a
|
|
16
16
|
* palette exists. [LAW:one-way-deps]
|
|
17
|
-
* - `
|
|
18
|
-
* `
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* - `withAnimation(config, frame)` — the engine config with `frames`,
|
|
18
|
+
* `stepped`, `tween`, `loop` and `glyphs` registered, drawn for a moment on
|
|
19
|
+
* a timeline, and the two engine hooks their holds reach the frame through
|
|
20
|
+
* installed beside them. It is the only registration that knows the
|
|
21
|
+
* template is evaluated at a time, and the time and the timeline are the
|
|
22
|
+
* host's to hand in (`./animation-funcs.ts`).
|
|
21
23
|
*
|
|
22
24
|
* `createRichTextEngine()` wires up `richTextFuncs()` only — it cannot supply a
|
|
23
25
|
* palette. Consumers that name theme colours call `paletteFuncs(getPalette)`
|
|
@@ -43,7 +45,7 @@ import type { RenderOptions } from "../core/protocol.js";
|
|
|
43
45
|
import { type DrawnAt } from "./color-funcs.js";
|
|
44
46
|
export { paletteFuncs } from "./palette-funcs.js";
|
|
45
47
|
export { colorFuncs, readableOnFunc, type DrawnAt } from "./color-funcs.js";
|
|
46
|
-
export {
|
|
48
|
+
export { withAnimation, templateFrame, type AnimationOptions, type TemplateFrame } from "./animation-funcs.js";
|
|
47
49
|
/**
|
|
48
50
|
* Funcs registered by the rich-js binding — the colour sinks, the palette-free
|
|
49
51
|
* colour math, text attributes, and the `link` cell-splitter. Nothing here
|
|
@@ -14,10 +14,12 @@
|
|
|
14
14
|
* - `paletteFuncs(getPalette)` — `color` and `ramp`, the two functions that
|
|
15
15
|
* resolve a palette name. This is the *only* registration that knows a
|
|
16
16
|
* palette exists. [LAW:one-way-deps]
|
|
17
|
-
* - `
|
|
18
|
-
* `
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* - `withAnimation(config, frame)` — the engine config with `frames`,
|
|
18
|
+
* `stepped`, `tween`, `loop` and `glyphs` registered, drawn for a moment on
|
|
19
|
+
* a timeline, and the two engine hooks their holds reach the frame through
|
|
20
|
+
* installed beside them. It is the only registration that knows the
|
|
21
|
+
* template is evaluated at a time, and the time and the timeline are the
|
|
22
|
+
* host's to hand in (`./animation-funcs.ts`).
|
|
21
23
|
*
|
|
22
24
|
* `createRichTextEngine()` wires up `richTextFuncs()` only — it cannot supply a
|
|
23
25
|
* palette. Consumers that name theme colours call `paletteFuncs(getPalette)`
|
|
@@ -45,7 +47,7 @@ import { richTextStyleFuncs } from "./style-funcs.js";
|
|
|
45
47
|
import { colorFuncs } from "./color-funcs.js";
|
|
46
48
|
export { paletteFuncs } from "./palette-funcs.js";
|
|
47
49
|
export { colorFuncs, readableOnFunc } from "./color-funcs.js";
|
|
48
|
-
export {
|
|
50
|
+
export { withAnimation, templateFrame } from "./animation-funcs.js";
|
|
49
51
|
/**
|
|
50
52
|
* Funcs registered by the rich-js binding — the colour sinks, the palette-free
|
|
51
53
|
* colour math, text attributes, and the `link` cell-splitter. Nothing here
|
|
@@ -84,6 +86,7 @@ export function richTextFuncs(drawnAt) {
|
|
|
84
86
|
export function createRichTextEngine() {
|
|
85
87
|
return createEngine({
|
|
86
88
|
fromString: (s) => new RichText(s),
|
|
89
|
+
isT: (v) => v instanceof RichText,
|
|
87
90
|
toString: (rt) => rt.plain,
|
|
88
91
|
funcs: richTextFuncs(),
|
|
89
92
|
});
|
|
@@ -83,7 +83,7 @@ import type { Palette } from "../themes/palette.js";
|
|
|
83
83
|
* @example
|
|
84
84
|
* ```ts
|
|
85
85
|
* const engine = createEngine({
|
|
86
|
-
* fromString: (s) => new RichText(s),
|
|
86
|
+
* fromString: (s) => new RichText(s), isT: (v) => v instanceof RichText,
|
|
87
87
|
* toString: (rt) => rt.plain,
|
|
88
88
|
* funcs: {
|
|
89
89
|
* ...richTextFuncs(),
|
|
@@ -111,7 +111,7 @@ function colorStops(tail, palette) {
|
|
|
111
111
|
* @example
|
|
112
112
|
* ```ts
|
|
113
113
|
* const engine = createEngine({
|
|
114
|
-
* fromString: (s) => new RichText(s),
|
|
114
|
+
* fromString: (s) => new RichText(s), isT: (v) => v instanceof RichText,
|
|
115
115
|
* toString: (rt) => rt.plain,
|
|
116
116
|
* funcs: {
|
|
117
117
|
* ...richTextFuncs(),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ColorRgba } from "../core/color.js";
|
|
2
|
-
import { Palette, type PaletteRole, type PaletteRoles } from "./palette.js";
|
|
2
|
+
import { Palette, type BaseRole, type PaletteRole, type PaletteRoles } from "./palette.js";
|
|
3
3
|
/**
|
|
4
4
|
* Base colors required to build a full semantic palette.
|
|
5
5
|
* All are ColorRgba — callers construct from whatever source (hex, HSL, etc.).
|
|
@@ -16,13 +16,14 @@ export interface BaseColors {
|
|
|
16
16
|
}
|
|
17
17
|
/** The eight roles every palette is given, and every role it may also state. */
|
|
18
18
|
export type StatedRoles = BaseColors & Partial<PaletteRoles>;
|
|
19
|
+
export declare const BASE_KEYS: readonly BaseRole[];
|
|
19
20
|
/** Every role of every palette, read off the rules. */
|
|
20
21
|
export declare const PALETTE_ROLES: readonly PaletteRole[];
|
|
21
22
|
/**
|
|
22
23
|
* Build a full semantic palette from its base colors and any other role it
|
|
23
24
|
* states: a stated role keeps its colour, and everything derived from it
|
|
24
25
|
* follows it, but for `text-*`, which is held to read on its `*-muted`. An
|
|
25
|
-
* authored theme is this with
|
|
26
|
+
* authored theme is this with roles stated; see `RULES` for what a role
|
|
26
27
|
* not stated becomes.
|
|
27
28
|
*
|
|
28
29
|
* A translucent colour is drawn onto `background` before anything is derived
|
|
@@ -152,7 +152,7 @@ const RULES = {
|
|
|
152
152
|
"scrollbar-background-hover": same("scrollbar-background"),
|
|
153
153
|
"scrollbar-corner-color": same("scrollbar-background"),
|
|
154
154
|
};
|
|
155
|
-
const BASE_KEYS = [...ACCENT_KEYS, "background", "foreground"];
|
|
155
|
+
export const BASE_KEYS = [...ACCENT_KEYS, "background", "foreground"];
|
|
156
156
|
/** Every role of every palette, read off the rules. */
|
|
157
157
|
export const PALETTE_ROLES = [...BASE_KEYS, ...Object.keys(RULES)];
|
|
158
158
|
const ROLE_NAMES = new Set(PALETTE_ROLES);
|
|
@@ -160,7 +160,7 @@ const ROLE_NAMES = new Set(PALETTE_ROLES);
|
|
|
160
160
|
* Build a full semantic palette from its base colors and any other role it
|
|
161
161
|
* states: a stated role keeps its colour, and everything derived from it
|
|
162
162
|
* follows it, but for `text-*`, which is held to read on its `*-muted`. An
|
|
163
|
-
* authored theme is this with
|
|
163
|
+
* authored theme is this with roles stated; see `RULES` for what a role
|
|
164
164
|
* not stated becomes.
|
|
165
165
|
*
|
|
166
166
|
* A translucent colour is drawn onto `background` before anything is derived
|
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
// below define the canonical name set for the registry. Adding a theme:
|
|
4
4
|
// 1. drop a new `data/<name>.ts` file,
|
|
5
5
|
// 2. add it here,
|
|
6
|
-
// 3.
|
|
7
|
-
// if you want a pre-built `TerminalTheme` constant alongside the
|
|
8
|
-
// registry palette. Without step 3 the theme is still fully usable
|
|
9
|
-
// via `getThemePalette(name)`.
|
|
6
|
+
// 3. add a matching `<NAME>` export in `terminalThemes.ts`.
|
|
10
7
|
import atomOneDark from "./atom-one-dark.js";
|
|
11
8
|
import atomOneLight from "./atom-one-light.js";
|
|
12
9
|
import catppuccinFrappe from "./catppuccin-frappe.js";
|
|
@@ -5,156 +5,13 @@ const theme = {
|
|
|
5
5
|
ansi: VGA_ANSI,
|
|
6
6
|
vars: {
|
|
7
7
|
"accent": "#0000FF",
|
|
8
|
-
"accent-darken-1": "#0000FF",
|
|
9
|
-
"accent-darken-2": "#0000FF",
|
|
10
|
-
"accent-darken-3": "#0000FF",
|
|
11
|
-
"accent-lighten-1": "#0000FF",
|
|
12
|
-
"accent-lighten-2": "#0000FF",
|
|
13
|
-
"accent-lighten-3": "#0000FF",
|
|
14
|
-
"accent-muted": "#0178D4",
|
|
15
8
|
"background": "#121212",
|
|
16
|
-
"background-darken-1": "#121212",
|
|
17
|
-
"background-darken-2": "#121212",
|
|
18
|
-
"background-darken-3": "#121212",
|
|
19
|
-
"background-lighten-1": "#121212",
|
|
20
|
-
"background-lighten-2": "#121212",
|
|
21
|
-
"background-lighten-3": "#121212",
|
|
22
|
-
"block-cursor-background": "#000080",
|
|
23
|
-
"block-cursor-blurred-background": "#0000804C",
|
|
24
|
-
"block-cursor-blurred-foreground": "#E0E0E0",
|
|
25
|
-
"block-cursor-foreground": "#E0E0E0",
|
|
26
|
-
"block-hover-background": "#00000019",
|
|
27
|
-
"boost": "#0178D4",
|
|
28
|
-
"boost-darken-1": "#0178D4",
|
|
29
|
-
"boost-darken-2": "#0178D4",
|
|
30
|
-
"boost-darken-3": "#0178D4",
|
|
31
|
-
"boost-lighten-1": "#0178D4",
|
|
32
|
-
"boost-lighten-2": "#0178D4",
|
|
33
|
-
"boost-lighten-3": "#0178D4",
|
|
34
|
-
"border": "#0000FF",
|
|
35
|
-
"border-blurred": "#000080",
|
|
36
|
-
"button-color-foreground": "#E0E0E0",
|
|
37
|
-
"button-foreground": "#E0E0E0",
|
|
38
9
|
"error": "#800000",
|
|
39
|
-
"error-darken-1": "#800000",
|
|
40
|
-
"error-darken-2": "#800000",
|
|
41
|
-
"error-darken-3": "#800000",
|
|
42
|
-
"error-lighten-1": "#800000",
|
|
43
|
-
"error-lighten-2": "#800000",
|
|
44
|
-
"error-lighten-3": "#800000",
|
|
45
|
-
"error-muted": "#0178D4",
|
|
46
|
-
"footer-background": "#121212",
|
|
47
|
-
"footer-description-background": "#00000000",
|
|
48
|
-
"footer-description-foreground": "#E0E0E0",
|
|
49
|
-
"footer-foreground": "#E0E0E0",
|
|
50
|
-
"footer-item-background": "#00000000",
|
|
51
|
-
"footer-key-background": "#00000000",
|
|
52
|
-
"footer-key-foreground": "#0000FF",
|
|
53
10
|
"foreground": "#E0E0E0",
|
|
54
|
-
"foreground-darken-1": "#E0E0E0",
|
|
55
|
-
"foreground-darken-2": "#E0E0E0",
|
|
56
|
-
"foreground-darken-3": "#E0E0E0",
|
|
57
|
-
"foreground-disabled": "#00000060",
|
|
58
|
-
"foreground-lighten-1": "#E0E0E0",
|
|
59
|
-
"foreground-lighten-2": "#E0E0E0",
|
|
60
|
-
"foreground-lighten-3": "#E0E0E0",
|
|
61
|
-
"foreground-muted": "#00000099",
|
|
62
|
-
"input-cursor-background": "#121212",
|
|
63
|
-
"input-cursor-foreground": "#E0E0E0",
|
|
64
|
-
"input-selection-background": "#000080",
|
|
65
|
-
"link-background": "#00000000",
|
|
66
|
-
"link-background-hover": "#000080",
|
|
67
|
-
"link-color": "#E0E0E0",
|
|
68
|
-
"link-color-hover": "#0178D4",
|
|
69
|
-
"markdown-h1-background": "#00000000",
|
|
70
|
-
"markdown-h1-color": "#000080",
|
|
71
|
-
"markdown-h2-background": "#00000000",
|
|
72
|
-
"markdown-h2-color": "#000080",
|
|
73
|
-
"markdown-h3-background": "#00000000",
|
|
74
|
-
"markdown-h3-color": "#000080",
|
|
75
|
-
"markdown-h4-background": "#00000000",
|
|
76
|
-
"markdown-h4-color": "#E0E0E0",
|
|
77
|
-
"markdown-h5-background": "#00000000",
|
|
78
|
-
"markdown-h5-color": "#E0E0E0",
|
|
79
|
-
"markdown-h6-background": "#00000000",
|
|
80
|
-
"markdown-h6-color": "#00000099",
|
|
81
|
-
"panel": "#121212",
|
|
82
|
-
"panel-darken-1": "#121212",
|
|
83
|
-
"panel-darken-2": "#121212",
|
|
84
|
-
"panel-darken-3": "#121212",
|
|
85
|
-
"panel-lighten-1": "#121212",
|
|
86
|
-
"panel-lighten-2": "#121212",
|
|
87
|
-
"panel-lighten-3": "#121212",
|
|
88
11
|
"primary": "#000080",
|
|
89
|
-
"primary-background": "#000080",
|
|
90
|
-
"primary-background-darken-1": "#000080",
|
|
91
|
-
"primary-background-darken-2": "#000080",
|
|
92
|
-
"primary-background-darken-3": "#000080",
|
|
93
|
-
"primary-background-lighten-1": "#000080",
|
|
94
|
-
"primary-background-lighten-2": "#000080",
|
|
95
|
-
"primary-background-lighten-3": "#000080",
|
|
96
|
-
"primary-darken-1": "#000080",
|
|
97
|
-
"primary-darken-2": "#000080",
|
|
98
|
-
"primary-darken-3": "#000080",
|
|
99
|
-
"primary-lighten-1": "#000080",
|
|
100
|
-
"primary-lighten-2": "#000080",
|
|
101
|
-
"primary-lighten-3": "#000080",
|
|
102
|
-
"primary-muted": "#0178D4",
|
|
103
|
-
"scrollbar": "#000080",
|
|
104
|
-
"scrollbar-active": "#000080",
|
|
105
|
-
"scrollbar-background": "#121212",
|
|
106
|
-
"scrollbar-background-active": "#121212",
|
|
107
|
-
"scrollbar-background-hover": "#121212",
|
|
108
|
-
"scrollbar-corner-color": "#E0E0E0",
|
|
109
|
-
"scrollbar-hover": "#000040",
|
|
110
12
|
"secondary": "#008080",
|
|
111
|
-
"secondary-background": "#008080",
|
|
112
|
-
"secondary-background-darken-1": "#008080",
|
|
113
|
-
"secondary-background-darken-2": "#008080",
|
|
114
|
-
"secondary-background-darken-3": "#008080",
|
|
115
|
-
"secondary-background-lighten-1": "#008080",
|
|
116
|
-
"secondary-background-lighten-2": "#008080",
|
|
117
|
-
"secondary-background-lighten-3": "#008080",
|
|
118
|
-
"secondary-darken-1": "#008080",
|
|
119
|
-
"secondary-darken-2": "#008080",
|
|
120
|
-
"secondary-darken-3": "#008080",
|
|
121
|
-
"secondary-lighten-1": "#008080",
|
|
122
|
-
"secondary-lighten-2": "#008080",
|
|
123
|
-
"secondary-lighten-3": "#008080",
|
|
124
|
-
"secondary-muted": "#0178D4",
|
|
125
13
|
"success": "#008000",
|
|
126
|
-
"success-darken-1": "#008000",
|
|
127
|
-
"success-darken-2": "#008000",
|
|
128
|
-
"success-darken-3": "#008000",
|
|
129
|
-
"success-lighten-1": "#008000",
|
|
130
|
-
"success-lighten-2": "#008000",
|
|
131
|
-
"success-lighten-3": "#008000",
|
|
132
|
-
"success-muted": "#0178D4",
|
|
133
|
-
"surface": "#121212",
|
|
134
|
-
"surface-active": "#131313",
|
|
135
|
-
"surface-darken-1": "#121212",
|
|
136
|
-
"surface-darken-2": "#121212",
|
|
137
|
-
"surface-darken-3": "#121212",
|
|
138
|
-
"surface-lighten-1": "#121212",
|
|
139
|
-
"surface-lighten-2": "#121212",
|
|
140
|
-
"surface-lighten-3": "#121212",
|
|
141
|
-
"text": "#E0E0E0",
|
|
142
|
-
"text-accent": "#5656FF",
|
|
143
|
-
"text-disabled": "#E0E0E0",
|
|
144
|
-
"text-error": "#AB5656",
|
|
145
|
-
"text-muted": "#E0E0E0",
|
|
146
|
-
"text-primary": "#5656AB",
|
|
147
|
-
"text-secondary": "#56ABAB",
|
|
148
|
-
"text-success": "#56AB56",
|
|
149
|
-
"text-warning": "#ABAB56",
|
|
150
14
|
"warning": "#808000",
|
|
151
|
-
"warning-darken-1": "#808000",
|
|
152
|
-
"warning-darken-2": "#808000",
|
|
153
|
-
"warning-darken-3": "#808000",
|
|
154
|
-
"warning-lighten-1": "#808000",
|
|
155
|
-
"warning-lighten-2": "#808000",
|
|
156
|
-
"warning-lighten-3": "#808000",
|
|
157
|
-
"warning-muted": "#0178D4",
|
|
158
15
|
},
|
|
159
16
|
};
|
|
160
17
|
export default theme;
|
package/dist/themes/ramp.d.ts
CHANGED
|
@@ -122,7 +122,7 @@ export declare class ColorRamp {
|
|
|
122
122
|
* [LAW:one-source-of-truth] When it next changes is `Animation.all`'s
|
|
123
123
|
* answer over the two parts; nothing here says it a second time. Whether
|
|
124
124
|
* the depth it is drawn at can show the move is decided where it is drawn
|
|
125
|
-
* (`gradient`, through `
|
|
125
|
+
* (`gradient`, through `stillWhereNothingMoves`).
|
|
126
126
|
*/
|
|
127
127
|
moving(motion: RampMotion): Animation<ColorRamp>;
|
|
128
128
|
}
|