@gtkx/cli 0.21.0 → 1.0.0-rc.2

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 (358) hide show
  1. package/README.md +173 -0
  2. package/bin/gtkx-dev-runner.js +9 -0
  3. package/dist/builder.d.ts +5 -52
  4. package/dist/builder.d.ts.map +1 -1
  5. package/dist/builder.js +24 -57
  6. package/dist/builder.js.map +1 -1
  7. package/dist/cli.d.ts +1 -2
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +24 -122
  10. package/dist/cli.js.map +1 -1
  11. package/dist/codegen/freshness.d.ts +11 -0
  12. package/dist/codegen/freshness.d.ts.map +1 -0
  13. package/dist/codegen/freshness.js +45 -0
  14. package/dist/codegen/freshness.js.map +1 -0
  15. package/dist/codegen/report.d.ts +4 -0
  16. package/dist/codegen/report.d.ts.map +1 -0
  17. package/dist/codegen/report.js +18 -0
  18. package/dist/codegen/report.js.map +1 -0
  19. package/dist/codegen/run-codegen.d.ts +35 -0
  20. package/dist/codegen/run-codegen.d.ts.map +1 -0
  21. package/dist/codegen/run-codegen.js +162 -0
  22. package/dist/codegen/run-codegen.js.map +1 -0
  23. package/dist/codegen/store-resolver.d.ts +24 -0
  24. package/dist/codegen/store-resolver.d.ts.map +1 -0
  25. package/dist/codegen/store-resolver.js +72 -0
  26. package/dist/codegen/store-resolver.js.map +1 -0
  27. package/dist/commands/build.d.ts +10 -0
  28. package/dist/commands/build.d.ts.map +1 -0
  29. package/dist/commands/build.js +34 -0
  30. package/dist/commands/build.js.map +1 -0
  31. package/dist/commands/codegen.d.ts +10 -0
  32. package/dist/commands/codegen.d.ts.map +1 -0
  33. package/dist/commands/codegen.js +42 -0
  34. package/dist/commands/codegen.js.map +1 -0
  35. package/dist/commands/dev.d.ts +6 -0
  36. package/dist/commands/dev.d.ts.map +1 -0
  37. package/dist/commands/dev.js +22 -0
  38. package/dist/commands/dev.js.map +1 -0
  39. package/dist/commands/docs.d.ts +20 -0
  40. package/dist/commands/docs.d.ts.map +1 -0
  41. package/dist/commands/docs.js +74 -0
  42. package/dist/commands/docs.js.map +1 -0
  43. package/dist/dev/icon-dir.d.ts +3 -0
  44. package/dist/dev/icon-dir.d.ts.map +1 -0
  45. package/dist/dev/icon-dir.js +16 -0
  46. package/dist/dev/icon-dir.js.map +1 -0
  47. package/dist/dev/refresh-tracker.d.ts +7 -0
  48. package/dist/dev/refresh-tracker.d.ts.map +1 -0
  49. package/dist/dev/refresh-tracker.js +19 -0
  50. package/dist/dev/refresh-tracker.js.map +1 -0
  51. package/dist/dev/runner-deps.d.ts +4 -0
  52. package/dist/dev/runner-deps.d.ts.map +1 -0
  53. package/dist/dev/runner-deps.js +55 -0
  54. package/dist/dev/runner-deps.js.map +1 -0
  55. package/dist/dev/runner-main.d.ts +3 -0
  56. package/dist/dev/runner-main.d.ts.map +1 -0
  57. package/dist/dev/runner-main.js +29 -0
  58. package/dist/dev/runner-main.js.map +1 -0
  59. package/dist/dev/runner.d.ts +24 -0
  60. package/dist/dev/runner.d.ts.map +1 -0
  61. package/dist/dev/runner.js +119 -0
  62. package/dist/dev/runner.js.map +1 -0
  63. package/dist/dev/schema-dir.d.ts +3 -0
  64. package/dist/dev/schema-dir.d.ts.map +1 -0
  65. package/dist/dev/schema-dir.js +12 -0
  66. package/dist/dev/schema-dir.js.map +1 -0
  67. package/dist/dev/supervisor.d.ts +18 -0
  68. package/dist/dev/supervisor.d.ts.map +1 -0
  69. package/dist/dev/supervisor.js +182 -0
  70. package/dist/dev/supervisor.js.map +1 -0
  71. package/dist/dev/vite-dev-server.d.ts +21 -0
  72. package/dist/dev/vite-dev-server.d.ts.map +1 -0
  73. package/dist/dev/vite-dev-server.js +13 -0
  74. package/dist/dev/vite-dev-server.js.map +1 -0
  75. package/dist/internal/banner.d.ts +4 -0
  76. package/dist/internal/banner.d.ts.map +1 -0
  77. package/dist/internal/banner.js +9 -0
  78. package/dist/internal/banner.js.map +1 -0
  79. package/dist/internal/data-dir.d.ts +4 -0
  80. package/dist/internal/data-dir.d.ts.map +1 -0
  81. package/dist/internal/data-dir.js +52 -0
  82. package/dist/internal/data-dir.js.map +1 -0
  83. package/dist/internal/entry-arg.d.ts +20 -0
  84. package/dist/internal/entry-arg.d.ts.map +1 -0
  85. package/dist/internal/entry-arg.js +36 -0
  86. package/dist/internal/entry-arg.js.map +1 -0
  87. package/dist/internal/errors.d.ts +5 -0
  88. package/dist/internal/errors.d.ts.map +1 -0
  89. package/dist/internal/errors.js +29 -0
  90. package/dist/internal/errors.js.map +1 -0
  91. package/dist/internal/list-files.d.ts +7 -0
  92. package/dist/internal/list-files.d.ts.map +1 -0
  93. package/dist/internal/list-files.js +15 -0
  94. package/dist/internal/list-files.js.map +1 -0
  95. package/dist/internal/resolve-cli-tool.d.ts +3 -0
  96. package/dist/internal/resolve-cli-tool.d.ts.map +1 -0
  97. package/dist/internal/resolve-cli-tool.js +27 -0
  98. package/dist/internal/resolve-cli-tool.js.map +1 -0
  99. package/dist/internal/staging-dir.d.ts +4 -0
  100. package/dist/internal/staging-dir.d.ts.map +1 -0
  101. package/dist/internal/staging-dir.js +17 -0
  102. package/dist/internal/staging-dir.js.map +1 -0
  103. package/dist/internal/xdg-data-dirs.d.ts +3 -0
  104. package/dist/internal/xdg-data-dirs.d.ts.map +1 -0
  105. package/dist/internal/xdg-data-dirs.js +10 -0
  106. package/dist/internal/xdg-data-dirs.js.map +1 -0
  107. package/dist/mcp/client.d.ts +28 -0
  108. package/dist/mcp/client.d.ts.map +1 -0
  109. package/dist/mcp/client.js +182 -0
  110. package/dist/mcp/client.js.map +1 -0
  111. package/dist/mcp/handlers.d.ts +9 -0
  112. package/dist/mcp/handlers.d.ts.map +1 -0
  113. package/dist/mcp/handlers.js +147 -0
  114. package/dist/mcp/handlers.js.map +1 -0
  115. package/dist/mcp/index.d.ts +4 -0
  116. package/dist/mcp/index.d.ts.map +1 -0
  117. package/dist/mcp/index.js +34 -0
  118. package/dist/mcp/index.js.map +1 -0
  119. package/dist/mcp/serialize-widget.d.ts +10 -0
  120. package/dist/mcp/serialize-widget.d.ts.map +1 -0
  121. package/dist/mcp/serialize-widget.js +23 -0
  122. package/dist/mcp/serialize-widget.js.map +1 -0
  123. package/dist/mcp/testing-loader.d.ts +5 -0
  124. package/dist/mcp/testing-loader.d.ts.map +1 -0
  125. package/dist/mcp/testing-loader.js +47 -0
  126. package/dist/mcp/testing-loader.js.map +1 -0
  127. package/dist/mcp/widget-registry.d.ts +14 -0
  128. package/dist/mcp/widget-registry.d.ts.map +1 -0
  129. package/dist/mcp/widget-registry.js +39 -0
  130. package/dist/mcp/widget-registry.js.map +1 -0
  131. package/dist/refresh-globals.d.ts +2 -0
  132. package/dist/refresh-globals.d.ts.map +1 -0
  133. package/dist/refresh-globals.js +8 -0
  134. package/dist/refresh-globals.js.map +1 -0
  135. package/dist/refresh-runtime.d.ts +10 -26
  136. package/dist/refresh-runtime.d.ts.map +1 -1
  137. package/dist/refresh-runtime.js +26 -48
  138. package/dist/refresh-runtime.js.map +1 -1
  139. package/dist/settings/compile.d.ts +3 -0
  140. package/dist/settings/compile.d.ts.map +1 -0
  141. package/dist/settings/compile.js +21 -0
  142. package/dist/settings/compile.js.map +1 -0
  143. package/dist/settings/parser.d.ts +24 -0
  144. package/dist/settings/parser.d.ts.map +1 -0
  145. package/dist/settings/parser.js +121 -0
  146. package/dist/settings/parser.js.map +1 -0
  147. package/dist/settings/render.d.ts +5 -0
  148. package/dist/settings/render.d.ts.map +1 -0
  149. package/dist/settings/render.js +122 -0
  150. package/dist/settings/render.js.map +1 -0
  151. package/dist/settings/schema.d.ts +13 -0
  152. package/dist/settings/schema.d.ts.map +1 -0
  153. package/dist/settings/schema.js +121 -0
  154. package/dist/settings/schema.js.map +1 -0
  155. package/dist/vite-plugins/asset-extensions.d.ts +5 -0
  156. package/dist/vite-plugins/asset-extensions.d.ts.map +1 -0
  157. package/dist/vite-plugins/asset-extensions.js +28 -0
  158. package/dist/vite-plugins/asset-extensions.js.map +1 -0
  159. package/dist/vite-plugins/built-url.d.ts +4 -0
  160. package/dist/vite-plugins/built-url.d.ts.map +1 -0
  161. package/dist/vite-plugins/built-url.js +36 -0
  162. package/dist/vite-plugins/built-url.js.map +1 -0
  163. package/dist/vite-plugins/css.d.ts +4 -0
  164. package/dist/vite-plugins/css.d.ts.map +1 -0
  165. package/dist/vite-plugins/css.js +38 -0
  166. package/dist/vite-plugins/css.js.map +1 -0
  167. package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts +8 -0
  168. package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts.map +1 -0
  169. package/dist/vite-plugins/fast-refresh/refresh-filter.js +19 -0
  170. package/dist/vite-plugins/fast-refresh/refresh-filter.js.map +1 -0
  171. package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts +6 -0
  172. package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts.map +1 -0
  173. package/dist/vite-plugins/fast-refresh/swc-refresh.js +70 -0
  174. package/dist/vite-plugins/fast-refresh/swc-refresh.js.map +1 -0
  175. package/dist/vite-plugins/icons.d.ts +4 -0
  176. package/dist/vite-plugins/icons.d.ts.map +1 -0
  177. package/dist/vite-plugins/icons.js +51 -0
  178. package/dist/vite-plugins/icons.js.map +1 -0
  179. package/dist/vite-plugins/index.d.ts +4 -0
  180. package/dist/vite-plugins/index.d.ts.map +1 -0
  181. package/dist/vite-plugins/index.js +22 -0
  182. package/dist/vite-plugins/index.js.map +1 -0
  183. package/dist/vite-plugins/native.d.ts +4 -0
  184. package/dist/vite-plugins/native.d.ts.map +1 -0
  185. package/dist/vite-plugins/native.js +62 -0
  186. package/dist/vite-plugins/native.js.map +1 -0
  187. package/dist/vite-plugins/react-compiler.d.ts +5 -0
  188. package/dist/vite-plugins/react-compiler.d.ts.map +1 -0
  189. package/dist/vite-plugins/react-compiler.js +62 -0
  190. package/dist/vite-plugins/react-compiler.js.map +1 -0
  191. package/dist/vite-plugins/react-dom-prebundle.d.ts +4 -0
  192. package/dist/vite-plugins/react-dom-prebundle.d.ts.map +1 -0
  193. package/dist/vite-plugins/react-dom-prebundle.js +12 -0
  194. package/dist/vite-plugins/react-dom-prebundle.js.map +1 -0
  195. package/dist/vite-plugins/resource-init-module.d.ts +6 -0
  196. package/dist/vite-plugins/resource-init-module.d.ts.map +1 -0
  197. package/dist/vite-plugins/resource-init-module.js +51 -0
  198. package/dist/vite-plugins/resource-init-module.js.map +1 -0
  199. package/dist/vite-plugins/resource-shared.d.ts +8 -0
  200. package/dist/vite-plugins/resource-shared.d.ts.map +1 -0
  201. package/dist/vite-plugins/resource-shared.js +28 -0
  202. package/dist/vite-plugins/resource-shared.js.map +1 -0
  203. package/dist/vite-plugins/resources.d.ts +5 -0
  204. package/dist/vite-plugins/resources.d.ts.map +1 -0
  205. package/dist/vite-plugins/resources.js +260 -0
  206. package/dist/vite-plugins/resources.js.map +1 -0
  207. package/dist/vite-plugins/settings-worker-env.d.ts +4 -0
  208. package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -0
  209. package/dist/vite-plugins/settings-worker-env.js +23 -0
  210. package/dist/vite-plugins/settings-worker-env.js.map +1 -0
  211. package/dist/vite-plugins/settings.d.ts +4 -0
  212. package/dist/vite-plugins/settings.d.ts.map +1 -0
  213. package/dist/vite-plugins/settings.js +214 -0
  214. package/dist/vite-plugins/settings.js.map +1 -0
  215. package/dist/vite-plugins/strip-query.d.ts +3 -0
  216. package/dist/vite-plugins/strip-query.d.ts.map +1 -0
  217. package/dist/vite-plugins/strip-query.js +6 -0
  218. package/dist/vite-plugins/strip-query.js.map +1 -0
  219. package/dist/vite-plugins/undeclared-library.d.ts +4 -0
  220. package/dist/vite-plugins/undeclared-library.d.ts.map +1 -0
  221. package/dist/vite-plugins/undeclared-library.js +50 -0
  222. package/dist/vite-plugins/undeclared-library.js.map +1 -0
  223. package/dist/vite-plugins/virtual-module.d.ts +22 -0
  224. package/dist/vite-plugins/virtual-module.d.ts.map +1 -0
  225. package/dist/vite-plugins/virtual-module.js +20 -0
  226. package/dist/vite-plugins/virtual-module.js.map +1 -0
  227. package/dist/vitest-plugin.d.ts +10 -0
  228. package/dist/vitest-plugin.d.ts.map +1 -0
  229. package/dist/vitest-plugin.js +12 -0
  230. package/dist/vitest-plugin.js.map +1 -0
  231. package/env.d.ts +91 -8
  232. package/package.json +30 -38
  233. package/src/babel-modules.d.ts +11 -0
  234. package/src/builder.ts +31 -86
  235. package/src/cli.ts +42 -0
  236. package/src/codegen/freshness.ts +65 -0
  237. package/src/codegen/report.ts +28 -0
  238. package/src/codegen/run-codegen.ts +260 -0
  239. package/src/codegen/store-resolver.ts +116 -0
  240. package/src/commands/build.ts +38 -0
  241. package/src/commands/codegen.ts +49 -0
  242. package/src/commands/dev.ts +24 -0
  243. package/src/commands/docs.ts +95 -0
  244. package/src/dev/icon-dir.ts +21 -0
  245. package/src/dev/refresh-tracker.ts +25 -0
  246. package/src/dev/runner-deps.ts +65 -0
  247. package/src/dev/runner-main.ts +34 -0
  248. package/src/dev/runner.ts +185 -0
  249. package/src/dev/schema-dir.ts +16 -0
  250. package/src/dev/supervisor.ts +276 -0
  251. package/src/dev/vite-dev-server.ts +36 -0
  252. package/src/internal/banner.ts +13 -0
  253. package/src/internal/data-dir.ts +70 -0
  254. package/src/internal/entry-arg.ts +46 -0
  255. package/src/internal/errors.ts +36 -0
  256. package/src/internal/list-files.ts +23 -0
  257. package/src/internal/resolve-cli-tool.ts +37 -0
  258. package/src/internal/staging-dir.ts +19 -0
  259. package/src/internal/xdg-data-dirs.ts +13 -0
  260. package/src/mcp/client.ts +235 -0
  261. package/src/mcp/handlers.ts +213 -0
  262. package/src/mcp/index.ts +46 -0
  263. package/src/mcp/serialize-widget.ts +41 -0
  264. package/src/mcp/testing-loader.ts +73 -0
  265. package/src/mcp/widget-registry.ts +49 -0
  266. package/src/refresh-globals.ts +10 -0
  267. package/src/refresh-runtime.ts +30 -55
  268. package/src/settings/compile.ts +22 -0
  269. package/src/settings/parser.ts +193 -0
  270. package/src/settings/render.ts +167 -0
  271. package/src/settings/schema.ts +169 -0
  272. package/src/vite-plugins/asset-extensions.ts +29 -0
  273. package/src/vite-plugins/built-url.ts +50 -0
  274. package/src/vite-plugins/css.ts +53 -0
  275. package/src/vite-plugins/fast-refresh/refresh-filter.ts +26 -0
  276. package/src/vite-plugins/fast-refresh/swc-refresh.ts +92 -0
  277. package/src/vite-plugins/icons.ts +74 -0
  278. package/src/vite-plugins/index.ts +25 -0
  279. package/src/vite-plugins/native.ts +83 -0
  280. package/src/vite-plugins/react-compiler.ts +84 -0
  281. package/src/vite-plugins/react-dom-prebundle.ts +17 -0
  282. package/src/vite-plugins/resource-init-module.ts +57 -0
  283. package/src/vite-plugins/resource-shared.ts +40 -0
  284. package/src/vite-plugins/resources.ts +366 -0
  285. package/src/vite-plugins/settings-worker-env.ts +30 -0
  286. package/src/vite-plugins/settings.ts +286 -0
  287. package/src/vite-plugins/strip-query.ts +7 -0
  288. package/src/vite-plugins/undeclared-library.ts +78 -0
  289. package/src/vite-plugins/virtual-module.ts +44 -0
  290. package/src/vitest-plugin.ts +13 -0
  291. package/dist/create.d.ts +0 -55
  292. package/dist/create.d.ts.map +0 -1
  293. package/dist/create.js +0 -236
  294. package/dist/create.js.map +0 -1
  295. package/dist/dev-server.d.ts +0 -37
  296. package/dist/dev-server.d.ts.map +0 -1
  297. package/dist/dev-server.js +0 -130
  298. package/dist/dev-server.js.map +0 -1
  299. package/dist/index.d.ts +0 -4
  300. package/dist/index.d.ts.map +0 -1
  301. package/dist/index.js +0 -4
  302. package/dist/index.js.map +0 -1
  303. package/dist/mcp-client.d.ts +0 -31
  304. package/dist/mcp-client.d.ts.map +0 -1
  305. package/dist/mcp-client.js +0 -430
  306. package/dist/mcp-client.js.map +0 -1
  307. package/dist/templates.d.ts +0 -9
  308. package/dist/templates.d.ts.map +0 -1
  309. package/dist/templates.js +0 -16
  310. package/dist/templates.js.map +0 -1
  311. package/dist/vite-plugin-gtkx-assets.d.ts +0 -20
  312. package/dist/vite-plugin-gtkx-assets.d.ts.map +0 -1
  313. package/dist/vite-plugin-gtkx-assets.js +0 -57
  314. package/dist/vite-plugin-gtkx-assets.js.map +0 -1
  315. package/dist/vite-plugin-gtkx-built-url.d.ts +0 -18
  316. package/dist/vite-plugin-gtkx-built-url.d.ts.map +0 -1
  317. package/dist/vite-plugin-gtkx-built-url.js +0 -43
  318. package/dist/vite-plugin-gtkx-built-url.js.map +0 -1
  319. package/dist/vite-plugin-gtkx-gsettings.d.ts +0 -28
  320. package/dist/vite-plugin-gtkx-gsettings.d.ts.map +0 -1
  321. package/dist/vite-plugin-gtkx-gsettings.js +0 -147
  322. package/dist/vite-plugin-gtkx-gsettings.js.map +0 -1
  323. package/dist/vite-plugin-gtkx-native.d.ts +0 -14
  324. package/dist/vite-plugin-gtkx-native.d.ts.map +0 -1
  325. package/dist/vite-plugin-gtkx-native.js +0 -53
  326. package/dist/vite-plugin-gtkx-native.js.map +0 -1
  327. package/dist/vite-plugin-gtkx-refresh.d.ts +0 -8
  328. package/dist/vite-plugin-gtkx-refresh.d.ts.map +0 -1
  329. package/dist/vite-plugin-gtkx-refresh.js +0 -37
  330. package/dist/vite-plugin-gtkx-refresh.js.map +0 -1
  331. package/dist/vite-plugin-swc-ssr-refresh.d.ts +0 -8
  332. package/dist/vite-plugin-swc-ssr-refresh.d.ts.map +0 -1
  333. package/dist/vite-plugin-swc-ssr-refresh.js +0 -46
  334. package/dist/vite-plugin-swc-ssr-refresh.js.map +0 -1
  335. package/src/cli.tsx +0 -154
  336. package/src/create.ts +0 -326
  337. package/src/dev-server.tsx +0 -162
  338. package/src/index.ts +0 -3
  339. package/src/mcp-client.ts +0 -518
  340. package/src/templates.ts +0 -26
  341. package/src/vite-plugin-gtkx-assets.ts +0 -69
  342. package/src/vite-plugin-gtkx-built-url.ts +0 -48
  343. package/src/vite-plugin-gtkx-gsettings.ts +0 -168
  344. package/src/vite-plugin-gtkx-native.ts +0 -64
  345. package/src/vite-plugin-gtkx-refresh.ts +0 -54
  346. package/src/vite-plugin-swc-ssr-refresh.ts +0 -61
  347. package/templates/claude/EXAMPLES.md.ejs +0 -744
  348. package/templates/claude/SKILL.md.ejs +0 -93
  349. package/templates/claude/WIDGETS.md.ejs +0 -820
  350. package/templates/config/vitest.config.ts.ejs +0 -11
  351. package/templates/gitignore.ejs +0 -4
  352. package/templates/package.json.ejs +0 -16
  353. package/templates/src/app.tsx.ejs +0 -32
  354. package/templates/src/dev.tsx.ejs +0 -5
  355. package/templates/src/gtkx-env.d.ts.ejs +0 -1
  356. package/templates/src/index.tsx.ejs +0 -5
  357. package/templates/tests/app.test.tsx.ejs +0 -16
  358. package/templates/tsconfig.json.ejs +0 -14
