@zaly/tui 0.0.4 → 0.0.5
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/dist/actions-CnVzKVID.d.mts +41 -0
- package/dist/actions-CnVzKVID.d.mts.map +1 -0
- package/dist/actions-DEIKF2ts.mjs +48 -0
- package/dist/actions-DEIKF2ts.mjs.map +1 -0
- package/dist/{box-DyaByEiG.mjs → box-DepqUtuo.mjs} +2 -2
- package/dist/{box-DyaByEiG.mjs.map → box-DepqUtuo.mjs.map} +1 -1
- package/dist/{builder-D49ECBEf.mjs → builder-T9oGIWFa.mjs} +2 -2
- package/dist/{builder-D49ECBEf.mjs.map → builder-T9oGIWFa.mjs.map} +1 -1
- package/dist/{callbacks-CNjGNxVw.mjs → callbacks-DcMBGQEO.mjs} +2 -2
- package/dist/{callbacks-CNjGNxVw.mjs.map → callbacks-DcMBGQEO.mjs.map} +1 -1
- package/dist/{client-D6C_uczF.mjs → client-BBdtbLp4.mjs} +5 -10
- package/dist/client-BBdtbLp4.mjs.map +1 -0
- package/dist/client-cIckDgAj.mjs +2 -0
- package/dist/clipboard-l_TWxxTf.mjs +404 -0
- package/dist/clipboard-l_TWxxTf.mjs.map +1 -0
- package/dist/clipboard.mjs +1 -403
- package/dist/ctx-Ctmvof1N.mjs +43 -0
- package/dist/ctx-Ctmvof1N.mjs.map +1 -0
- package/dist/ctx-DhJIKuOX.mjs +2 -0
- package/dist/divider-cclEAdPx.mjs +9 -0
- package/dist/divider-cclEAdPx.mjs.map +1 -0
- package/dist/files-Aw3iWpXD.d.mts +29 -0
- package/dist/files-Aw3iWpXD.d.mts.map +1 -0
- package/dist/files-BvThQpOf.mjs +42 -0
- package/dist/files-BvThQpOf.mjs.map +1 -0
- package/dist/github-Cy2hfWJ7.mjs +137 -0
- package/dist/github-Cy2hfWJ7.mjs.map +1 -0
- package/dist/github-DS00VoOj.d.mts +64 -0
- package/dist/github-DS00VoOj.d.mts.map +1 -0
- package/dist/image-BTxDPPiT.d.mts +37 -0
- package/dist/image-BTxDPPiT.d.mts.map +1 -0
- package/dist/index.mjs +6 -202
- package/dist/index.mjs.map +1 -1
- package/dist/input-CRBuTrsL.mjs +497 -0
- package/dist/input-CRBuTrsL.mjs.map +1 -0
- package/dist/{inspect-D1d9t-ni.mjs → inspect-BaKG6cU_.mjs} +2 -2
- package/dist/{inspect-D1d9t-ni.mjs.map → inspect-BaKG6cU_.mjs.map} +1 -1
- package/dist/log-DYHEYX_z.mjs +130 -0
- package/dist/log-DYHEYX_z.mjs.map +1 -0
- package/dist/logger-Ch0LwSG_.mjs +71 -0
- package/dist/logger-Ch0LwSG_.mjs.map +1 -0
- package/dist/markdown-CYHHoYu0.mjs +124 -0
- package/dist/markdown-CYHHoYu0.mjs.map +1 -0
- package/dist/markdown.mjs +1 -1
- package/dist/overlay-9xNgsuuy.mjs +18 -0
- package/dist/overlay-9xNgsuuy.mjs.map +1 -0
- package/dist/{picker-ndVVt6qF.mjs → picker-cH-rc7-X.mjs} +5 -5
- package/dist/{picker-ndVVt6qF.mjs.map → picker-cH-rc7-X.mjs.map} +1 -1
- package/dist/queries-B_lOwEiE.mjs +200 -0
- package/dist/queries-B_lOwEiE.mjs.map +1 -0
- package/dist/{registry-U654j61Y.mjs → registry-CdeLjUo2.mjs} +2 -4
- package/dist/registry-CdeLjUo2.mjs.map +1 -0
- package/dist/render-CPUD4yaW.mjs +33 -0
- package/dist/render-CPUD4yaW.mjs.map +1 -0
- package/dist/{renderer-CxL4xbkl.mjs → renderer-DJ1pWXSL.mjs} +8 -7
- package/dist/{renderer-CxL4xbkl.mjs.map → renderer-DJ1pWXSL.mjs.map} +1 -1
- package/dist/renderer-Dgj_qEOA.mjs +2 -0
- package/dist/{renderer-CdLCkJB-.mjs → renderer-qSMVeNSV.mjs} +3 -5
- package/dist/{renderer-CdLCkJB-.mjs.map → renderer-qSMVeNSV.mjs.map} +1 -1
- package/dist/select-m7NE6Rwa.mjs +195 -0
- package/dist/select-m7NE6Rwa.mjs.map +1 -0
- package/dist/services/logger.mjs +1 -70
- package/dist/services/notifier.mjs +2 -2
- package/dist/services/picker.d.mts +1 -1
- package/dist/services/picker.mjs +6 -6
- package/dist/services/prompt.d.mts +1 -1
- package/dist/services/prompt.mjs +5 -5
- package/dist/shiki/server.d.mts +1 -0
- package/dist/shiki/server.mjs +129 -0
- package/dist/shiki/server.mjs.map +1 -0
- package/dist/{shiki-BrjVUkeh.mjs → shiki-B5NwIiot.mjs} +5 -10
- package/dist/shiki-B5NwIiot.mjs.map +1 -0
- package/dist/shiki-BK-v9CtF.mjs +12 -0
- package/dist/shiki-BK-v9CtF.mjs.map +1 -0
- package/dist/show-DR2x1YFc.mjs +85 -0
- package/dist/show-DR2x1YFc.mjs.map +1 -0
- package/dist/style.mjs +2 -2
- package/dist/text-9lwQeqYr.d.mts +33 -0
- package/dist/text-9lwQeqYr.d.mts.map +1 -0
- package/dist/text-DILrol9j.mjs +32 -0
- package/dist/text-DILrol9j.mjs.map +1 -0
- package/dist/text-q26V6_Sc.mjs +111 -0
- package/dist/text-q26V6_Sc.mjs.map +1 -0
- package/dist/text.d.mts +2 -33
- package/dist/text.mjs +1 -110
- package/dist/themes.mjs +1 -1
- package/dist/tree-Bo1afYhe.mjs +73 -0
- package/dist/tree-Bo1afYhe.mjs.map +1 -0
- package/dist/widget-BkMwhY2p.mjs +40 -0
- package/dist/widget-BkMwhY2p.mjs.map +1 -0
- package/dist/widget-M7jD8Rgg.d.mts +49 -0
- package/dist/widget-M7jD8Rgg.d.mts.map +1 -0
- package/dist/widgets/autocomplete.mjs +2 -2
- package/dist/widgets/box.mjs +1 -1
- package/dist/widgets/code.mjs +7 -7
- package/dist/widgets/completions/actions.d.mts +2 -41
- package/dist/widgets/completions/actions.mjs +1 -47
- package/dist/widgets/completions/files.d.mts +2 -29
- package/dist/widgets/completions/files.mjs +1 -41
- package/dist/widgets/completions/github.d.mts +2 -64
- package/dist/widgets/completions/github.mjs +1 -136
- package/dist/widgets/completions/index.d.mts +3 -3
- package/dist/widgets/completions/index.mjs +3 -3
- package/dist/widgets/diff.d.mts +1 -1
- package/dist/widgets/diff.mjs +3 -3
- package/dist/widgets/divider.mjs +1 -8
- package/dist/widgets/image.d.mts +2 -37
- package/dist/widgets/image.mjs +1 -1
- package/dist/widgets/input.mjs +1 -496
- package/dist/widgets/log.mjs +1 -129
- package/dist/widgets/markdown.d.mts +2 -2
- package/dist/widgets/markdown.mjs +1 -123
- package/dist/widgets/overlay.mjs +1 -17
- package/dist/widgets/picker.mjs +1 -1
- package/dist/widgets/select.mjs +1 -194
- package/dist/widgets/show.mjs +1 -84
- package/dist/widgets/text.mjs +1 -31
- package/dist/widgets/tree.mjs +1 -72
- package/dist/widgets/widget.d.mts +2 -49
- package/dist/widgets/widget.mjs +1 -39
- package/dist/worker-BvRm4OsW.mjs +2 -0
- package/dist/worker-T6SdPzUH.mjs +52 -0
- package/dist/worker-T6SdPzUH.mjs.map +1 -0
- package/package.json +5 -1
- package/dist/client-D6C_uczF.mjs.map +0 -1
- package/dist/clipboard.mjs.map +0 -1
- package/dist/registry-U654j61Y.mjs.map +0 -1
- package/dist/render-DxVLqqB9.mjs +0 -74
- package/dist/render-DxVLqqB9.mjs.map +0 -1
- package/dist/rolldown-runtime-D7D4PA-g.mjs +0 -13
- package/dist/services/logger.mjs.map +0 -1
- package/dist/shiki-BrjVUkeh.mjs.map +0 -1
- package/dist/text.d.mts.map +0 -1
- package/dist/text.mjs.map +0 -1
- package/dist/widgets/completions/actions.d.mts.map +0 -1
- package/dist/widgets/completions/actions.mjs.map +0 -1
- package/dist/widgets/completions/files.d.mts.map +0 -1
- package/dist/widgets/completions/files.mjs.map +0 -1
- package/dist/widgets/completions/github.d.mts.map +0 -1
- package/dist/widgets/completions/github.mjs.map +0 -1
- package/dist/widgets/divider.mjs.map +0 -1
- package/dist/widgets/image.d.mts.map +0 -1
- package/dist/widgets/input.mjs.map +0 -1
- package/dist/widgets/log.mjs.map +0 -1
- package/dist/widgets/markdown.mjs.map +0 -1
- package/dist/widgets/overlay.mjs.map +0 -1
- package/dist/widgets/select.mjs.map +0 -1
- package/dist/widgets/show.mjs.map +0 -1
- package/dist/widgets/text.mjs.map +0 -1
- package/dist/widgets/tree.mjs.map +0 -1
- package/dist/widgets/widget.d.mts.map +0 -1
- package/dist/widgets/widget.mjs.map +0 -1
- package/dist/worker-DjHuQSbY.mjs +0 -27
- package/dist/worker-DjHuQSbY.mjs.map +0 -1
|
@@ -1,124 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as Node } from "../node-BZ7f6HzU.mjs";
|
|
3
|
-
import { calcLayout, expandTabs, formatText } from "../text.mjs";
|
|
4
|
-
import { textContent } from "./text.mjs";
|
|
5
|
-
import { t as RenderContext } from "../render-DxVLqqB9.mjs";
|
|
6
|
-
import { t as codeToAnsi } from "../shiki-BrjVUkeh.mjs";
|
|
7
|
-
import { n as shikiWorker } from "../client-D6C_uczF.mjs";
|
|
8
|
-
import { hasColors } from "@zaly/shared/env";
|
|
9
|
-
//#region src/widgets/markdown.ts
|
|
10
|
-
var Markdown = class extends Node {
|
|
11
|
-
images = /* @__PURE__ */ new Map();
|
|
12
|
-
#renderer;
|
|
13
|
-
#code = /* @__PURE__ */ new Map();
|
|
14
|
-
#update = signal(0);
|
|
15
|
-
#gen = 0;
|
|
16
|
-
#worker;
|
|
17
|
-
#images;
|
|
18
|
-
constructor(state) {
|
|
19
|
-
super(state);
|
|
20
|
-
const context = useContext(RenderContext);
|
|
21
|
-
this.#images = context?.images;
|
|
22
|
-
this.#worker = createAsync(async () => {
|
|
23
|
-
const update = this.#update.get();
|
|
24
|
-
const todo = [...this.#code.values()].filter((c) => c.gen === this.#gen && !c.result);
|
|
25
|
-
if (!todo.length) return update;
|
|
26
|
-
await Promise.all(todo.map(async (req) => {
|
|
27
|
-
req.ac ??= new AbortController();
|
|
28
|
-
req.inflight ??= codeToAnsi(req.code, req.lang, {
|
|
29
|
-
signal: req.ac.signal,
|
|
30
|
-
theme: req.theme
|
|
31
|
-
});
|
|
32
|
-
try {
|
|
33
|
-
req.result = await req.inflight;
|
|
34
|
-
} catch (error) {
|
|
35
|
-
if (req.ac.signal.aborted) {
|
|
36
|
-
if (this.#code.get(req.key) === req) this.#code.delete(req.key);
|
|
37
|
-
} else throw error;
|
|
38
|
-
}
|
|
39
|
-
}));
|
|
40
|
-
return update + 1;
|
|
41
|
-
}, { initialValue: 0 });
|
|
42
|
-
}
|
|
43
|
-
/** Find a highlighted result for a prefix of `code` in the cache. This
|
|
44
|
-
* handles streaming updates where the full code block isn't available yet
|
|
45
|
-
* and prevents flashing un-highlighted text on each update. */
|
|
46
|
-
#streamingHighlight(code, lang, theme) {
|
|
47
|
-
let ret;
|
|
48
|
-
for (const c of this.#code.values()) {
|
|
49
|
-
if (!c.result || c.lang !== lang || c.theme !== theme) continue;
|
|
50
|
-
if (code.startsWith(c.code) && c.code.length > (ret?.code.length ?? 0)) ret = c;
|
|
51
|
-
}
|
|
52
|
-
if (ret) ret.gen = this.#gen;
|
|
53
|
-
return ret?.result ? ret.result + code.slice(ret.code.length) : code;
|
|
54
|
-
}
|
|
55
|
-
#highlight(code, lang, theme) {
|
|
56
|
-
if (!lang) return code;
|
|
57
|
-
const key = shikiWorker.key({
|
|
58
|
-
code,
|
|
59
|
-
lang,
|
|
60
|
-
theme
|
|
61
|
-
});
|
|
62
|
-
const ret = this.#code.get(key);
|
|
63
|
-
if (ret) ret.gen = this.#gen;
|
|
64
|
-
if (ret?.result) return ret.result;
|
|
65
|
-
else if (!ret) this.#code.set(key, {
|
|
66
|
-
code,
|
|
67
|
-
gen: this.#gen,
|
|
68
|
-
key,
|
|
69
|
-
lang,
|
|
70
|
-
theme
|
|
71
|
-
});
|
|
72
|
-
return this.#streamingHighlight(code, lang, theme);
|
|
73
|
-
}
|
|
74
|
-
async _render(ctx) {
|
|
75
|
-
if (!this.#renderer) {
|
|
76
|
-
const { MarkdownRenderer } = await import("../renderer-CdLCkJB-.mjs").then((n) => n.n);
|
|
77
|
-
this.#renderer = new MarkdownRenderer({
|
|
78
|
-
...this.state.options,
|
|
79
|
-
parent: this
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
let source = await textContent(this.state.content, ctx);
|
|
83
|
-
source = expandTabs(source);
|
|
84
|
-
let formatted;
|
|
85
|
-
if (!hasColors) formatted = this.#renderer.normalizeEol(source, source);
|
|
86
|
-
else {
|
|
87
|
-
this.#gen++;
|
|
88
|
-
formatted = await this.#renderer.render(source, {
|
|
89
|
-
...ctx,
|
|
90
|
-
highlight: (code, lang) => this.#highlight(code, lang, ctx.style.theme.shiki),
|
|
91
|
-
images: unwrap(this.#images) ?? true
|
|
92
|
-
});
|
|
93
|
-
for (const [k, c] of this.#code.entries()) if (c.gen !== this.#gen) {
|
|
94
|
-
c.ac?.abort();
|
|
95
|
-
if (c.result !== void 0) this.#code.delete(k);
|
|
96
|
-
}
|
|
97
|
-
if (this.#code.values().some((c) => !c.inflight)) {
|
|
98
|
-
this.#update.set(this.#gen);
|
|
99
|
-
this.#worker();
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return formatText(formatted, {
|
|
103
|
-
indent: true,
|
|
104
|
-
style: this.state.style ? ctx.style.add(this.state.style) : void 0,
|
|
105
|
-
width: ctx.width,
|
|
106
|
-
wrap: this.state.wrap,
|
|
107
|
-
wrapBg: true
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
async layout(ctx) {
|
|
111
|
-
return calcLayout(await textContent(this.state.content, ctx));
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
function markdown(first, style) {
|
|
115
|
-
if (typeof first === "string" || typeof first === "function") return new Markdown({
|
|
116
|
-
content: first,
|
|
117
|
-
...style
|
|
118
|
-
});
|
|
119
|
-
return new Markdown(first);
|
|
120
|
-
}
|
|
121
|
-
//#endregion
|
|
1
|
+
import { n as markdown, t as Markdown } from "../markdown-CYHHoYu0.mjs";
|
|
122
2
|
export { Markdown, markdown };
|
|
123
|
-
|
|
124
|
-
//# sourceMappingURL=markdown.mjs.map
|
package/dist/widgets/overlay.mjs
CHANGED
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/widgets/overlay.ts
|
|
3
|
-
function overlay(state, ...children) {
|
|
4
|
-
const node = box({
|
|
5
|
-
visible: false,
|
|
6
|
-
...state
|
|
7
|
-
}, ...children);
|
|
8
|
-
node.withActions({ "overlay.close": {
|
|
9
|
-
desc: "Close overlay",
|
|
10
|
-
fn: () => node.state.removeOnClose ?? true ? node.ctx?.overlay.remove(node) : node.hide(),
|
|
11
|
-
keys: ["esc", "ctrl-c"]
|
|
12
|
-
} });
|
|
13
|
-
return node;
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
1
|
+
import { t as overlay } from "../overlay-9xNgsuuy.mjs";
|
|
16
2
|
export { overlay };
|
|
17
|
-
|
|
18
|
-
//# sourceMappingURL=overlay.mjs.map
|
package/dist/widgets/picker.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as picker } from "../picker-
|
|
1
|
+
import { t as picker } from "../picker-cH-rc7-X.mjs";
|
|
2
2
|
export { picker };
|
package/dist/widgets/select.mjs
CHANGED
|
@@ -1,195 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as Node } from "../node-BZ7f6HzU.mjs";
|
|
3
|
-
import { n as resolveSize } from "../size-D8JogYLy.mjs";
|
|
4
|
-
import { fitAnsi, stringWidth } from "@zaly/shared/ansi";
|
|
5
|
-
//#region src/widgets/select.ts
|
|
6
|
-
/**
|
|
7
|
-
* Selectable list. Items are rendered one per row with an active-row
|
|
8
|
-
* highlight; navigation actions (`next`, `prev`, `first`, `last`,
|
|
9
|
-
* `accept`, `complete`, `cancel`) live on `this.actions`, same pattern as
|
|
10
|
-
* `Input`.
|
|
11
|
-
*
|
|
12
|
-
* Used standalone for simple lists and as the underlying list primitive for
|
|
13
|
-
* `picker`, `tree`, and `autocomplete`. Doesn't open/close itself — callers
|
|
14
|
-
* control visibility via `state.visible`.
|
|
15
|
-
*/
|
|
16
|
-
var Select = class Select extends Node {
|
|
17
|
-
static type = "select";
|
|
18
|
-
type = Select.type;
|
|
19
|
-
actions = {
|
|
20
|
-
"select.accept": () => {
|
|
21
|
-
const items = this.#items;
|
|
22
|
-
if (items.length === 0) return;
|
|
23
|
-
this.emit("accept", { item: items[this.active] });
|
|
24
|
-
},
|
|
25
|
-
"select.close": () => {
|
|
26
|
-
this.emit("close");
|
|
27
|
-
},
|
|
28
|
-
"select.complete": () => {
|
|
29
|
-
const items = this.#items;
|
|
30
|
-
if (items.length === 0) return;
|
|
31
|
-
this.emit("complete", { item: items[this.active] });
|
|
32
|
-
},
|
|
33
|
-
"select.first": () => {
|
|
34
|
-
if (this.#items.length === 0) return;
|
|
35
|
-
this.active = 0;
|
|
36
|
-
},
|
|
37
|
-
"select.last": () => {
|
|
38
|
-
const n = this.#items.length;
|
|
39
|
-
if (n === 0) return;
|
|
40
|
-
this.active = n - 1;
|
|
41
|
-
},
|
|
42
|
-
"select.next": () => {
|
|
43
|
-
if (this.#items.length === 0) return;
|
|
44
|
-
this.active += this.#direction;
|
|
45
|
-
},
|
|
46
|
-
"select.page-down": () => {
|
|
47
|
-
if (this.#items.length === 0) return;
|
|
48
|
-
const page = Math.max(this.pageSize - 1, 1);
|
|
49
|
-
this.state.active = this.#clamp(this.active + this.#direction * page);
|
|
50
|
-
},
|
|
51
|
-
"select.page-up": () => {
|
|
52
|
-
if (this.#items.length === 0) return;
|
|
53
|
-
const page = Math.max(this.pageSize - 1, 1);
|
|
54
|
-
this.state.active = this.#clamp(this.active - this.#direction * page);
|
|
55
|
-
},
|
|
56
|
-
"select.prev": () => {
|
|
57
|
-
if (this.#items.length === 0) return;
|
|
58
|
-
this.active -= this.#direction;
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
/** Top of the currently-rendered window, in absolute item indices.
|
|
62
|
-
* Updated per render using the pin-until-leave rule: stays put
|
|
63
|
-
* while `active` remains in `[start, start + visible)`, slides just
|
|
64
|
-
* enough to re-admit it otherwise. */
|
|
65
|
-
#windowStart = 0;
|
|
66
|
-
constructor(initial) {
|
|
67
|
-
super({
|
|
68
|
-
active: 0,
|
|
69
|
-
...initial
|
|
70
|
-
});
|
|
71
|
-
let active = this.item;
|
|
72
|
-
effect(() => {
|
|
73
|
-
const next = this.item;
|
|
74
|
-
if (next === active) return;
|
|
75
|
-
active = next;
|
|
76
|
-
this.emit("changed", {
|
|
77
|
-
active: this.active,
|
|
78
|
-
item: next
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
get #direction() {
|
|
83
|
-
return this.state.reverse ? -1 : 1;
|
|
84
|
-
}
|
|
85
|
-
get #items() {
|
|
86
|
-
return unwrap(this.state.items);
|
|
87
|
-
}
|
|
88
|
-
#clamp(i) {
|
|
89
|
-
const n = this.#items.length;
|
|
90
|
-
return n === 0 ? 0 : Math.max(0, Math.min(n - 1, i));
|
|
91
|
-
}
|
|
92
|
-
set active(i) {
|
|
93
|
-
const n = this.#items.length;
|
|
94
|
-
this.state.active = n === 0 ? 0 : (i % n + n) % n;
|
|
95
|
-
}
|
|
96
|
-
get active() {
|
|
97
|
-
const a = this.state.active ?? 0;
|
|
98
|
-
const n = this.#items.length;
|
|
99
|
-
if (n === 0) return 0;
|
|
100
|
-
return Math.max(0, Math.min(n - 1, a));
|
|
101
|
-
}
|
|
102
|
-
bind(node) {
|
|
103
|
-
let n;
|
|
104
|
-
const getn = () => n = node instanceof Node ? node : node();
|
|
105
|
-
this.on("mount", () => getn().addActionTarget(this));
|
|
106
|
-
this.on("unmount", () => n?.removeActionTarget(this));
|
|
107
|
-
if (this.mounted) getn().addActionTarget(this);
|
|
108
|
-
return this;
|
|
109
|
-
}
|
|
110
|
-
get count() {
|
|
111
|
-
return this.#items.length;
|
|
112
|
-
}
|
|
113
|
-
get pageSize() {
|
|
114
|
-
return unwrap(this.state.maxHeight) ?? Math.max(this.#items.length, 1);
|
|
115
|
-
}
|
|
116
|
-
get item() {
|
|
117
|
-
return this.#items[this.active];
|
|
118
|
-
}
|
|
119
|
-
_render(ctx) {
|
|
120
|
-
const items = this.#items;
|
|
121
|
-
if (items.length === 0) return [];
|
|
122
|
-
const width = resolveSize(this.state.width ?? "fill", ctx.width) ?? ctx.width;
|
|
123
|
-
const active = this.active;
|
|
124
|
-
const height = Math.min(this.pageSize, items.length);
|
|
125
|
-
if (height === 0) return [];
|
|
126
|
-
let start = this.#windowStart;
|
|
127
|
-
if (active < start) start = active;
|
|
128
|
-
else if (active >= start + height) start = active - height + 1;
|
|
129
|
-
start = Math.max(0, Math.min(Math.max(0, items.length - height), start));
|
|
130
|
-
this.#windowStart = start;
|
|
131
|
-
const visible = items.slice(start, start + height);
|
|
132
|
-
const renderer = this.renderer;
|
|
133
|
-
const rows = [];
|
|
134
|
-
for (let i = start; i < start + height; i++) {
|
|
135
|
-
const item = items[i];
|
|
136
|
-
let row = renderer(item, {
|
|
137
|
-
...ctx,
|
|
138
|
-
active: i === active,
|
|
139
|
-
items,
|
|
140
|
-
visible
|
|
141
|
-
}).replace(/\n/g, " ");
|
|
142
|
-
row = fitAnsi(row, width);
|
|
143
|
-
rows.push(i === active ? ctx.style.optionActive(row) : row);
|
|
144
|
-
}
|
|
145
|
-
if (this.state.reverse) rows.reverse();
|
|
146
|
-
if (this.state.counter ?? items.length > height) {
|
|
147
|
-
const label = `(${items.length === 0 ? 0 : active + 1}/${items.length}${this.state.more ? "+" : ""})`;
|
|
148
|
-
rows.push(ctx.style.gutter(fitAnsi(label, width)));
|
|
149
|
-
}
|
|
150
|
-
return rows;
|
|
151
|
-
}
|
|
152
|
-
get renderer() {
|
|
153
|
-
return unwrap(this.state.render) ?? this.defaultRenderer();
|
|
154
|
-
}
|
|
155
|
-
extendRenderer(fn) {
|
|
156
|
-
const prev = this.renderer;
|
|
157
|
-
this.state.render = fn(prev);
|
|
158
|
-
return this;
|
|
159
|
-
}
|
|
160
|
-
defaultRenderer() {
|
|
161
|
-
let visible = [];
|
|
162
|
-
let labelWidth = 0;
|
|
163
|
-
const update = (ctx) => {
|
|
164
|
-
if (ctx.visible === visible) return;
|
|
165
|
-
visible = ctx.visible;
|
|
166
|
-
if (!visible.some((i) => i.desc)) return labelWidth = ctx.width;
|
|
167
|
-
labelWidth = this.state.labelWidth ?? 0;
|
|
168
|
-
labelWidth ||= visible.map(itemLabel).reduce((max, label) => Math.max(max, stringWidth(label)), 0);
|
|
169
|
-
labelWidth = Math.min(labelWidth, Math.floor(ctx.width / 2));
|
|
170
|
-
};
|
|
171
|
-
return (item, ctx) => {
|
|
172
|
-
update(ctx);
|
|
173
|
-
const label = fitAnsi(itemLabel(item), labelWidth);
|
|
174
|
-
if (!item.desc) return ctx.style.optionName(label);
|
|
175
|
-
const desc = fitAnsi(item.desc ?? "", Math.max(0, ctx.width - labelWidth - 2));
|
|
176
|
-
return `${ctx.style.optionName(label)} ${ctx.style.optionDesc(desc)}`;
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
const itemLabel = (item) => (item.name ?? item.text).replace(/\s+/g, " ").trim();
|
|
181
|
-
/**
|
|
182
|
-
* Factory for a selectable list.
|
|
183
|
-
*
|
|
184
|
-
* ```ts
|
|
185
|
-
* const s = select({ items: [{ text: "/help" }, { text: "/quit" }] })
|
|
186
|
-
* s.on("accept", ({ item }) => console.log("picked", item.text))
|
|
187
|
-
* ```
|
|
188
|
-
*/
|
|
189
|
-
function select(state) {
|
|
190
|
-
return new Select(state);
|
|
191
|
-
}
|
|
192
|
-
//#endregion
|
|
1
|
+
import { n as select, t as Select } from "../select-m7NE6Rwa.mjs";
|
|
193
2
|
export { Select, select };
|
|
194
|
-
|
|
195
|
-
//# sourceMappingURL=select.mjs.map
|
package/dist/widgets/show.mjs
CHANGED
|
@@ -1,85 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as Node } from "../node-BZ7f6HzU.mjs";
|
|
3
|
-
//#region src/widgets/show.ts
|
|
4
|
-
/** Conditional fragment backing `show()`. Branches are created lazily:
|
|
5
|
-
* a `use` factory only runs the first time its condition wins. Once
|
|
6
|
-
* created, the branch remains mounted and owned; inactive branches simply
|
|
7
|
-
* don't participate in layout/rendering and contribute zero rows.
|
|
8
|
-
*
|
|
9
|
-
* Lazy factories run under the owner captured at `show()` creation time,
|
|
10
|
-
* so context reads behave as if the branch had been constructed eagerly.
|
|
11
|
-
*/
|
|
12
|
-
var Show = class extends Node {
|
|
13
|
-
#state = [];
|
|
14
|
-
#owner = useActiveOwner();
|
|
15
|
-
constructor(spec) {
|
|
16
|
-
super({});
|
|
17
|
-
let fallback = false;
|
|
18
|
-
for (const s of spec) {
|
|
19
|
-
if (fallback) throw new Error("Show: `fallback` must be the final argument");
|
|
20
|
-
if (typeof s === "function") {
|
|
21
|
-
this.#state.push({
|
|
22
|
-
use: s,
|
|
23
|
-
when: true
|
|
24
|
-
});
|
|
25
|
-
fallback = true;
|
|
26
|
-
} else this.#state.push(s);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
#nodes(s, use) {
|
|
30
|
-
if (s.children) return s.children;
|
|
31
|
-
const create = () => untrack(use);
|
|
32
|
-
const nodes = this.#owner ? withOwner(this.#owner, create) : create();
|
|
33
|
-
s.children = Array.isArray(nodes) ? nodes : [nodes];
|
|
34
|
-
for (const c of s.children) this.add(c);
|
|
35
|
-
return s.children;
|
|
36
|
-
}
|
|
37
|
-
layoutChildren() {
|
|
38
|
-
for (const s of this.#state) {
|
|
39
|
-
const matches = unwrap(s.when);
|
|
40
|
-
if (s.use === void 0) {
|
|
41
|
-
if (!matches) return [];
|
|
42
|
-
continue;
|
|
43
|
-
} else if (!matches) continue;
|
|
44
|
-
return this.#nodes(s, s.use);
|
|
45
|
-
}
|
|
46
|
-
return [];
|
|
47
|
-
}
|
|
48
|
-
/** Standalone-render fallback. Box parents go through
|
|
49
|
-
* `layoutChildren` and bypass this; only fires when `Show` sits
|
|
50
|
-
* outside a layout container (root, overlay, etc.). */
|
|
51
|
-
async _render(ctx) {
|
|
52
|
-
const targets = this.layoutChildren();
|
|
53
|
-
return (await Promise.all(targets.map((c) => c.render(ctx)))).flat();
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
/** Lazy conditional rendering.
|
|
57
|
-
*
|
|
58
|
-
* Specs are evaluated from left to right:
|
|
59
|
-
* - `{ when }` is a guard. When false, rendering stops with no rows; when
|
|
60
|
-
* true, evaluation continues.
|
|
61
|
-
* - `{ when, use }` is a conditional branch. The first branch whose
|
|
62
|
-
* condition is truthy is rendered.
|
|
63
|
-
* - A final bare factory is the fallback branch and must be the last
|
|
64
|
-
* argument.
|
|
65
|
-
*
|
|
66
|
-
* Branch factories are lazy and run at most once. Created branches stay
|
|
67
|
-
* mounted across toggles, preserving state, effects, and async resources.
|
|
68
|
-
*
|
|
69
|
-
* ```ts
|
|
70
|
-
* show({ when: isLoading }, () => spinner({ color: "accent" }))
|
|
71
|
-
*
|
|
72
|
-
* show(
|
|
73
|
-
* { when: full },
|
|
74
|
-
* { when: isError, use: () => errorView() },
|
|
75
|
-
* () => resultView()
|
|
76
|
-
* )
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
function show(...spec) {
|
|
80
|
-
return new Show(spec);
|
|
81
|
-
}
|
|
82
|
-
//#endregion
|
|
1
|
+
import { t as show } from "../show-DR2x1YFc.mjs";
|
|
83
2
|
export { show };
|
|
84
|
-
|
|
85
|
-
//# sourceMappingURL=show.mjs.map
|
package/dist/widgets/text.mjs
CHANGED
|
@@ -1,32 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as Node } from "../node-BZ7f6HzU.mjs";
|
|
3
|
-
import { calcLayout, formatText } from "../text.mjs";
|
|
4
|
-
//#region src/widgets/text.ts
|
|
5
|
-
var Text = class extends Node {
|
|
6
|
-
async _render(ctx) {
|
|
7
|
-
return formatText(await textContent(this.state.content, ctx), {
|
|
8
|
-
style: ctx.style.add(this.state),
|
|
9
|
-
width: ctx.width,
|
|
10
|
-
wrap: this.state.wrap
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
async layout(ctx) {
|
|
14
|
-
return calcLayout(await textContent(this.state.content, ctx), { wrap: this.state.wrap });
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
async function textContent(content, ctx) {
|
|
18
|
-
if (content === void 0) return;
|
|
19
|
-
const raw = unwrap(content);
|
|
20
|
-
return unwrap(typeof raw === "string" ? raw : await raw(ctx));
|
|
21
|
-
}
|
|
22
|
-
function text(first, style) {
|
|
23
|
-
if (typeof first === "string" || typeof first === "function") return new Text({
|
|
24
|
-
content: first,
|
|
25
|
-
...style
|
|
26
|
-
});
|
|
27
|
-
return new Text(first);
|
|
28
|
-
}
|
|
29
|
-
//#endregion
|
|
1
|
+
import { n as text, r as textContent, t as Text } from "../text-DILrol9j.mjs";
|
|
30
2
|
export { Text, text, textContent };
|
|
31
|
-
|
|
32
|
-
//# sourceMappingURL=text.mjs.map
|
package/dist/widgets/tree.mjs
CHANGED
|
@@ -1,73 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { widget } from "./widget.mjs";
|
|
3
|
-
import { select } from "./select.mjs";
|
|
4
|
-
import { stringWidth } from "@zaly/shared/ansi";
|
|
5
|
-
//#region src/widgets/tree.ts
|
|
6
|
-
const icons = {
|
|
7
|
-
last: "╰─",
|
|
8
|
-
middle: "├─",
|
|
9
|
-
vertical: "│ "
|
|
10
|
-
};
|
|
11
|
-
var Tree = class {
|
|
12
|
-
root;
|
|
13
|
-
nodes = /* @__PURE__ */ new Map();
|
|
14
|
-
items = [];
|
|
15
|
-
constructor(root) {
|
|
16
|
-
this.root = root;
|
|
17
|
-
this.#build(root, void 0, true);
|
|
18
|
-
}
|
|
19
|
-
#build(item, parent, last) {
|
|
20
|
-
this.nodes.set(item, {
|
|
21
|
-
last,
|
|
22
|
-
parent
|
|
23
|
-
});
|
|
24
|
-
this.items.push(item);
|
|
25
|
-
const children = item.children ?? [];
|
|
26
|
-
for (let c = 0; c < children.length; c++) {
|
|
27
|
-
const child = children[c];
|
|
28
|
-
this.#build(child, item, c === children.length - 1);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
node(item) {
|
|
32
|
-
return this.nodes.get(item);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
const tree = widget((props) => {
|
|
36
|
-
const builder = memo(() => new Tree(unwrap(props.tree)));
|
|
37
|
-
const items = memo(() => props.root === true ? builder().items : builder().items.slice(1));
|
|
38
|
-
const activeFn = typeof props.active === "function" ? props.active : (i) => i === props.active;
|
|
39
|
-
const active = props.active ? items().findIndex((i) => activeFn(i)) : -1;
|
|
40
|
-
const ret = select({
|
|
41
|
-
...props,
|
|
42
|
-
active: active === -1 ? 0 : active,
|
|
43
|
-
items
|
|
44
|
-
});
|
|
45
|
-
ret.extendRenderer((prev) => (item, ctx) => {
|
|
46
|
-
const t = builder();
|
|
47
|
-
const path = [];
|
|
48
|
-
const s = ctx.style;
|
|
49
|
-
const itemNode = t.node(item);
|
|
50
|
-
let n = t.node(item);
|
|
51
|
-
while (n?.parent) {
|
|
52
|
-
if (props.root !== true && n.parent === props.tree) break;
|
|
53
|
-
let icon = "";
|
|
54
|
-
if (n !== itemNode) icon = n.last ? " " : icons.vertical;
|
|
55
|
-
else icon = n.last ? icons.last : icons.middle;
|
|
56
|
-
path.unshift(icon);
|
|
57
|
-
n = t.node(n.parent);
|
|
58
|
-
}
|
|
59
|
-
const prefix = path.join("");
|
|
60
|
-
const prefixWidth = stringWidth(prefix);
|
|
61
|
-
const text = prev(item, {
|
|
62
|
-
...ctx,
|
|
63
|
-
prefixWidth,
|
|
64
|
-
width: ctx.width - prefixWidth
|
|
65
|
-
}).replace(/\s/g, " ");
|
|
66
|
-
return `${s.gutter(prefix)}${text}`;
|
|
67
|
-
});
|
|
68
|
-
return Object.assign(ret, { items });
|
|
69
|
-
});
|
|
70
|
-
//#endregion
|
|
1
|
+
import { t as tree } from "../tree-Bo1afYhe.mjs";
|
|
71
2
|
export { tree };
|
|
72
|
-
|
|
73
|
-
//# sourceMappingURL=tree.mjs.map
|
|
@@ -1,49 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type Props = Record<string, unknown>;
|
|
4
|
-
/**
|
|
5
|
-
* A widget factory: takes some args, returns a `Node`.
|
|
6
|
-
*
|
|
7
|
-
* The default `A = never[]` makes the *bare* `Widget` the universal
|
|
8
|
-
* "any widget" type — the `(...args: never[]) => Node` idiom. Every
|
|
9
|
-
* concrete factory (zero-arg, `state + ...children`, single-props) is
|
|
10
|
-
* assignable to it, so it works both as the `widget()` constraint and
|
|
11
|
-
* as a stored value type (`details?: Widget`, invoked zero-arg). Supply
|
|
12
|
-
* `A` explicitly for a precise signature: `Widget<[State<LogState>]>`.
|
|
13
|
-
*/
|
|
14
|
-
type Widget<A extends unknown[] = never[], N extends Node = Node> = (...args: A) => N;
|
|
15
|
-
/**
|
|
16
|
-
* Type helper for declaring widgets — runtime identity, just `return fn`.
|
|
17
|
-
*
|
|
18
|
-
* Three things it earns:
|
|
19
|
-
* 1. Inference at the declaration site: TS infers `S` from the function
|
|
20
|
-
* parameter and enforces it on every call site.
|
|
21
|
-
* 2. A consistent grep target: every component reads as
|
|
22
|
-
* `export const foo = widget((props) => …)`.
|
|
23
|
-
* 3. A future seam for instrumentation, lifecycle wrappers, devtools.
|
|
24
|
-
*
|
|
25
|
-
* The factory body runs **once** at construction. Reactive content lives
|
|
26
|
-
* in leaf thunks (`text(({ style }) => …)`), not by re-running the body
|
|
27
|
-
* — this is the Solid model, not React's. `ctx` is therefore unavailable
|
|
28
|
-
* inside the factory; reach for it inside leaf thunks where it belongs.
|
|
29
|
-
*
|
|
30
|
-
* ```ts
|
|
31
|
-
* const status = widget((props: { level: "ok" | "warn"; msg: string }) =>
|
|
32
|
-
* text(({ style }) => `${style.bold[props.level]("●")} ${style.dim(props.msg)}`),
|
|
33
|
-
* )
|
|
34
|
-
*
|
|
35
|
-
* status({ level: "ok", msg: "all systems nominal" })
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
/**
|
|
39
|
-
* Call-site args derived from `S`:
|
|
40
|
-
* - If `S` declares `children`, `children` is injected from rest args;
|
|
41
|
-
* state at the call site has `children` omitted, then `...children`.
|
|
42
|
-
* - Otherwise, no rest is allowed.
|
|
43
|
-
* - Either way, the state arg is optional when every field of the
|
|
44
|
-
* resolved state is optional (so bare `widget()` works).
|
|
45
|
-
*/
|
|
46
|
-
declare function widget<T extends Widget>(fn: T): T;
|
|
47
|
-
//#endregion
|
|
48
|
-
export { Props, Widget, widget };
|
|
49
|
-
//# sourceMappingURL=widget.d.mts.map
|
|
1
|
+
import { n as Widget, r as widget, t as Props } from "../widget-M7jD8Rgg.mjs";
|
|
2
|
+
export { Props, Widget, widget };
|
package/dist/widgets/widget.mjs
CHANGED
|
@@ -1,40 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/widgets/widget.ts
|
|
3
|
-
/**
|
|
4
|
-
* Type helper for declaring widgets — runtime identity, just `return fn`.
|
|
5
|
-
*
|
|
6
|
-
* Three things it earns:
|
|
7
|
-
* 1. Inference at the declaration site: TS infers `S` from the function
|
|
8
|
-
* parameter and enforces it on every call site.
|
|
9
|
-
* 2. A consistent grep target: every component reads as
|
|
10
|
-
* `export const foo = widget((props) => …)`.
|
|
11
|
-
* 3. A future seam for instrumentation, lifecycle wrappers, devtools.
|
|
12
|
-
*
|
|
13
|
-
* The factory body runs **once** at construction. Reactive content lives
|
|
14
|
-
* in leaf thunks (`text(({ style }) => …)`), not by re-running the body
|
|
15
|
-
* — this is the Solid model, not React's. `ctx` is therefore unavailable
|
|
16
|
-
* inside the factory; reach for it inside leaf thunks where it belongs.
|
|
17
|
-
*
|
|
18
|
-
* ```ts
|
|
19
|
-
* const status = widget((props: { level: "ok" | "warn"; msg: string }) =>
|
|
20
|
-
* text(({ style }) => `${style.bold[props.level]("●")} ${style.dim(props.msg)}`),
|
|
21
|
-
* )
|
|
22
|
-
*
|
|
23
|
-
* status({ level: "ok", msg: "all systems nominal" })
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
/**
|
|
27
|
-
* Call-site args derived from `S`:
|
|
28
|
-
* - If `S` declares `children`, `children` is injected from rest args;
|
|
29
|
-
* state at the call site has `children` omitted, then `...children`.
|
|
30
|
-
* - Otherwise, no rest is allowed.
|
|
31
|
-
* - Either way, the state arg is optional when every field of the
|
|
32
|
-
* resolved state is optional (so bare `widget()` works).
|
|
33
|
-
*/
|
|
34
|
-
function widget(fn) {
|
|
35
|
-
return ((...args) => createNode(() => fn(...args)));
|
|
36
|
-
}
|
|
37
|
-
//#endregion
|
|
1
|
+
import { t as widget } from "../widget-BkMwhY2p.mjs";
|
|
38
2
|
export { widget };
|
|
39
|
-
|
|
40
|
-
//# sourceMappingURL=widget.mjs.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//#region src/shiki/worker.ts
|
|
2
|
+
const workerHost = {
|
|
3
|
+
onMessage: (handler) => {
|
|
4
|
+
if (typeof globalThis.addEventListener === "function") {
|
|
5
|
+
globalThis.addEventListener("message", (event) => void handler(event.data));
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
import("node:worker_threads").then(({ parentPort }) => {
|
|
9
|
+
parentPort?.on("message", (message) => void handler(message));
|
|
10
|
+
});
|
|
11
|
+
},
|
|
12
|
+
postMessage: (message) => {
|
|
13
|
+
if (typeof globalThis.postMessage === "function") {
|
|
14
|
+
globalThis.postMessage(message);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
import("node:worker_threads").then(({ parentPort }) => {
|
|
18
|
+
parentPort?.postMessage(message);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
async function createWorker() {
|
|
23
|
+
const scriptURL = new URL(import.meta.resolve("#shiki-worker"));
|
|
24
|
+
if (typeof globalThis.Worker === "function") {
|
|
25
|
+
const w = new Worker(scriptURL, { type: "module" });
|
|
26
|
+
w.unref?.();
|
|
27
|
+
return {
|
|
28
|
+
on: (event, handler) => {
|
|
29
|
+
if (event === "error") w.addEventListener(event, (e) => void handler(e.error ?? new Error(e.message)));
|
|
30
|
+
else w.addEventListener(event, (e) => void handler(e.data));
|
|
31
|
+
w.unref?.();
|
|
32
|
+
},
|
|
33
|
+
postMessage: (message) => w.postMessage(message),
|
|
34
|
+
terminate: () => w.terminate()
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const { Worker: NodeWorker } = await import("node:worker_threads");
|
|
38
|
+
const worker = new NodeWorker(scriptURL);
|
|
39
|
+
worker.unref();
|
|
40
|
+
return {
|
|
41
|
+
on: (event, handler) => {
|
|
42
|
+
worker.on(event, (e) => void handler(e));
|
|
43
|
+
worker.unref();
|
|
44
|
+
},
|
|
45
|
+
postMessage: (message) => worker.postMessage(message),
|
|
46
|
+
terminate: () => void worker.terminate()
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { workerHost as n, createWorker as t };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=worker-T6SdPzUH.mjs.map
|