@zaly/tui 0.0.12 → 0.1.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.
Files changed (250) hide show
  1. package/assets/schemas/shiki-language.schema.json +352 -0
  2. package/assets/schemas/shiki-theme.schema.json +71 -0
  3. package/assets/schemas/theme.schema.json +226 -1046
  4. package/assets/themes/andromeeda.json +97 -0
  5. package/assets/themes/ayu-dark.json +31 -25
  6. package/assets/themes/ayu-light.json +106 -0
  7. package/assets/themes/ayu-mirage.json +106 -0
  8. package/assets/themes/catppuccin-frappe.json +43 -40
  9. package/assets/themes/catppuccin-latte.json +43 -40
  10. package/assets/themes/catppuccin-macchiato.json +43 -40
  11. package/assets/themes/catppuccin-mocha.json +43 -40
  12. package/assets/themes/dark-plus.json +99 -0
  13. package/assets/themes/dracula.json +47 -47
  14. package/assets/themes/everforest-dark.json +28 -26
  15. package/assets/themes/everforest-light.json +28 -26
  16. package/assets/themes/github-dark-default.json +107 -0
  17. package/assets/themes/github-dark-dimmed.json +107 -0
  18. package/assets/themes/github-light-default.json +107 -0
  19. package/assets/themes/gruvbox-dark-hard.json +98 -0
  20. package/assets/themes/gruvbox-dark-medium.json +34 -29
  21. package/assets/themes/gruvbox-light-medium.json +98 -0
  22. package/assets/themes/horizon-bright.json +101 -0
  23. package/assets/themes/horizon.json +101 -0
  24. package/assets/themes/iterm2/LICENSE +25 -0
  25. package/assets/themes/iterm2/README.md +28 -0
  26. package/assets/themes/iterm2/catppuccin-latte.json +140 -0
  27. package/assets/themes/iterm2/catppuccin-mocha.json +140 -0
  28. package/assets/themes/iterm2/github-dark.json +140 -0
  29. package/assets/themes/iterm2/github.json +140 -0
  30. package/assets/themes/iterm2/gruvbox-dark.json +140 -0
  31. package/assets/themes/iterm2/gruvbox-light.json +140 -0
  32. package/assets/themes/iterm2/nord.json +140 -0
  33. package/assets/themes/iterm2/tokyonight-day.json +140 -0
  34. package/assets/themes/iterm2/tokyonight-moon.json +140 -0
  35. package/assets/themes/kanagawa-dragon.json +55 -49
  36. package/assets/themes/kanagawa-lotus.json +105 -0
  37. package/assets/themes/kanagawa-wave.json +56 -50
  38. package/assets/themes/light-plus.json +99 -0
  39. package/assets/themes/material-theme-lighter.json +102 -0
  40. package/assets/themes/material-theme-palenight.json +52 -45
  41. package/assets/themes/material-theme.json +102 -0
  42. package/assets/themes/min-dark.json +69 -14
  43. package/assets/themes/min-light.json +68 -17
  44. package/assets/themes/monokai.json +54 -47
  45. package/assets/themes/night-owl-light.json +105 -0
  46. package/assets/themes/night-owl.json +57 -49
  47. package/assets/themes/nord.json +53 -39
  48. package/assets/themes/one-dark-pro.json +46 -38
  49. package/assets/themes/one-light.json +52 -41
  50. package/assets/themes/poimandres.json +51 -49
  51. package/assets/themes/rose-pine-dawn.json +99 -0
  52. package/assets/themes/rose-pine-moon.json +99 -0
  53. package/assets/themes/rose-pine.json +50 -33
  54. package/assets/themes/solarized-dark.json +38 -31
  55. package/assets/themes/solarized-light.json +40 -33
  56. package/assets/themes/synthwave-84.json +47 -30
  57. package/assets/themes/tokyonight-day.json +3 -3
  58. package/assets/themes/tokyonight-moon.json +3 -2
  59. package/assets/themes/tokyonight-night.json +3 -2
  60. package/assets/themes/tokyonight-storm.json +3 -2
  61. package/assets/themes/vesper.json +50 -42
  62. package/assets/themes/vitesse-black.json +103 -0
  63. package/assets/themes/vitesse-dark.json +26 -30
  64. package/assets/themes/vitesse-light.json +26 -30
  65. package/dist/{actions-Dc4D4uSf.d.mts → actions--ODlgCQ5.d.mts} +4 -4
  66. package/dist/{actions-Dc4D4uSf.d.mts.map → actions--ODlgCQ5.d.mts.map} +1 -1
  67. package/dist/{ansi-DZlXaItJ.mjs → ansi-CMv71xVr.mjs} +3 -31
  68. package/dist/ansi-CMv71xVr.mjs.map +1 -0
  69. package/dist/ansi.d.mts +1 -1
  70. package/dist/ansi.mjs +1 -1
  71. package/dist/{autocomplete-StW1QJZJ.d.mts → autocomplete-CD30kSe_.d.mts} +4 -4
  72. package/dist/{autocomplete-StW1QJZJ.d.mts.map → autocomplete-CD30kSe_.d.mts.map} +1 -1
  73. package/dist/{box-BkP4MF82.mjs → box-C_N_7ChP.mjs} +2 -2
  74. package/dist/{box-BkP4MF82.mjs.map → box-C_N_7ChP.mjs.map} +1 -1
  75. package/dist/builder-Chwtk0nQ.mjs +196 -0
  76. package/dist/builder-Chwtk0nQ.mjs.map +1 -0
  77. package/dist/{callbacks-BwWTCqPJ.mjs → callbacks-DLecWn7G.mjs} +4 -4
  78. package/dist/{callbacks-BwWTCqPJ.mjs.map → callbacks-DLecWn7G.mjs.map} +1 -1
  79. package/dist/client-CNGt-dOt.mjs +1 -0
  80. package/dist/{client-C2GXKfJ1.mjs → client-D7qz4TZt.mjs} +7 -3
  81. package/dist/client-D7qz4TZt.mjs.map +1 -0
  82. package/dist/color-DBMQLv4Y.mjs +37 -0
  83. package/dist/color-DBMQLv4Y.mjs.map +1 -0
  84. package/dist/{ctx-B7BmPUCD.mjs → ctx-BaQ2hP5u.mjs} +3 -3
  85. package/dist/{ctx-B7BmPUCD.mjs.map → ctx-BaQ2hP5u.mjs.map} +1 -1
  86. package/dist/ctx-CndlTp1T.mjs +1 -0
  87. package/dist/{divider-TSx9NhI_.mjs → divider-BlNNN2OS.mjs} +2 -2
  88. package/dist/{divider-TSx9NhI_.mjs.map → divider-BlNNN2OS.mjs.map} +1 -1
  89. package/dist/{files-7DUYSeNc.d.mts → files-B_5HDBPp.d.mts} +3 -3
  90. package/dist/{files-7DUYSeNc.d.mts.map → files-B_5HDBPp.d.mts.map} +1 -1
  91. package/dist/{github-C1KfXk98.d.mts → github-CyRwUQ3y.d.mts} +3 -3
  92. package/dist/{github-C1KfXk98.d.mts.map → github-CyRwUQ3y.d.mts.map} +1 -1
  93. package/dist/{image-VaT7AN-S.d.mts → image-BLls2F4t.d.mts} +2 -2
  94. package/dist/{image-VaT7AN-S.d.mts.map → image-BLls2F4t.d.mts.map} +1 -1
  95. package/dist/image-Cqtj3yRA.mjs +178 -0
  96. package/dist/image-Cqtj3yRA.mjs.map +1 -0
  97. package/dist/image.d.mts +1 -1
  98. package/dist/index.d.mts +13 -4
  99. package/dist/index.d.mts.map +1 -1
  100. package/dist/index.mjs +8 -7
  101. package/dist/index.mjs.map +1 -1
  102. package/dist/{input-BGTTujDN.mjs → input-ET2YEMcl.mjs} +2 -2
  103. package/dist/{input-BGTTujDN.mjs.map → input-ET2YEMcl.mjs.map} +1 -1
  104. package/dist/{input-BAYux7qo.d.mts → input-NuD8TH8N.d.mts} +3 -3
  105. package/dist/{input-BAYux7qo.d.mts.map → input-NuD8TH8N.d.mts.map} +1 -1
  106. package/dist/{inspect-CfNydMgO.d.mts → inspect-B1uXxdKC.d.mts} +2 -2
  107. package/dist/{inspect-CfNydMgO.d.mts.map → inspect-B1uXxdKC.d.mts.map} +1 -1
  108. package/dist/{inspect-jG_W4njH.mjs → inspect-Cxzs-W0g.mjs} +2 -2
  109. package/dist/{inspect-jG_W4njH.mjs.map → inspect-Cxzs-W0g.mjs.map} +1 -1
  110. package/dist/kitty-DKQYsQfH.mjs +1 -0
  111. package/dist/{log-ByKlM4iI.mjs → log-B4djzy2m.mjs} +4 -4
  112. package/dist/{log-ByKlM4iI.mjs.map → log-B4djzy2m.mjs.map} +1 -1
  113. package/dist/{logger-DSQb0sLP.mjs → logger-CvJCITzP.mjs} +3 -3
  114. package/dist/{logger-DSQb0sLP.mjs.map → logger-CvJCITzP.mjs.map} +1 -1
  115. package/dist/{markdown-CwRmWuU6.mjs → markdown-D3ZtRn6C.mjs} +9 -8
  116. package/dist/markdown-D3ZtRn6C.mjs.map +1 -0
  117. package/dist/markdown.d.mts +1 -1
  118. package/dist/markdown.d.mts.map +1 -1
  119. package/dist/markdown.mjs +1 -1
  120. package/dist/math-CU0wmC9N.mjs +1 -0
  121. package/dist/math-Dd7a1irv.mjs +206 -0
  122. package/dist/math-Dd7a1irv.mjs.map +1 -0
  123. package/dist/oklch-Bsh5swbC.mjs +99 -0
  124. package/dist/oklch-Bsh5swbC.mjs.map +1 -0
  125. package/dist/{overlay-BnvOKtGT.mjs → overlay-LvOjG7kn.mjs} +2 -2
  126. package/dist/{overlay-BnvOKtGT.mjs.map → overlay-LvOjG7kn.mjs.map} +1 -1
  127. package/dist/{picker-DQs_IW77.d.mts → picker-B-OxKKnD.d.mts} +5 -5
  128. package/dist/{picker-DQs_IW77.d.mts.map → picker-B-OxKKnD.d.mts.map} +1 -1
  129. package/dist/{picker-Dh5IUrTk.mjs → picker-f6xjgACX.mjs} +2 -2
  130. package/dist/{picker-Dh5IUrTk.mjs.map → picker-f6xjgACX.mjs.map} +1 -1
  131. package/dist/{queries-B_lOwEiE.mjs → queries-BUkBxkuM.mjs} +66 -3
  132. package/dist/queries-BUkBxkuM.mjs.map +1 -0
  133. package/dist/{queries-BDX8mcl5.d.mts → queries-C75-wG1B.d.mts} +19 -4
  134. package/dist/{queries-BDX8mcl5.d.mts.map → queries-C75-wG1B.d.mts.map} +1 -1
  135. package/dist/{registry-D-suU3g0.mjs → registry-DUWpSPoo.mjs} +202 -57
  136. package/dist/registry-DUWpSPoo.mjs.map +1 -0
  137. package/dist/{render-DEIUNLkh.mjs → render-B7LfNM5K.mjs} +2 -2
  138. package/dist/{render-DEIUNLkh.mjs.map → render-B7LfNM5K.mjs.map} +1 -1
  139. package/dist/{renderer-zDNlAovy.mjs → renderer-BLsd-wrG.mjs} +110 -14
  140. package/dist/renderer-BLsd-wrG.mjs.map +1 -0
  141. package/dist/renderer-YHbR7JZ4.mjs +1 -0
  142. package/dist/{renderer-MQue4Da5.mjs → renderer-aAtkFgll.mjs} +8 -7
  143. package/dist/renderer-aAtkFgll.mjs.map +1 -0
  144. package/dist/{select-J2KtwxyK.d.mts → select-BKE5LzdN.d.mts} +3 -3
  145. package/dist/{select-J2KtwxyK.d.mts.map → select-BKE5LzdN.d.mts.map} +1 -1
  146. package/dist/services/logger.d.mts +1 -1
  147. package/dist/services/logger.mjs +1 -1
  148. package/dist/services/notifier.d.mts +1 -1
  149. package/dist/services/notifier.mjs +2 -2
  150. package/dist/services/picker.d.mts +5 -5
  151. package/dist/services/picker.mjs +6 -6
  152. package/dist/services/prompt.d.mts +4 -4
  153. package/dist/services/prompt.mjs +5 -5
  154. package/dist/shiki/server.mjs +37 -14
  155. package/dist/shiki/server.mjs.map +1 -1
  156. package/dist/shiki-B4U0s8jT.mjs +635 -0
  157. package/dist/shiki-B4U0s8jT.mjs.map +1 -0
  158. package/dist/shiki-CJauRusM.mjs +20 -0
  159. package/dist/shiki-CJauRusM.mjs.map +1 -0
  160. package/dist/style-DslRHzI4.mjs +109 -0
  161. package/dist/style-DslRHzI4.mjs.map +1 -0
  162. package/dist/style.d.mts +4 -3
  163. package/dist/style.d.mts.map +1 -1
  164. package/dist/style.mjs +4 -4
  165. package/dist/{text-CkQ7Irmt.mjs → text-BoJdKXLU.mjs} +2 -2
  166. package/dist/{text-CkQ7Irmt.mjs.map → text-BoJdKXLU.mjs.map} +1 -1
  167. package/dist/{text-CCYs9RB2.d.mts → text-CmxbA8lk.d.mts} +3 -3
  168. package/dist/{text-CCYs9RB2.d.mts.map → text-CmxbA8lk.d.mts.map} +1 -1
  169. package/dist/{text-XvPfweeg.mjs → text-DPrhma4x.mjs} +2 -2
  170. package/dist/{text-XvPfweeg.mjs.map → text-DPrhma4x.mjs.map} +1 -1
  171. package/dist/text.d.mts +1 -1
  172. package/dist/text.mjs +1 -1
  173. package/dist/theme-C8LkcoaK.mjs +61 -0
  174. package/dist/theme-C8LkcoaK.mjs.map +1 -0
  175. package/dist/theme-DVX8dvGG.mjs +1794 -0
  176. package/dist/theme-DVX8dvGG.mjs.map +1 -0
  177. package/dist/themes.d.mts +213 -73
  178. package/dist/themes.d.mts.map +1 -1
  179. package/dist/themes.mjs +1 -1
  180. package/dist/{tree-DJl5W_B7.d.mts → tree-CTvSpF9b.d.mts} +3 -3
  181. package/dist/{tree-DJl5W_B7.d.mts.map → tree-CTvSpF9b.d.mts.map} +1 -1
  182. package/dist/{types-D2EYlzmK.d.mts → types-C9ceMsbJ.d.mts} +136 -128
  183. package/dist/types-C9ceMsbJ.d.mts.map +1 -0
  184. package/dist/{widget-DPqBbB57.d.mts → widget-DlF32PRp.d.mts} +2 -2
  185. package/dist/{widget-DPqBbB57.d.mts.map → widget-DlF32PRp.d.mts.map} +1 -1
  186. package/dist/widgets/autocomplete.d.mts +1 -1
  187. package/dist/widgets/autocomplete.mjs +2 -2
  188. package/dist/widgets/box.d.mts +1 -1
  189. package/dist/widgets/box.mjs +1 -1
  190. package/dist/widgets/code.d.mts +4 -2
  191. package/dist/widgets/code.d.mts.map +1 -1
  192. package/dist/widgets/code.mjs +8 -7
  193. package/dist/widgets/code.mjs.map +1 -1
  194. package/dist/widgets/completions/actions.d.mts +1 -1
  195. package/dist/widgets/completions/files.d.mts +1 -1
  196. package/dist/widgets/completions/github.d.mts +1 -1
  197. package/dist/widgets/completions/index.d.mts +3 -3
  198. package/dist/widgets/diff.d.mts +2 -2
  199. package/dist/widgets/diff.d.mts.map +1 -1
  200. package/dist/widgets/diff.mjs +35 -12
  201. package/dist/widgets/diff.mjs.map +1 -1
  202. package/dist/widgets/divider.d.mts +2 -2
  203. package/dist/widgets/divider.mjs +1 -1
  204. package/dist/widgets/image.d.mts +1 -1
  205. package/dist/widgets/image.mjs +4 -4
  206. package/dist/widgets/image.mjs.map +1 -1
  207. package/dist/widgets/input.d.mts +1 -1
  208. package/dist/widgets/input.mjs +1 -1
  209. package/dist/widgets/log.d.mts +1 -1
  210. package/dist/widgets/log.mjs +1 -1
  211. package/dist/widgets/markdown.d.mts +4 -4
  212. package/dist/widgets/markdown.d.mts.map +1 -1
  213. package/dist/widgets/markdown.mjs +1 -1
  214. package/dist/widgets/overlay.d.mts +1 -1
  215. package/dist/widgets/overlay.mjs +1 -1
  216. package/dist/widgets/picker.d.mts +1 -1
  217. package/dist/widgets/picker.mjs +1 -1
  218. package/dist/widgets/progress.d.mts +2 -2
  219. package/dist/widgets/select.d.mts +1 -1
  220. package/dist/widgets/show.d.mts +1 -1
  221. package/dist/widgets/spinner.d.mts +2 -2
  222. package/dist/widgets/text.d.mts +1 -1
  223. package/dist/widgets/text.mjs +1 -1
  224. package/dist/widgets/tree.d.mts +1 -1
  225. package/dist/widgets/widget.d.mts +1 -1
  226. package/package.json +5 -7
  227. package/assets/themes/dracula-soft.json +0 -100
  228. package/assets/themes/github-dark.json +0 -104
  229. package/assets/themes/github-light.json +0 -104
  230. package/dist/ansi-DZlXaItJ.mjs.map +0 -1
  231. package/dist/builder-1z5ewEWK.mjs +0 -386
  232. package/dist/builder-1z5ewEWK.mjs.map +0 -1
  233. package/dist/client-C2GXKfJ1.mjs.map +0 -1
  234. package/dist/client-bzdHIDL2.mjs +0 -1
  235. package/dist/ctx-D_JgJ8Eo.mjs +0 -1
  236. package/dist/image-Cm5T-uw-.mjs +0 -108
  237. package/dist/image-Cm5T-uw-.mjs.map +0 -1
  238. package/dist/markdown-CwRmWuU6.mjs.map +0 -1
  239. package/dist/queries-B_lOwEiE.mjs.map +0 -1
  240. package/dist/registry-D-suU3g0.mjs.map +0 -1
  241. package/dist/renderer-DhqbEVVR.mjs +0 -1
  242. package/dist/renderer-MQue4Da5.mjs.map +0 -1
  243. package/dist/renderer-zDNlAovy.mjs.map +0 -1
  244. package/dist/shiki--ASSYv4_.mjs +0 -12
  245. package/dist/shiki--ASSYv4_.mjs.map +0 -1
  246. package/dist/shiki-D7l5--zz.mjs +0 -432
  247. package/dist/shiki-D7l5--zz.mjs.map +0 -1
  248. package/dist/theme.config-B3Yx--C2.mjs +0 -855
  249. package/dist/theme.config-B3Yx--C2.mjs.map +0 -1
  250. package/dist/types-D2EYlzmK.d.mts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"ansi-DZlXaItJ.mjs","names":[],"sources":["../src/style/color.ts","../src/style/ansi.ts"],"sourcesContent":["import type { HexColor, RGB } from \"./types.ts\"\n\nimport { clamp } from \"@zaly/shared\"\n\nconst hexByte = (n: number): string => clamp(Math.round(n), 0, 255).toString(16).padStart(2, \"0\")\n\nexport function toHex(c: RGB): HexColor\nexport function toHex(r: number, g: number, b: number): HexColor\nexport function toHex(x: number | RGB, y?: number, z?: number): HexColor {\n const [r, g, b] = Array.isArray(x) ? x : [x, y!, z!]\n return `#${hexByte(r)}${hexByte(g)}${hexByte(b)}`\n}\n\nexport function parseHex(hex: string): RGB {\n let s = hex.charCodeAt(0) === 0x23 ? hex.slice(1) : hex // strip leading #\n if (s.length === 4) s = s.slice(0, 3) // strip alpha\n if (s.length === 8) s = s.slice(0, 6) // strip alpha\n if (s.length === 3) {\n // Expand \"abc\" → \"aabbcc\" without allocating an array.\n s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2]\n }\n if (s.length !== 6) throw new Error(`invalid hex color: ${hex}`)\n const n = Number.parseInt(s, 16)\n if (Number.isNaN(n)) throw new Error(`invalid hex color: ${hex}`)\n return [(n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]\n}\n\nexport function isHexColor(s: string): s is HexColor {\n return /^#[0-9a-fA-F]{3,8}$/.test(s)\n}\n","import type { AnsiColor, AnsiStyle } from \"./types.ts\"\n\nimport { sliceAnsi } from \"@zaly/shared/ansi\"\nimport { hasColors } from \"@zaly/shared/env\"\nimport { isHexColor, parseHex, toHex } from \"./color.ts\"\n\n/** Optional wrap mode: `\"word\"` (default) breaks at word boundaries;\n * `\"char\"` hard-wraps mid-word. */\nexport interface WrapOpts {\n mode?: \"word\" | \"char\"\n}\n\n// ---- ANSI escape categories -------------------------------------------\n// OSC 8 hyperlink sequence. ESC + backslash is the \"string terminator\" (ST)\n// that closes the OSC. Format: `ESC]8;;URL ST TEXT ESC]8;; ST`.\nconst OSC8 = \"\\x1b]8;;\"\nconst ST = \"\\x1b\\\\\"\nexport const RESET = \"\\x1b[0m\"\n\n// Attribute → SGR code. Order matters for stable output.\nconst ATTRS = [\n [\"bold\", 1],\n [\"dim\", 2],\n [\"italic\", 3],\n [\"underline\", 4],\n [\"inverse\", 7],\n [\"strikethrough\", 9],\n] as const satisfies readonly (readonly [keyof AnsiStyle, number])[]\n\n// Standard 8-color ANSI palette. Offsets from SGR 30 (fg) and 40 (bg).\nconst ANSI_OFFSET: Record<string, number> = {\n black: 0,\n blue: 4,\n cyan: 6,\n green: 2,\n magenta: 5,\n red: 1,\n white: 7,\n yellow: 3,\n}\n\nconst ANSI_BG: Record<number, AnsiColor> = {\n 100: \"gray\", // or \"brightBlack\" if that exists\n 101: \"brightRed\",\n 102: \"brightGreen\",\n 103: \"brightYellow\",\n 104: \"brightBlue\",\n 105: \"brightMagenta\",\n 106: \"brightCyan\",\n 107: \"brightWhite\",\n 40: \"black\",\n 41: \"red\",\n 42: \"green\",\n 43: \"yellow\",\n 44: \"blue\",\n 45: \"magenta\",\n 46: \"cyan\",\n 47: \"white\",\n}\n\nconst notFound = Symbol(\"not found\")\nconst colorCache = new Map<string, string | typeof notFound>()\n\n/**\n * Wrap `text` in an OSC 8 hyperlink pointing at `url`. Modern terminals\n * (iTerm2, kitty, WezTerm, VS Code, Ghostty, …) render the text as\n * clickable while falling back gracefully to plain text elsewhere.\n *\n * Safe to nest ANSI SGR styling inside the `text` argument — OSC 8 is a\n * separate escape category and doesn't conflict.\n *\n * An empty `url` short-circuits and returns `text` unchanged, so callers\n * can unconditionally pipe link text through this helper.\n *\n * @internal\n */\nexport function hyperlink(url: string, text: string): string {\n if (url === \"\") return text\n return `${OSC8}${url}${ST}${text}${OSC8}${ST}`\n}\n\nexport function ansiColor(color: AnsiColor, kind: \"fg\" | \"bg\"): string | undefined {\n if (!hasColors) return\n const key = `${color}-${kind}`\n let cached = colorCache.get(key)\n if (cached === undefined) colorCache.set(key, (cached = _ansiColor(color, kind)) ?? notFound)\n return cached === notFound ? undefined : cached\n}\n\nfunction _ansiColor(color: AnsiColor, kind: \"fg\" | \"bg\"): string | undefined {\n if (color === \"inherit\") return\n // Gray aliases to brightBlack.\n if (color === \"gray\" || color === \"grey\") return String(kind === \"fg\" ? 90 : 100)\n\n const base = color in ANSI_OFFSET ? color : undefined\n if (base !== undefined) return String((kind === \"fg\" ? 30 : 40) + ANSI_OFFSET[base])\n\n if (color.startsWith(\"bright\")) {\n const rest = color.slice(\"bright\".length).toLowerCase()\n if (rest in ANSI_OFFSET) return String((kind === \"fg\" ? 90 : 100) + ANSI_OFFSET[rest])\n }\n\n const rgb = isHexColor(color) ? parseHex(color) : undefined\n if (rgb) {\n const indicator = kind === \"fg\" ? 38 : 48\n return `${indicator};2;${rgb[0]};${rgb[1]};${rgb[2]}`\n }\n}\n\nexport function openAnsi(style: AnsiStyle) {\n if (!hasColors) return \"\"\n const params: (number | string | undefined)[] = []\n for (const [key, code] of ATTRS) if (style[key]) params.push(code)\n if (style.fg !== undefined) params.push(ansiColor(style.fg, \"fg\"))\n if (style.bg !== undefined) params.push(ansiColor(style.bg, \"bg\"))\n const attrs = params.filter((p) => p !== undefined)\n if (attrs.length === 0) return \"\"\n return `\\x1b[${attrs.join(\";\")}m`\n}\n\nexport function styleAnsi(text: string, style?: AnsiStyle): string {\n if (!style) return text\n const open = openAnsi(style)\n if (open === \"\") return text\n return `${open}${text}${RESET}`\n}\n\n/**\n * Post-process a styled string so an outer style is re-applied after any\n * inner full-reset (`\\x1b[0m`). Without this, a child's reset clobbers\n * the parent's bg/fg/attrs for the remainder of the line.\n *\n * `escape` is the already-built SGR run to re-emit after each reset\n * (typically the return value of `openStyle(parentStyle, theme)`). If\n * empty, the input is returned unchanged.\n *\n * Inlined indexOf loop rather than `String.prototype.replaceAll` — the\n * manual version avoids the regex/object allocation overhead of\n * `replaceAll` and runs meaningfully faster on short strings (hot in\n * the builder's `apply`, called once per styled span). Pattern taken\n * from ansis's nested-style resolver.\n *\n * @internal\n */\nexport function reapplyStyle(s: string, escape: string): string {\n if (escape === \"\" || !s.includes(RESET)) return s\n const replacement = RESET + escape\n const searchLength = RESET.length\n let result = \"\"\n let lastPos = 0\n let pos = s.indexOf(RESET)\n while (pos !== -1) {\n result += s.slice(lastPos, pos) + replacement\n lastPos = pos + searchLength\n pos = s.indexOf(RESET, lastPos)\n }\n return result + s.slice(lastPos)\n}\n\n/** Resolve terminal-default color resets without changing explicit child colors. */\nexport function applyDefaultColors(text: string, fg: string, bg: string): string {\n if ((!fg && !bg) || !text.includes(\"\\x1b[\")) return text\n const fgParams = fg.slice(2, -1)\n const bgParams = bg.slice(2, -1)\n return text.replaceAll(/\\x1b\\[([\\d;:]*)m/g, (match, raw: string) => {\n const params = raw.split(\";\")\n const next: string[] = []\n let changed = false\n for (let i = 0; i < params.length; i++) {\n const param = params[i]\n const code = Number(param)\n if (code === 0) {\n next.push(param, ...[fgParams, bgParams].filter(Boolean))\n changed = true\n } else if (code === 39 && fgParams) {\n next.push(fgParams)\n changed = true\n } else if (code === 49 && bgParams) {\n next.push(bgParams)\n changed = true\n } else {\n next.push(param)\n // RGB components and palette indexes can themselves be 0, 39, or 49.\n if (code === 38 || code === 48 || code === 58) {\n let count = 0\n if (params[i + 1] === \"2\") count = 4\n else if (params[i + 1] === \"5\") count = 2\n next.push(...params.slice(i + 1, i + 1 + count))\n i += count\n }\n }\n }\n return changed ? `\\x1b[${next.join(\";\")}m` : match\n })\n}\n\nexport function stripAnsiBg(s: string): string {\n return s.replaceAll(/\\x1b\\[([0-9;]*)m/g, (match, raw: string) => {\n const next = stripBgParams(raw)\n if (next === raw) return match\n return next === \"\" ? \"\" : `\\x1b[${next}m`\n })\n}\n\nfunction stripBgParams(raw: string): string {\n if (raw === \"\") return raw\n const params = raw.split(\";\").map(Number)\n const ret: number[] = []\n for (let i = 0; i < params.length; i++) {\n const p = params[i]\n if ((p >= 40 && p <= 47) || (p >= 100 && p <= 107) || p === 49) continue\n if (p === 48) {\n const mode = params[i + 1]\n if (mode === 2) {\n i += 4\n continue\n }\n if (mode === 5) {\n i += 2\n continue\n }\n continue\n }\n ret.push(p)\n }\n return ret.join(\";\")\n}\n\nexport function ansiBg(str: string, idx: number): AnsiColor | undefined {\n const cell = sliceAnsi(str, idx, idx + 1)\n\n let bg: AnsiColor | undefined\n\n for (const match of cell.matchAll(/\\x1b\\[([0-9;]*)m/g)) {\n const params = match[1].split(\";\").map(Number)\n\n for (let i = 0; i < params.length; i++) {\n const p = params[i]\n\n if ((p >= 40 && p <= 47) || (p >= 100 && p <= 107)) {\n bg = ANSI_BG[p]\n } else if (p === 48 && params[i + 1] === 2) {\n bg = toHex(params[i + 2], params[i + 3], params[i + 4])\n i += 4\n }\n }\n }\n\n return bg\n}\n"],"mappings":"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"}