@@ -0,0 +1,50 @@
1
+ import type { Plugin } from "vite";
2
+
3
+ const renderAssetUrl = (
4
+ filename: string,
5
+ type: string,
6
+ assetBase: string | undefined,
7
+ ): { runtime: string } | undefined => {
8
+ if (type !== "asset") {
9
+ return undefined;
10
+ }
11
+
12
+ if (assetBase) {
13
+ const executableDir = "require(\"path\").dirname(process.execPath)";
14
+
15
+ return {
16
+ runtime:
17
+ `require("path").join(${executableDir},` +
18
+ `${JSON.stringify(assetBase)},${JSON.stringify(filename)})`,
19
+ };
20
+ }
21
+
22
+ const filenameLiteral = JSON.stringify(`./${filename}`);
23
+
24
+ return {
25
+ runtime: `new URL(${filenameLiteral}, import.meta.url).pathname`,
26
+ };
27
+ };
28
+
29
+ function gtkxBuiltUrl(assetBase?: string): Plugin {
30
+ return {
31
+ name: "gtkx:built-url",
32
+ apply: "build",
33
+
34
+ config(userConfig) {
35
+ if (userConfig.experimental?.renderBuiltUrl) {
36
+ return;
37
+ }
38
+
39
+ return {
40
+ experimental: {
41
+ renderBuiltUrl(filename, { type }) {
42
+ return renderAssetUrl(filename, type, assetBase);
43
+ },
44
+ },
45
+ };
46
+ },
47
+ };
48
+ }
49
+
50
+ export { gtkxBuiltUrl };
@@ -0,0 +1,53 @@
1
+ import type { Plugin } from "vite";
2
+ import { readFileSync } from "node:fs";
3
+ import { createVirtualNamespace } from "./virtual-module.js";
4
+
5
+ type CssResolveContext = Parameters<typeof resolveToVirtual>[0];
6
+ type CssResolveRequest = Parameters<typeof resolveToVirtual>[1];
7
+
8
+ const CSS_RE = /\.css$/i;
9
+ const INJECT_SUFFIX = "?inject";
10
+ const VIRTUAL_PREFIX = "\0gtkx-css:";
11
+ const { isVirtual, fromVirtualId, resolveToVirtual } = createVirtualNamespace(VIRTUAL_PREFIX);
12
+
13
+ const resolveCssId = async (ctx: CssResolveContext, request: CssResolveRequest): Promise<string | undefined> => {
14
+ if (!CSS_RE.test(request.source)) {
15
+ return;
16
+ }
17
+
18
+ const virtualId = await resolveToVirtual(ctx, request);
19
+
20
+ if (virtualId === undefined) {
21
+ return;
22
+ }
23
+
24
+ return virtualId + INJECT_SUFFIX;
25
+ };
26
+
27
+ const loadInjectedCss = (id: string): string | undefined => {
28
+ if (!isVirtual(id) || !id.endsWith(INJECT_SUFFIX)) {
29
+ return;
30
+ }
31
+
32
+ const filePath = fromVirtualId(id.slice(0, -INJECT_SUFFIX.length));
33
+ const content = readFileSync(filePath, "utf8");
34
+
35
+ return ["import { injectGlobal } from \"@gtkx/css\";", `injectGlobal(${JSON.stringify(content)});`].join("\n");
36
+ };
37
+
38
+ function gtkxCss(): Plugin {
39
+ return {
40
+ name: "gtkx:css",
41
+ enforce: "pre",
42
+
43
+ resolveId(source, importer, options) {
44
+ return resolveCssId(this, { source, importer, options });
45
+ },
46
+
47
+ load(id) {
48
+ return loadInjectedCss(id);
49
+ },
50
+ };
51
+ }
52
+
53
+ export { gtkxCss };
@@ -0,0 +1,26 @@
1
+ const REFRESH_REG = "$RefreshReg$";
2
+ const REFRESH_SIG = "$RefreshSig$";
3
+ const REFRESH_RUNTIME_SPECIFIER = "@gtkx/cli/refresh-runtime";
4
+ const REFRESH_INCLUDE = /\.[tj]sx?$/;
5
+ const REFRESH_EXCLUDE = /node_modules|[/\\]dist[/\\]|[/\\]\.gtkx[/\\]/;
6
+
7
+ const shouldTransformForRefresh = (
8
+ id: string,
9
+ transformOptions: { ssr?: boolean | undefined } | undefined,
10
+ ): boolean => {
11
+ if (!transformOptions?.ssr) {
12
+ return false;
13
+ }
14
+
15
+ if (!REFRESH_INCLUDE.test(id)) {
16
+ return false;
17
+ }
18
+
19
+ if (REFRESH_EXCLUDE.test(id)) {
20
+ return false;
21
+ }
22
+
23
+ return true;
24
+ };
25
+
26
+ export { REFRESH_REG, REFRESH_SIG, REFRESH_RUNTIME_SPECIFIER, shouldTransformForRefresh };
@@ -0,0 +1,92 @@
1
+ import type { Plugin } from "vite";
2
+ import { type Output, type Options as SwcOptions, transform } from "@swc/core";
3
+ import { fileURLToPath } from "node:url";
4
+ import { REFRESH_REG, REFRESH_RUNTIME_SPECIFIER, REFRESH_SIG, shouldTransformForRefresh } from "./refresh-filter.js";
5
+
6
+ const buildSwcOptions = (id: string): SwcOptions => {
7
+ const isTsx = id.endsWith(".tsx");
8
+ const isTs = id.endsWith(".ts") || isTsx;
9
+
10
+ return {
11
+ filename: id,
12
+ sourceFileName: id,
13
+ sourceMaps: true,
14
+ jsc: {
15
+ parser: isTs ? { syntax: "typescript", tsx: isTsx } : { syntax: "ecmascript", jsx: true },
16
+ transform: {
17
+ react: {
18
+ runtime: "automatic",
19
+ development: true,
20
+ refresh: true,
21
+ },
22
+ },
23
+ target: "es2022",
24
+ },
25
+ };
26
+ };
27
+
28
+ const buildRefreshResult = (result: Output): { code: string; map?: string } =>
29
+ result.map === undefined ? { code: result.code } : { code: result.code, map: result.map };
30
+
31
+ const injectRefreshRegistration = (
32
+ code: string,
33
+ id: string,
34
+ transformOptions: { ssr?: boolean | undefined } | undefined,
35
+ ): { code: string; map: null } | undefined => {
36
+ if (!shouldTransformForRefresh(id, transformOptions)) {
37
+ return;
38
+ }
39
+
40
+ if (!code.includes(REFRESH_REG) && !code.includes(REFRESH_SIG)) {
41
+ return;
42
+ }
43
+
44
+ const header = `
45
+ import { createModuleRegistration as __createModuleRegistration__ } from "${REFRESH_RUNTIME_SPECIFIER}";
46
+ const { ${REFRESH_REG}, ${REFRESH_SIG} } = __createModuleRegistration__(${JSON.stringify(id)});
47
+ `;
48
+
49
+ return { code: header + code, map: null };
50
+ };
51
+
52
+ function gtkxSwcRefresh(): Plugin {
53
+ return {
54
+ name: "gtkx:swc-refresh",
55
+ enforce: "pre",
56
+ apply: "serve",
57
+
58
+ async transform(code, id, transformOptions) {
59
+ if (!shouldTransformForRefresh(id, transformOptions)) {
60
+ return;
61
+ }
62
+
63
+ const result = await transform(code, buildSwcOptions(id));
64
+
65
+ return buildRefreshResult(result);
66
+ },
67
+ };
68
+ }
69
+
70
+ function gtkxRefreshRuntime(): Plugin {
71
+ return {
72
+ name: "gtkx:refresh-runtime",
73
+ enforce: "post",
74
+ apply: "serve",
75
+
76
+ resolveId(id) {
77
+ if (id !== REFRESH_RUNTIME_SPECIFIER) {
78
+ return;
79
+ }
80
+
81
+ return fileURLToPath(import.meta.resolve(REFRESH_RUNTIME_SPECIFIER));
82
+ },
83
+
84
+ transform(code, id, transformOptions) {
85
+ return injectRefreshRegistration(code, id, transformOptions);
86
+ },
87
+ };
88
+ }
89
+
90
+ const gtkxFastRefresh = (): Plugin[] => [gtkxSwcRefresh(), gtkxRefreshRuntime()];
91
+
92
+ export { gtkxSwcRefresh, gtkxRefreshRuntime, gtkxFastRefresh };
@@ -0,0 +1,74 @@
1
+ import type { Plugin, UserConfig } from "vite";
2
+ import { info } from "@gtkx/utils";
3
+ import { readFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { prependBanner } from "../internal/banner.js";
6
+ import { resolveDataDir } from "../internal/data-dir.js";
7
+ import { type ListedFile, listFilesRecursive } from "../internal/list-files.js";
8
+
9
+ type PluginState = {
10
+ iconsDir: string | null;
11
+ };
12
+
13
+ type PluginContext = {
14
+ emitFile: (file: { type: "asset"; fileName: string; source: Buffer }) => void;
15
+ };
16
+
17
+ const ICONS_DIR = "icons";
18
+
19
+ const XDG_ENV_BANNER = [
20
+ "process.env.XDG_DATA_DIRS = [",
21
+ " decodeURIComponent(new URL(\".\", import.meta.url).pathname),",
22
+ " process.env.XDG_DATA_DIRS || \"/usr/local/share:/usr/share\",",
23
+ "].join(\":\");",
24
+ ].join("\n");
25
+
26
+ const findIconFiles = (iconsDir: string | null): ListedFile[] =>
27
+ iconsDir === null ? [] : listFilesRecursive(iconsDir);
28
+
29
+ const resolveIconsDir = (config: UserConfig): string | null => {
30
+ const root = config.root ?? process.cwd();
31
+ const dataDir = resolveDataDir(root);
32
+
33
+ return dataDir === null ? null : join(root, dataDir, ICONS_DIR);
34
+ };
35
+
36
+ const emitIcons = (ctx: PluginContext, icons: ListedFile[]): void => {
37
+ for (const { absPath, rel } of icons) {
38
+ ctx.emitFile({ type: "asset", fileName: join(ICONS_DIR, rel), source: readFileSync(absPath) });
39
+ }
40
+
41
+ if (icons.length > 0) {
42
+ info(`Copied ${String(icons.length)} icon(s) into ${ICONS_DIR}/`);
43
+ }
44
+ };
45
+
46
+ function gtkxIcons(): Plugin {
47
+ const state: PluginState = {
48
+ iconsDir: null,
49
+ };
50
+
51
+ return {
52
+ name: "gtkx:icons",
53
+ enforce: "pre",
54
+ apply: "build",
55
+
56
+ config(config: UserConfig) {
57
+ state.iconsDir = resolveIconsDir(config);
58
+ },
59
+
60
+ outputOptions(options) {
61
+ if (findIconFiles(state.iconsDir).length === 0) {
62
+ return;
63
+ }
64
+
65
+ return prependBanner(options, XDG_ENV_BANNER);
66
+ },
67
+
68
+ buildEnd() {
69
+ emitIcons(this, findIconFiles(state.iconsDir));
70
+ },
71
+ };
72
+ }
73
+
74
+ export { gtkxIcons };
@@ -0,0 +1,25 @@
1
+ import type { Plugin } from "vite";
2
+ import { createConfigLoader } from "@gtkx/config/internal";
3
+ import createConfigPlugin from "@gtkx/config/vite-plugin";
4
+ import { gtkxCss } from "./css.js";
5
+ import { gtkxIcons } from "./icons.js";
6
+ import { gtkxReactCompiler } from "./react-compiler.js";
7
+ import { gtkxResources } from "./resources.js";
8
+ import { gtkxSettings } from "./settings.js";
9
+ import { gtkxUndeclaredLibrary } from "./undeclared-library.js";
10
+
11
+ const gtkxVitePlugins = (mode?: string): Plugin[] => {
12
+ const loadConfig = createConfigLoader(mode === undefined ? {} : { mode });
13
+
14
+ return [
15
+ createConfigPlugin({ name: "gtkx:config", loadConfig }),
16
+ gtkxUndeclaredLibrary(mode),
17
+ gtkxSettings(),
18
+ gtkxIcons(),
19
+ gtkxResources(loadConfig),
20
+ gtkxCss(),
21
+ gtkxReactCompiler(loadConfig),
22
+ ];
23
+ };
24
+
25
+ export { gtkxVitePlugins };
@@ -0,0 +1,83 @@
1
+ import type { Plugin } from "vite";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { createRequire } from "node:module";
4
+ import { arch, platform } from "node:os";
5
+ import { dirname, join } from "node:path";
6
+ import { stripQuery } from "./strip-query.js";
7
+
8
+ const EMITTED_BINDING_SPECIFIER = "./gtkx.node";
9
+
10
+ function resolveBinaryPath(projectRequire: ReturnType<typeof createRequire>, currentArch: string): string {
11
+ const nativeRoot = dirname(projectRequire.resolve("@gtkx/native/package.json"));
12
+ const localBinary = join(nativeRoot, `native.linux-${currentArch}-gnu.node`);
13
+
14
+ return existsSync(localBinary) ? localBinary : projectRequire.resolve(`@gtkx/native-linux-${currentArch}-gnu`);
15
+ }
16
+
17
+ function resolvePlatformBinary(projectRequire: ReturnType<typeof createRequire>): Buffer {
18
+ const currentPlatform = platform();
19
+
20
+ if (currentPlatform !== "linux") {
21
+ throw new Error(`Unsupported build platform: ${currentPlatform}, only Linux is supported`);
22
+ }
23
+
24
+ const currentArch = arch();
25
+
26
+ if (currentArch !== "x64" && currentArch !== "arm64") {
27
+ throw new Error(`Unsupported build architecture: ${currentArch}, only x64 and arm64 are supported`);
28
+ }
29
+
30
+ return readFileSync(resolveBinaryPath(projectRequire, currentArch));
31
+ }
32
+
33
+ function rewriteLoader(code: string): string {
34
+ const idents: string[] = [];
35
+
36
+ for (const match of code.matchAll(/export\s*\{\s*([A-Za-z0-9_$]+)\s*\}/g)) {
37
+ const ident = match[1];
38
+
39
+ if (ident) {
40
+ idents.push(ident);
41
+ }
42
+ }
43
+
44
+ const bindings = idents.join(", ");
45
+
46
+ return [
47
+ "import { createRequire as __gtkxCreateRequire } from \"node:module\";",
48
+ `const __gtkxNative = __gtkxCreateRequire(import.meta.url)(${JSON.stringify(EMITTED_BINDING_SPECIFIER)});`,
49
+ `const { ${bindings} } = __gtkxNative;`,
50
+ `export { ${bindings} };`,
51
+ ].join("\n");
52
+ }
53
+
54
+ function gtkxNative(root: string): Plugin {
55
+ const projectRequire = createRequire(join(root, "package.json"));
56
+ let cachedLoaderPath: string | undefined;
57
+
58
+ const loaderPath = (): string => {
59
+ cachedLoaderPath ??= join(dirname(projectRequire.resolve("@gtkx/native/package.json")), "index.js");
60
+
61
+ return cachedLoaderPath;
62
+ };
63
+
64
+ return {
65
+ name: "gtkx:native",
66
+ enforce: "pre",
67
+ apply: "build",
68
+
69
+ buildStart() {
70
+ this.emitFile({ type: "asset", fileName: "gtkx.node", source: resolvePlatformBinary(projectRequire) });
71
+ },
72
+
73
+ resolveId(id) {
74
+ return id === EMITTED_BINDING_SPECIFIER ? { id, external: true } : null;
75
+ },
76
+
77
+ transform(code, id) {
78
+ return stripQuery(id) === loaderPath() ? rewriteLoader(code) : null;
79
+ },
80
+ };
81
+ }
82
+
83
+ export { gtkxNative };
@@ -0,0 +1,84 @@
1
+ import type { ResolvedReactCompilerOptions } from "@gtkx/config";
2
+ import type { Plugin, ResolvedConfig, UserConfig } from "vite";
3
+ import { transformAsync } from "@babel/core";
4
+ import babelPresetTypescriptNs from "@babel/preset-typescript";
5
+ import { type ConfigLoader, createConfigLoader } from "@gtkx/config/internal";
6
+ import babelPluginReactCompilerNs from "babel-plugin-react-compiler";
7
+
8
+ type ReactCompilerState = {
9
+ root: string;
10
+ options: ResolvedReactCompilerOptions | null;
11
+ };
12
+
13
+ const babelPresetTypescript = babelPresetTypescriptNs.default ?? babelPresetTypescriptNs;
14
+ const babelPluginReactCompiler = babelPluginReactCompilerNs.default ?? babelPluginReactCompilerNs;
15
+ const SOURCE_EXTENSION = /\.[jt]sx?$/;
16
+ const TYPESCRIPT_EXTENSION = /\.tsx?$/;
17
+ const NODE_MODULES = /(?:^|\/)node_modules\//;
18
+
19
+ const isProjectSource = (root: string, id: string): boolean => {
20
+ if (!SOURCE_EXTENSION.test(id)) {
21
+ return false;
22
+ }
23
+
24
+ if (NODE_MODULES.test(id)) {
25
+ return false;
26
+ }
27
+
28
+ if (root !== "" && !id.startsWith(`${root}/`)) {
29
+ return false;
30
+ }
31
+
32
+ return true;
33
+ };
34
+
35
+ const compileSource = async (code: string, id: string, options: ResolvedReactCompilerOptions) => {
36
+ const result = await transformAsync(code, {
37
+ filename: id,
38
+ babelrc: false,
39
+ configFile: false,
40
+ sourceMaps: true,
41
+ parserOpts: { plugins: id.endsWith(".ts") ? [] : ["jsx"] },
42
+ presets: TYPESCRIPT_EXTENSION.test(id) ? [babelPresetTypescript] : [],
43
+ plugins: [[babelPluginReactCompiler, options]],
44
+ });
45
+
46
+ if (!result?.code) {
47
+ return;
48
+ }
49
+
50
+ return result.map == null ? { code: result.code } : { code: result.code, map: JSON.stringify(result.map) };
51
+ };
52
+
53
+ function gtkxReactCompiler(loadConfig: ConfigLoader = createConfigLoader()): Plugin {
54
+ const state: ReactCompilerState = {
55
+ root: "",
56
+ options: null,
57
+ };
58
+
59
+ return {
60
+ name: "gtkx:react-compiler",
61
+ enforce: "pre",
62
+
63
+ async config(config: UserConfig) {
64
+ const resolved = await loadConfig(config.root ?? process.cwd());
65
+ state.options = resolved.reactCompiler;
66
+ },
67
+
68
+ configResolved(config: ResolvedConfig) {
69
+ state.root = config.root;
70
+ },
71
+
72
+ async transform(code, id) {
73
+ const options = state.options;
74
+
75
+ if (options === null || !isProjectSource(state.root, id)) {
76
+ return;
77
+ }
78
+
79
+ return compileSource(code, id, options);
80
+ },
81
+ };
82
+ }
83
+
84
+ export { gtkxReactCompiler };
@@ -0,0 +1,17 @@
1
+ import type { Plugin } from "vite";
2
+
3
+ const gtkxReactDomPrebundle = (): Plugin => ({
4
+ name: "gtkx:react-dom-prebundle",
5
+ enforce: "post",
6
+ config(config) {
7
+ config.optimizeDeps ??= {};
8
+
9
+ if (config.optimizeDeps.include) {
10
+ config.optimizeDeps.include = config.optimizeDeps.include.filter(
11
+ (dep) => dep !== "react-dom" && !dep.startsWith("react-dom/"),
12
+ );
13
+ }
14
+ },
15
+ });
16
+
17
+ export { gtkxReactDomPrebundle };
@@ -0,0 +1,57 @@
1
+ import { BUNDLE_FILENAME, REFRESH_EXPORT } from "./resource-shared.js";
2
+
3
+ const buildInitModuleSource = (): string =>
4
+ [
5
+ "import { dirname, join } from \"node:path\";",
6
+ "import { fileURLToPath } from \"node:url\";",
7
+ "import { Resource, resourcesRegister } from \"@gtkx/gi/gio\";",
8
+ "",
9
+ "const bundleDir = dirname(fileURLToPath(import.meta.url));",
10
+ `const resource = Resource.load(join(bundleDir, ${JSON.stringify(BUNDLE_FILENAME)}));`,
11
+ "resourcesRegister(resource);",
12
+ "",
13
+ "export function ensureRegistered() {}",
14
+ `export function ${REFRESH_EXPORT}() {}`,
15
+ ].join("\n");
16
+
17
+ const devInitModuleSource = (bundlePath: string): string => {
18
+ const bundlePathLiteral = JSON.stringify(bundlePath);
19
+
20
+ return [
21
+ "import { existsSync, statSync } from \"node:fs\";",
22
+ "import { Resource, resourcesRegister, resourcesUnregister } from \"@gtkx/gi/gio\";",
23
+ "",
24
+ "let current = null;",
25
+ "let lastSig = \"\";",
26
+ "",
27
+ "function register() {",
28
+ ` const next = Resource.load(${bundlePathLiteral});`,
29
+ " if (current) resourcesUnregister(current);",
30
+ " resourcesRegister(next);",
31
+ " current = next;",
32
+ "}",
33
+ "",
34
+ "export function ensureRegistered() {",
35
+ ` if (!existsSync(${bundlePathLiteral})) return;`,
36
+ ` const { size, mtimeMs } = statSync(${bundlePathLiteral});`,
37
+ " const sig = size + \":\" + mtimeMs;",
38
+ " if (sig === lastSig) return;",
39
+ " register();",
40
+ " lastSig = sig;",
41
+ "}",
42
+ "",
43
+ "ensureRegistered();",
44
+ "",
45
+ `export function ${REFRESH_EXPORT}() {`,
46
+ ` if (!existsSync(${bundlePathLiteral})) return;`,
47
+ " register();",
48
+ ` const { size, mtimeMs } = statSync(${bundlePathLiteral});`,
49
+ " lastSig = size + \":\" + mtimeMs;",
50
+ "}",
51
+ ].join("\n");
52
+ };
53
+
54
+ const renderInitModule = (options: { isBuild: boolean; devBundlePath: string }): string =>
55
+ options.isBuild ? buildInitModuleSource() : devInitModuleSource(options.devBundlePath);
56
+
57
+ export { renderInitModule };
@@ -0,0 +1,40 @@
1
+ import { createVirtualNamespace } from "./virtual-module.js";
2
+
3
+ const VIRTUAL_PREFIX = "\0gtkx-resources:";
4
+ const VIRTUAL_INIT = "\0gtkx-resources-init";
5
+ const BUNDLE_FILENAME = "gtkx.gresource";
6
+ const REL_SEPARATOR = "\0rel=";
7
+ const REFRESH_EXPORT = "__refresh";
8
+ const { isVirtual, toVirtualId, fromVirtualId } = createVirtualNamespace(VIRTUAL_PREFIX);
9
+
10
+ const escapeXml = (value: string): string =>
11
+ value.replaceAll(/[<>&"']/g, (char) => {
12
+ switch (char) {
13
+ case "<": {
14
+ return "&lt;";
15
+ }
16
+ case ">": {
17
+ return "&gt;";
18
+ }
19
+ case "&": {
20
+ return "&amp;";
21
+ }
22
+ case "\"": {
23
+ return "&quot;";
24
+ }
25
+ default: {
26
+ return "&apos;";
27
+ }
28
+ }
29
+ });
30
+
31
+ export {
32
+ VIRTUAL_INIT,
33
+ BUNDLE_FILENAME,
34
+ REL_SEPARATOR,
35
+ REFRESH_EXPORT,
36
+ escapeXml,
37
+ isVirtual,
38
+ toVirtualId,
39
+ fromVirtualId,
40
+ };