@zakmandhro/bunti 0.1.5 → 0.2.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/AGENTS.md +65 -0
- package/README.md +81 -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 +12 -2
- package/dist/components/Button.d.ts.map +1 -1
- package/dist/components/Button.js +35 -24
- 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 +172 -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 +29 -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 +83 -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 +563 -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 +16 -0
- package/dist/dsl/interaction.d.ts.map +1 -0
- package/dist/dsl/interaction.js +101 -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 +510 -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 +93 -22
- 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 +111 -6
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +163 -23
- 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 +137 -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,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bunti DSL state hooks: useState, useAsync, usePersistentState.
|
|
3
|
+
*
|
|
4
|
+
* Implementations close over the ScreenState only, so they are shared
|
|
5
|
+
* unchanged by every context created for that screen.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { recordKeylessHook } from '../diagnostics';
|
|
10
|
+
export function createHooks(state) {
|
|
11
|
+
const hooks = {
|
|
12
|
+
useAsync(keyOrFetcher, fetcherOrOptions, maybeOptions) {
|
|
13
|
+
let key;
|
|
14
|
+
let fetcher;
|
|
15
|
+
let options;
|
|
16
|
+
if (typeof keyOrFetcher === 'string') {
|
|
17
|
+
key = keyOrFetcher;
|
|
18
|
+
fetcher = fetcherOrOptions;
|
|
19
|
+
options = maybeOptions;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
if (state.hookCounter === undefined) {
|
|
23
|
+
state.hookCounter = 0;
|
|
24
|
+
}
|
|
25
|
+
const index = state.hookCounter++;
|
|
26
|
+
recordKeylessHook(state, index, 'useAsync');
|
|
27
|
+
key = `_async_hook_${index}`;
|
|
28
|
+
fetcher = keyOrFetcher;
|
|
29
|
+
options = fetcherOrOptions;
|
|
30
|
+
}
|
|
31
|
+
const interval = options?.interval ?? 0;
|
|
32
|
+
const dataKey = `${key}_data`;
|
|
33
|
+
const loadingKey = `${key}_loading`;
|
|
34
|
+
const errorKey = `${key}_error`;
|
|
35
|
+
const lastFetchKey = `${key}_lastFetch`;
|
|
36
|
+
const fetchingKey = `${key}_fetching`;
|
|
37
|
+
if (!state.componentState.has(loadingKey)) {
|
|
38
|
+
state.componentState.set(loadingKey, true);
|
|
39
|
+
}
|
|
40
|
+
const lastFetch = state.componentState.get(lastFetchKey);
|
|
41
|
+
const isFetching = state.componentState.get(fetchingKey);
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
const shouldFetch = !isFetching &&
|
|
44
|
+
(lastFetch === undefined ||
|
|
45
|
+
(interval > 0 && now - lastFetch >= interval));
|
|
46
|
+
if (shouldFetch) {
|
|
47
|
+
state.componentState.set(fetchingKey, true);
|
|
48
|
+
state.componentState.set(lastFetchKey, now);
|
|
49
|
+
fetcher()
|
|
50
|
+
.then((result) => {
|
|
51
|
+
state.componentState.set(dataKey, result);
|
|
52
|
+
state.componentState.set(loadingKey, false);
|
|
53
|
+
state.componentState.set(errorKey, undefined);
|
|
54
|
+
state.requestTick?.();
|
|
55
|
+
})
|
|
56
|
+
.catch((err) => {
|
|
57
|
+
state.componentState.set(errorKey, err);
|
|
58
|
+
state.componentState.set(loadingKey, false);
|
|
59
|
+
state.requestTick?.();
|
|
60
|
+
})
|
|
61
|
+
.finally(() => {
|
|
62
|
+
state.componentState.set(fetchingKey, false);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
data: state.componentState.get(dataKey),
|
|
67
|
+
loading: state.componentState.get(loadingKey),
|
|
68
|
+
error: state.componentState.get(errorKey),
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
useState(keyOrInitial, maybeInitial) {
|
|
72
|
+
let key;
|
|
73
|
+
let initial;
|
|
74
|
+
if (maybeInitial === undefined) {
|
|
75
|
+
if (state.hookCounter === undefined) {
|
|
76
|
+
state.hookCounter = 0;
|
|
77
|
+
}
|
|
78
|
+
const index = state.hookCounter++;
|
|
79
|
+
recordKeylessHook(state, index, 'useState');
|
|
80
|
+
key = `_state_hook_${index}`;
|
|
81
|
+
initial = keyOrInitial;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
key = keyOrInitial;
|
|
85
|
+
initial = maybeInitial;
|
|
86
|
+
}
|
|
87
|
+
if (!state.componentState.has(key)) {
|
|
88
|
+
state.componentState.set(key, initial);
|
|
89
|
+
}
|
|
90
|
+
return [
|
|
91
|
+
state.componentState.get(key),
|
|
92
|
+
(val) => {
|
|
93
|
+
state.componentState.set(key, val);
|
|
94
|
+
state.requestTick?.();
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
},
|
|
98
|
+
usePersistentState(key, initial) {
|
|
99
|
+
if (!state.componentState.has(key)) {
|
|
100
|
+
const storeDir = join(process.cwd(), '.tmp');
|
|
101
|
+
const storeFile = join(storeDir, 'bunti_store.json');
|
|
102
|
+
let fileVal;
|
|
103
|
+
try {
|
|
104
|
+
if (existsSync(storeFile)) {
|
|
105
|
+
const data = readFileSync(storeFile, 'utf-8');
|
|
106
|
+
const parsed = JSON.parse(data);
|
|
107
|
+
fileVal = parsed[key];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Ignore
|
|
112
|
+
}
|
|
113
|
+
const finalVal = fileVal !== undefined ? fileVal : initial;
|
|
114
|
+
state.componentState.set(key, finalVal);
|
|
115
|
+
}
|
|
116
|
+
return [
|
|
117
|
+
state.componentState.get(key),
|
|
118
|
+
(val) => {
|
|
119
|
+
state.componentState.set(key, val);
|
|
120
|
+
const storeDir = join(process.cwd(), '.tmp');
|
|
121
|
+
const storeFile = join(storeDir, 'bunti_store.json');
|
|
122
|
+
try {
|
|
123
|
+
if (!existsSync(storeDir)) {
|
|
124
|
+
mkdirSync(storeDir, { recursive: true });
|
|
125
|
+
}
|
|
126
|
+
let currentStore = {};
|
|
127
|
+
if (existsSync(storeFile)) {
|
|
128
|
+
try {
|
|
129
|
+
currentStore = JSON.parse(readFileSync(storeFile, 'utf-8'));
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
currentStore = {};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
currentStore[key] = val;
|
|
136
|
+
writeFileSync(storeFile, JSON.stringify(currentStore, null, 2), 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Ignore
|
|
140
|
+
}
|
|
141
|
+
state.requestTick?.();
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
return hooks;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/dsl/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bunti DSL interaction: hitboxes, hover/press/click queries, and focus
|
|
3
|
+
* management.
|
|
4
|
+
*
|
|
5
|
+
* Click semantics: a 'click' KeyEvent is emitted once, on SGR mouse RELEASE,
|
|
6
|
+
* carrying the press-origin coordinates (state.clickX/clickY). isClicked is
|
|
7
|
+
* therefore true exactly one frame per click — components fire actions once
|
|
8
|
+
* per click instead of every frame the button is held.
|
|
9
|
+
*/
|
|
10
|
+
import type { Rect, RectInput } from '../geometry';
|
|
11
|
+
import type { ScreenState } from '../state';
|
|
12
|
+
import type { BuntiContext } from './types';
|
|
13
|
+
type Interaction = Pick<BuntiContext, 'focusable' | 'isFocused' | 'focus' | 'focusNext' | 'hitbox' | 'isHovered' | 'isPressed' | 'isClicked' | 'isHoverEnter' | 'isHoverLeave'>;
|
|
14
|
+
export declare function createInteraction(state: ScreenState, resolveRect: (bounds: RectInput) => Rect): Interaction;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=interaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../../src/dsl/interaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAU,WAAW,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,KAAK,WAAW,GAAG,IAAI,CACrB,YAAY,EACV,WAAW,GACX,WAAW,GACX,OAAO,GACP,WAAW,GACX,QAAQ,GACR,WAAW,GACX,WAAW,GACX,WAAW,GACX,cAAc,GACd,cAAc,CACjB,CAAC;AA6BF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,GACvC,WAAW,CAkFb"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bunti DSL interaction: hitboxes, hover/press/click queries, and focus
|
|
3
|
+
* management.
|
|
4
|
+
*
|
|
5
|
+
* Click semantics: a 'click' KeyEvent is emitted once, on SGR mouse RELEASE,
|
|
6
|
+
* carrying the press-origin coordinates (state.clickX/clickY). isClicked is
|
|
7
|
+
* therefore true exactly one frame per click — components fire actions once
|
|
8
|
+
* per click instead of every frame the button is held.
|
|
9
|
+
*/
|
|
10
|
+
function contains(box, x, y) {
|
|
11
|
+
return (x >= box.x && x < box.x + box.width && y >= box.y && y < box.y + box.height);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* True when this frame carries a click. `state.keys` covers events drained
|
|
15
|
+
* by the render loop; the `state.lastKey === 'click'` check keeps manually
|
|
16
|
+
* driven states (tests, custom loops) working.
|
|
17
|
+
*/
|
|
18
|
+
function frameHasClick(state) {
|
|
19
|
+
if (state.lastKey === 'click')
|
|
20
|
+
return true;
|
|
21
|
+
return (state.keys?.some((e) => e.key === 'click' && e.kind !== 'release') ?? false);
|
|
22
|
+
}
|
|
23
|
+
/** Click test point: press-origin when available, mouse position otherwise. */
|
|
24
|
+
function clickX(state) {
|
|
25
|
+
return state.clickX ?? state.mouseX;
|
|
26
|
+
}
|
|
27
|
+
function clickY(state) {
|
|
28
|
+
return state.clickY ?? state.mouseY;
|
|
29
|
+
}
|
|
30
|
+
export function createInteraction(state, resolveRect) {
|
|
31
|
+
const interaction = {
|
|
32
|
+
focusable(id) {
|
|
33
|
+
if (!state.focusableIds.includes(id)) {
|
|
34
|
+
state.focusableIds.push(id);
|
|
35
|
+
}
|
|
36
|
+
if (!state.focusedId)
|
|
37
|
+
state.focusedId = id;
|
|
38
|
+
return state.focusedId === id;
|
|
39
|
+
},
|
|
40
|
+
isFocused(id) {
|
|
41
|
+
return state.focusedId === id;
|
|
42
|
+
},
|
|
43
|
+
focus(id) {
|
|
44
|
+
state.focusedId = id;
|
|
45
|
+
},
|
|
46
|
+
focusNext() {
|
|
47
|
+
if (state.focusableIds.length === 0)
|
|
48
|
+
return;
|
|
49
|
+
const idx = state.focusableIds.indexOf(state.focusedId || '');
|
|
50
|
+
const nextIdx = (idx + 1) % state.focusableIds.length;
|
|
51
|
+
state.focusedId = state.focusableIds[nextIdx];
|
|
52
|
+
},
|
|
53
|
+
hitbox(id, bounds) {
|
|
54
|
+
const rect = resolveRect(bounds);
|
|
55
|
+
const box = { id, ...rect };
|
|
56
|
+
state.hitboxes.set(id, box);
|
|
57
|
+
const hovered = contains(box, state.mouseX, state.mouseY);
|
|
58
|
+
// Hover-change tracking against the last evaluation of this id.
|
|
59
|
+
const prevHovered = state.hoverStates.get(id) ?? false;
|
|
60
|
+
if (hovered !== prevHovered) {
|
|
61
|
+
if (hovered) {
|
|
62
|
+
state.hoverEntered.add(id);
|
|
63
|
+
state.hoverLeft.delete(id);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
state.hoverLeft.add(id);
|
|
67
|
+
state.hoverEntered.delete(id);
|
|
68
|
+
}
|
|
69
|
+
state.hoverStates.set(id, hovered);
|
|
70
|
+
}
|
|
71
|
+
const pressed = hovered && state.isMouseDown && state.mouseButton === 0;
|
|
72
|
+
const clicked = frameHasClick(state) && contains(box, clickX(state), clickY(state));
|
|
73
|
+
return { box, hovered, pressed, clicked };
|
|
74
|
+
},
|
|
75
|
+
isHovered(id) {
|
|
76
|
+
const box = state.hitboxes.get(id);
|
|
77
|
+
if (!box)
|
|
78
|
+
return false;
|
|
79
|
+
return contains(box, state.mouseX, state.mouseY);
|
|
80
|
+
},
|
|
81
|
+
isPressed(id) {
|
|
82
|
+
return (interaction.isHovered(id) &&
|
|
83
|
+
state.isMouseDown &&
|
|
84
|
+
state.mouseButton === 0);
|
|
85
|
+
},
|
|
86
|
+
isClicked(id) {
|
|
87
|
+
const box = state.hitboxes.get(id);
|
|
88
|
+
if (!box)
|
|
89
|
+
return false;
|
|
90
|
+
return (frameHasClick(state) && contains(box, clickX(state), clickY(state)));
|
|
91
|
+
},
|
|
92
|
+
isHoverEnter(id) {
|
|
93
|
+
return state.hoverEntered.has(id);
|
|
94
|
+
},
|
|
95
|
+
isHoverLeave(id) {
|
|
96
|
+
return state.hoverLeft.has(id);
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
return interaction;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction.js","sourceRoot":"","sources":["../../src/dsl/interaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bunti DSL layer machinery: transparent buffers, layer screen states,
|
|
3
|
+
* painted-bounds tracking, and back-buffer compositing.
|
|
4
|
+
*/
|
|
5
|
+
import type { Rect } from '../geometry';
|
|
6
|
+
import type { Cell, ScreenState } from '../state';
|
|
7
|
+
export declare function createLayerScreenState(state: ScreenState): ScreenState;
|
|
8
|
+
/**
|
|
9
|
+
* Tight min/max bounds of a layer buffer's painted cells, or null when the
|
|
10
|
+
* layer painted nothing. Used at composite time to place drop shadows.
|
|
11
|
+
*/
|
|
12
|
+
export declare function layerContentBounds(buffer: Cell[], width: number): Rect | null;
|
|
13
|
+
export declare function compositeLayer(state: ScreenState, buffer: Cell[]): void;
|
|
14
|
+
//# sourceMappingURL=layers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../src/dsl/layers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAkBlD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAOtE;AAWD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAoB7E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,QAqBhE"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bunti DSL layer machinery: transparent buffers, layer screen states,
|
|
3
|
+
* painted-bounds tracking, and back-buffer compositing.
|
|
4
|
+
*/
|
|
5
|
+
function createTransparentBuffer(size) {
|
|
6
|
+
return Array.from({ length: size }, () => ({
|
|
7
|
+
char: ' ',
|
|
8
|
+
fg: undefined,
|
|
9
|
+
bg: undefined,
|
|
10
|
+
fgCode: undefined,
|
|
11
|
+
bgCode: undefined,
|
|
12
|
+
bold: false,
|
|
13
|
+
italic: false,
|
|
14
|
+
underline: false,
|
|
15
|
+
dim: false,
|
|
16
|
+
strike: false,
|
|
17
|
+
skip: true,
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
export function createLayerScreenState(state) {
|
|
21
|
+
const size = state.width * state.height;
|
|
22
|
+
return {
|
|
23
|
+
...state,
|
|
24
|
+
frontBuffer: createTransparentBuffer(size),
|
|
25
|
+
backBuffer: createTransparentBuffer(size),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Whether a layer-buffer cell holds painted content. Transparent cells are
|
|
30
|
+
* skip cells with the pristine ' ' char; painted wide-glyph tails are skip
|
|
31
|
+
* cells too but carry the '' char, so they count as content.
|
|
32
|
+
*/
|
|
33
|
+
function isPainted(cell) {
|
|
34
|
+
return !cell.skip || cell.char === '';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Tight min/max bounds of a layer buffer's painted cells, or null when the
|
|
38
|
+
* layer painted nothing. Used at composite time to place drop shadows.
|
|
39
|
+
*/
|
|
40
|
+
export function layerContentBounds(buffer, width) {
|
|
41
|
+
let minX = Infinity;
|
|
42
|
+
let minY = Infinity;
|
|
43
|
+
let maxX = -1;
|
|
44
|
+
let maxY = -1;
|
|
45
|
+
const height = Math.floor(buffer.length / width);
|
|
46
|
+
for (let y = 0; y < height; y++) {
|
|
47
|
+
const rowOffset = y * width;
|
|
48
|
+
for (let x = 0; x < width; x++) {
|
|
49
|
+
if (!isPainted(buffer[rowOffset + x]))
|
|
50
|
+
continue;
|
|
51
|
+
if (x < minX)
|
|
52
|
+
minX = x;
|
|
53
|
+
if (x > maxX)
|
|
54
|
+
maxX = x;
|
|
55
|
+
if (y < minY)
|
|
56
|
+
minY = y;
|
|
57
|
+
if (y > maxY)
|
|
58
|
+
maxY = y;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (maxX < 0)
|
|
62
|
+
return null;
|
|
63
|
+
return { x: minX, y: minY, width: maxX - minX + 1, height: maxY - minY + 1 };
|
|
64
|
+
}
|
|
65
|
+
export function compositeLayer(state, buffer) {
|
|
66
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
67
|
+
const source = buffer[i];
|
|
68
|
+
// Transparent cells never composite; painted wide-glyph tails
|
|
69
|
+
// (skip + '' char) must, or stale chars peek through under the glyph.
|
|
70
|
+
if (!isPainted(source))
|
|
71
|
+
continue;
|
|
72
|
+
const target = state.backBuffer[i];
|
|
73
|
+
target.char = source.char;
|
|
74
|
+
target.fg = source.fg;
|
|
75
|
+
target.bg = source.bg;
|
|
76
|
+
target.bold = source.bold;
|
|
77
|
+
target.italic = source.italic;
|
|
78
|
+
target.underline = source.underline;
|
|
79
|
+
target.dim = source.dim;
|
|
80
|
+
target.strike = source.strike;
|
|
81
|
+
target.fgCode = source.fgCode;
|
|
82
|
+
target.bgCode = source.bgCode;
|
|
83
|
+
target.skip = source.skip;
|
|
84
|
+
target.raw = source.raw;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=layers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/dsl/layers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bunti DSL motion helpers: animate, fade, typewriter, flicker, transition,
|
|
3
|
+
* stagger, restartAnimation, and per-frame timing (dt / frame).
|
|
4
|
+
*/
|
|
5
|
+
import type { ScreenState } from '../state';
|
|
6
|
+
import type { BuntiContext } from './types';
|
|
7
|
+
type Motion = Pick<BuntiContext, 'animate' | 'fade' | 'typewriter' | 'flicker' | 'transition' | 'stagger' | 'restartAnimation' | 'dt' | 'frame'>;
|
|
8
|
+
export declare function createMotion(state: ScreenState, useState: BuntiContext['useState']): Motion;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=motion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motion.d.ts","sourceRoot":"","sources":["../../src/dsl/motion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,SAAS,CAAC;AA2B/D,KAAK,MAAM,GAAG,IAAI,CAChB,YAAY,EACV,SAAS,GACT,MAAM,GACN,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,SAAS,GACT,kBAAkB,GAClB,IAAI,GACJ,OAAO,CACV,CAAC;AAEF,wBAAgB,YAAY,CAC1B,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,GACjC,MAAM,CAoKR"}
|
|
@@ -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"}
|