@@ -1,386 +0,0 @@
1
- import { t as defaultTheme } from "./registry-D-suU3g0.mjs";
2
- import { d as parseHex, f as toHex, o as openAnsi, s as reapplyStyle, t as RESET, u as isHexColor } from "./ansi-DZlXaItJ.mjs";
3
- import { clamp } from "@zaly/shared";
4
- //#region src/style/oklch.ts
5
- const cache = /* @__PURE__ */ new Map();
6
- function srgbToLinear(c) {
7
- return c <= .04045 ? c / 12.92 : ((c + .055) / 1.055) ** 2.4;
8
- }
9
- function linearToSrgb(c) {
10
- return c <= .0031308 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - .055;
11
- }
12
- function hexToOklch(hex) {
13
- const [r8, g8, b8] = parseHex(hex);
14
- const r = srgbToLinear(r8 / 255);
15
- const g = srgbToLinear(g8 / 255);
16
- const b = srgbToLinear(b8 / 255);
17
- const l = .4122214708 * r + .5363325363 * g + .0514459929 * b;
18
- const m = .2119034982 * r + .6806995451 * g + .1073969566 * b;
19
- const s = .0883024619 * r + .2817188376 * g + .6299787005 * b;
20
- const lp = Math.cbrt(l);
21
- const mp = Math.cbrt(m);
22
- const sp = Math.cbrt(s);
23
- const L = .2104542553 * lp + .793617785 * mp - .0040720468 * sp;
24
- const a = 1.9779984951 * lp - 2.428592205 * mp + .4505937099 * sp;
25
- const b2 = .0259040371 * lp + .7827717662 * mp - .808675766 * sp;
26
- return {
27
- C: Math.hypot(a, b2),
28
- L,
29
- h: (Math.atan2(b2, a) * 180 / Math.PI + 360) % 360
30
- };
31
- }
32
- /** Convert OKLCH → linear sRGB (unclamped — callers can test for gamut). */
33
- function oklchToLinearRgb({ L, C, h }) {
34
- const hr = h * Math.PI / 180;
35
- const a = C * Math.cos(hr);
36
- const b2 = C * Math.sin(hr);
37
- const lp = L + .3963377774 * a + .2158037573 * b2;
38
- const mp = L - .1055613458 * a - .0638541728 * b2;
39
- const sp = L - .0894841775 * a - 1.291485548 * b2;
40
- const l = lp ** 3;
41
- const m = mp ** 3;
42
- const s = sp ** 3;
43
- return [
44
- 4.0767416621 * l - 3.3077115913 * m + .2309699292 * s,
45
- -1.2684380046 * l + 2.6097574011 * m - .3413193965 * s,
46
- -.0041960863 * l - .7034186147 * m + 1.707614701 * s
47
- ];
48
- }
49
- function inGamut([r, g, b], eps = .001) {
50
- return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps;
51
- }
52
- /**
53
- * Convert OKLCH → hex, reducing chroma via binary search when the
54
- * straightforward conversion falls outside sRGB. The search keeps `L`
55
- * and `h` fixed and shrinks `C` toward the achromatic axis until the
56
- * color fits, which is the CSS Color Level 4-recommended behavior.
57
- */
58
- function oklchToHex(oklch) {
59
- let rgb = oklchToLinearRgb(oklch);
60
- if (!inGamut(rgb)) {
61
- let lo = 0;
62
- let hi = oklch.C;
63
- for (let i = 0; i < 24; i++) {
64
- const mid = (lo + hi) / 2;
65
- if (inGamut(oklchToLinearRgb({
66
- ...oklch,
67
- C: mid
68
- }))) lo = mid;
69
- else hi = mid;
70
- }
71
- rgb = oklchToLinearRgb({
72
- ...oklch,
73
- C: lo
74
- });
75
- }
76
- const [r, g, b] = rgb.map((c) => linearToSrgb(Math.max(0, Math.min(1, c))));
77
- return toHex(r * 255, g * 255, b * 255);
78
- }
79
- function shiftLightness(hex, delta) {
80
- const key = `${hex}:${delta}`;
81
- let ret = cache.get(key);
82
- if (ret) return ret;
83
- const okl = hexToOklch(hex);
84
- const L = clamp(okl.L + delta, 0, 1);
85
- const margin = Math.min(L, 1 - L);
86
- const C = okl.C * Math.min(1, margin / .1);
87
- cache.set(key, ret = oklchToHex({
88
- ...okl,
89
- C,
90
- L
91
- }));
92
- return ret;
93
- }
94
- //#endregion
95
- //#region src/style/style.ts
96
- /**
97
- * Build the opening SGR escape for a style descriptor. Returns '' if nothing
98
- * would be emitted. Unresolvable colors (invalid or 'inherit') are dropped.
99
- *
100
- * When `theme` is provided, `fg`/`bg` values matching a theme color slot
101
- * (e.g. `"primary"`, `"muted"`) are resolved against it first. The output
102
- * ordering is attrs → fg → bg, combined into a single `\x1b[...m` run.
103
- *
104
- * @internal
105
- */
106
- function openStyle(style, theme) {
107
- const resolver = ThemeResolver.from(theme);
108
- const ansiStyle = {
109
- ...style,
110
- bg: style.bg !== void 0 ? resolver.getColor(style.bg, "bg") : void 0,
111
- fg: style.fg !== void 0 ? resolver.getColor(style.fg, "fg") : void 0
112
- };
113
- return openAnsi(ansiStyle);
114
- }
115
- /**
116
- * Resolve a style-slot reference into a `Style` object. A ref is either a
117
- * theme slot name (string), an inline `Style`, or `undefined`:
118
- *
119
- * - Inline `Style` → returned as-is (no slot lookup).
120
- * - String ref pointing at a **Color** slot → wrapped as `{ fg: <color> }`.
121
- * - String ref pointing at a **Style** slot → returned directly.
122
- * - String ref that doesn't match a slot → treated as a fg color
123
- * (`{ fg: <ref> }`) and resolved downstream by `colorParams`.
124
- * - `undefined` → `{}` (emits nothing).
125
- *
126
- * @internal
127
- */
128
- function resolveStyle(ref, theme) {
129
- return ThemeResolver.from(theme).getStyle(ref);
130
- }
131
- function parseColor(c) {
132
- const m = c.match(/^(.+?)([+-]\d{1,3})$/);
133
- if (!m) return { base: c };
134
- let lightness = Number(m[2]);
135
- if (!Number.isFinite(lightness)) throw new TypeError(`Invalid color step in color "${c}": ${m[2]}`);
136
- lightness = Math.abs(lightness) < 1 ? lightness : lightness / 100;
137
- return {
138
- base: m[1],
139
- lightness
140
- };
141
- }
142
- var ThemeResolver = class ThemeResolver {
143
- static #cache = /* @__PURE__ */ new Map();
144
- static #main = new ThemeResolver();
145
- #theme;
146
- #styleCache = /* @__PURE__ */ new Map();
147
- #colorCache = /* @__PURE__ */ new Map();
148
- constructor(theme = {}) {
149
- this.#theme = theme;
150
- }
151
- static from(theme) {
152
- if (theme === void 0) return this.#main;
153
- let resolver = this.#cache.get(theme);
154
- if (!resolver) {
155
- resolver = new ThemeResolver(theme);
156
- this.#cache.set(theme, resolver);
157
- }
158
- return resolver;
159
- }
160
- getStyle(ref, seen) {
161
- if (ref === void 0) return {};
162
- if (typeof ref === "object") return ref.style ? {
163
- ...this.getStyle(ref.style, seen),
164
- ...ref
165
- } : ref;
166
- let ret = this.#styleCache.get(ref);
167
- if (ret) return ret;
168
- seen ??= /* @__PURE__ */ new Set();
169
- if (seen.has(ref)) throw new TypeError(`Circular dependency for theme slot "${ref}".`);
170
- seen.add(ref);
171
- const value = this.#theme[ref];
172
- ret = value === void 0 ? { fg: ref } : this.getStyle(value, seen);
173
- this.#styleCache.set(ref, ret);
174
- return ret;
175
- }
176
- getColor(ref, kind = "fg", seen) {
177
- if (ref === void 0) return "inherit";
178
- const key = `${kind}:${ref}`;
179
- let ret = this.#colorCache.get(key);
180
- if (ret) return ret;
181
- seen ??= /* @__PURE__ */ new Set();
182
- if (seen.has(ref)) throw new TypeError(`Circular dependency for theme slot "${ref}".`);
183
- seen.add(ref);
184
- const { base, lightness } = parseColor(ref);
185
- let value = this.#theme[base] ?? base;
186
- if (typeof value === "object") value = this.getColor(value[kind], kind, seen);
187
- else if (value !== base) value = this.getColor(value, kind, seen);
188
- ret = lightness !== void 0 && isHexColor(value) ? shiftLightness(value, lightness) : value;
189
- this.#colorCache.set(key, ret);
190
- return ret;
191
- }
192
- };
193
- //#endregion
194
- //#region src/style/builder.ts
195
- /**
196
- * Build styled strings via chainable property access.
197
- *
198
- * ```ts
199
- * style().red.bold("err") // → "\x1b[1;31merr\x1b[0m"
200
- * style().primary.bgAccent("x") // theme slots via the default theme
201
- * style(myTheme).primary("x") // override the bound theme
202
- * style().fg("#82aaff")("x") // hex via the escape hatch
203
- * style().primary[300]("x") // tonal variant of the last color
204
- * style().bgDiffAdd[200].fgDiffAdd("x") // per-channel variants on a Style slot
205
- * ```
206
- *
207
- * Each property access returns a fresh builder, so intermediates can be
208
- * reused and extended without mutation:
209
- *
210
- * ```ts
211
- * const err = style().red.bold
212
- * err("oops"); err.underline("fatal")
213
- * ```
214
- *
215
- * Calling an empty builder is a no-op: `styleBuilder()("x")` returns `"x"` unchanged.
216
- */
217
- function styleBuilder(theme = defaultTheme) {
218
- return build({
219
- current: {},
220
- last: void 0,
221
- theme: theme === false ? {
222
- ...defaultTheme,
223
- enabled: false
224
- } : theme
225
- });
226
- }
227
- const ATTRS = /* @__PURE__ */ new Set([
228
- "bold",
229
- "dim",
230
- "italic",
231
- "underline",
232
- "inverse",
233
- "strikethrough"
234
- ]);
235
- function applyStyle(state, text) {
236
- if (!text || state.theme.enabled === false) return text;
237
- const open = openStyle(state.current, state.theme);
238
- return open === "" ? text : open + reapplyStyle(text, open) + RESET;
239
- }
240
- function applyOp(fn, arg) {
241
- if (typeof arg === "string" || typeof arg === "number") {
242
- const key = String(arg);
243
- const hit = fn[key];
244
- if (hit !== void 0) return hit;
245
- const child = fulfill(fn.state, arg);
246
- Reflect.defineProperty(fn, key, {
247
- configurable: false,
248
- value: child,
249
- writable: false
250
- });
251
- return child;
252
- }
253
- return fulfill(fn.state, arg);
254
- }
255
- /** Turn a parked chain + its arg into the real child chain. */
256
- function fulfill(state, arg) {
257
- const { current, last, theme, pending } = state;
258
- switch (pending) {
259
- case "fg": return build({
260
- current: {
261
- ...current,
262
- fg: arg
263
- },
264
- last: "fg",
265
- theme
266
- });
267
- case "bg": return build({
268
- current: {
269
- ...current,
270
- bg: arg
271
- },
272
- last: "bg",
273
- theme
274
- });
275
- case "lighten":
276
- case "darken": {
277
- if (last === void 0) return build({
278
- current,
279
- last,
280
- theme
281
- });
282
- const existing = current[last];
283
- if (typeof existing !== "string" || existing === "inherit") return build({
284
- current,
285
- last,
286
- theme
287
- });
288
- const next = `${existing.replace(/[+-]\d+$/, "")}${pending === "lighten" ? "+" : "-"}${Math.abs(arg)}`;
289
- return build({
290
- current: {
291
- ...current,
292
- [last]: next
293
- },
294
- last,
295
- theme
296
- });
297
- }
298
- default: return build({
299
- current: {
300
- ...current,
301
- ...resolveStyle(arg, theme)
302
- },
303
- last,
304
- theme
305
- });
306
- }
307
- }
308
- /** Resolve a single property access on a chain to its child chain. */
309
- function compileKey(state, key) {
310
- const { current, last, theme } = state;
311
- if (key === "fg" || key === "bg" || key === "lighten" || key === "darken" || key === "add") return build({
312
- current,
313
- last,
314
- pending: key,
315
- theme
316
- });
317
- if (ATTRS.has(key)) return build({
318
- current: {
319
- ...current,
320
- [key]: true
321
- },
322
- last,
323
- theme
324
- });
325
- if (key.startsWith("bg") && key.length > 2 && key[2] === key[2].toUpperCase()) {
326
- const color = key[2].toLowerCase() + key.slice(3);
327
- return build({
328
- current: {
329
- ...current,
330
- bg: color
331
- },
332
- last: "bg",
333
- theme
334
- });
335
- }
336
- if (key.startsWith("fg") && key.length > 2 && key[2] === key[2].toUpperCase()) {
337
- const color = key[2].toLowerCase() + key.slice(3);
338
- return build({
339
- current: {
340
- ...current,
341
- fg: color
342
- },
343
- last: "fg",
344
- theme
345
- });
346
- }
347
- return build({
348
- current: {
349
- ...current,
350
- ...resolveStyle(key, theme)
351
- },
352
- last: "fg",
353
- theme
354
- });
355
- }
356
- /** Shared Proxy handler — one instance, used by every chain. Reads
357
- * state off the target (the `BuilderFn`), so chain construction
358
- * doesn't allocate a fresh handler object per `build()` call. */
359
- const proxyHandler = { get(target, key) {
360
- if (typeof key !== "string") return void 0;
361
- const cached = target[key];
362
- if (cached !== void 0) return cached;
363
- if (target.state.pending !== void 0) return void 0;
364
- const child = compileKey(target.state, key);
365
- if (child === void 0) return void 0;
366
- Reflect.defineProperty(target, key, {
367
- configurable: false,
368
- value: child,
369
- writable: false
370
- });
371
- return child;
372
- } };
373
- function build(state) {
374
- const fn = state.pending === void 0 ? function apply(text) {
375
- return applyStyle(state, text);
376
- } : function applyOpCall(arg) {
377
- return applyOp(fn, arg);
378
- };
379
- fn.state = state;
380
- fn.theme = state.theme;
381
- return new Proxy(fn, proxyHandler);
382
- }
383
- //#endregion
384
- export { openStyle as n, styleBuilder as t };
385
-
386
- //# sourceMappingURL=builder-1z5ewEWK.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"builder-1z5ewEWK.mjs","names":[],"sources":["../src/style/oklch.ts","../src/style/style.ts","../src/style/builder.ts"],"sourcesContent":["/**\n * OKLCH-based tonal scale generation for theme colors.\n *\n * Given a base hex color, `variant(hex, step)` returns a hex variant at\n * the Tailwind-v4-ish step (50..950). The base color's hue and chroma\n * are preserved; only lightness moves. When the resulting color falls\n * outside sRGB, chroma is reduced via binary search (CSS Color Level 4\n * \"MinDE chroma reduction\") until the color fits — that avoids the\n * saturation blowout you get from naive HSL lightening at the extremes.\n *\n * Matrix constants come from Björn Ottosson's reference OKLab spec:\n * https://bottosson.github.io/posts/oklab/\n */\n\nimport type { HexColor } from \"./types.ts\"\n\nimport { clamp } from \"@zaly/shared\"\nimport { parseHex, toHex } from \"./color.ts\"\n\nexport interface OKLCH {\n L: number\n C: number\n h: number\n}\n\nconst cache = new Map<string, HexColor>()\n\n// ---------- conversions ----------\n\nfunction srgbToLinear(c: number): number {\n return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4\n}\n\nfunction linearToSrgb(c: number): number {\n return c <= 0.0031308 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055\n}\n\nexport function hexToOklch(hex: string): OKLCH {\n const [r8, g8, b8] = parseHex(hex)\n const r = srgbToLinear(r8 / 255)\n const g = srgbToLinear(g8 / 255)\n const b = srgbToLinear(b8 / 255)\n\n const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b\n const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b\n const s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b\n const lp = Math.cbrt(l)\n const mp = Math.cbrt(m)\n const sp = Math.cbrt(s)\n const L = 0.2104542553 * lp + 0.793617785 * mp - 0.0040720468 * sp\n const a = 1.9779984951 * lp - 2.428592205 * mp + 0.4505937099 * sp\n const b2 = 0.0259040371 * lp + 0.7827717662 * mp - 0.808675766 * sp\n const C = Math.hypot(a, b2)\n const h = ((Math.atan2(b2, a) * 180) / Math.PI + 360) % 360\n return { C, L, h }\n}\n\n/** Convert OKLCH → linear sRGB (unclamped — callers can test for gamut). */\nfunction oklchToLinearRgb({ L, C, h }: OKLCH): [number, number, number] {\n const hr = (h * Math.PI) / 180\n const a = C * Math.cos(hr)\n const b2 = C * Math.sin(hr)\n const lp = L + 0.3963377774 * a + 0.2158037573 * b2\n const mp = L - 0.1055613458 * a - 0.0638541728 * b2\n const sp = L - 0.0894841775 * a - 1.291485548 * b2\n const l = lp ** 3\n const m = mp ** 3\n const s = sp ** 3\n const r = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s\n const g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s\n const b = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s\n return [r, g, b]\n}\n\nfunction inGamut([r, g, b]: [number, number, number], eps = 0.001): boolean {\n return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps\n}\n\n/**\n * Convert OKLCH → hex, reducing chroma via binary search when the\n * straightforward conversion falls outside sRGB. The search keeps `L`\n * and `h` fixed and shrinks `C` toward the achromatic axis until the\n * color fits, which is the CSS Color Level 4-recommended behavior.\n */\nexport function oklchToHex(oklch: OKLCH): HexColor {\n let rgb = oklchToLinearRgb(oklch)\n if (!inGamut(rgb)) {\n // Binary-search on C.\n let lo = 0\n let hi = oklch.C\n for (let i = 0; i < 24; i++) {\n const mid = (lo + hi) / 2\n if (inGamut(oklchToLinearRgb({ ...oklch, C: mid }))) lo = mid\n else hi = mid\n }\n rgb = oklchToLinearRgb({ ...oklch, C: lo })\n }\n const [r, g, b] = rgb.map((c) => linearToSrgb(Math.max(0, Math.min(1, c)))) as [\n number,\n number,\n number,\n ]\n return toHex(r * 255, g * 255, b * 255)\n}\n\nexport function shiftLightness(hex: HexColor, delta: number): HexColor {\n const key = `${hex}:${delta}`\n let ret = cache.get(key)\n if (ret) return ret\n\n const okl = hexToOklch(hex)\n const L = clamp(okl.L + delta, 0, 1)\n // Pull chroma toward 0 as L approaches an extreme. Keeps near-white\n // and near-black from going out of gamut.\n const margin = Math.min(L, 1 - L)\n const C = okl.C * Math.min(1, margin / 0.1)\n cache.set(key, (ret = oklchToHex({ ...okl, C, L })))\n return ret\n}\n","import type { Theme } from \"../themes/types.ts\"\nimport type { AnsiColor, AnsiStyle, Color, Style } from \"./types.ts\"\n\nimport { openAnsi } from \"./ansi.ts\"\nimport { isHexColor } from \"./color.ts\"\nimport { shiftLightness } from \"./oklch.ts\"\n\n/**\n * Build the opening SGR escape for a style descriptor. Returns '' if nothing\n * would be emitted. Unresolvable colors (invalid or 'inherit') are dropped.\n *\n * When `theme` is provided, `fg`/`bg` values matching a theme color slot\n * (e.g. `\"primary\"`, `\"muted\"`) are resolved against it first. The output\n * ordering is attrs → fg → bg, combined into a single `\\x1b[...m` run.\n *\n * @internal\n */\nexport function openStyle(style: Style, theme?: Theme): string {\n const resolver = ThemeResolver.from(theme)\n const ansiStyle: AnsiStyle = {\n ...style,\n bg: style.bg !== undefined ? resolver.getColor(style.bg, \"bg\") : undefined,\n fg: style.fg !== undefined ? resolver.getColor(style.fg, \"fg\") : undefined,\n }\n return openAnsi(ansiStyle)\n}\n\n/**\n * Resolve a style-slot reference into a `Style` object. A ref is either a\n * theme slot name (string), an inline `Style`, or `undefined`:\n *\n * - Inline `Style` → returned as-is (no slot lookup).\n * - String ref pointing at a **Color** slot → wrapped as `{ fg: <color> }`.\n * - String ref pointing at a **Style** slot → returned directly.\n * - String ref that doesn't match a slot → treated as a fg color\n * (`{ fg: <ref> }`) and resolved downstream by `colorParams`.\n * - `undefined` → `{}` (emits nothing).\n *\n * @internal\n */\nexport function resolveStyle(ref: string | Style | undefined, theme?: Theme): Style {\n return ThemeResolver.from(theme).getStyle(ref)\n}\n\nfunction parseColor(c: string): { base: string; lightness?: number } {\n const m = c.match(/^(.+?)([+-]\\d{1,3})$/)\n if (!m) return { base: c }\n let lightness = Number(m[2])\n if (!Number.isFinite(lightness))\n throw new TypeError(`Invalid color step in color \"${c}\": ${m[2]}`)\n lightness = Math.abs(lightness) < 1 ? lightness : lightness / 100\n return { base: m[1], lightness }\n}\n\nclass ThemeResolver {\n static #cache = new Map<Partial<Theme>, ThemeResolver>()\n static #main = new ThemeResolver()\n #theme: Partial<Theme>\n #styleCache = new Map<string, Style>()\n #colorCache = new Map<string, string>()\n\n private constructor(theme: Partial<Theme> = {}) {\n this.#theme = theme\n }\n\n static from(theme?: Theme): ThemeResolver {\n if (theme === undefined) return this.#main\n let resolver = this.#cache.get(theme)\n if (!resolver) {\n resolver = new ThemeResolver(theme)\n this.#cache.set(theme, resolver)\n }\n return resolver\n }\n\n getStyle(ref?: string | Style, seen?: Set<string>): Style {\n if (ref === undefined) return {}\n if (typeof ref === \"object\")\n return ref.style ? { ...this.getStyle(ref.style, seen), ...ref } : ref\n\n let ret = this.#styleCache.get(ref)\n if (ret) return ret\n\n seen ??= new Set<string>()\n if (seen.has(ref)) throw new TypeError(`Circular dependency for theme slot \"${ref}\".`)\n seen.add(ref)\n\n const value = this.#theme[ref as keyof Theme]\n ret = value === undefined ? { fg: ref as Color } : this.getStyle(value, seen)\n this.#styleCache.set(ref, ret)\n return ret\n }\n\n getColor(ref?: string, kind: \"fg\" | \"bg\" = \"fg\", seen?: Set<string>): AnsiColor {\n if (ref === undefined) return \"inherit\"\n\n const key = `${kind}:${ref}`\n let ret = this.#colorCache.get(key)\n if (ret) return ret as AnsiColor\n\n seen ??= new Set<string>()\n if (seen.has(ref)) throw new TypeError(`Circular dependency for theme slot \"${ref}\".`)\n seen.add(ref)\n\n const { base, lightness } = parseColor(ref)\n\n let value = this.#theme[base as keyof Theme] ?? base\n if (typeof value === \"object\") value = this.getColor(value[kind], kind, seen)\n else if (value !== base) value = this.getColor(value, kind, seen)\n ret = lightness !== undefined && isHexColor(value) ? shiftLightness(value, lightness) : value\n this.#colorCache.set(key, ret)\n return ret as AnsiColor\n }\n}\n","import type { Theme } from \"../themes/types.ts\"\nimport type {\n AnsiColorName,\n AnyStyle,\n BrightAnsiColorName,\n Color,\n Style,\n ThemeKey,\n} from \"./types.ts\"\n\nimport { defaultTheme } from \"../themes/registry.ts\"\nimport { reapplyStyle, RESET } from \"./ansi.ts\"\nimport { openStyle, resolveStyle } from \"./style.ts\"\n\ntype AttrName = \"bold\" | \"dim\" | \"italic\" | \"underline\" | \"inverse\" | \"strikethrough\"\n\n// Theme color slots that can chain as fg/bg. `fg`/`bg` become setter methods\n// below, so exclude them here to avoid naming collisions. `dim` is an attr on\n// the chain; users wanting theme-slot-dim for fg use `.fg(\"dim\")`.\ntype ChainSlot<Ansi extends boolean = true> =\n | Exclude<ThemeKey, \"fg\" | \"bg\" | AttrName>\n | (Ansi extends true ? AnsiColorName : never)\n | (Ansi extends true ? BrightAnsiColorName : never)\n\nexport type StyleBuilder<Ansi extends boolean = false> = {\n theme: Theme\n (text: string): string\n fg: (color: Color<Ansi>) => StyleBuilder<Ansi>\n bg: (color: Color<Ansi>) => StyleBuilder<Ansi>\n add: (slot?: ThemeKey | AnyStyle) => StyleBuilder<Ansi>\n lighten: (n: number) => StyleBuilder<Ansi>\n darken: (n: number) => StyleBuilder<Ansi>\n // oxlint-disable-next-line typescript/consistent-indexed-object-style -- mapped over a key union, not an open string index\n} & {\n readonly [\n K in\n | AttrName\n | ChainSlot<Ansi>\n | `bg${Capitalize<ChainSlot<Ansi>>}`\n | `fg${Capitalize<ChainSlot<Ansi>>}`\n ]: StyleBuilder<Ansi>\n}\n\n/**\n * Build styled strings via chainable property access.\n *\n * ```ts\n * style().red.bold(\"err\") // → \"\\x1b[1;31merr\\x1b[0m\"\n * style().primary.bgAccent(\"x\") // theme slots via the default theme\n * style(myTheme).primary(\"x\") // override the bound theme\n * style().fg(\"#82aaff\")(\"x\") // hex via the escape hatch\n * style().primary[300](\"x\") // tonal variant of the last color\n * style().bgDiffAdd[200].fgDiffAdd(\"x\") // per-channel variants on a Style slot\n * ```\n *\n * Each property access returns a fresh builder, so intermediates can be\n * reused and extended without mutation:\n *\n * ```ts\n * const err = style().red.bold\n * err(\"oops\"); err.underline(\"fatal\")\n * ```\n *\n * Calling an empty builder is a no-op: `styleBuilder()(\"x\")` returns `\"x\"` unchanged.\n */\nexport function styleBuilder<Ansi extends boolean = false>(\n theme: Theme | false = defaultTheme\n): StyleBuilder<Ansi> {\n return build({\n current: {},\n last: undefined,\n theme: theme === false ? { ...defaultTheme, enabled: false } : theme,\n }) as StyleBuilder<Ansi>\n}\n\nconst ATTRS = new Set<string>([\"bold\", \"dim\", \"italic\", \"underline\", \"inverse\", \"strikethrough\"])\n\n/** Pending \"arg-taking\" op on a chain. Set when the caller accesses\n * `.fg` / `.bg` / `.alpha` / `.add` — the chain is \"parked\" waiting\n * for its argument. Calling the parked chain consumes the arg and\n * produces the real child chain. */\ntype PendingOp = \"fg\" | \"bg\" | \"darken\" | \"add\" | \"lighten\"\n\n/** All the inputs a chain needs to behave correctly, gathered in one\n * object so we can pass it around cheaply instead of closing over\n * four separate vars. `current` is the accumulated Style, `last`\n * tracks which of `fg`/`bg` was most recently touched (for `[step]`\n * and `.alpha()`), `theme` is the resolved theme, `pending` is set\n * on parked arg-taking chains. */\ninterface BuilderState {\n current: Style\n last: \"fg\" | \"bg\" | undefined\n theme: Theme & { enabled?: boolean }\n pending?: PendingOp\n}\n\n/** The function wrapped by every chain's Proxy. Carries its own state\n * so module-level handlers can read it without closure gymnastics. */\ntype BuilderFn = {\n state: BuilderState\n theme: Theme\n} & (((text: string) => string) | ((arg: Color | number | Style | undefined) => StyleBuilder))\n\n// --- module-level handlers (shared across every chain) -----------------\n\nfunction applyStyle(state: BuilderState, text: string): string {\n if (!text || state.theme.enabled === false) return text\n const open = openStyle(state.current, state.theme)\n return open === \"\" ? text : open + reapplyStyle(text, open) + RESET\n}\n\nfunction applyOp(fn: BuilderFn, arg: Color | number | Style | undefined): StyleBuilder {\n // Cache primitive args on the call target itself via `defineProperty`\n // — repeated `.fg(\"#82aaff\")` hits the same child chain after the\n // first call, no rebuild. Object args (e.g. raw Style for `add`)\n // can't be property keys (`\"[object Object]\"` collision), so those\n // always rebuild.\n if (typeof arg === \"string\" || typeof arg === \"number\") {\n const key = String(arg)\n const hit = (fn as unknown as Record<string, unknown>)[key]\n if (hit !== undefined) return hit as StyleBuilder\n const child = fulfill(fn.state, arg)\n Reflect.defineProperty(fn, key, { configurable: false, value: child, writable: false })\n return child\n }\n return fulfill(fn.state, arg)\n}\n\n/** Turn a parked chain + its arg into the real child chain. */\nfunction fulfill(state: BuilderState, arg: unknown): StyleBuilder {\n const { current, last, theme, pending } = state\n switch (pending) {\n case \"fg\": {\n return build({ current: { ...current, fg: arg as Color }, last: \"fg\", theme })\n }\n case \"bg\": {\n return build({ current: { ...current, bg: arg as Color }, last: \"bg\", theme })\n }\n case \"lighten\":\n case \"darken\": {\n if (last === undefined) return build({ current, last, theme })\n const existing = current[last]\n if (typeof existing !== \"string\" || existing === \"inherit\") {\n return build({ current, last, theme })\n }\n const stripped = existing.replace(/[+-]\\d+$/, \"\")\n const n = Math.abs(arg as number)\n const next = `${stripped}${pending === \"lighten\" ? \"+\" : \"-\"}${n}` as Color\n return build({ current: { ...current, [last]: next }, last, theme })\n }\n default: {\n // \"add\" — no pending pending? defaults to rebuild with undef arg.\n return build({\n current: { ...current, ...resolveStyle(arg as string | Style | undefined, theme) },\n last,\n theme,\n })\n }\n }\n}\n\n/** Resolve a single property access on a chain to its child chain. */\nfunction compileKey(state: BuilderState, key: string): StyleBuilder | undefined {\n const { current, last, theme } = state\n\n // Arg-taking ops come back as chains parked in the `pending` state.\n if (key === \"fg\" || key === \"bg\" || key === \"lighten\" || key === \"darken\" || key === \"add\") {\n return build({ current, last, pending: key, theme })\n }\n\n if (ATTRS.has(key)) return build({ current: { ...current, [key]: true }, last, theme })\n\n // `bgFoo` / `fgFoo` → set the channel to the color at slot `foo`.\n // When the slot is a Style, `colorParams` extracts that channel.\n if (key.startsWith(\"bg\") && key.length > 2 && key[2] === key[2].toUpperCase()) {\n const color = (key[2].toLowerCase() + key.slice(3)) as Color\n return build({ current: { ...current, bg: color }, last: \"bg\", theme })\n }\n if (key.startsWith(\"fg\") && key.length > 2 && key[2] === key[2].toUpperCase()) {\n const color = (key[2].toLowerCase() + key.slice(3)) as Color\n return build({ current: { ...current, fg: color }, last: \"fg\", theme })\n }\n\n // Style-valued theme slot → merge its fields into the chain.\n // Anything else (ANSI color names, hex, unresolved slot refs) is\n // treated as a fg color by `colorParams` downstream.\n return build({ current: { ...current, ...resolveStyle(key, theme) }, last: \"fg\", theme })\n}\n\n/** Shared Proxy handler — one instance, used by every chain. Reads\n * state off the target (the `BuilderFn`), so chain construction\n * doesn't allocate a fresh handler object per `build()` call. */\nconst proxyHandler: ProxyHandler<BuilderFn> = {\n get(target, key) {\n if (typeof key !== \"string\") return undefined\n const cached = (target as unknown as Record<string, unknown>)[key]\n if (cached !== undefined) return cached\n // Parked chains can't be chained further — they're waiting for a call.\n if (target.state.pending !== undefined) return undefined\n const child = compileKey(target.state, key)\n if (child === undefined) return undefined\n Reflect.defineProperty(target, key, { configurable: false, value: child, writable: false })\n return child\n },\n}\n\nfunction build(state: BuilderState): StyleBuilder {\n // Two dedicated function shapes so V8 sees a stable signature on\n // each hot path — styling text vs. consuming an op arg are both\n // monomorphic after the build-time ternary.\n const fn = (\n state.pending === undefined\n ? function apply(text: string): string {\n return applyStyle(state, text)\n }\n : function applyOpCall(arg: Color | number | Style | undefined): StyleBuilder {\n return applyOp(fn, arg)\n }\n ) as BuilderFn\n fn.state = state\n fn.theme = state.theme\n return new Proxy(fn, proxyHandler) as unknown as StyleBuilder\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-C2GXKfJ1.mjs","names":[],"sources":["../src/shiki/client.ts"],"sourcesContent":["import type {\n ShikiJob,\n ShikiOpts,\n ShikiRequest,\n ShikiResult,\n ShikiWorkerMessage,\n ShikiWorkerRequest,\n} from \"./types.ts\"\nimport type { WorkerInstance } from \"./worker.ts\"\n\nimport { hash, toError } from \"@zaly/shared\"\nimport { hasColors } from \"@zaly/shared/env\"\nimport { isShikiLang } from \"../schemas/gen/shiki.ts\"\n\nfunction isJob(s: ShikiJob | ShikiResult): s is ShikiJob {\n return \"key\" in s && \"lang\" in s\n}\n\nconst MAX_CACHE_SIZE = 100\n// Max jobs posted to the worker. Worker still processes serially.\nconst MAX_RUNNING = 2\nconst REQUEST_TIMEOUT = 30_000\n\nexport class ShikiWorkerClient {\n #id = 0\n #cache = new Map<string, ShikiJob>()\n #queue = new Map<number, ShikiJob>()\n #running = new Map<number, ShikiJob>()\n #results: ShikiResult[] = []\n #timeouts = new Map<number, ReturnType<typeof setTimeout>>()\n #worker?: WorkerInstance<ShikiWorkerRequest, ShikiWorkerMessage>\n #workerPromise?: Promise<WorkerInstance<ShikiWorkerRequest, ShikiWorkerMessage>>\n #timeout: number\n #updateScheduled: Promise<void> | undefined = undefined\n #updatePending = false\n\n constructor(opts: { timeout?: number } = {}) {\n this.#timeout = opts.timeout ?? REQUEST_TIMEOUT\n }\n\n key(req: ShikiRequest): string {\n return req.key ?? hash(`${req.lang}:${req.code}:${req.theme ?? \"default\"}`)\n }\n\n toJob(req: ShikiRequest): ShikiJob | ShikiResult {\n const id = ++this.#id\n const key = this.key(req)\n if (!hasColors) return { error: \"terminal does not support colors\", id, key, value: req.code }\n if (!isShikiLang(req.lang))\n return { error: `unsupported language: ${req.lang}`, id, key, value: req.code }\n const cached = this.#cache.get(key)\n if (cached) {\n this.#cache.delete(key)\n this.#cache.set(key, cached) // bump to end of LRU\n return cached\n }\n while (this.#cache.size > MAX_CACHE_SIZE) this.#cache.delete(this.#cache.keys().next().value!)\n const ret: ShikiJob = { ...req, id, key, lang: req.lang, ...Promise.withResolvers() }\n this.#cache.set(key, ret)\n return ret\n }\n\n highlight(code: string, lang: string, opts: ShikiOpts = {}): Promise<ShikiResult> {\n const req: ShikiRequest = { code, lang, signal: opts.signal, theme: opts.theme }\n const job = this.toJob(req)\n if (!isJob(job)) return Promise.resolve(job)\n if (!job.scheduled) {\n this.#queue.set(job.id, job)\n job.signal?.addEventListener(\"abort\", () => this.update(), { once: true })\n this.update()\n }\n return job.promise\n }\n\n dispose(): void {\n const error = new Error(\"Shiki worker disposed\")\n this.#rejectAll(error)\n }\n\n async #request(job: ShikiJob): Promise<void> {\n job.scheduled = true\n this.#running.set(job.id, job)\n const worker = await this.#createWorker()\n const { signal: _s, promise: _prom, resolve: _res, reject: _rej, ...msg } = job\n const timeout = setTimeout(\n () =>\n this.#fail(\n new Error(`Shiki worker timed out after ${this.#timeout}ms (${job.lang}, ${job.key})`)\n ),\n this.#timeout\n )\n timeout.unref()\n this.#timeouts.set(job.id, timeout)\n // oxlint-disable-next-line unicorn/require-post-message-target-origin\n worker.postMessage(msg)\n }\n\n async #createWorker(): Promise<WorkerInstance<ShikiWorkerRequest, ShikiWorkerMessage>> {\n if (this.#worker) return this.#worker\n this.#workerPromise ??= (async () => {\n const { createWorker } = await import(\"./worker.ts\")\n const worker = await createWorker<ShikiWorkerRequest, ShikiWorkerMessage>()\n const ready = Promise.withResolvers<void>()\n let started = false\n const timeout = setTimeout(\n () => ready.reject(new Error(`Shiki worker did not start within ${this.#timeout}ms`)),\n this.#timeout\n )\n timeout.unref()\n worker.on(\"message\", (event) => {\n if (event.type === \"ready\") {\n started = true\n ready.resolve()\n return\n }\n this.#clearTimeout(event.id)\n this.#running.delete(event.id)\n this.#results.push(event)\n this.update()\n })\n worker.on(\"error\", (error) => {\n if (started) this.#fail(error)\n else ready.reject(error)\n })\n try {\n await ready.promise\n return worker\n } catch (error) {\n worker.terminate()\n throw error\n } finally {\n clearTimeout(timeout)\n }\n })()\n return (this.#worker = await this.#workerPromise)\n }\n\n update() {\n this.#updatePending = true\n if (this.#updateScheduled) return\n this.#updateScheduled = (async () => {\n while (this.#updatePending) {\n this.#updatePending = false\n // oxlint-disable-next-line no-await-in-loop\n await this.#update()\n }\n })()\n .catch((error) => this.#fail(error))\n .finally(() => {\n this.#updateScheduled = undefined\n if (this.#updatePending) this.update()\n })\n }\n\n async #update() {\n // Resolve pending results\n while (this.#results.length) {\n const result = this.#results.shift()!\n const job = this.#queue.get(result.id)\n if (job) {\n if (result.error) {\n const error = new Error(result.error)\n // oxlint-disable-next-line no-console\n console.error(\"Shiki highlighting failed:\", error)\n job.reject(error)\n } else job.resolve(result)\n\n // oxlint-disable-next-line no-await-in-loop\n await new Promise((resolve) => setImmediate(resolve)) // yield to event loop between batches\n this.#queue.delete(job.id)\n }\n }\n\n // Clean up aborted jobs\n for (const job of this.#queue.values()) {\n if (job.signal?.aborted && !job.scheduled) {\n job.reject(new Error(\"Job aborted\"))\n this.#queue.delete(job.id)\n this.#cache.delete(job.key)\n }\n }\n\n if (this.#running.size >= MAX_RUNNING || this.#queue.size === 0) return\n\n // Schedule new jobs up to concurrency limit, prioritizing the most recently requested ones (LIFO)\n const todo = [...this.#queue.values()]\n .filter((j) => !j.scheduled)\n .slice(-(MAX_RUNNING - this.#running.size))\n await Promise.all(todo.map((j) => this.#request(j)))\n }\n\n #clearTimeout(id: number): void {\n const timeout = this.#timeouts.get(id)\n if (timeout) clearTimeout(timeout)\n this.#timeouts.delete(id)\n }\n\n #fail(error: unknown): void {\n error = toError(error)\n // oxlint-disable-next-line no-console\n console.error(\"Shiki worker failed:\", error)\n this.#rejectAll(error)\n }\n\n #rejectAll(error: unknown): void {\n for (const { reject } of this.#queue.values()) reject(error)\n this.#cache.clear()\n this.#queue.clear()\n this.#running.clear()\n this.#results = []\n for (const timeout of this.#timeouts.values()) clearTimeout(timeout)\n this.#timeouts.clear()\n this.#updatePending = false\n this.#worker?.terminate()\n this.#worker = undefined\n this.#workerPromise = undefined\n }\n}\n\nexport const shikiWorker = new ShikiWorkerClient()\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- export { n as shikiWorker } from "./client-C2GXKfJ1.mjs";
@@ -1 +0,0 @@
1
- export { t as createCtx } from "./ctx-B7BmPUCD.mjs";
@@ -1,108 +0,0 @@
1
- import { stripAnsi } from "@zaly/shared/ansi";
2
- import { basename } from "pathe";
3
- //#region src/markdown/image.ts
4
- /**
5
- * Image callback + post-processor for the markdown pipeline.
6
- *
7
- * The markdown renderer is synchronous (callbacks return strings), but
8
- * image preparation is async (sharp metadata, KGP transmit, format
9
- * conversion). We reconcile with a two-pass approach:
10
- *
11
- * 1. During rendering, the `image` callback pushes `{ src, alt }` into
12
- * the entries array and emits a compact `<img id=N>` marker where
13
- * `N` is the entry's index. The marker is plain text so any
14
- * renderer (marked or `Bun.markdown.render`) emits it verbatim.
15
- * 2. After rendering, `resolve(ctx, rendered)` renders every unique
16
- * src concurrently via cached `Image` nodes, then replaces each
17
- * marker with either the rendered rows (for *block* images — ones
18
- * that end up on their own line) or the markdown alt text (for
19
- * inline images, which would otherwise break text flow).
20
- *
21
- * The caller passes in a persistent `cache: Map<src, Image>` owned by
22
- * the Markdown instance so re-renders reuse the same Image node (and
23
- * therefore the same KGP placement id, which the spec guarantees is a
24
- * flicker-free move/resize).
25
- */
26
- function createImageCallback(host) {
27
- const entries = [];
28
- const cache = host.images;
29
- return {
30
- cb(alt, meta) {
31
- const id = entries.length;
32
- entries.push({
33
- alt,
34
- src: meta.src
35
- });
36
- return `<img id=${id}>`;
37
- },
38
- async resolve(ctx, rendered) {
39
- if (entries.length === 0) return rendered;
40
- const { Image } = await import("./widgets/image.mjs");
41
- const ordinals = /* @__PURE__ */ new Map();
42
- const rowsByEntry = [];
43
- const used = /* @__PURE__ */ new Set();
44
- await Promise.all(entries.map(async (entry, idx) => {
45
- const ord = ordinals.get(entry.src) ?? 0;
46
- ordinals.set(entry.src, ord + 1);
47
- const key = `${entry.src}\u0000${ord}`;
48
- used.add(key);
49
- let img = cache.get(key);
50
- if (img === void 0) {
51
- img = new Image({
52
- alt: entry.alt,
53
- src: entry.src
54
- });
55
- host.add(img);
56
- cache.set(key, img);
57
- }
58
- rowsByEntry[idx] = await img.render(ctx);
59
- }));
60
- for (const [key] of cache) if (!used.has(key)) {
61
- const img = cache.get(key);
62
- if (img) {
63
- host.remove(img);
64
- cache.delete(key);
65
- }
66
- }
67
- const out = [];
68
- for (const line of rendered.split("\n")) {
69
- const matched = [];
70
- for (const m of line.matchAll(MARKER_RE)) {
71
- const idx = Number(m[1]);
72
- matched.push({
73
- entry: entries[idx],
74
- rows: rowsByEntry[idx] ?? []
75
- });
76
- }
77
- if (matched.length === 0) {
78
- out.push(line);
79
- continue;
80
- }
81
- if (matched.length === 1 && stripAnsi(line.replace(MARKER_RE, "")).trim() === "" && matched[0].rows.length > 0) {
82
- out.push(...matched[0].rows);
83
- continue;
84
- }
85
- out.push(line.replaceAll(MARKER_RE, (_, idxStr) => labelOf(entries[Number(idxStr)])));
86
- for (const { rows } of matched) if (rows.some(isRealGraphics)) out.push(...rows);
87
- }
88
- return out.join("\n");
89
- }
90
- };
91
- }
92
- /** Friendly inline placeholder for an image that can't render at this
93
- * position. Prefers the markdown alt text; falls back to the basename
94
- * of the source path (so `[clip.png]` instead of `[/tmp/long/path/clip.png]`),
95
- * and "image" for anything weirder. */
96
- function labelOf(entry) {
97
- return `[${entry.alt !== "" ? entry.alt : basename(entry.src) || "image"}]`;
98
- }
99
- const MARKER_RE = /<img id=(\d+)>/g;
100
- /** True when a row contains a Kitty Graphics Protocol escape (transmit
101
- * or place) — i.e. real image data, not the text alt fallback. */
102
- function isRealGraphics(row) {
103
- return row.includes("\x1B_G");
104
- }
105
- //#endregion
106
- export { createImageCallback };
107
-
108
- //# sourceMappingURL=image-Cm5T-uw-.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"image-Cm5T-uw-.mjs","names":[],"sources":["../src/markdown/image.ts"],"sourcesContent":["import type { RenderCtx } from \"../core/ctx.ts\"\nimport type { Node } from \"../core/node.ts\"\nimport type { Image } from \"../widgets/image.ts\"\nimport type { MdCallbacks, MdImageMeta } from \"./types.ts\"\n\nimport { stripAnsi } from \"@zaly/shared/ansi\"\nimport { basename } from \"pathe\"\n\n/** Minimal host shape the image callback needs. Any Node-like parent\n * with a per-src `Image` cache satisfies it — the `Markdown` widget is\n * the primary caller but the interface keeps this file decoupled from\n * widget internals (and breaks the widgets↔markdown import loop). */\nexport interface ImageHost {\n /** Per-src cache so re-renders reuse the same `Image` — same KGP\n * placement id, which the spec guarantees is a flicker-free\n * move/resize. */\n images: Map<string, Image>\n /** Attach a freshly-created `Image` as a child so mount/unmount\n * propagate. */\n add: (child: Node) => unknown\n remove: (child: Node) => unknown\n}\n\n/** Per-occurrence image metadata collected during markdown rendering. */\ninterface ImageEntry {\n src: string\n alt: string\n}\n\n/**\n * Image callback + post-processor for the markdown pipeline.\n *\n * The markdown renderer is synchronous (callbacks return strings), but\n * image preparation is async (sharp metadata, KGP transmit, format\n * conversion). We reconcile with a two-pass approach:\n *\n * 1. During rendering, the `image` callback pushes `{ src, alt }` into\n * the entries array and emits a compact `<img id=N>` marker where\n * `N` is the entry's index. The marker is plain text so any\n * renderer (marked or `Bun.markdown.render`) emits it verbatim.\n * 2. After rendering, `resolve(ctx, rendered)` renders every unique\n * src concurrently via cached `Image` nodes, then replaces each\n * marker with either the rendered rows (for *block* images — ones\n * that end up on their own line) or the markdown alt text (for\n * inline images, which would otherwise break text flow).\n *\n * The caller passes in a persistent `cache: Map<src, Image>` owned by\n * the Markdown instance so re-renders reuse the same Image node (and\n * therefore the same KGP placement id, which the spec guarantees is a\n * flicker-free move/resize).\n */\nexport function createImageCallback(host: ImageHost): {\n cb: MdCallbacks[\"image\"]\n resolve: (ctx: RenderCtx, rendered: string) => Promise<string>\n} {\n const entries: ImageEntry[] = []\n const cache = host.images\n\n return {\n cb(alt: string, meta: MdImageMeta): string {\n const id = entries.length\n entries.push({ alt, src: meta.src })\n return `<img id=${id}>`\n },\n\n async resolve(ctx: RenderCtx, rendered: string): Promise<string> {\n if (entries.length === 0) return rendered\n\n // `Image` is heavy (pulls image-meta, sharp lazy loaders, KGP\n // encoder) and 99% of markdown has no images. Load it only when\n // we have something to place.\n const { Image } = await import(\"../widgets/image.ts\")\n\n // One Image (and therefore one KGP `placementId`) per occurrence\n // so multiple references to the same `src` show up as distinct\n // placements on screen. Cache key is `${src}\\0${ordinal-within-src}`\n // — the ordinal makes each repeated reference stable across\n // re-renders (slot 0 is always slot 0, so the placementId stays\n // pinned and KGP gives a flicker-free move/resize). Image bytes\n // are de-duped at a different layer (`transmitOnce` in kitty.ts),\n // so multiple occurrences cost N placements but only one transmit.\n const ordinals = new Map<string, number>()\n const rowsByEntry: string[][] = []\n const used = new Set<string>()\n await Promise.all(\n entries.map(async (entry, idx) => {\n const ord = ordinals.get(entry.src) ?? 0\n ordinals.set(entry.src, ord + 1)\n const key = `${entry.src}\\u0000${ord}`\n used.add(key)\n let img = cache.get(key)\n if (img === undefined) {\n img = new Image({ alt: entry.alt, src: entry.src })\n host.add(img)\n cache.set(key, img)\n }\n rowsByEntry[idx] = await img.render(ctx)\n })\n )\n\n for (const [key] of cache) {\n if (!used.has(key)) {\n const img = cache.get(key)\n if (img) {\n host.remove(img)\n cache.delete(key)\n }\n }\n }\n\n // Walk the rendered output line by line:\n // - Marker alone on its line (whitespace + ANSI tolerated) →\n // replace the line with the full image rows.\n // - Marker mid-line → inline ref placeholder, then splice the\n // image rows on the next line(s) so the picture still\n // appears below the surrounding text.\n // Multiple markers on one mid-line all get inline refs; their\n // image rows stack underneath in document order.\n const out: string[] = []\n for (const line of rendered.split(\"\\n\")) {\n const matched: { entry: ImageEntry; rows: string[] }[] = []\n for (const m of line.matchAll(MARKER_RE)) {\n const idx = Number(m[1])\n matched.push({ entry: entries[idx], rows: rowsByEntry[idx] ?? [] })\n }\n\n if (matched.length === 0) {\n out.push(line)\n continue\n }\n\n const lineHasOnlyMarker =\n matched.length === 1 && stripAnsi(line.replace(MARKER_RE, \"\")).trim() === \"\"\n\n if (lineHasOnlyMarker && matched[0].rows.length > 0) {\n out.push(...matched[0].rows)\n continue\n }\n\n // Mid-line: replace each marker with a nice inline ref, then\n // append every image's rows below the line in order. Skip rows\n // that don't contain real graphics (KGP escapes) — when the\n // terminal can't render images, `Image.render` falls back to a\n // single-row alt-text representation, which would just\n // duplicate the inline label we already emitted.\n out.push(\n line.replaceAll(MARKER_RE, (_, idxStr: string) => labelOf(entries[Number(idxStr)]))\n )\n for (const { rows } of matched) {\n if (rows.some(isRealGraphics)) out.push(...rows)\n }\n }\n return out.join(\"\\n\")\n },\n }\n}\n\n/** Friendly inline placeholder for an image that can't render at this\n * position. Prefers the markdown alt text; falls back to the basename\n * of the source path (so `[clip.png]` instead of `[/tmp/long/path/clip.png]`),\n * and \"image\" for anything weirder. */\nfunction labelOf(entry: ImageEntry): string {\n const label = entry.alt !== \"\" ? entry.alt : basename(entry.src) || \"image\"\n return `[${label}]`\n}\n\nconst MARKER_RE = /<img id=(\\d+)>/g\n\n/** True when a row contains a Kitty Graphics Protocol escape (transmit\n * or place) — i.e. real image data, not the text alt fallback. */\nfunction isRealGraphics(row: string): boolean {\n return row.includes(\"\\x1b_G\")\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,SAAgB,oBAAoB,MAGlC;CACA,MAAM,UAAwB,CAAC;CAC/B,MAAM,QAAQ,KAAK;CAEnB,OAAO;EACL,GAAG,KAAa,MAA2B;GACzC,MAAM,KAAK,QAAQ;GACnB,QAAQ,KAAK;IAAE;IAAK,KAAK,KAAK;GAAI,CAAC;GACnC,OAAO,WAAW,GAAG;EACvB;EAEA,MAAM,QAAQ,KAAgB,UAAmC;GAC/D,IAAI,QAAQ,WAAW,GAAG,OAAO;GAKjC,MAAM,EAAE,UAAU,MAAM,OAAO;GAU/B,MAAM,2BAAW,IAAI,IAAoB;GACzC,MAAM,cAA0B,CAAC;GACjC,MAAM,uBAAO,IAAI,IAAY;GAC7B,MAAM,QAAQ,IACZ,QAAQ,IAAI,OAAO,OAAO,QAAQ;IAChC,MAAM,MAAM,SAAS,IAAI,MAAM,GAAG,KAAK;IACvC,SAAS,IAAI,MAAM,KAAK,MAAM,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,QAAQ;IACjC,KAAK,IAAI,GAAG;IACZ,IAAI,MAAM,MAAM,IAAI,GAAG;IACvB,IAAI,QAAQ,KAAA,GAAW;KACrB,MAAM,IAAI,MAAM;MAAE,KAAK,MAAM;MAAK,KAAK,MAAM;KAAI,CAAC;KAClD,KAAK,IAAI,GAAG;KACZ,MAAM,IAAI,KAAK,GAAG;IACpB;IACA,YAAY,OAAO,MAAM,IAAI,OAAO,GAAG;GACzC,CAAC,CACH;GAEA,KAAK,MAAM,CAAC,QAAQ,OAClB,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG;IAClB,MAAM,MAAM,MAAM,IAAI,GAAG;IACzB,IAAI,KAAK;KACP,KAAK,OAAO,GAAG;KACf,MAAM,OAAO,GAAG;IAClB;GACF;GAWF,MAAM,MAAgB,CAAC;GACvB,KAAK,MAAM,QAAQ,SAAS,MAAM,IAAI,GAAG;IACvC,MAAM,UAAmD,CAAC;IAC1D,KAAK,MAAM,KAAK,KAAK,SAAS,SAAS,GAAG;KACxC,MAAM,MAAM,OAAO,EAAE,EAAE;KACvB,QAAQ,KAAK;MAAE,OAAO,QAAQ;MAAM,MAAM,YAAY,QAAQ,CAAC;KAAE,CAAC;IACpE;IAEA,IAAI,QAAQ,WAAW,GAAG;KACxB,IAAI,KAAK,IAAI;KACb;IACF;IAKA,IAFE,QAAQ,WAAW,KAAK,UAAU,KAAK,QAAQ,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM,MAEnD,QAAQ,EAAE,CAAC,KAAK,SAAS,GAAG;KACnD,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC,IAAI;KAC3B;IACF;IAQA,IAAI,KACF,KAAK,WAAW,YAAY,GAAG,WAAmB,QAAQ,QAAQ,OAAO,MAAM,EAAE,CAAC,CACpF;IACA,KAAK,MAAM,EAAE,UAAU,SACrB,IAAI,KAAK,KAAK,cAAc,GAAG,IAAI,KAAK,GAAG,IAAI;GAEnD;GACA,OAAO,IAAI,KAAK,IAAI;EACtB;CACF;AACF;;;;;AAMA,SAAS,QAAQ,OAA2B;CAE1C,OAAO,IADO,MAAM,QAAQ,KAAK,MAAM,MAAM,SAAS,MAAM,GAAG,KAAK,QACnD;AACnB;AAEA,MAAM,YAAY;;;AAIlB,SAAS,eAAe,KAAsB;CAC5C,OAAO,IAAI,SAAS,QAAQ;AAC9B"}