@zakmandhro/bunti 0.1.5 → 0.2.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.
- package/AGENTS.md +65 -0
- package/README.md +86 -11
- package/dist/cli.d.ts +44 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +147 -0
- package/dist/cli.js.map +1 -0
- package/dist/colors.d.ts +77 -7
- package/dist/colors.d.ts.map +1 -1
- package/dist/colors.js +238 -39
- package/dist/colors.js.map +1 -1
- package/dist/components/Box.d.ts +6 -0
- package/dist/components/Box.d.ts.map +1 -1
- package/dist/components/Box.js +5 -0
- package/dist/components/Box.js.map +1 -1
- package/dist/components/Button.d.ts +15 -2
- package/dist/components/Button.d.ts.map +1 -1
- package/dist/components/Button.js +45 -25
- package/dist/components/Button.js.map +1 -1
- package/dist/components/Card.d.ts +24 -2
- package/dist/components/Card.d.ts.map +1 -1
- package/dist/components/Card.js +56 -14
- package/dist/components/Card.js.map +1 -1
- package/dist/components/Header.d.ts +11 -1
- package/dist/components/Header.d.ts.map +1 -1
- package/dist/components/Header.js +12 -8
- package/dist/components/Header.js.map +1 -1
- package/dist/components/Input.d.ts +10 -1
- package/dist/components/Input.d.ts.map +1 -1
- package/dist/components/Input.js +176 -41
- package/dist/components/Input.js.map +1 -1
- package/dist/components/Link.d.ts +21 -0
- package/dist/components/Link.d.ts.map +1 -0
- package/dist/components/Link.js +38 -0
- package/dist/components/Link.js.map +1 -0
- package/dist/components/Modal.d.ts +25 -0
- package/dist/components/Modal.d.ts.map +1 -1
- package/dist/components/Modal.js +88 -24
- package/dist/components/Modal.js.map +1 -1
- package/dist/components/Progress.d.ts +27 -0
- package/dist/components/Progress.d.ts.map +1 -0
- package/dist/components/Progress.js +39 -0
- package/dist/components/Progress.js.map +1 -0
- package/dist/components/Spinner.d.ts +19 -0
- package/dist/components/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner.js +27 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +3 -0
- package/dist/components/index.js.map +1 -1
- package/dist/data/nf-glyphs.d.ts +11 -0
- package/dist/data/nf-glyphs.d.ts.map +1 -0
- package/dist/data/nf-glyphs.js +535 -0
- package/dist/data/nf-glyphs.js.map +1 -0
- package/dist/data/nf-names.d.ts +8 -0
- package/dist/data/nf-names.d.ts.map +1 -0
- package/dist/data/nf-names.js +2 -0
- package/dist/data/nf-names.js.map +1 -0
- package/dist/demo-registry.d.ts +27 -0
- package/dist/demo-registry.d.ts.map +1 -0
- package/dist/demo-registry.js +57 -0
- package/dist/demo-registry.js.map +1 -0
- package/dist/demos/2048.ts +743 -0
- package/dist/demos/animation.ts +246 -0
- package/dist/demos/demo-layout.ts +124 -0
- package/dist/demos/engine.ts +374 -0
- package/dist/demos/interaction.ts +91 -0
- package/dist/demos/login.ts +203 -0
- package/dist/demos/mission-control.ts +558 -0
- package/dist/demos/showcase.ts +224 -0
- package/dist/detect.d.ts +92 -3
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +218 -40
- package/dist/detect.js.map +1 -1
- package/dist/diagnostics.d.ts +73 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +225 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/dsl/context.d.ts +11 -0
- package/dist/dsl/context.d.ts.map +1 -0
- package/dist/dsl/context.js +658 -0
- package/dist/dsl/context.js.map +1 -0
- package/dist/dsl/hooks.d.ts +12 -0
- package/dist/dsl/hooks.d.ts.map +1 -0
- package/dist/dsl/hooks.js +148 -0
- package/dist/dsl/hooks.js.map +1 -0
- package/dist/dsl/interaction.d.ts +31 -0
- package/dist/dsl/interaction.d.ts.map +1 -0
- package/dist/dsl/interaction.js +150 -0
- package/dist/dsl/interaction.js.map +1 -0
- package/dist/dsl/layers.d.ts +14 -0
- package/dist/dsl/layers.d.ts.map +1 -0
- package/dist/dsl/layers.js +87 -0
- package/dist/dsl/layers.js.map +1 -0
- package/dist/dsl/motion.d.ts +10 -0
- package/dist/dsl/motion.d.ts.map +1 -0
- package/dist/dsl/motion.js +150 -0
- package/dist/dsl/motion.js.map +1 -0
- package/dist/dsl/render.d.ts +22 -0
- package/dist/dsl/render.d.ts.map +1 -0
- package/dist/dsl/render.js +69 -0
- package/dist/dsl/render.js.map +1 -0
- package/dist/dsl/types.d.ts +555 -0
- package/dist/dsl/types.d.ts.map +1 -0
- package/dist/dsl/types.js +33 -0
- package/dist/dsl/types.js.map +1 -0
- package/dist/dsl.d.ts +13 -154
- package/dist/dsl.d.ts.map +1 -1
- package/dist/dsl.js +12 -658
- package/dist/dsl.js.map +1 -1
- package/dist/easing.d.ts +41 -1
- package/dist/easing.d.ts.map +1 -1
- package/dist/easing.js +105 -2
- package/dist/easing.js.map +1 -1
- package/dist/geometry.d.ts +39 -0
- package/dist/geometry.d.ts.map +1 -1
- package/dist/geometry.js +20 -0
- package/dist/geometry.js.map +1 -1
- package/dist/icons-full.d.ts +5 -0
- package/dist/icons-full.d.ts.map +1 -0
- package/dist/icons-full.js +31 -0
- package/dist/icons-full.js.map +1 -0
- package/dist/icons.d.ts +426 -5
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +144 -15
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +95 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +177 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/input.js +533 -0
- package/dist/input.js.map +1 -0
- package/dist/layout.d.ts +153 -7
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +221 -34
- package/dist/layout.js.map +1 -1
- package/dist/render.d.ts +33 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +431 -116
- package/dist/render.js.map +1 -1
- package/dist/state.d.ts +156 -3
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +25 -0
- package/dist/state.js.map +1 -1
- package/dist/theme.d.ts +129 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +167 -0
- package/dist/theme.js.map +1 -0
- package/dist/themes/catppuccin-mocha.d.ts +19 -0
- package/dist/themes/catppuccin-mocha.d.ts.map +1 -0
- package/dist/themes/catppuccin-mocha.js +36 -0
- package/dist/themes/catppuccin-mocha.js.map +1 -0
- package/dist/themes/dracula.d.ts +21 -0
- package/dist/themes/dracula.d.ts.map +1 -0
- package/dist/themes/dracula.js +37 -0
- package/dist/themes/dracula.js.map +1 -0
- package/dist/themes/github-light.d.ts +21 -0
- package/dist/themes/github-light.d.ts.map +1 -0
- package/dist/themes/github-light.js +36 -0
- package/dist/themes/github-light.js.map +1 -0
- package/dist/themes/index.d.ts +19 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +17 -0
- package/dist/themes/index.js.map +1 -0
- package/dist/themes/nord.d.ts +23 -0
- package/dist/themes/nord.d.ts.map +1 -0
- package/dist/themes/nord.js +38 -0
- package/dist/themes/nord.js.map +1 -0
- package/dist/themes/one-dark-pro.d.ts +21 -0
- package/dist/themes/one-dark-pro.d.ts.map +1 -0
- package/dist/themes/one-dark-pro.js +36 -0
- package/dist/themes/one-dark-pro.js.map +1 -0
- package/dist/themes/tokyo-night.d.ts +20 -0
- package/dist/themes/tokyo-night.d.ts.map +1 -0
- package/dist/themes/tokyo-night.js +37 -0
- package/dist/themes/tokyo-night.js.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -0
- package/dist/utils.js.map +1 -1
- package/dist/vendor/colors.d.ts +45 -0
- package/dist/vendor/colors.d.ts.map +1 -0
- package/dist/vendor/colors.js +72 -0
- package/dist/vendor/colors.js.map +1 -0
- package/llms.txt +79 -0
- package/package.json +23 -7
- package/dist/data/glyphs.d.ts +0 -5
- package/dist/data/glyphs.d.ts.map +0 -1
- package/dist/data/glyphs.js +0 -29
- package/dist/data/glyphs.js.map +0 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bunti DSL motion helpers: animate, fade, typewriter, flicker, transition,
|
|
3
|
+
* stagger, restartAnimation, and per-frame timing (dt / frame).
|
|
4
|
+
*/
|
|
5
|
+
import { fade } from '../colors';
|
|
6
|
+
import { clamp01 } from '../easing';
|
|
7
|
+
function graphemes(text) {
|
|
8
|
+
const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
|
|
9
|
+
return Array.from(segmenter.segment(text), ({ segment }) => segment);
|
|
10
|
+
}
|
|
11
|
+
/** Deterministic 0-1 hash (FNV-1a) for time-bucketed flicker. */
|
|
12
|
+
function hash01(seed) {
|
|
13
|
+
let h = 2166136261;
|
|
14
|
+
for (let i = 0; i < seed.length; i++) {
|
|
15
|
+
h ^= seed.charCodeAt(i);
|
|
16
|
+
h = Math.imul(h, 16777619);
|
|
17
|
+
}
|
|
18
|
+
return ((h >>> 0) % 100000) / 100000;
|
|
19
|
+
}
|
|
20
|
+
const identity = (t) => t;
|
|
21
|
+
/** Namespaced componentState key for transition edge tracking. */
|
|
22
|
+
const transitionKey = (id) => `_motion:transition:${id}`;
|
|
23
|
+
export function createMotion(state, useState) {
|
|
24
|
+
return {
|
|
25
|
+
// loop() owns timing: it stamps state.dt / state.frameCount each tick.
|
|
26
|
+
// Outside a loop (tests, one-shot renders) both default to 0.
|
|
27
|
+
dt: state.dt ?? 0,
|
|
28
|
+
frame: state.frameCount ?? 0,
|
|
29
|
+
animate(duration, options = {}) {
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
const start = options.id
|
|
32
|
+
? useState(`${options.id}_start`, now)[0]
|
|
33
|
+
: state.startTime;
|
|
34
|
+
const elapsed = now - start - (options.delay || 0);
|
|
35
|
+
const ease = options.easing ?? identity;
|
|
36
|
+
if (elapsed < 0 || duration <= 0)
|
|
37
|
+
return ease(0);
|
|
38
|
+
if (options.loop === 'yoyo') {
|
|
39
|
+
// 0 -> 1 -> 0 over two durations; easing applies to each leg.
|
|
40
|
+
const phase = (elapsed % (duration * 2)) / duration;
|
|
41
|
+
return ease(phase <= 1 ? phase : 2 - phase);
|
|
42
|
+
}
|
|
43
|
+
if (options.loop)
|
|
44
|
+
return ease((elapsed % duration) / duration);
|
|
45
|
+
return ease(Math.min(1, elapsed / duration));
|
|
46
|
+
},
|
|
47
|
+
fade,
|
|
48
|
+
/**
|
|
49
|
+
* Visibility-driven enter/exit progress for immediate-mode UIs.
|
|
50
|
+
* Tracks visible-flag edges in componentState; `mounted` stays true
|
|
51
|
+
* through the exit animation so callers keep rendering while a panel
|
|
52
|
+
* animates out. Mid-animation flips retarget from the current progress
|
|
53
|
+
* (no jumps).
|
|
54
|
+
*/
|
|
55
|
+
transition(id, visible, options = {}) {
|
|
56
|
+
const now = Date.now();
|
|
57
|
+
const duration = Math.max(0, options.duration ?? 300);
|
|
58
|
+
const exitDuration = Math.max(0, options.exitDuration ?? duration);
|
|
59
|
+
const ease = options.easing ?? identity;
|
|
60
|
+
const key = transitionKey(id);
|
|
61
|
+
let rec = state.componentState.get(key);
|
|
62
|
+
if (rec === undefined) {
|
|
63
|
+
// First sight: visible components animate in from 0; hidden ones
|
|
64
|
+
// start fully exited (mounted false immediately).
|
|
65
|
+
rec = { visible, flippedAt: visible ? now : now - exitDuration - 1 };
|
|
66
|
+
state.componentState.set(key, rec);
|
|
67
|
+
}
|
|
68
|
+
const rawAt = (r) => {
|
|
69
|
+
if (r.visible) {
|
|
70
|
+
return duration <= 0 ? 1 : clamp01((now - r.flippedAt) / duration);
|
|
71
|
+
}
|
|
72
|
+
return exitDuration <= 0
|
|
73
|
+
? 0
|
|
74
|
+
: 1 - clamp01((now - r.flippedAt) / exitDuration);
|
|
75
|
+
};
|
|
76
|
+
if (rec.visible !== visible) {
|
|
77
|
+
// Retarget from the current raw progress so mid-animation flips
|
|
78
|
+
// continue smoothly instead of restarting the full leg.
|
|
79
|
+
const current = rawAt(rec);
|
|
80
|
+
rec.visible = visible;
|
|
81
|
+
rec.flippedAt = visible
|
|
82
|
+
? now - current * duration
|
|
83
|
+
: now - (1 - current) * exitDuration;
|
|
84
|
+
}
|
|
85
|
+
const raw = rawAt(rec);
|
|
86
|
+
return {
|
|
87
|
+
progress: ease(raw),
|
|
88
|
+
mounted: visible || raw > 0,
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* Cascading entrance progress: item `index` starts `index * delay` ms
|
|
93
|
+
* into the timeline and runs for `duration` ms. The timeline is the
|
|
94
|
+
* screen's elapsed time, or an animate()-style `id` clock when given
|
|
95
|
+
* (restartAnimation(id) then replays the cascade).
|
|
96
|
+
*/
|
|
97
|
+
stagger(index, options) {
|
|
98
|
+
const now = Date.now();
|
|
99
|
+
const start = options.id
|
|
100
|
+
? useState(`${options.id}_start`, now)[0]
|
|
101
|
+
: state.startTime;
|
|
102
|
+
const elapsed = now - start - index * options.delay;
|
|
103
|
+
const ease = options.easing ?? identity;
|
|
104
|
+
if (options.duration <= 0)
|
|
105
|
+
return ease(elapsed >= 0 ? 1 : 0);
|
|
106
|
+
return ease(clamp01(elapsed / options.duration));
|
|
107
|
+
},
|
|
108
|
+
/** Resets an animate()/typewriter()/stagger() id clock to "now". */
|
|
109
|
+
restartAnimation(id) {
|
|
110
|
+
state.componentState.set(`${id}_start`, Date.now());
|
|
111
|
+
state.requestTick?.();
|
|
112
|
+
},
|
|
113
|
+
typewriter(text, options = {}) {
|
|
114
|
+
const now = Date.now();
|
|
115
|
+
const start = options.id
|
|
116
|
+
? useState(`${options.id}_start`, now)[0]
|
|
117
|
+
: state.startTime;
|
|
118
|
+
const delay = options.delay ?? 0;
|
|
119
|
+
const elapsed = Math.max(0, now - start - delay);
|
|
120
|
+
const cps = options.cps ?? 24;
|
|
121
|
+
const chars = graphemes(text);
|
|
122
|
+
const rawIndex = Math.floor((elapsed / 1000) * cps);
|
|
123
|
+
const index = options.loop && chars.length > 0
|
|
124
|
+
? rawIndex % (chars.length + 1)
|
|
125
|
+
: Math.min(chars.length, rawIndex);
|
|
126
|
+
const blinkRate = options.blinkRate ?? 450;
|
|
127
|
+
const showCursor = options.blink === false ||
|
|
128
|
+
Math.floor(elapsed / blinkRate) % 2 === 0 ||
|
|
129
|
+
index < chars.length;
|
|
130
|
+
return {
|
|
131
|
+
text: chars.slice(0, index).join(''),
|
|
132
|
+
cursor: showCursor ? (options.cursor ?? '█') : ' ',
|
|
133
|
+
done: index >= chars.length,
|
|
134
|
+
index,
|
|
135
|
+
progress: chars.length === 0 ? 1 : index / chars.length,
|
|
136
|
+
};
|
|
137
|
+
},
|
|
138
|
+
/**
|
|
139
|
+
* Time-based flicker: deterministic per interval bucket (hash of the
|
|
140
|
+
* bucket + id), so the flicker rate is fps-independent while keeping
|
|
141
|
+
* the same visual character as the old per-frame Math.random.
|
|
142
|
+
*/
|
|
143
|
+
flicker(intensity = 0.5, options = {}) {
|
|
144
|
+
const interval = Math.max(1, options.interval ?? 50);
|
|
145
|
+
const bucket = Math.floor((Date.now() - state.startTime) / interval);
|
|
146
|
+
return hash01(`${options.id ?? ''}:${bucket}`) > 1 - intensity;
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=motion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motion.js","sourceRoot":"","sources":["../../src/dsl/motion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bunti DSL primary entry point: render.
|
|
3
|
+
*/
|
|
4
|
+
import { type ScreenOptions } from '../state';
|
|
5
|
+
import type { BuntiContext } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Starts a Bunti app: runs `callback` every frame (immediate mode —
|
|
8
|
+
* redraw the whole screen from state each call) and flushes only the
|
|
9
|
+
* changed cells to the terminal. The returned promise resolves when the
|
|
10
|
+
* loop stops (ctx.requestStop() or Ctrl+C). Pass `once: true` to render
|
|
11
|
+
* a single frame and return. Keyboard input needs a real TTY on stdin:
|
|
12
|
+
* piped input is ignored.
|
|
13
|
+
* @example
|
|
14
|
+
* await render((ctx) => {
|
|
15
|
+
* ctx.box({ width: 30, border: 'rounded' }, (s) => s.text('hi'));
|
|
16
|
+
* if (ctx.lastKey === 'q') ctx.requestStop();
|
|
17
|
+
* }, { keyboard: true, mouse: true, alternateBuffer: true, hideCursor: true });
|
|
18
|
+
*/
|
|
19
|
+
export declare function render(callback: ((b: BuntiContext) => void) | string, options?: ScreenOptions & {
|
|
20
|
+
once?: boolean;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/dsl/render.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAC1B,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,MAAM,EAC9C,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,iBAkDjD"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bunti DSL primary entry point: render.
|
|
3
|
+
*/
|
|
4
|
+
import { init } from '../icons';
|
|
5
|
+
import { flush, loop } from '../render';
|
|
6
|
+
import { ANSI, clearBackBuffer, createScreenState, } from '../state';
|
|
7
|
+
import { createScreenContext } from './context';
|
|
8
|
+
/**
|
|
9
|
+
* Starts a Bunti app: runs `callback` every frame (immediate mode —
|
|
10
|
+
* redraw the whole screen from state each call) and flushes only the
|
|
11
|
+
* changed cells to the terminal. The returned promise resolves when the
|
|
12
|
+
* loop stops (ctx.requestStop() or Ctrl+C). Pass `once: true` to render
|
|
13
|
+
* a single frame and return. Keyboard input needs a real TTY on stdin:
|
|
14
|
+
* piped input is ignored.
|
|
15
|
+
* @example
|
|
16
|
+
* await render((ctx) => {
|
|
17
|
+
* ctx.box({ width: 30, border: 'rounded' }, (s) => s.text('hi'));
|
|
18
|
+
* if (ctx.lastKey === 'q') ctx.requestStop();
|
|
19
|
+
* }, { keyboard: true, mouse: true, alternateBuffer: true, hideCursor: true });
|
|
20
|
+
*/
|
|
21
|
+
export async function render(callback, options = {}) {
|
|
22
|
+
if (typeof Bun === 'undefined') {
|
|
23
|
+
throw new Error('Bunti is Bun-native and uses Bun runtime APIs. ' +
|
|
24
|
+
'Run with Bun >=1.0: https://bun.sh — Node.js is not supported.');
|
|
25
|
+
}
|
|
26
|
+
// createScreenState runs env detection once per render() (state.terminal).
|
|
27
|
+
const state = createScreenState(options);
|
|
28
|
+
// Icon tier: an explicit ScreenOptions.nerdFont always wins; otherwise the
|
|
29
|
+
// detected profile decides ('yes'/'assumed-yes' -> Nerd Font glyphs).
|
|
30
|
+
if (options.nerdFont !== undefined) {
|
|
31
|
+
await init({ nerdFont: options.nerdFont });
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
await init({ profile: state.terminal });
|
|
35
|
+
}
|
|
36
|
+
const tick = () => {
|
|
37
|
+
clearBackBuffer(state);
|
|
38
|
+
const b = createScreenContext(state);
|
|
39
|
+
if (typeof callback === 'string') {
|
|
40
|
+
b.blit(0, 0, callback);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
callback(b);
|
|
44
|
+
}
|
|
45
|
+
if (state.isStopped)
|
|
46
|
+
return;
|
|
47
|
+
b.flushFlow();
|
|
48
|
+
if (state.isStopped)
|
|
49
|
+
return;
|
|
50
|
+
flush(state);
|
|
51
|
+
};
|
|
52
|
+
if (options.once) {
|
|
53
|
+
tick();
|
|
54
|
+
// Let the terminal settle for a frame, then resolve. No interval or
|
|
55
|
+
// stdin listener was started in once mode, so nothing keeps the event
|
|
56
|
+
// loop alive and the host process (never killed by the library) can
|
|
57
|
+
// continue or exit naturally.
|
|
58
|
+
await new Promise((resolve) => {
|
|
59
|
+
setTimeout(resolve, 50);
|
|
60
|
+
});
|
|
61
|
+
// flush() hides the cursor per-frame when requested; a once-shot must
|
|
62
|
+
// not leave the user's cursor invisible.
|
|
63
|
+
if (options.hideCursor)
|
|
64
|
+
process.stdout.write(ANSI.showCursor);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
await loop(state, (_s) => tick());
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/dsl/render.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EACL,IAAI,EACJ,eAAe,EACf,iBAAiB,GAElB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGhD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,QAA8C,EAC9C,UAA8C,EAAE;IAEhD,IAAI,OAAO,GAAG,KAAK,WAAW,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,iDAAiD;YAC/C,gEAAgE,CACnE,CAAC;IACJ,CAAC;IAED,2EAA2E;IAC3E,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEzC,2EAA2E;IAC3E,sEAAsE;IACtE,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,eAAe,CAAC,KAAK,CAAC,CAAC;QACvB,MAAM,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,CAAC,CAAC,CAAC;QACd,CAAC;QACD,IAAI,KAAK,CAAC,SAAS;YAAE,OAAO;QAC5B,CAAC,CAAC,SAAS,EAAE,CAAC;QACd,IAAI,KAAK,CAAC,SAAS;YAAE,OAAO;QAC5B,KAAK,CAAC,KAAK,CAAC,CAAC;IACf,CAAC,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,EAAE,CAAC;QACP,oEAAoE;QACpE,sEAAsE;QACtE,oEAAoE;QACpE,8BAA8B;QAC9B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,sEAAsE;QACtE,yCAAyC;QACzC,IAAI,OAAO,CAAC,UAAU;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IAED,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC"}
|