@zaly/tui 0.0.4

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.
Files changed (228) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/assets/schemas/theme.schema.json +899 -0
  4. package/assets/themes/LICENSE-tokyonight.txt +201 -0
  5. package/assets/themes/NOTICES.md +69 -0
  6. package/assets/themes/ayu-dark.json +119 -0
  7. package/assets/themes/catppuccin-frappe.json +124 -0
  8. package/assets/themes/catppuccin-latte.json +124 -0
  9. package/assets/themes/catppuccin-macchiato.json +124 -0
  10. package/assets/themes/catppuccin-mocha.json +124 -0
  11. package/assets/themes/dracula-soft.json +119 -0
  12. package/assets/themes/dracula.json +119 -0
  13. package/assets/themes/everforest-dark.json +118 -0
  14. package/assets/themes/everforest-light.json +118 -0
  15. package/assets/themes/github-dark.json +123 -0
  16. package/assets/themes/github-light.json +123 -0
  17. package/assets/themes/gruvbox-dark-medium.json +112 -0
  18. package/assets/themes/kanagawa-dragon.json +115 -0
  19. package/assets/themes/kanagawa-wave.json +115 -0
  20. package/assets/themes/material-theme-palenight.json +114 -0
  21. package/assets/themes/min-dark.json +55 -0
  22. package/assets/themes/min-light.json +59 -0
  23. package/assets/themes/monokai.json +116 -0
  24. package/assets/themes/night-owl.json +116 -0
  25. package/assets/themes/nord.json +101 -0
  26. package/assets/themes/one-dark-pro.json +110 -0
  27. package/assets/themes/one-light.json +108 -0
  28. package/assets/themes/poimandres.json +123 -0
  29. package/assets/themes/rose-pine.json +98 -0
  30. package/assets/themes/solarized-dark.json +116 -0
  31. package/assets/themes/solarized-light.json +116 -0
  32. package/assets/themes/synthwave-84.json +100 -0
  33. package/assets/themes/tokyonight-day.json +157 -0
  34. package/assets/themes/tokyonight-moon.json +157 -0
  35. package/assets/themes/tokyonight-night.json +157 -0
  36. package/assets/themes/tokyonight-storm.json +157 -0
  37. package/assets/themes/vesper.json +103 -0
  38. package/assets/themes/vitesse-dark.json +126 -0
  39. package/assets/themes/vitesse-light.json +126 -0
  40. package/dist/ansi-Clq0ozyA.mjs +206 -0
  41. package/dist/ansi-Clq0ozyA.mjs.map +1 -0
  42. package/dist/ansi.d.mts +48 -0
  43. package/dist/ansi.d.mts.map +1 -0
  44. package/dist/ansi.mjs +2 -0
  45. package/dist/autocomplete-Dfw-yQDa.d.mts +100 -0
  46. package/dist/autocomplete-Dfw-yQDa.d.mts.map +1 -0
  47. package/dist/box-DyaByEiG.mjs +386 -0
  48. package/dist/box-DyaByEiG.mjs.map +1 -0
  49. package/dist/builder-D49ECBEf.mjs +385 -0
  50. package/dist/builder-D49ECBEf.mjs.map +1 -0
  51. package/dist/callbacks-CNjGNxVw.mjs +279 -0
  52. package/dist/callbacks-CNjGNxVw.mjs.map +1 -0
  53. package/dist/client-D6C_uczF.mjs +142 -0
  54. package/dist/client-D6C_uczF.mjs.map +1 -0
  55. package/dist/clipboard.d.mts +104 -0
  56. package/dist/clipboard.d.mts.map +1 -0
  57. package/dist/clipboard.mjs +404 -0
  58. package/dist/clipboard.mjs.map +1 -0
  59. package/dist/flex-Bguo-fUe.mjs +202 -0
  60. package/dist/flex-Bguo-fUe.mjs.map +1 -0
  61. package/dist/image-Cm5T-uw-.mjs +108 -0
  62. package/dist/image-Cm5T-uw-.mjs.map +1 -0
  63. package/dist/image.d.mts +123 -0
  64. package/dist/image.d.mts.map +1 -0
  65. package/dist/image.mjs +2 -0
  66. package/dist/index.d.mts +64 -0
  67. package/dist/index.d.mts.map +1 -0
  68. package/dist/index.mjs +222 -0
  69. package/dist/index.mjs.map +1 -0
  70. package/dist/input-B5Vy-iaa.d.mts +141 -0
  71. package/dist/input-B5Vy-iaa.d.mts.map +1 -0
  72. package/dist/inspect-D1d9t-ni.mjs +101 -0
  73. package/dist/inspect-D1d9t-ni.mjs.map +1 -0
  74. package/dist/inspect-D6FW_QUo.d.mts +67 -0
  75. package/dist/inspect-D6FW_QUo.d.mts.map +1 -0
  76. package/dist/kitty-JbCJC0iQ.mjs +673 -0
  77. package/dist/kitty-JbCJC0iQ.mjs.map +1 -0
  78. package/dist/markdown.d.mts +24 -0
  79. package/dist/markdown.d.mts.map +1 -0
  80. package/dist/markdown.mjs +2 -0
  81. package/dist/md.bun.d.mts +14 -0
  82. package/dist/md.bun.d.mts.map +1 -0
  83. package/dist/md.bun.mjs +28 -0
  84. package/dist/md.bun.mjs.map +1 -0
  85. package/dist/md.node.d.mts +14 -0
  86. package/dist/md.node.d.mts.map +1 -0
  87. package/dist/md.node.mjs +126 -0
  88. package/dist/md.node.mjs.map +1 -0
  89. package/dist/node-BZ7f6HzU.mjs +316 -0
  90. package/dist/node-BZ7f6HzU.mjs.map +1 -0
  91. package/dist/picker-D8OLb6kZ.d.mts +36 -0
  92. package/dist/picker-D8OLb6kZ.d.mts.map +1 -0
  93. package/dist/picker-ndVVt6qF.mjs +621 -0
  94. package/dist/picker-ndVVt6qF.mjs.map +1 -0
  95. package/dist/queries-DH3bj74K.d.mts +1963 -0
  96. package/dist/queries-DH3bj74K.d.mts.map +1 -0
  97. package/dist/reactive-f7NpAi69.mjs +623 -0
  98. package/dist/reactive-f7NpAi69.mjs.map +1 -0
  99. package/dist/registry-U654j61Y.mjs +356 -0
  100. package/dist/registry-U654j61Y.mjs.map +1 -0
  101. package/dist/render-DxVLqqB9.mjs +74 -0
  102. package/dist/render-DxVLqqB9.mjs.map +1 -0
  103. package/dist/renderer-CdLCkJB-.mjs +42 -0
  104. package/dist/renderer-CdLCkJB-.mjs.map +1 -0
  105. package/dist/renderer-CxL4xbkl.mjs +2644 -0
  106. package/dist/renderer-CxL4xbkl.mjs.map +1 -0
  107. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  108. package/dist/search-FvGnswRl.d.mts +49 -0
  109. package/dist/search-FvGnswRl.d.mts.map +1 -0
  110. package/dist/select-CbmAZdpt.d.mts +116 -0
  111. package/dist/select-CbmAZdpt.d.mts.map +1 -0
  112. package/dist/services/logger.d.mts +2 -0
  113. package/dist/services/logger.mjs +71 -0
  114. package/dist/services/logger.mjs.map +1 -0
  115. package/dist/services/notifier.d.mts +17 -0
  116. package/dist/services/notifier.d.mts.map +1 -0
  117. package/dist/services/notifier.mjs +71 -0
  118. package/dist/services/notifier.mjs.map +1 -0
  119. package/dist/services/picker.d.mts +36 -0
  120. package/dist/services/picker.d.mts.map +1 -0
  121. package/dist/services/picker.mjs +137 -0
  122. package/dist/services/picker.mjs.map +1 -0
  123. package/dist/services/prompt.d.mts +30 -0
  124. package/dist/services/prompt.d.mts.map +1 -0
  125. package/dist/services/prompt.mjs +83 -0
  126. package/dist/services/prompt.mjs.map +1 -0
  127. package/dist/shiki-BrjVUkeh.mjs +423 -0
  128. package/dist/shiki-BrjVUkeh.mjs.map +1 -0
  129. package/dist/size-D8JogYLy.mjs +34 -0
  130. package/dist/size-D8JogYLy.mjs.map +1 -0
  131. package/dist/style.d.mts +10 -0
  132. package/dist/style.d.mts.map +1 -0
  133. package/dist/style.mjs +4 -0
  134. package/dist/text.d.mts +33 -0
  135. package/dist/text.d.mts.map +1 -0
  136. package/dist/text.mjs +111 -0
  137. package/dist/text.mjs.map +1 -0
  138. package/dist/theme.config-CU3B50HN.mjs +832 -0
  139. package/dist/theme.config-CU3B50HN.mjs.map +1 -0
  140. package/dist/themes.d.mts +113 -0
  141. package/dist/themes.d.mts.map +1 -0
  142. package/dist/themes.mjs +2 -0
  143. package/dist/tree-C28QOVIK.d.mts +23 -0
  144. package/dist/tree-C28QOVIK.d.mts.map +1 -0
  145. package/dist/types-B9Eh7k2v.d.mts +212 -0
  146. package/dist/types-B9Eh7k2v.d.mts.map +1 -0
  147. package/dist/types-D3jk1rtk.d.mts +140 -0
  148. package/dist/types-D3jk1rtk.d.mts.map +1 -0
  149. package/dist/utils-3M4D_AXZ.mjs +40 -0
  150. package/dist/utils-3M4D_AXZ.mjs.map +1 -0
  151. package/dist/widgets/autocomplete.d.mts +2 -0
  152. package/dist/widgets/autocomplete.mjs +165 -0
  153. package/dist/widgets/autocomplete.mjs.map +1 -0
  154. package/dist/widgets/box.d.mts +2 -0
  155. package/dist/widgets/box.mjs +2 -0
  156. package/dist/widgets/code.d.mts +48 -0
  157. package/dist/widgets/code.d.mts.map +1 -0
  158. package/dist/widgets/code.mjs +59 -0
  159. package/dist/widgets/code.mjs.map +1 -0
  160. package/dist/widgets/completions/actions.d.mts +41 -0
  161. package/dist/widgets/completions/actions.d.mts.map +1 -0
  162. package/dist/widgets/completions/actions.mjs +48 -0
  163. package/dist/widgets/completions/actions.mjs.map +1 -0
  164. package/dist/widgets/completions/files.d.mts +29 -0
  165. package/dist/widgets/completions/files.d.mts.map +1 -0
  166. package/dist/widgets/completions/files.mjs +42 -0
  167. package/dist/widgets/completions/files.mjs.map +1 -0
  168. package/dist/widgets/completions/github.d.mts +64 -0
  169. package/dist/widgets/completions/github.d.mts.map +1 -0
  170. package/dist/widgets/completions/github.mjs +137 -0
  171. package/dist/widgets/completions/github.mjs.map +1 -0
  172. package/dist/widgets/completions/index.d.mts +4 -0
  173. package/dist/widgets/completions/index.mjs +4 -0
  174. package/dist/widgets/diff.d.mts +57 -0
  175. package/dist/widgets/diff.d.mts.map +1 -0
  176. package/dist/widgets/diff.mjs +199 -0
  177. package/dist/widgets/diff.mjs.map +1 -0
  178. package/dist/widgets/divider.d.mts +11 -0
  179. package/dist/widgets/divider.d.mts.map +1 -0
  180. package/dist/widgets/divider.mjs +9 -0
  181. package/dist/widgets/divider.mjs.map +1 -0
  182. package/dist/widgets/image.d.mts +37 -0
  183. package/dist/widgets/image.d.mts.map +1 -0
  184. package/dist/widgets/image.mjs +77 -0
  185. package/dist/widgets/image.mjs.map +1 -0
  186. package/dist/widgets/input.d.mts +2 -0
  187. package/dist/widgets/input.mjs +497 -0
  188. package/dist/widgets/input.mjs.map +1 -0
  189. package/dist/widgets/log.d.mts +2 -0
  190. package/dist/widgets/log.mjs +130 -0
  191. package/dist/widgets/log.mjs.map +1 -0
  192. package/dist/widgets/markdown.d.mts +45 -0
  193. package/dist/widgets/markdown.d.mts.map +1 -0
  194. package/dist/widgets/markdown.mjs +124 -0
  195. package/dist/widgets/markdown.mjs.map +1 -0
  196. package/dist/widgets/overlay.d.mts +2 -0
  197. package/dist/widgets/overlay.mjs +18 -0
  198. package/dist/widgets/overlay.mjs.map +1 -0
  199. package/dist/widgets/picker.d.mts +2 -0
  200. package/dist/widgets/picker.mjs +2 -0
  201. package/dist/widgets/progress.d.mts +48 -0
  202. package/dist/widgets/progress.d.mts.map +1 -0
  203. package/dist/widgets/progress.mjs +48 -0
  204. package/dist/widgets/progress.mjs.map +1 -0
  205. package/dist/widgets/select.d.mts +2 -0
  206. package/dist/widgets/select.mjs +195 -0
  207. package/dist/widgets/select.mjs.map +1 -0
  208. package/dist/widgets/show.d.mts +55 -0
  209. package/dist/widgets/show.d.mts.map +1 -0
  210. package/dist/widgets/show.mjs +85 -0
  211. package/dist/widgets/show.mjs.map +1 -0
  212. package/dist/widgets/spinner.d.mts +65 -0
  213. package/dist/widgets/spinner.d.mts.map +1 -0
  214. package/dist/widgets/spinner.mjs +147 -0
  215. package/dist/widgets/spinner.mjs.map +1 -0
  216. package/dist/widgets/text.d.mts +2 -0
  217. package/dist/widgets/text.mjs +32 -0
  218. package/dist/widgets/text.mjs.map +1 -0
  219. package/dist/widgets/tree.d.mts +2 -0
  220. package/dist/widgets/tree.mjs +73 -0
  221. package/dist/widgets/tree.mjs.map +1 -0
  222. package/dist/widgets/widget.d.mts +49 -0
  223. package/dist/widgets/widget.d.mts.map +1 -0
  224. package/dist/widgets/widget.mjs +40 -0
  225. package/dist/widgets/widget.mjs.map +1 -0
  226. package/dist/worker-DjHuQSbY.mjs +27 -0
  227. package/dist/worker-DjHuQSbY.mjs.map +1 -0
  228. package/package.json +117 -0
@@ -0,0 +1,116 @@
1
+ import { Nt as Size, P as RenderCtx, X as State, f as BaseEvents, nt as Reactive, p as Node, rt as Ref } from "./queries-DH3bj74K.mjs";
2
+ import { f as Style } from "./types-B9Eh7k2v.mjs";
3
+ //#region src/widgets/select.d.ts
4
+ /** Default shape for selectable options. `text` is the canonical
5
+ * searchable/fallback label. `name` overrides the displayed label in the
6
+ * default renderer, and `desc` is shown as a dim right-column description. */
7
+ type Option = {
8
+ name?: string;
9
+ desc?: string;
10
+ text: string;
11
+ };
12
+ type OptionRenderCtx<T> = RenderCtx & {
13
+ visible: readonly T[];
14
+ items: readonly T[];
15
+ active?: boolean;
16
+ prefixWidth?: number;
17
+ };
18
+ /** Per-row rendering hook. `ctx.active` lets callers branch on selection
19
+ * state (e.g. swap an icon or pick a different fg) — but Select still
20
+ * applies the `optionActive` theme slot uniformly so the highlight stays
21
+ * visually consistent. The returned string is clipped/padded to the row
22
+ * width by Select. */
23
+ type OptionRender<T> = (item: T, ctx: OptionRenderCtx<T>) => string;
24
+ interface SelectState<T extends Option = Option> extends Style {
25
+ /** Items to show. Accepts a signal accessor so the list can be
26
+ * driven from reactive state (filtered results, search, etc.). */
27
+ items: Reactive<readonly T[]>;
28
+ /** Index of the highlighted row. Defaults to 0; clamped on render. */
29
+ active?: number;
30
+ /** Max item rows visible at once. The counter (when shown) is an
31
+ * extra row on top of this, not counted against the cap. Window
32
+ * slides to keep `active` in view (pin-until-leave). */
33
+ maxHeight?: Reactive<number>;
34
+ /** Show a `(active+1 / total)` footer as an extra row when items
35
+ * don't fit. `undefined` (default) auto-shows when needed;
36
+ * `false` disables, `true` forces on. */
37
+ counter?: boolean;
38
+ /** Render width. Defaults to `fill`. */
39
+ width?: Size;
40
+ /** Width of the label column for the default renderer. Defaults to the
41
+ * widest visible label, capped to half the row width. Ignored when
42
+ * `render` is set. */
43
+ labelWidth?: number;
44
+ /** Per-item renderer. When omitted, the default two-column layout uses
45
+ * `name ?? text` as the label and `desc` as the right-column hint. */
46
+ render?: Reactive<OptionRender<T> | undefined>;
47
+ reverse?: boolean;
48
+ /** Whether there are more items available than are currently shown. This is a hint for the
49
+ * default renderer to show a "more" indicator in the counter. */
50
+ more?: boolean;
51
+ }
52
+ interface SelectEvents<T extends Option = Option> extends BaseEvents {
53
+ /** Fired when the user completes the active item. Payload is the item. */
54
+ complete: {
55
+ item: T;
56
+ };
57
+ /** Fired when the user picks the active item. Payload is the item. */
58
+ accept: {
59
+ item: T;
60
+ };
61
+ /** Fired when the user closes the select (esc). */
62
+ close: {};
63
+ changed: {
64
+ active: number;
65
+ item?: T;
66
+ };
67
+ }
68
+ /**
69
+ * Selectable list. Items are rendered one per row with an active-row
70
+ * highlight; navigation actions (`next`, `prev`, `first`, `last`,
71
+ * `accept`, `complete`, `cancel`) live on `this.actions`, same pattern as
72
+ * `Input`.
73
+ *
74
+ * Used standalone for simple lists and as the underlying list primitive for
75
+ * `picker`, `tree`, and `autocomplete`. Doesn't open/close itself — callers
76
+ * control visibility via `state.visible`.
77
+ */
78
+ declare class Select<T extends Option = Option> extends Node<SelectState<T>, SelectEvents<T>> {
79
+ #private;
80
+ static readonly type = "select";
81
+ readonly type = "select";
82
+ actions: {
83
+ "select.accept": () => void;
84
+ "select.close": () => void;
85
+ "select.complete": () => void;
86
+ "select.first": () => void;
87
+ "select.last": () => void;
88
+ "select.next": () => void;
89
+ "select.page-down": () => void;
90
+ "select.page-up": () => void;
91
+ "select.prev": () => void;
92
+ };
93
+ constructor(initial: SelectState<T>);
94
+ set active(i: number);
95
+ get active(): number;
96
+ bind(node: Node | Ref<Node>): this;
97
+ get count(): number;
98
+ get pageSize(): number;
99
+ get item(): T | undefined;
100
+ protected _render(ctx: RenderCtx): string[];
101
+ get renderer(): OptionRender<T>;
102
+ extendRenderer(fn: (prev: OptionRender<T>) => OptionRender<T>): this;
103
+ defaultRenderer(): OptionRender<Option>;
104
+ }
105
+ /**
106
+ * Factory for a selectable list.
107
+ *
108
+ * ```ts
109
+ * const s = select({ items: [{ text: "/help" }, { text: "/quit" }] })
110
+ * s.on("accept", ({ item }) => console.log("picked", item.text))
111
+ * ```
112
+ */
113
+ declare function select<T extends Option = Option>(state: State<SelectState<T>>): Select<T>;
114
+ //#endregion
115
+ export { SelectEvents as a, Select as i, OptionRender as n, SelectState as o, OptionRenderCtx as r, select as s, Option as t };
116
+ //# sourceMappingURL=select-CbmAZdpt.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-CbmAZdpt.d.mts","names":[],"sources":["../src/widgets/select.ts"],"mappings":";;;;;;KAgBY;EACV;EACA;EACA;;KAGU,gBAAgB,KAAK;EAC/B,kBAAkB;EAClB,gBAAgB;EAChB;EACA;;;;;;;KAQU,aAAa,MAAM,MAAM,GAAG,KAAK,gBAAgB;UAE5C,YAAY,UAAU,SAAS,gBAAgB;;;EAG9D,OAAO,kBAAkB;;EAEzB;;;;EAIA,YAAY;;;;EAIZ;;EAEA,QAAQ;;;;EAIR;;;EAGA,SAAS,SAAS,aAAa;EAC/B;;;EAGA;;UAGe,aAAa,UAAU,SAAS,gBAAgB;;EAE/D;IAAY,MAAM;;;EAElB;IAAU,MAAM;;;EAEhB;EACA;IAAW;IAAgB,OAAO;;;;;;;;;;;;;cAavB,OAAO,UAAU,SAAS,gBAAgB,KAAK,YAAY,IAAI,aAAa;;kBACvE;WACE;EAET;;;;;;;;;;;EAqDT,YAAY,SAAS,YAAY;MAyB7B,OAAO;MAKP;EAOJ,KAAK,MAAM,OAAO,IAAI;MASlB;MAIA;MAIA,QAAQ;YAIF,QAAQ,KAAK;MA2CnB,YAAY,aAAa;EAI7B,eAAe,KAAK,MAAM,aAAa,OAAO,aAAa;EAM3D,mBAAmB,aAAa;;;;;;;;;;iBAmClB,OAAO,UAAU,SAAS,QAAQ,OAAO,MAAM,YAAY,MAAM,OAAO"}
@@ -0,0 +1,2 @@
1
+ import { D as LoggerStream, E as LogStyleOverride, O as TuiReporter, T as LogEntryFactory, k as TuiReporterOpts } from "../queries-DH3bj74K.mjs";
2
+ export { LogEntryFactory, LogStyleOverride, LoggerStream, TuiReporter, TuiReporterOpts };
@@ -0,0 +1,71 @@
1
+ import { t as Node } from "../node-BZ7f6HzU.mjs";
2
+ import { n as inspectFormat, r as isMarkdown } from "../inspect-D1d9t-ni.mjs";
3
+ import { log } from "../widgets/log.mjs";
4
+ //#region src/services/logger.ts
5
+ const ERR_LEVELS = /* @__PURE__ */ new Set([
6
+ "error",
7
+ "fatal",
8
+ "warn"
9
+ ]);
10
+ function defaultWrite(text, kind) {
11
+ if (typeof process === "undefined") return;
12
+ (kind === "stderr" ? process.stderr : process.stdout).write(text);
13
+ }
14
+ var TuiReporter = class {
15
+ #stream;
16
+ #opts;
17
+ #factory;
18
+ constructor(opts = {}) {
19
+ this.#opts = opts;
20
+ this.#factory = opts.factory ?? ((level, msg) => this.#defaultFactory(level, msg));
21
+ }
22
+ attach(stream) {
23
+ this.#stream = stream;
24
+ return this;
25
+ }
26
+ detach() {
27
+ this.#stream = void 0;
28
+ return this;
29
+ }
30
+ $log({ level, msg }) {
31
+ if (this.#stream) {
32
+ this.#stream.append(() => {
33
+ const node = this.#factory(level, msg);
34
+ return this.#opts.wrap?.(node) ?? node;
35
+ });
36
+ return;
37
+ }
38
+ this.#writeFallback(level, msg);
39
+ }
40
+ #defaultFactory(level, msg) {
41
+ const nodes = msg.filter((m) => m instanceof Node);
42
+ msg = msg.filter((m) => !(m instanceof Node));
43
+ msg = this.#opts.stacktrace ? msg : msg.map((v) => v instanceof Error ? v.message : v);
44
+ if (msg.length && msg.every((m) => typeof m === "string")) msg = [msg.join(" ")];
45
+ let text = msg.length === 1 && typeof msg[0] === "string" ? msg[0] : void 0;
46
+ if (msg.length === 0) text = "";
47
+ const markdown = (this.#opts.markdown ?? true) && text !== void 0 && isMarkdown(text);
48
+ const overrides = this.#opts.styles?.[level] ?? {};
49
+ return log({
50
+ content: text ?? ((ctx) => inspectFormat(msg, {
51
+ ...this.#opts,
52
+ style: ctx.style
53
+ })),
54
+ level,
55
+ markdown,
56
+ ...overrides
57
+ }, ...nodes);
58
+ }
59
+ /** String path for the no-stream fallback — builds a plain inspected
60
+ * line (no prefix chrome) and writes it to stdout/stderr. Keeps the
61
+ * fallback synchronous and ordered. */
62
+ #writeFallback(level, msg) {
63
+ const str = inspectFormat(msg, this.#opts);
64
+ const kind = ERR_LEVELS.has(level) ? "stderr" : "stdout";
65
+ (this.#opts.write ?? defaultWrite)(`${str}\n`, kind);
66
+ }
67
+ };
68
+ //#endregion
69
+ export { TuiReporter };
70
+
71
+ //# sourceMappingURL=logger.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.mjs","names":["#opts","#factory","#defaultFactory","#stream","#writeFallback"],"sources":["../../src/services/logger.ts"],"sourcesContent":["import type { LogEntry, LogLevel, LogReporter } from \"@zaly/shared/logger\"\nimport type { InspectOpts } from \"../style/inspect.ts\"\nimport type { LogState } from \"../widgets/log.ts\"\n\nimport { Node } from \"../core/node.ts\"\nimport { inspectFormat, isMarkdown } from \"../style/inspect.ts\"\nimport { log } from \"../widgets/log.ts\"\n\n/** Minimal stream surface the logger needs. Stream satisfies this. */\nexport interface LoggerStream {\n append: (node: () => Node) => unknown\n}\n\nexport type LogEntryFactory = (level: LogLevel, msg: unknown[]) => Node\n\nexport type LogStyleOverride = Omit<LogState, \"level\" | \"content\">\n\nexport interface TuiReporterOpts extends InspectOpts {\n /** Render string messages as markdown when they look like it.\n * Default: `true`. */\n markdown?: boolean\n /** Per-level overrides for the default `log()` widget style fields. */\n styles?: Partial<Record<LogLevel, LogStyleOverride>>\n /** Override the node produced per entry. Default uses `log()`. */\n factory?: LogEntryFactory\n wrap?: (node: Node) => Node\n /** Fallback writer for when no stream is attached. Defaults to\n * `process.stdout/stderr`. Injectable for tests. */\n write?: (text: string, kind: \"stdout\" | \"stderr\") => void\n}\n\nconst ERR_LEVELS = new Set<LogLevel>([\"error\", \"fatal\", \"warn\"])\n\nfunction defaultWrite(text: string, kind: \"stdout\" | \"stderr\"): void {\n if (typeof process === \"undefined\") return\n const stream = kind === \"stderr\" ? process.stderr : process.stdout\n stream.write(text)\n}\n\nexport class TuiReporter implements LogReporter {\n #stream?: LoggerStream\n #opts: TuiReporterOpts\n #factory: LogEntryFactory\n\n constructor(opts: TuiReporterOpts = {}) {\n this.#opts = opts\n this.#factory = opts.factory ?? ((level, msg) => this.#defaultFactory(level, msg))\n }\n\n attach(stream: LoggerStream): this {\n this.#stream = stream\n return this\n }\n\n detach(): this {\n this.#stream = undefined\n return this\n }\n\n $log({ level, msg }: LogEntry): void {\n if (this.#stream) {\n this.#stream.append(() => {\n const node = this.#factory(level, msg)\n return this.#opts.wrap?.(node) ?? node\n })\n return\n }\n this.#writeFallback(level, msg)\n }\n\n #defaultFactory(level: LogLevel, msg: unknown[]): Node {\n const nodes = msg.filter((m): m is Node => m instanceof Node)\n msg = msg.filter((m) => !(m instanceof Node))\n\n // Convert Error objects to their message unless stacktrace is requested.\n msg = this.#opts.stacktrace ? msg : msg.map((v) => (v instanceof Error ? v.message : v))\n\n // If all remaining messages are strings, join them into one string for the log content.\n if (msg.length && msg.every((m) => typeof m === \"string\")) msg = [msg.join(\" \")]\n\n // If there's exactly one string message, use it as the log content;\n // otherwise, leave it undefined to be formatted with `inspect()`.\n // Text allow markdown if the message looks like markdown and the option is enabled.\n let text = msg.length === 1 && typeof msg[0] === \"string\" ? msg[0] : undefined\n if (msg.length === 0) text = \"\"\n const markdown = (this.#opts.markdown ?? true) && text !== undefined && isMarkdown(text)\n const overrides = this.#opts.styles?.[level] ?? {}\n return log(\n {\n content: text ?? ((ctx) => inspectFormat(msg, { ...this.#opts, style: ctx.style })),\n level,\n markdown,\n ...overrides,\n },\n ...nodes\n )\n }\n\n /** String path for the no-stream fallback — builds a plain inspected\n * line (no prefix chrome) and writes it to stdout/stderr. Keeps the\n * fallback synchronous and ordered. */\n #writeFallback(level: LogLevel, msg: unknown[]): void {\n const str = inspectFormat(msg, this.#opts)\n const kind: \"stdout\" | \"stderr\" = ERR_LEVELS.has(level) ? \"stderr\" : \"stdout\"\n const write = this.#opts.write ?? defaultWrite\n write(`${str}\\n`, kind)\n }\n}\n"],"mappings":";;;;AA+BA,MAAM,6BAAa,IAAI,IAAc;CAAC;CAAS;CAAS;AAAM,CAAC;AAE/D,SAAS,aAAa,MAAc,MAAiC;CACnE,IAAI,OAAO,YAAY,aAAa;CAEpC,CADe,SAAS,WAAW,QAAQ,SAAS,QAAQ,OAAA,CACrD,MAAM,IAAI;AACnB;AAEA,IAAa,cAAb,MAAgD;CAC9C;CACA;CACA;CAEA,YAAY,OAAwB,CAAC,GAAG;EACtC,KAAKA,QAAQ;EACb,KAAKC,WAAW,KAAK,aAAa,OAAO,QAAQ,KAAKC,gBAAgB,OAAO,GAAG;CAClF;CAEA,OAAO,QAA4B;EACjC,KAAKC,UAAU;EACf,OAAO;CACT;CAEA,SAAe;EACb,KAAKA,UAAU,KAAA;EACf,OAAO;CACT;CAEA,KAAK,EAAE,OAAO,OAAuB;EACnC,IAAI,KAAKA,SAAS;GAChB,KAAKA,QAAQ,aAAa;IACxB,MAAM,OAAO,KAAKF,SAAS,OAAO,GAAG;IACrC,OAAO,KAAKD,MAAM,OAAO,IAAI,KAAK;GACpC,CAAC;GACD;EACF;EACA,KAAKI,eAAe,OAAO,GAAG;CAChC;CAEA,gBAAgB,OAAiB,KAAsB;EACrD,MAAM,QAAQ,IAAI,QAAQ,MAAiB,aAAa,IAAI;EAC5D,MAAM,IAAI,QAAQ,MAAM,EAAE,aAAa,KAAK;EAG5C,MAAM,KAAKJ,MAAM,aAAa,MAAM,IAAI,KAAK,MAAO,aAAa,QAAQ,EAAE,UAAU,CAAE;EAGvF,IAAI,IAAI,UAAU,IAAI,OAAO,MAAM,OAAO,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC;EAK/E,IAAI,OAAO,IAAI,WAAW,KAAK,OAAO,IAAI,OAAO,WAAW,IAAI,KAAK,KAAA;EACrE,IAAI,IAAI,WAAW,GAAG,OAAO;EAC7B,MAAM,YAAY,KAAKA,MAAM,YAAY,SAAS,SAAS,KAAA,KAAa,WAAW,IAAI;EACvF,MAAM,YAAY,KAAKA,MAAM,SAAS,UAAU,CAAC;EACjD,OAAO,IACL;GACE,SAAS,UAAU,QAAQ,cAAc,KAAK;IAAE,GAAG,KAAKA;IAAO,OAAO,IAAI;GAAM,CAAC;GACjF;GACA;GACA,GAAG;EACL,GACA,GAAG,KACL;CACF;;;;CAKA,eAAe,OAAiB,KAAsB;EACpD,MAAM,MAAM,cAAc,KAAK,KAAKA,KAAK;EACzC,MAAM,OAA4B,WAAW,IAAI,KAAK,IAAI,WAAW;EAErE,CADc,KAAKA,MAAM,SAAS,aAAA,CAC5B,GAAG,IAAI,KAAK,IAAI;CACxB;AACF"}
@@ -0,0 +1,17 @@
1
+ import { A as LogState, C as OverlaySurface, F as Overlay, nt as Reactive } from "../queries-DH3bj74K.mjs";
2
+ import { LogLevel } from "@zaly/shared/logger";
3
+ //#region src/services/notifier.d.ts
4
+ type NotifProps = Omit<LogState, "content" | "level"> & {
5
+ level?: LogLevel;
6
+ timeout?: number;
7
+ keep?: () => boolean;
8
+ onClose?: () => void;
9
+ };
10
+ declare class Notifier {
11
+ #private;
12
+ constructor(ui: OverlaySurface);
13
+ notify(msg: Reactive<string>, opts?: NotifProps): Overlay;
14
+ }
15
+ //#endregion
16
+ export { NotifProps, Notifier };
17
+ //# sourceMappingURL=notifier.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifier.d.mts","names":[],"sources":["../../src/services/notifier.ts"],"mappings":";;;KAUY,aAAa,KAAK;EAC5B,QAAQ;EACR;EACA;EACA;;cASW;;EAKX,YAAY,IAAI;EAmDhB,OAAO,KAAK,kBAAkB,OAAO,aAAa"}
@@ -0,0 +1,71 @@
1
+ import { log } from "../widgets/log.mjs";
2
+ import { overlay } from "../widgets/overlay.mjs";
3
+ //#region src/services/notifier.ts
4
+ var Notifier = class {
5
+ #ui;
6
+ #active = /* @__PURE__ */ new Map();
7
+ #queue = [];
8
+ constructor(ui) {
9
+ this.#ui = ui;
10
+ ui.on("render-node", (state) => {
11
+ const notif = this.#active.get(state.node);
12
+ if (!notif) return;
13
+ notif.state = state;
14
+ setImmediate(() => this.#check());
15
+ });
16
+ }
17
+ #notif(msg, opts) {
18
+ return overlay({
19
+ padding: [0, 0],
20
+ width: 40,
21
+ x: -40,
22
+ y: 1,
23
+ zIndex: 1e3
24
+ }, log({
25
+ level: "info",
26
+ ...opts,
27
+ content: msg,
28
+ style: "notif"
29
+ }));
30
+ }
31
+ #start(notif) {
32
+ this.#active.set(notif.node, notif);
33
+ notif.node.state.visible = true;
34
+ const t = setInterval(() => {
35
+ if (notif.opts?.keep?.()) return;
36
+ clearInterval(t);
37
+ this.#active.delete(notif.node);
38
+ this.#ui.close(notif.node);
39
+ notif.opts?.onClose?.();
40
+ this.#check();
41
+ }, notif.opts?.timeout ?? 3e3);
42
+ t.unref();
43
+ }
44
+ #check() {
45
+ while (this.#queue.length) {
46
+ const termHeight = this.#ui.$r.terminal.rows;
47
+ let y = 2;
48
+ for (const n of this.#active.values()) {
49
+ if (!n.state) return;
50
+ y = Math.max(y, n.state.y + n.state.height + 1);
51
+ }
52
+ if (termHeight - y < 10) return;
53
+ const next = this.#queue.shift();
54
+ next.node.state.y = y;
55
+ this.#start(next);
56
+ }
57
+ }
58
+ notify(msg, opts) {
59
+ const node = this.#ui.add(() => this.#notif(msg, opts));
60
+ this.#queue.push({
61
+ node,
62
+ opts
63
+ });
64
+ setImmediate(() => this.#check());
65
+ return node;
66
+ }
67
+ };
68
+ //#endregion
69
+ export { Notifier };
70
+
71
+ //# sourceMappingURL=notifier.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifier.mjs","names":["#ui","#active","#check","#queue","#start","#notif"],"sources":["../../src/services/notifier.ts"],"sourcesContent":["import type { LogLevel } from \"@zaly/shared/logger\"\nimport type { Node } from \"../core/node.ts\"\nimport type { Reactive } from \"../core/reactive.ts\"\nimport type { OverlayRenderState, OverlaySurface } from \"../renderer/overlay.ts\"\nimport type { LogState } from \"../widgets/log.ts\"\nimport type { Overlay } from \"../widgets/overlay.ts\"\n\nimport { log } from \"../widgets/log.ts\"\nimport { overlay } from \"../widgets/overlay.ts\"\n\nexport type NotifProps = Omit<LogState, \"content\" | \"level\"> & {\n level?: LogLevel\n timeout?: number\n keep?: () => boolean\n onClose?: () => void\n}\n\ntype Notif = {\n node: Overlay\n opts?: NotifProps\n state?: OverlayRenderState\n}\n\nexport class Notifier {\n #ui: OverlaySurface\n #active = new Map<Node, Notif>()\n #queue: Notif[] = []\n\n constructor(ui: OverlaySurface) {\n this.#ui = ui\n ui.on(\"render-node\", (state) => {\n const notif = this.#active.get(state.node)\n if (!notif) return\n notif.state = state\n setImmediate(() => this.#check())\n })\n }\n\n #notif(msg: Reactive<string>, opts?: NotifProps) {\n return overlay(\n { padding: [0, 0], width: 40, x: -40, y: 1, zIndex: 1000 },\n log({\n level: \"info\",\n ...opts,\n content: msg,\n style: \"notif\",\n })\n )\n }\n\n #start(notif: Notif) {\n this.#active.set(notif.node, notif)\n notif.node.state.visible = true\n const t = setInterval(() => {\n if (notif.opts?.keep?.()) return\n clearInterval(t)\n this.#active.delete(notif.node)\n this.#ui.close(notif.node)\n notif.opts?.onClose?.()\n this.#check()\n }, notif.opts?.timeout ?? 3000)\n t.unref()\n }\n\n #check() {\n while (this.#queue.length) {\n const termHeight = this.#ui.$r.terminal.rows\n let y = 2\n for (const n of this.#active.values()) {\n if (!n.state) return // wait till it renders\n y = Math.max(y, n.state.y + n.state.height + 1)\n }\n if (termHeight - y < 10) return // Don't start if less than 10 rows remain below the last notif\n const next = this.#queue.shift()!\n next.node.state.y = y\n this.#start(next)\n }\n }\n\n notify(msg: Reactive<string>, opts?: NotifProps): Overlay {\n const node = this.#ui.add(() => this.#notif(msg, opts))\n this.#queue.push({ node, opts })\n setImmediate(() => this.#check())\n return node\n }\n}\n"],"mappings":";;;AAuBA,IAAa,WAAb,MAAsB;CACpB;CACA,0BAAU,IAAI,IAAiB;CAC/B,SAAkB,CAAC;CAEnB,YAAY,IAAoB;EAC9B,KAAKA,MAAM;EACX,GAAG,GAAG,gBAAgB,UAAU;GAC9B,MAAM,QAAQ,KAAKC,QAAQ,IAAI,MAAM,IAAI;GACzC,IAAI,CAAC,OAAO;GACZ,MAAM,QAAQ;GACd,mBAAmB,KAAKC,OAAO,CAAC;EAClC,CAAC;CACH;CAEA,OAAO,KAAuB,MAAmB;EAC/C,OAAO,QACL;GAAE,SAAS,CAAC,GAAG,CAAC;GAAG,OAAO;GAAI,GAAG;GAAK,GAAG;GAAG,QAAQ;EAAK,GACzD,IAAI;GACF,OAAO;GACP,GAAG;GACH,SAAS;GACT,OAAO;EACT,CAAC,CACH;CACF;CAEA,OAAO,OAAc;EACnB,KAAKD,QAAQ,IAAI,MAAM,MAAM,KAAK;EAClC,MAAM,KAAK,MAAM,UAAU;EAC3B,MAAM,IAAI,kBAAkB;GAC1B,IAAI,MAAM,MAAM,OAAO,GAAG;GAC1B,cAAc,CAAC;GACf,KAAKA,QAAQ,OAAO,MAAM,IAAI;GAC9B,KAAKD,IAAI,MAAM,MAAM,IAAI;GACzB,MAAM,MAAM,UAAU;GACtB,KAAKE,OAAO;EACd,GAAG,MAAM,MAAM,WAAW,GAAI;EAC9B,EAAE,MAAM;CACV;CAEA,SAAS;EACP,OAAO,KAAKC,OAAO,QAAQ;GACzB,MAAM,aAAa,KAAKH,IAAI,GAAG,SAAS;GACxC,IAAI,IAAI;GACR,KAAK,MAAM,KAAK,KAAKC,QAAQ,OAAO,GAAG;IACrC,IAAI,CAAC,EAAE,OAAO;IACd,IAAI,KAAK,IAAI,GAAG,EAAE,MAAM,IAAI,EAAE,MAAM,SAAS,CAAC;GAChD;GACA,IAAI,aAAa,IAAI,IAAI;GACzB,MAAM,OAAO,KAAKE,OAAO,MAAM;GAC/B,KAAK,KAAK,MAAM,IAAI;GACpB,KAAKC,OAAO,IAAI;EAClB;CACF;CAEA,OAAO,KAAuB,MAA4B;EACxD,MAAM,OAAO,KAAKJ,IAAI,UAAU,KAAKK,OAAO,KAAK,IAAI,CAAC;EACtD,KAAKF,OAAO,KAAK;GAAE;GAAM;EAAK,CAAC;EAC/B,mBAAmB,KAAKD,OAAO,CAAC;EAChC,OAAO;CACT;AACF"}
@@ -0,0 +1,36 @@
1
+ import { C as OverlaySurface, F as Overlay, Lt as ActionFilter, Q as Accessor, nt as Reactive, rt as Ref } from "../queries-DH3bj74K.mjs";
2
+ import { t as Input } from "../input-B5Vy-iaa.mjs";
3
+ import { i as Select, t as Option } from "../select-CbmAZdpt.mjs";
4
+ import { i as PickerTreeProps, n as PickerItem, r as PickerSelectProps } from "../picker-D8OLb6kZ.mjs";
5
+ import { Widget } from "../widgets/widget.mjs";
6
+ //#region src/services/picker.d.ts
7
+ type ToggleItem = PickerItem & {
8
+ enabled?: boolean;
9
+ };
10
+ type PickOpts<T extends Option = Option> = {
11
+ title?: Reactive<string>;
12
+ multi?: boolean | {
13
+ action?: boolean;
14
+ render?: boolean;
15
+ };
16
+ ref?: Ref<Select<T>>;
17
+ details?: Widget | string;
18
+ clearInput?: boolean;
19
+ restoreInput?: boolean;
20
+ whichKey?: boolean | ActionFilter;
21
+ } & (Omit<PickerSelectProps<T>, "input"> | Omit<PickerTreeProps<T>, "input">);
22
+ declare class Picker {
23
+ #private;
24
+ constructor(ui: OverlaySurface, input: Input);
25
+ get isOpen(): Accessor<boolean>;
26
+ close(opts?: {
27
+ all?: boolean;
28
+ }): void;
29
+ get active(): Overlay | undefined;
30
+ suspend(): void;
31
+ resume(): void;
32
+ pick<T extends Option = Option>(opts: PickOpts<T>): Promise<T | undefined>;
33
+ }
34
+ //#endregion
35
+ export { PickOpts, Picker, ToggleItem };
36
+ //# sourceMappingURL=picker.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker.d.mts","names":[],"sources":["../../src/services/picker.ts"],"mappings":";;;;;;KAkBY,aAAa;EAAe;;KAE5B,SAAS,UAAU,SAAS;EACtC,QAAQ;EACR;IAAoB;IAAkB;;EACtC,MAAM,IAAI,OAAO;EACjB,UAAU;EACV;EACA;EACA,qBAAqB;KAClB,KAAK,kBAAkB,eAAe,KAAK,gBAAgB;cAEnD;;EAMX,YAAY,IAAI,gBAAgB,OAAO;MAKnC,UALmC;EAyFvC,MAAM;IAAQ;;MAQV,UAAM;EAIV;EAIA;EAIM,KAAK,UAAU,SAAS,QAAQ,MAAM,SAAS,KAAK,QAAQ"}
@@ -0,0 +1,137 @@
1
+ import { c as createRef, y as signal } from "../reactive-f7NpAi69.mjs";
2
+ import { r as isMarkdown } from "../inspect-D1d9t-ni.mjs";
3
+ import { text } from "../widgets/text.mjs";
4
+ import { markdown } from "../widgets/markdown.mjs";
5
+ import { overlay } from "../widgets/overlay.mjs";
6
+ import { divider } from "../widgets/divider.mjs";
7
+ import { t as picker } from "../picker-ndVVt6qF.mjs";
8
+ //#region src/services/picker.ts
9
+ var Picker = class {
10
+ #ui;
11
+ #input;
12
+ #open = signal(false);
13
+ #active = [];
14
+ constructor(ui, input) {
15
+ this.#ui = ui;
16
+ this.#input = input;
17
+ }
18
+ get isOpen() {
19
+ return this.#open.get;
20
+ }
21
+ #pick(opts) {
22
+ const children = [];
23
+ if (opts.title) children.push(markdown(opts.title, { style: "borderTitle" }));
24
+ if (opts.details) if (typeof opts.details === "string") children.push(isMarkdown(opts.details) ? markdown(opts.details) : text(opts.details));
25
+ else children.push(opts.details());
26
+ const select = picker({
27
+ maxHeight: 8,
28
+ ...opts
29
+ });
30
+ select.ref(opts.ref);
31
+ if (opts.multi) this.#multi(select, opts.multi === true ? {} : opts.multi);
32
+ const wk = this.#whichKey(select, opts.whichKey);
33
+ if (wk) children.push(wk);
34
+ if (children.length > 0) children.push(divider({ style: "border" }));
35
+ return overlay({
36
+ padding: [0, 1],
37
+ relative: "ui",
38
+ style: "ui",
39
+ verticalAnchor: "bottom",
40
+ x: 0,
41
+ y: 1
42
+ }, divider({ style: "accent" }), ...children, select);
43
+ }
44
+ #whichKey(select, opts) {
45
+ if (opts === false || opts === void 0) return;
46
+ const filter = opts === true ? { hidden: false } : opts;
47
+ const ret = text((ctx) => {
48
+ const s = ctx.style;
49
+ const bo = s.syntaxDelimiter.dim("<");
50
+ const bc = s.syntaxDelimiter.dim(">");
51
+ return this.#ui.$r.actions.whichKey(select, { filter }).map((a) => {
52
+ const name = s.muted(a.desc ?? a.cmd ?? a.id);
53
+ return `${a.keys.map((k) => bo + s.syntaxSpecial.dim(k) + bc).join(s.delim.dim("/"))} ${name.toLowerCase()}`;
54
+ }).join(s.delim(" • "));
55
+ });
56
+ select.once("mount", () => ret.invalidate());
57
+ return ret;
58
+ }
59
+ #multi(select, opts = {}) {
60
+ if (opts.render !== false) select.extendRenderer((prev) => (item, ctx) => {
61
+ const s = ctx.style;
62
+ const row = prev(item, {
63
+ ...ctx,
64
+ width: ctx.width - 4
65
+ });
66
+ const enabled = item.enabled;
67
+ if (enabled === void 0) return row;
68
+ return `${enabled ? s.mdListChecked("[x]") : s.mdListUnchecked("[ ]")} ${row}`;
69
+ });
70
+ if (opts.action !== false) select.withActions({ "picker.toggle": {
71
+ desc: "Toggle item",
72
+ fn: () => {
73
+ const active = select.item;
74
+ if (!active) return;
75
+ active.enabled = !active.enabled;
76
+ select.invalidate();
77
+ },
78
+ keys: ["tab", "enter"],
79
+ priority: 10
80
+ } });
81
+ }
82
+ close(opts = {}) {
83
+ while (this.#active.length > 0) {
84
+ const node = this.#active.pop();
85
+ this.#ui.close(node);
86
+ if (!opts.all) break;
87
+ }
88
+ }
89
+ get active() {
90
+ return this.#active.at(-1);
91
+ }
92
+ suspend() {
93
+ this.active?.hide();
94
+ }
95
+ resume() {
96
+ this.active?.show();
97
+ }
98
+ async pick(opts) {
99
+ this.active?.hide();
100
+ const res = Promise.withResolvers();
101
+ let settled = false;
102
+ const clear = opts.clearInput ?? true;
103
+ const restore = opts.restoreInput ?? true;
104
+ const prevInput = clear ? this.#input.consume().value : void 0;
105
+ const ref = opts.ref ?? createRef();
106
+ const node = this.#ui.open(() => this.#pick({
107
+ ...opts,
108
+ input: this.#input,
109
+ ref
110
+ }));
111
+ this.#active.push(node);
112
+ this.#open.set(true);
113
+ const select = ref();
114
+ const ac = new AbortController();
115
+ const done = (value) => {
116
+ if (settled) return;
117
+ settled = true;
118
+ ac.abort();
119
+ this.#active = this.#active.filter((n) => n !== node);
120
+ if (restore && prevInput !== void 0) this.#input.replace(prevInput);
121
+ else if (!restore) this.#input.consume();
122
+ res.resolve(value);
123
+ this.#ui.close(node);
124
+ this.active?.show();
125
+ this.#open.set(this.#active.length > 0);
126
+ };
127
+ node.once("unmount", () => done(), { signal: ac.signal });
128
+ select.once("close", () => done(), { signal: ac.signal });
129
+ select.once("accept", ({ item }) => done(item), { signal: ac.signal });
130
+ select.once("complete", ({ item }) => done(item), { signal: ac.signal });
131
+ return res.promise;
132
+ }
133
+ };
134
+ //#endregion
135
+ export { Picker };
136
+
137
+ //# sourceMappingURL=picker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker.mjs","names":["#ui","#input","#open","#multi","#whichKey","#active","#pick"],"sources":["../../src/services/picker.ts"],"sourcesContent":["import type { Node } from \"../core/node.ts\"\nimport type { Reactive, Ref } from \"../core/reactive.ts\"\nimport type { ActionFilter } from \"../input/actions.ts\"\nimport type { OverlaySurface } from \"../renderer/overlay.ts\"\nimport type { Input } from \"../widgets/input.ts\"\nimport type { Overlay } from \"../widgets/overlay.ts\"\nimport type { PickerItem, PickerSelectProps, PickerTreeProps } from \"../widgets/picker.ts\"\nimport type { Option, Select } from \"../widgets/select.ts\"\nimport type { Widget } from \"../widgets/widget.ts\"\n\nimport { createRef, signal } from \"../core/reactive.ts\"\nimport { isMarkdown } from \"../style/inspect.ts\"\nimport { divider } from \"../widgets/divider.ts\"\nimport { markdown } from \"../widgets/markdown.ts\"\nimport { overlay } from \"../widgets/overlay.ts\"\nimport { picker } from \"../widgets/picker.ts\"\nimport { text } from \"../widgets/text.ts\"\n\nexport type ToggleItem = PickerItem & { enabled?: boolean }\n\nexport type PickOpts<T extends Option = Option> = {\n title?: Reactive<string>\n multi?: boolean | { action?: boolean; render?: boolean }\n ref?: Ref<Select<T>>\n details?: Widget | string\n clearInput?: boolean\n restoreInput?: boolean\n whichKey?: boolean | ActionFilter\n} & (Omit<PickerSelectProps<T>, \"input\"> | Omit<PickerTreeProps<T>, \"input\">)\n\nexport class Picker {\n #ui: OverlaySurface\n #input: Input\n #open = signal(false)\n #active: Overlay[] = []\n\n constructor(ui: OverlaySurface, input: Input) {\n this.#ui = ui\n this.#input = input\n }\n\n get isOpen() {\n return this.#open.get\n }\n\n #pick<T extends Option = Option>(\n opts: PickOpts<T> & { input: Input; ref: Ref<Select<T>> }\n ): Overlay {\n const children: Node[] = []\n if (opts.title) children.push(markdown(opts.title, { style: \"borderTitle\" }))\n if (opts.details) {\n if (typeof opts.details === \"string\")\n children.push(isMarkdown(opts.details) ? markdown(opts.details) : text(opts.details))\n else children.push(opts.details())\n }\n\n const select = picker<T>({ maxHeight: 8, ...opts })\n select.ref(opts.ref)\n if (opts.multi)\n this.#multi(select as unknown as Select<ToggleItem>, opts.multi === true ? {} : opts.multi)\n\n const wk = this.#whichKey(select as unknown as Select, opts.whichKey)\n if (wk) children.push(wk)\n\n if (children.length > 0) children.push(divider({ style: \"border\" }))\n return overlay(\n {\n padding: [0, 1],\n relative: \"ui\",\n style: \"ui\",\n verticalAnchor: \"bottom\",\n x: 0,\n y: 1,\n },\n divider({ style: \"accent\" }),\n ...children,\n select\n )\n }\n\n #whichKey(select: Select, opts: PickOpts[\"whichKey\"]): Node | undefined {\n if (opts === false || opts === undefined) return\n const filter = opts === true ? { hidden: false } : opts\n const ret = text((ctx) => {\n const s = ctx.style\n const bo = s.syntaxDelimiter.dim(\"<\")\n const bc = s.syntaxDelimiter.dim(\">\")\n const wk = this.#ui.$r.actions.whichKey(select, { filter })\n const parts = wk.map((a) => {\n const name = s.muted(a.desc ?? a.cmd ?? a.id)\n const keys = a.keys.map((k) => bo + s.syntaxSpecial.dim(k) + bc).join(s.delim.dim(\"/\"))\n return `${keys} ${name.toLowerCase()}`\n })\n return parts.join(s.delim(\" • \"))\n })\n\n select.once(\"mount\", () => ret.invalidate())\n return ret\n }\n\n #multi(select: Select<ToggleItem>, opts: { action?: boolean; render?: boolean } = {}) {\n if (opts.render !== false)\n select.extendRenderer((prev) => (item, ctx) => {\n const s = ctx.style\n const row = prev(item, { ...ctx, width: ctx.width - 4 })\n const enabled = item.enabled\n if (enabled === undefined) return row\n return `${enabled ? s.mdListChecked(\"[x]\") : s.mdListUnchecked(\"[ ]\")} ${row}`\n })\n if (opts.action !== false)\n select.withActions({\n \"picker.toggle\": {\n desc: \"Toggle item\",\n fn: () => {\n const active = select.item\n if (!active) return\n active.enabled = !active.enabled\n select.invalidate()\n },\n keys: [\"tab\", \"enter\"],\n priority: 10,\n },\n })\n }\n\n close(opts: { all?: boolean } = {}) {\n while (this.#active.length > 0) {\n const node = this.#active.pop()!\n this.#ui.close(node)\n if (!opts.all) break\n }\n }\n\n get active() {\n return this.#active.at(-1)\n }\n\n suspend() {\n this.active?.hide()\n }\n\n resume() {\n this.active?.show()\n }\n\n async pick<T extends Option = Option>(opts: PickOpts<T>): Promise<T | undefined> {\n this.active?.hide()\n const res = Promise.withResolvers<T | undefined>()\n let settled = false\n const clear = opts.clearInput ?? true\n const restore = opts.restoreInput ?? true\n const prevInput = clear ? this.#input.consume().value : undefined\n const ref = opts.ref ?? createRef<Select<T>>()\n const node = this.#ui.open(() => this.#pick({ ...opts, input: this.#input, ref }))\n this.#active.push(node)\n this.#open.set(true)\n const select = ref()\n\n const ac = new AbortController()\n const done = (value?: T) => {\n if (settled) return\n settled = true\n ac.abort()\n this.#active = this.#active.filter((n) => n !== node)\n if (restore && prevInput !== undefined) this.#input.replace(prevInput)\n else if (!restore) this.#input.consume()\n res.resolve(value)\n this.#ui.close(node)\n this.active?.show()\n this.#open.set(this.#active.length > 0)\n }\n\n node.once(\"unmount\", () => done(), { signal: ac.signal })\n select.once(\"close\", () => done(), { signal: ac.signal })\n select.once(\"accept\", ({ item }) => done(item), { signal: ac.signal })\n select.once(\"complete\", ({ item }) => done(item), { signal: ac.signal })\n\n return res.promise\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { C as OverlaySurface, Q as Accessor } from "../queries-DH3bj74K.mjs";
2
+ import { t as Input } from "../input-B5Vy-iaa.mjs";
3
+ import { n as PickerItem } from "../picker-D8OLb6kZ.mjs";
4
+ import { Widget } from "../widgets/widget.mjs";
5
+ //#region src/services/prompt.d.ts
6
+ type ToggleItem = PickerItem & {
7
+ enabled?: boolean;
8
+ };
9
+ type PromptOpts = {
10
+ title?: string;
11
+ details?: Widget | string;
12
+ clearInput?: boolean;
13
+ restoreInput?: boolean;
14
+ };
15
+ type PromptEvents = {
16
+ close: {};
17
+ submit: {
18
+ value: string;
19
+ };
20
+ };
21
+ declare class Prompt {
22
+ #private;
23
+ constructor(ui: OverlaySurface, input: Input);
24
+ get isOpen(): Accessor<boolean>;
25
+ close(): void;
26
+ open(msg: string | PromptOpts): Promise<string | undefined>;
27
+ }
28
+ //#endregion
29
+ export { Prompt, PromptEvents, PromptOpts, ToggleItem };
30
+ //# sourceMappingURL=prompt.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.mts","names":[],"sources":["../../src/services/prompt.ts"],"mappings":";;;;;KAcY,aAAa;EAAe;;KAE5B;EACV;EACA,UAAU;EACV;EACA;;KAGU;EACV;EACA;IAAU;;;cAGC;;EAMX,YAAY,IAAI,gBAAgB,OAAO;MAKnC,UALmC;EA+CvC;EAOM,KAAK,cAAc,aAAa"}
@@ -0,0 +1,83 @@
1
+ import { y as signal } from "../reactive-f7NpAi69.mjs";
2
+ import { r as isMarkdown } from "../inspect-D1d9t-ni.mjs";
3
+ import { text } from "../widgets/text.mjs";
4
+ import { markdown } from "../widgets/markdown.mjs";
5
+ import { overlay } from "../widgets/overlay.mjs";
6
+ import { divider } from "../widgets/divider.mjs";
7
+ //#region src/services/prompt.ts
8
+ var Prompt = class {
9
+ #ui;
10
+ #input;
11
+ #open = signal(false);
12
+ #node;
13
+ constructor(ui, input) {
14
+ this.#ui = ui;
15
+ this.#input = input;
16
+ }
17
+ get isOpen() {
18
+ return this.#open.get;
19
+ }
20
+ #overlay(opts) {
21
+ const children = [];
22
+ if (opts.title) children.push(isMarkdown(opts.title) ? markdown(opts.title, { style: "borderTitle" }) : text(opts.title, { style: "borderTitle" }));
23
+ if (opts.details) if (typeof opts.details === "string") children.push(isMarkdown(opts.details) ? markdown(opts.details) : text(opts.details));
24
+ else children.push(opts.details());
25
+ const ret = overlay({
26
+ padding: [0, 1],
27
+ relative: "ui",
28
+ style: "ui",
29
+ verticalAnchor: "bottom",
30
+ x: 0,
31
+ y: 1
32
+ }, divider({ style: "accent" }), ...children).withEvents();
33
+ return ret.withActions({
34
+ "prompt.close": {
35
+ fn: () => void ret.emit("close"),
36
+ keys: ["esc"]
37
+ },
38
+ "prompt.submit": {
39
+ fn: () => void ret.emit("submit", { value: this.#input.state.value ?? "" }),
40
+ keys: ["enter"]
41
+ }
42
+ });
43
+ }
44
+ close() {
45
+ const node = this.#node;
46
+ if (!node) return;
47
+ this.#ui.close(node);
48
+ this.#node = void 0;
49
+ }
50
+ async open(msg) {
51
+ this.close();
52
+ const opts = typeof msg === "string" ? { title: msg } : msg;
53
+ const res = Promise.withResolvers();
54
+ let settled = false;
55
+ const clear = opts.clearInput ?? true;
56
+ const restore = opts.restoreInput ?? true;
57
+ const prevInput = clear ? this.#input.consume().value : void 0;
58
+ const node = this.#ui.open(() => this.#overlay(opts));
59
+ this.#node = node;
60
+ this.#open.set(true);
61
+ this.#input.addActionTarget(node);
62
+ const ac = new AbortController();
63
+ const done = (value) => {
64
+ if (settled) return;
65
+ settled = true;
66
+ ac.abort();
67
+ this.#input.removeActionTarget(node);
68
+ if (restore && prevInput !== void 0) this.#input.replace(prevInput);
69
+ else if (!restore) this.#input.consume();
70
+ res.resolve(value);
71
+ this.close();
72
+ this.#open.set(false);
73
+ };
74
+ node.once("unmount", () => done(), { signal: ac.signal });
75
+ node.once("close", () => done(), { signal: ac.signal });
76
+ node.once("submit", ({ value }) => done(value), { signal: ac.signal });
77
+ return res.promise;
78
+ }
79
+ };
80
+ //#endregion
81
+ export { Prompt };
82
+
83
+ //# sourceMappingURL=prompt.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.mjs","names":["#ui","#input","#open","#node","#overlay"],"sources":["../../src/services/prompt.ts"],"sourcesContent":["import type { Node } from \"../core/node.ts\"\nimport type { OverlaySurface } from \"../renderer/overlay.ts\"\nimport type { Input } from \"../widgets/input.ts\"\nimport type { Overlay } from \"../widgets/overlay.ts\"\nimport type { PickerItem } from \"../widgets/picker.ts\"\nimport type { Widget } from \"../widgets/widget.ts\"\n\nimport { signal } from \"../core/reactive.ts\"\nimport { isMarkdown } from \"../style/inspect.ts\"\nimport { divider } from \"../widgets/divider.ts\"\nimport { markdown } from \"../widgets/markdown.ts\"\nimport { overlay } from \"../widgets/overlay.ts\"\nimport { text } from \"../widgets/text.ts\"\n\nexport type ToggleItem = PickerItem & { enabled?: boolean }\n\nexport type PromptOpts = {\n title?: string\n details?: Widget | string\n clearInput?: boolean\n restoreInput?: boolean\n}\n\nexport type PromptEvents = {\n close: {}\n submit: { value: string }\n}\n\nexport class Prompt {\n #ui: OverlaySurface\n #input: Input\n #open = signal(false)\n #node?: Overlay\n\n constructor(ui: OverlaySurface, input: Input) {\n this.#ui = ui\n this.#input = input\n }\n\n get isOpen() {\n return this.#open.get\n }\n\n #overlay(opts: PromptOpts) {\n const children: Node[] = []\n if (opts.title)\n children.push(\n isMarkdown(opts.title)\n ? markdown(opts.title, { style: \"borderTitle\" })\n : text(opts.title, { style: \"borderTitle\" })\n )\n if (opts.details) {\n if (typeof opts.details === \"string\")\n children.push(isMarkdown(opts.details) ? markdown(opts.details) : text(opts.details))\n else children.push(opts.details())\n }\n\n const ret = overlay(\n {\n padding: [0, 1],\n relative: \"ui\",\n style: \"ui\",\n verticalAnchor: \"bottom\",\n x: 0,\n y: 1,\n },\n divider({ style: \"accent\" }),\n ...children\n ).withEvents<PromptEvents>()\n return ret.withActions({\n \"prompt.close\": {\n fn: () => void ret.emit(\"close\"),\n keys: [\"esc\"],\n },\n \"prompt.submit\": {\n fn: () => void ret.emit(\"submit\", { value: this.#input.state.value ?? \"\" }),\n keys: [\"enter\"],\n },\n })\n }\n\n close() {\n const node = this.#node\n if (!node) return\n this.#ui.close(node)\n this.#node = undefined\n }\n\n async open(msg: string | PromptOpts): Promise<string | undefined> {\n this.close()\n const opts = typeof msg === \"string\" ? { title: msg } : msg\n const res = Promise.withResolvers<string | undefined>()\n let settled = false\n const clear = opts.clearInput ?? true\n const restore = opts.restoreInput ?? true\n const prevInput = clear ? this.#input.consume().value : undefined\n const node = this.#ui.open(() => this.#overlay(opts))\n this.#node = node\n this.#open.set(true)\n this.#input.addActionTarget(node)\n\n const ac = new AbortController()\n const done = (value?: string) => {\n if (settled) return\n settled = true\n ac.abort()\n this.#input.removeActionTarget(node)\n if (restore && prevInput !== undefined) this.#input.replace(prevInput)\n else if (!restore) this.#input.consume()\n res.resolve(value)\n this.close()\n this.#open.set(false)\n }\n\n node.once(\"unmount\", () => done(), { signal: ac.signal })\n node.once(\"close\", () => done(), { signal: ac.signal })\n node.once(\"submit\", ({ value }) => done(value), { signal: ac.signal })\n\n return res.promise\n }\n}\n"],"mappings":";;;;;;;AA4BA,IAAa,SAAb,MAAoB;CAClB;CACA;CACA,QAAQ,OAAO,KAAK;CACpB;CAEA,YAAY,IAAoB,OAAc;EAC5C,KAAKA,MAAM;EACX,KAAKC,SAAS;CAChB;CAEA,IAAI,SAAS;EACX,OAAO,KAAKC,MAAM;CACpB;CAEA,SAAS,MAAkB;EACzB,MAAM,WAAmB,CAAC;EAC1B,IAAI,KAAK,OACP,SAAS,KACP,WAAW,KAAK,KAAK,IACjB,SAAS,KAAK,OAAO,EAAE,OAAO,cAAc,CAAC,IAC7C,KAAK,KAAK,OAAO,EAAE,OAAO,cAAc,CAAC,CAC/C;EACF,IAAI,KAAK,SACP,IAAI,OAAO,KAAK,YAAY,UAC1B,SAAS,KAAK,WAAW,KAAK,OAAO,IAAI,SAAS,KAAK,OAAO,IAAI,KAAK,KAAK,OAAO,CAAC;OACjF,SAAS,KAAK,KAAK,QAAQ,CAAC;EAGnC,MAAM,MAAM,QACV;GACE,SAAS,CAAC,GAAG,CAAC;GACd,UAAU;GACV,OAAO;GACP,gBAAgB;GAChB,GAAG;GACH,GAAG;EACL,GACA,QAAQ,EAAE,OAAO,SAAS,CAAC,GAC3B,GAAG,QACL,CAAC,CAAC,WAAyB;EAC3B,OAAO,IAAI,YAAY;GACrB,gBAAgB;IACd,UAAU,KAAK,IAAI,KAAK,OAAO;IAC/B,MAAM,CAAC,KAAK;GACd;GACA,iBAAiB;IACf,UAAU,KAAK,IAAI,KAAK,UAAU,EAAE,OAAO,KAAKD,OAAO,MAAM,SAAS,GAAG,CAAC;IAC1E,MAAM,CAAC,OAAO;GAChB;EACF,CAAC;CACH;CAEA,QAAQ;EACN,MAAM,OAAO,KAAKE;EAClB,IAAI,CAAC,MAAM;EACX,KAAKH,IAAI,MAAM,IAAI;EACnB,KAAKG,QAAQ,KAAA;CACf;CAEA,MAAM,KAAK,KAAuD;EAChE,KAAK,MAAM;EACX,MAAM,OAAO,OAAO,QAAQ,WAAW,EAAE,OAAO,IAAI,IAAI;EACxD,MAAM,MAAM,QAAQ,cAAkC;EACtD,IAAI,UAAU;EACd,MAAM,QAAQ,KAAK,cAAc;EACjC,MAAM,UAAU,KAAK,gBAAgB;EACrC,MAAM,YAAY,QAAQ,KAAKF,OAAO,QAAQ,CAAC,CAAC,QAAQ,KAAA;EACxD,MAAM,OAAO,KAAKD,IAAI,WAAW,KAAKI,SAAS,IAAI,CAAC;EACpD,KAAKD,QAAQ;EACb,KAAKD,MAAM,IAAI,IAAI;EACnB,KAAKD,OAAO,gBAAgB,IAAI;EAEhC,MAAM,KAAK,IAAI,gBAAgB;EAC/B,MAAM,QAAQ,UAAmB;GAC/B,IAAI,SAAS;GACb,UAAU;GACV,GAAG,MAAM;GACT,KAAKA,OAAO,mBAAmB,IAAI;GACnC,IAAI,WAAW,cAAc,KAAA,GAAW,KAAKA,OAAO,QAAQ,SAAS;QAChE,IAAI,CAAC,SAAS,KAAKA,OAAO,QAAQ;GACvC,IAAI,QAAQ,KAAK;GACjB,KAAK,MAAM;GACX,KAAKC,MAAM,IAAI,KAAK;EACtB;EAEA,KAAK,KAAK,iBAAiB,KAAK,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC;EACxD,KAAK,KAAK,eAAe,KAAK,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC;EACtD,KAAK,KAAK,WAAW,EAAE,YAAY,KAAK,KAAK,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC;EAErE,OAAO,IAAI;CACb;AACF"}