@gtkx/cli 1.0.0-rc.1 → 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 (286) hide show
  1. package/dist/builder.d.ts +3 -2
  2. package/dist/builder.d.ts.map +1 -1
  3. package/dist/builder.js +2 -1
  4. package/dist/builder.js.map +1 -1
  5. package/dist/cli.d.ts +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +21 -6
  8. package/dist/cli.js.map +1 -1
  9. package/dist/codegen/freshness.d.ts +5 -5
  10. package/dist/codegen/freshness.d.ts.map +1 -1
  11. package/dist/codegen/freshness.js +26 -23
  12. package/dist/codegen/freshness.js.map +1 -1
  13. package/dist/codegen/report.d.ts +2 -1
  14. package/dist/codegen/report.d.ts.map +1 -1
  15. package/dist/codegen/report.js +4 -2
  16. package/dist/codegen/report.js.map +1 -1
  17. package/dist/codegen/run-codegen.d.ts +8 -8
  18. package/dist/codegen/run-codegen.d.ts.map +1 -1
  19. package/dist/codegen/run-codegen.js +72 -43
  20. package/dist/codegen/run-codegen.js.map +1 -1
  21. package/dist/codegen/store-resolver.d.ts +8 -5
  22. package/dist/codegen/store-resolver.d.ts.map +1 -1
  23. package/dist/codegen/store-resolver.js +26 -6
  24. package/dist/codegen/store-resolver.js.map +1 -1
  25. package/dist/commands/build.d.ts +4 -3
  26. package/dist/commands/build.d.ts.map +1 -1
  27. package/dist/commands/build.js +2 -1
  28. package/dist/commands/build.js.map +1 -1
  29. package/dist/commands/codegen.d.ts +2 -1
  30. package/dist/commands/codegen.d.ts.map +1 -1
  31. package/dist/commands/codegen.js +6 -4
  32. package/dist/commands/codegen.js.map +1 -1
  33. package/dist/commands/dev.d.ts +2 -1
  34. package/dist/commands/dev.d.ts.map +1 -1
  35. package/dist/commands/dev.js +2 -1
  36. package/dist/commands/dev.js.map +1 -1
  37. package/dist/commands/docs.d.ts +2 -1
  38. package/dist/commands/docs.d.ts.map +1 -1
  39. package/dist/commands/docs.js +22 -7
  40. package/dist/commands/docs.js.map +1 -1
  41. package/dist/dev/icon-dir.d.ts +2 -1
  42. package/dist/dev/icon-dir.d.ts.map +1 -1
  43. package/dist/dev/icon-dir.js +6 -3
  44. package/dist/dev/icon-dir.js.map +1 -1
  45. package/dist/dev/refresh-tracker.d.ts +5 -4
  46. package/dist/dev/refresh-tracker.d.ts.map +1 -1
  47. package/dist/dev/refresh-tracker.js +6 -5
  48. package/dist/dev/refresh-tracker.js.map +1 -1
  49. package/dist/dev/runner-deps.d.ts +2 -1
  50. package/dist/dev/runner-deps.d.ts.map +1 -1
  51. package/dist/dev/runner-deps.js +20 -4
  52. package/dist/dev/runner-deps.js.map +1 -1
  53. package/dist/dev/runner-main.d.ts +2 -1
  54. package/dist/dev/runner-main.d.ts.map +1 -1
  55. package/dist/dev/runner-main.js +3 -2
  56. package/dist/dev/runner-main.js.map +1 -1
  57. package/dist/dev/runner.d.ts +6 -5
  58. package/dist/dev/runner.d.ts.map +1 -1
  59. package/dist/dev/runner.js +69 -38
  60. package/dist/dev/runner.js.map +1 -1
  61. package/dist/dev/schema-dir.d.ts +2 -1
  62. package/dist/dev/schema-dir.d.ts.map +1 -1
  63. package/dist/dev/schema-dir.js +4 -2
  64. package/dist/dev/schema-dir.js.map +1 -1
  65. package/dist/dev/supervisor.d.ts +7 -6
  66. package/dist/dev/supervisor.d.ts.map +1 -1
  67. package/dist/dev/supervisor.js +107 -67
  68. package/dist/dev/supervisor.js.map +1 -1
  69. package/dist/dev/vite-dev-server.d.ts +3 -3
  70. package/dist/dev/vite-dev-server.d.ts.map +1 -1
  71. package/dist/dev/vite-dev-server.js +2 -1
  72. package/dist/dev/vite-dev-server.js.map +1 -1
  73. package/dist/internal/banner.d.ts +2 -1
  74. package/dist/internal/banner.d.ts.map +1 -1
  75. package/dist/internal/banner.js +2 -1
  76. package/dist/internal/banner.js.map +1 -1
  77. package/dist/internal/data-dir.d.ts +3 -2
  78. package/dist/internal/data-dir.d.ts.map +1 -1
  79. package/dist/internal/data-dir.js +29 -14
  80. package/dist/internal/data-dir.js.map +1 -1
  81. package/dist/internal/entry-arg.d.ts +5 -4
  82. package/dist/internal/entry-arg.d.ts.map +1 -1
  83. package/dist/internal/entry-arg.js +10 -7
  84. package/dist/internal/entry-arg.js.map +1 -1
  85. package/dist/internal/errors.d.ts +3 -2
  86. package/dist/internal/errors.d.ts.map +1 -1
  87. package/dist/internal/errors.js +7 -5
  88. package/dist/internal/errors.js.map +1 -1
  89. package/dist/internal/list-files.d.ts +3 -2
  90. package/dist/internal/list-files.d.ts.map +1 -1
  91. package/dist/internal/list-files.js +5 -3
  92. package/dist/internal/list-files.js.map +1 -1
  93. package/dist/internal/resolve-cli-tool.d.ts +2 -1
  94. package/dist/internal/resolve-cli-tool.d.ts.map +1 -1
  95. package/dist/internal/resolve-cli-tool.js +17 -10
  96. package/dist/internal/resolve-cli-tool.js.map +1 -1
  97. package/dist/internal/staging-dir.d.ts +3 -2
  98. package/dist/internal/staging-dir.d.ts.map +1 -1
  99. package/dist/internal/staging-dir.js +3 -2
  100. package/dist/internal/staging-dir.js.map +1 -1
  101. package/dist/internal/xdg-data-dirs.d.ts +2 -1
  102. package/dist/internal/xdg-data-dirs.d.ts.map +1 -1
  103. package/dist/internal/xdg-data-dirs.js +4 -2
  104. package/dist/internal/xdg-data-dirs.js.map +1 -1
  105. package/dist/mcp/client.d.ts +9 -4
  106. package/dist/mcp/client.d.ts.map +1 -1
  107. package/dist/mcp/client.js +106 -81
  108. package/dist/mcp/client.js.map +1 -1
  109. package/dist/mcp/handlers.d.ts +3 -2
  110. package/dist/mcp/handlers.d.ts.map +1 -1
  111. package/dist/mcp/handlers.js +89 -61
  112. package/dist/mcp/handlers.js.map +1 -1
  113. package/dist/mcp/index.d.ts +2 -2
  114. package/dist/mcp/index.d.ts.map +1 -1
  115. package/dist/mcp/index.js +30 -13
  116. package/dist/mcp/index.js.map +1 -1
  117. package/dist/mcp/serialize-widget.d.ts +3 -3
  118. package/dist/mcp/serialize-widget.d.ts.map +1 -1
  119. package/dist/mcp/serialize-widget.js +9 -6
  120. package/dist/mcp/serialize-widget.js.map +1 -1
  121. package/dist/mcp/testing-loader.d.ts +3 -4
  122. package/dist/mcp/testing-loader.d.ts.map +1 -1
  123. package/dist/mcp/testing-loader.js +43 -21
  124. package/dist/mcp/testing-loader.js.map +1 -1
  125. package/dist/mcp/widget-registry.d.ts +3 -2
  126. package/dist/mcp/widget-registry.d.ts.map +1 -1
  127. package/dist/mcp/widget-registry.js +4 -3
  128. package/dist/mcp/widget-registry.js.map +1 -1
  129. package/dist/refresh-globals.d.ts +2 -0
  130. package/dist/refresh-globals.d.ts.map +1 -0
  131. package/dist/refresh-globals.js +8 -0
  132. package/dist/refresh-globals.js.map +1 -0
  133. package/dist/refresh-runtime.d.ts +5 -11
  134. package/dist/refresh-runtime.d.ts.map +1 -1
  135. package/dist/refresh-runtime.js +16 -14
  136. package/dist/refresh-runtime.js.map +1 -1
  137. package/dist/settings/compile.d.ts +2 -1
  138. package/dist/settings/compile.d.ts.map +1 -1
  139. package/dist/settings/compile.js +6 -4
  140. package/dist/settings/compile.js.map +1 -1
  141. package/dist/settings/parser.d.ts +6 -5
  142. package/dist/settings/parser.d.ts.map +1 -1
  143. package/dist/settings/parser.js +26 -22
  144. package/dist/settings/parser.js.map +1 -1
  145. package/dist/settings/render.d.ts +3 -2
  146. package/dist/settings/render.d.ts.map +1 -1
  147. package/dist/settings/render.js +38 -64
  148. package/dist/settings/render.js.map +1 -1
  149. package/dist/settings/schema.d.ts +8 -8
  150. package/dist/settings/schema.d.ts.map +1 -1
  151. package/dist/settings/schema.js +61 -43
  152. package/dist/settings/schema.js.map +1 -1
  153. package/dist/vite-plugins/asset-extensions.d.ts +4 -3
  154. package/dist/vite-plugins/asset-extensions.d.ts.map +1 -1
  155. package/dist/vite-plugins/asset-extensions.js +4 -3
  156. package/dist/vite-plugins/asset-extensions.js.map +1 -1
  157. package/dist/vite-plugins/built-url.d.ts +2 -1
  158. package/dist/vite-plugins/built-url.d.ts.map +1 -1
  159. package/dist/vite-plugins/built-url.js +19 -13
  160. package/dist/vite-plugins/built-url.js.map +1 -1
  161. package/dist/vite-plugins/css.d.ts +2 -1
  162. package/dist/vite-plugins/css.d.ts.map +1 -1
  163. package/dist/vite-plugins/css.js +23 -15
  164. package/dist/vite-plugins/css.js.map +1 -1
  165. package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts +5 -4
  166. package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts.map +1 -1
  167. package/dist/vite-plugins/fast-refresh/refresh-filter.js +11 -7
  168. package/dist/vite-plugins/fast-refresh/refresh-filter.js.map +1 -1
  169. package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts +4 -3
  170. package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts.map +1 -1
  171. package/dist/vite-plugins/fast-refresh/swc-refresh.js +45 -41
  172. package/dist/vite-plugins/fast-refresh/swc-refresh.js.map +1 -1
  173. package/dist/vite-plugins/icons.d.ts +2 -1
  174. package/dist/vite-plugins/icons.d.ts.map +1 -1
  175. package/dist/vite-plugins/icons.js +24 -20
  176. package/dist/vite-plugins/icons.js.map +1 -1
  177. package/dist/vite-plugins/index.d.ts +2 -1
  178. package/dist/vite-plugins/index.d.ts.map +1 -1
  179. package/dist/vite-plugins/index.js +3 -2
  180. package/dist/vite-plugins/index.js.map +1 -1
  181. package/dist/vite-plugins/native.d.ts +2 -1
  182. package/dist/vite-plugins/native.d.ts.map +1 -1
  183. package/dist/vite-plugins/native.js +6 -4
  184. package/dist/vite-plugins/native.js.map +1 -1
  185. package/dist/vite-plugins/react-compiler.d.ts +3 -2
  186. package/dist/vite-plugins/react-compiler.d.ts.map +1 -1
  187. package/dist/vite-plugins/react-compiler.js +26 -20
  188. package/dist/vite-plugins/react-compiler.js.map +1 -1
  189. package/dist/vite-plugins/react-dom-prebundle.d.ts +2 -1
  190. package/dist/vite-plugins/react-dom-prebundle.d.ts.map +1 -1
  191. package/dist/vite-plugins/react-dom-prebundle.js +2 -1
  192. package/dist/vite-plugins/react-dom-prebundle.js.map +1 -1
  193. package/dist/vite-plugins/resource-init-module.d.ts +2 -1
  194. package/dist/vite-plugins/resource-init-module.d.ts.map +1 -1
  195. package/dist/vite-plugins/resource-init-module.js +39 -38
  196. package/dist/vite-plugins/resource-init-module.js.map +1 -1
  197. package/dist/vite-plugins/resource-shared.d.ts +7 -5
  198. package/dist/vite-plugins/resource-shared.d.ts.map +1 -1
  199. package/dist/vite-plugins/resource-shared.js +17 -10
  200. package/dist/vite-plugins/resource-shared.js.map +1 -1
  201. package/dist/vite-plugins/resources.d.ts +3 -2
  202. package/dist/vite-plugins/resources.d.ts.map +1 -1
  203. package/dist/vite-plugins/resources.js +94 -54
  204. package/dist/vite-plugins/resources.js.map +1 -1
  205. package/dist/vite-plugins/settings-worker-env.d.ts +2 -1
  206. package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
  207. package/dist/vite-plugins/settings-worker-env.js +4 -2
  208. package/dist/vite-plugins/settings-worker-env.js.map +1 -1
  209. package/dist/vite-plugins/settings.d.ts +2 -1
  210. package/dist/vite-plugins/settings.d.ts.map +1 -1
  211. package/dist/vite-plugins/settings.js +56 -32
  212. package/dist/vite-plugins/settings.js.map +1 -1
  213. package/dist/vite-plugins/strip-query.d.ts +3 -0
  214. package/dist/vite-plugins/strip-query.d.ts.map +1 -0
  215. package/dist/vite-plugins/strip-query.js +6 -0
  216. package/dist/vite-plugins/strip-query.js.map +1 -0
  217. package/dist/vite-plugins/undeclared-library.d.ts +2 -1
  218. package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
  219. package/dist/vite-plugins/undeclared-library.js +8 -5
  220. package/dist/vite-plugins/undeclared-library.js.map +1 -1
  221. package/dist/vite-plugins/virtual-module.d.ts +2 -2
  222. package/dist/vite-plugins/virtual-module.d.ts.map +1 -1
  223. package/dist/vite-plugins/virtual-module.js +5 -3
  224. package/dist/vite-plugins/virtual-module.js.map +1 -1
  225. package/dist/vitest-plugin.d.ts.map +1 -1
  226. package/dist/vitest-plugin.js.map +1 -1
  227. package/env.d.ts +21 -61
  228. package/package.json +12 -14
  229. package/src/babel-modules.d.ts +0 -2
  230. package/src/builder.ts +7 -6
  231. package/src/cli.ts +26 -6
  232. package/src/codegen/freshness.ts +38 -25
  233. package/src/codegen/report.ts +10 -2
  234. package/src/codegen/run-codegen.ts +135 -60
  235. package/src/codegen/store-resolver.ts +56 -15
  236. package/src/commands/build.ts +3 -2
  237. package/src/commands/codegen.ts +9 -4
  238. package/src/commands/dev.ts +3 -4
  239. package/src/commands/docs.ts +36 -7
  240. package/src/dev/icon-dir.ts +13 -3
  241. package/src/dev/refresh-tracker.ts +12 -8
  242. package/src/dev/runner-deps.ts +30 -7
  243. package/src/dev/runner-main.ts +4 -3
  244. package/src/dev/runner.ts +100 -41
  245. package/src/dev/schema-dir.ts +7 -2
  246. package/src/dev/supervisor.ts +169 -71
  247. package/src/dev/vite-dev-server.ts +4 -2
  248. package/src/internal/banner.ts +5 -1
  249. package/src/internal/data-dir.ts +47 -16
  250. package/src/internal/entry-arg.ts +16 -8
  251. package/src/internal/errors.ts +15 -7
  252. package/src/internal/list-files.ts +10 -4
  253. package/src/internal/resolve-cli-tool.ts +28 -12
  254. package/src/internal/staging-dir.ts +5 -2
  255. package/src/internal/xdg-data-dirs.ts +8 -2
  256. package/src/mcp/client.ts +143 -85
  257. package/src/mcp/handlers.ts +126 -69
  258. package/src/mcp/index.ts +38 -14
  259. package/src/mcp/serialize-widget.ts +15 -8
  260. package/src/mcp/testing-loader.ts +64 -23
  261. package/src/mcp/widget-registry.ts +11 -5
  262. package/src/refresh-globals.ts +10 -0
  263. package/src/refresh-runtime.ts +20 -16
  264. package/src/settings/compile.ts +7 -4
  265. package/src/settings/parser.ts +69 -30
  266. package/src/settings/render.ts +66 -66
  267. package/src/settings/schema.ts +100 -46
  268. package/src/vite-plugins/asset-extensions.ts +4 -3
  269. package/src/vite-plugins/built-url.ts +30 -15
  270. package/src/vite-plugins/css.ts +35 -20
  271. package/src/vite-plugins/fast-refresh/refresh-filter.ts +18 -10
  272. package/src/vite-plugins/fast-refresh/swc-refresh.ts +60 -47
  273. package/src/vite-plugins/icons.ts +40 -24
  274. package/src/vite-plugins/index.ts +6 -3
  275. package/src/vite-plugins/native.ts +14 -5
  276. package/src/vite-plugins/react-compiler.ts +44 -30
  277. package/src/vite-plugins/react-dom-prebundle.ts +4 -1
  278. package/src/vite-plugins/resource-init-module.ts +41 -38
  279. package/src/vite-plugins/resource-shared.ts +27 -14
  280. package/src/vite-plugins/resources.ts +153 -59
  281. package/src/vite-plugins/settings-worker-env.ts +7 -2
  282. package/src/vite-plugins/settings.ts +107 -42
  283. package/src/vite-plugins/strip-query.ts +7 -0
  284. package/src/vite-plugins/undeclared-library.ts +21 -12
  285. package/src/vite-plugins/virtual-module.ts +9 -2
  286. package/src/vitest-plugin.ts +1 -2
@@ -1,54 +1,57 @@
1
- import { BUNDLE_FILENAME } from "./resource-shared.js";
1
+ import { BUNDLE_FILENAME, REFRESH_EXPORT } from "./resource-shared.js";
2
2
 
3
3
  const buildInitModuleSource = (): string =>
4
4
  [
5
- `import { dirname, join } from "node:path";`,
6
- `import { fileURLToPath } from "node:url";`,
7
- `import { resourceLoad, resourcesRegister } from "@gtkx/gi/gio";`,
8
- ``,
9
- `const bundleDir = dirname(fileURLToPath(import.meta.url));`,
10
- `const resource = resourceLoad(join(bundleDir, ${JSON.stringify(BUNDLE_FILENAME)}));`,
11
- `resourcesRegister(resource);`,
12
- ``,
13
- `export function ensureRegistered() {}`,
14
- `export function __refresh() {}`,
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
15
  ].join("\n");
16
16
 
17
17
  const devInitModuleSource = (bundlePath: string): string => {
18
18
  const bundlePathLiteral = JSON.stringify(bundlePath);
19
+
19
20
  return [
20
- `import { existsSync, statSync } from "node:fs";`,
21
- `import { resourceLoad, resourcesRegister, resourcesUnregister } from "@gtkx/gi/gio";`,
22
- ``,
23
- `let current = null;`,
24
- `let lastSig = "";`,
25
- ``,
26
- `function register() {`,
27
- ` const next = resourceLoad(${bundlePathLiteral});`,
28
- ` if (current) resourcesUnregister(current);`,
29
- ` resourcesRegister(next);`,
30
- ` current = next;`,
31
- `}`,
32
- ``,
33
- `export function ensureRegistered() {`,
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() {",
34
35
  ` if (!existsSync(${bundlePathLiteral})) return;`,
35
36
  ` const { size, mtimeMs } = statSync(${bundlePathLiteral});`,
36
- ` const sig = size + ":" + mtimeMs;`,
37
- ` if (sig === lastSig) return;`,
38
- ` register();`,
39
- ` lastSig = sig;`,
40
- `}`,
41
- ``,
42
- `ensureRegistered();`,
43
- ``,
44
- `export function __refresh() {`,
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}() {`,
45
46
  ` if (!existsSync(${bundlePathLiteral})) return;`,
46
- ` register();`,
47
+ " register();",
47
48
  ` const { size, mtimeMs } = statSync(${bundlePathLiteral});`,
48
- ` lastSig = size + ":" + mtimeMs;`,
49
- `}`,
49
+ " lastSig = size + \":\" + mtimeMs;",
50
+ "}",
50
51
  ].join("\n");
51
52
  };
52
53
 
53
- export const renderInitModule = (options: { isBuild: boolean; devBundlePath: string }): string =>
54
+ const renderInitModule = (options: { isBuild: boolean; devBundlePath: string }): string =>
54
55
  options.isBuild ? buildInitModuleSource() : devInitModuleSource(options.devBundlePath);
56
+
57
+ export { renderInitModule };
@@ -1,27 +1,40 @@
1
1
  import { createVirtualNamespace } from "./virtual-module.js";
2
2
 
3
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);
4
9
 
5
- export const VIRTUAL_INIT = "\0gtkx-resources-init";
6
-
7
- export const BUNDLE_FILENAME = "gtkx.gresource";
8
-
9
- export const REL_SEPARATOR = "\0rel=";
10
-
11
- export const { isVirtual, toVirtualId, fromVirtualId } = createVirtualNamespace(VIRTUAL_PREFIX);
12
-
13
- export const escapeXml = (value: string): string =>
10
+ const escapeXml = (value: string): string =>
14
11
  value.replaceAll(/[<>&"']/g, (char) => {
15
12
  switch (char) {
16
- case "<":
13
+ case "<": {
17
14
  return "&lt;";
18
- case ">":
15
+ }
16
+ case ">": {
19
17
  return "&gt;";
20
- case "&":
18
+ }
19
+ case "&": {
21
20
  return "&amp;";
22
- case '"':
21
+ }
22
+ case "\"": {
23
23
  return "&quot;";
24
- default:
24
+ }
25
+ default: {
25
26
  return "&apos;";
27
+ }
26
28
  }
27
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
+ };
@@ -1,10 +1,10 @@
1
+ import type { Plugin, ResolvedConfig, UserConfig, ViteDevServer } from "vite";
2
+ import { type ConfigLoader, createConfigLoader } from "@gtkx/config/internal";
3
+ import { error, formatChildProcessError, info, sortStrings } from "@gtkx/utils";
1
4
  import { execFileSync } from "node:child_process";
2
5
  import { copyFileSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
3
6
  import { tmpdir } from "node:os";
4
7
  import { dirname, join } from "node:path";
5
- import { type ConfigLoader, createConfigLoader } from "@gtkx/config/internal";
6
- import { error, formatChildProcessError, info } from "@gtkx/utils";
7
- import type { Plugin, ResolvedConfig, UserConfig, ViteDevServer } from "vite";
8
8
  import { DATA_IMPORT_PREFIX, resolveDataDir } from "../internal/data-dir.js";
9
9
  import { type ListedFile, listFilesRecursive } from "../internal/list-files.js";
10
10
  import { resolveCliTool } from "../internal/resolve-cli-tool.js";
@@ -16,22 +16,12 @@ import {
16
16
  escapeXml,
17
17
  fromVirtualId,
18
18
  isVirtual,
19
+ REFRESH_EXPORT,
19
20
  REL_SEPARATOR,
20
21
  toVirtualId,
21
22
  VIRTUAL_INIT,
22
23
  } from "./resource-shared.js";
23
-
24
- const DATA_PREFIX = `${DATA_IMPORT_PREFIX}/`;
25
-
26
- const RESOURCE_COMPILER = "glib-compile-resources";
27
- const MANIFEST_PREFIX = "/";
28
-
29
- const deriveResourcePrefix = (applicationId: string): string => `/${applicationId.replaceAll(".", "/")}`;
30
-
31
- const stripQuery = (source: string): string => {
32
- const queryIndex = source.indexOf("?");
33
- return queryIndex === -1 ? source : source.slice(0, queryIndex);
34
- };
24
+ import { stripQuery } from "./strip-query.js";
35
25
 
36
26
  type ResourceEntry = {
37
27
  sourcePath: string;
@@ -51,32 +41,44 @@ type PluginState = {
51
41
  dataDir: string | null;
52
42
  };
53
43
 
44
+ const DATA_PREFIX = `${DATA_IMPORT_PREFIX}/`;
45
+ const RESOURCE_COMPILER = "glib-compile-resources";
46
+ const MANIFEST_PREFIX = "/";
47
+
48
+ const deriveResourcePrefix = (applicationId: string): string => `/${applicationId.replaceAll(".", "/")}`;
49
+
54
50
  const compileBundle = (state: PluginState, outputPath: string): Buffer =>
55
51
  withStagingDir("resources", (dir) => {
56
52
  const manifest = stageBundle(dir, state.entries);
53
+
57
54
  return runCompiler(dir, manifest, outputPath);
58
55
  });
59
56
 
60
57
  const stageBundle = (dir: string, entries: Map<string, ResourceEntry>): string => {
61
58
  const fileNodes: string[] = [];
59
+
62
60
  for (const entry of entries.values()) {
63
61
  const targetPath = join(dir, entry.stagedRelPath);
64
62
  mkdirSync(dirname(targetPath), { recursive: true });
65
63
  copyFileSync(entry.sourcePath, targetPath);
66
64
  fileNodes.push(` <file>${escapeXml(entry.stagedRelPath)}</file>`);
67
65
  }
66
+
68
67
  const prefix = escapeXml(MANIFEST_PREFIX);
69
68
  const manifest = join(dir, "gtkx.gresource.xml");
69
+
70
70
  const xml = [
71
- `<?xml version="1.0" encoding="UTF-8"?>`,
72
- `<gresources>`,
71
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
72
+ "<gresources>",
73
73
  ` <gresource prefix="${prefix}">`,
74
74
  ...fileNodes,
75
- ` </gresource>`,
76
- `</gresources>`,
77
- ``,
75
+ " </gresource>",
76
+ "</gresources>",
77
+ "",
78
78
  ].join("\n");
79
+
79
80
  writeFileSync(manifest, xml);
81
+
80
82
  return manifest;
81
83
  };
82
84
 
@@ -89,42 +91,63 @@ const runCompiler = (sourceDir: string, manifest: string, outputPath: string): B
89
91
  ]);
90
92
  } catch (error) {
91
93
  const details = formatChildProcessError(error);
92
- throw new Error(`${RESOURCE_COMPILER} failed${details ? `:\n${details}` : ""}`, { cause: error });
94
+ const suffix = details ? `:\n${details}` : "";
95
+ throw new Error(`${RESOURCE_COMPILER} failed${suffix}`, { cause: error });
93
96
  }
97
+
94
98
  return readFileSync(outputPath);
95
99
  };
96
100
 
97
101
  const ensureStagingDir = (state: PluginState): void => {
98
- if (!state.devStagingDir) {
99
- state.devStagingDir = mkdtempSync(join(tmpdir(), "gtkx-resources-dev-"));
100
- state.devBundlePath = join(state.devStagingDir, BUNDLE_FILENAME);
102
+ if (state.devStagingDir) {
103
+ return;
101
104
  }
105
+
106
+ state.devStagingDir = mkdtempSync(join(tmpdir(), "gtkx-resources-dev-"));
107
+ state.devBundlePath = join(state.devStagingDir, BUNDLE_FILENAME);
102
108
  };
103
109
 
104
- const entriesSignature = (state: PluginState): string =>
105
- [...state.entries.keys()].sort((a, b) => a.localeCompare(b)).join("\0");
110
+ const entriesSignature = (state: PluginState): string => sortStrings(state.entries.keys()).join("\0");
106
111
 
107
112
  const compileDevBundle = (state: PluginState): void => {
108
113
  ensureStagingDir(state);
109
- if (state.entries.size === 0) return;
114
+
115
+ if (state.entries.size === 0) {
116
+ return;
117
+ }
118
+
110
119
  compileBundle(state, state.devBundlePath);
111
120
  state.compiledSignature = entriesSignature(state);
112
121
  };
113
122
 
123
+ const isRefreshHook = (value: unknown): value is () => void => typeof value === "function";
124
+
114
125
  const reregisterDevBundle = async (state: PluginState): Promise<void> => {
115
126
  const server = state.server;
116
- if (!server) return;
117
- const mod = (await server.ssrLoadModule(VIRTUAL_INIT)) as { __refresh?: () => void };
118
- mod.__refresh?.();
127
+
128
+ if (!server) {
129
+ return;
130
+ }
131
+
132
+ const mod = await server.ssrLoadModule(VIRTUAL_INIT);
133
+ const refresh: unknown = mod[REFRESH_EXPORT];
134
+
135
+ if (isRefreshHook(refresh)) {
136
+ refresh();
137
+ }
119
138
  };
120
139
 
121
140
  const scanDataAssets = (dataDir: string): ListedFile[] => listFilesRecursive(dataDir, (name) => ASSET_RE.test(name));
122
141
 
123
142
  const primeDevBundle = (state: PluginState): void => {
124
- if (state.dataDir === null) return;
143
+ if (state.dataDir === null) {
144
+ return;
145
+ }
146
+
125
147
  for (const { absPath, rel } of scanDataAssets(state.dataDir)) {
126
148
  registerEntry(state, absPath, rel);
127
149
  }
150
+
128
151
  compileDevBundle(state);
129
152
  };
130
153
 
@@ -136,21 +159,56 @@ const registerDevAsset = (state: PluginState): void => {
136
159
 
137
160
  const registerEntry = (state: PluginState, absPath: string, rel: string): ResourceEntry => {
138
161
  const existing = state.entries.get(absPath);
139
- if (existing) return existing;
162
+
163
+ if (existing) {
164
+ return existing;
165
+ }
140
166
 
141
167
  const resourcePath = `${state.prefix}/${rel}`;
168
+
142
169
  const entry: ResourceEntry = {
143
170
  sourcePath: absPath,
144
171
  stagedRelPath: resourcePath.replace(/^\/+/, ""),
145
172
  resourcePath,
146
173
  };
174
+
147
175
  state.entries.set(absPath, entry);
148
176
  state.sourcePaths.add(absPath);
177
+
149
178
  return entry;
150
179
  };
151
180
 
152
181
  const isTrackedSource = (state: PluginState, file: string): boolean => state.sourcePaths.has(file);
153
182
 
183
+ const dataAssetSource = (source: string): string | null => {
184
+ const clean = stripQuery(source);
185
+
186
+ if (!clean.startsWith(DATA_PREFIX) || !ASSET_PATH_RE.test(clean)) {
187
+ return null;
188
+ }
189
+
190
+ return clean;
191
+ };
192
+
193
+ const resolvedAssetId = (
194
+ resolved: { id: string; external: boolean | string } | null,
195
+ clean: string,
196
+ ): string | undefined => {
197
+ if (!resolved || resolved.external) {
198
+ return undefined;
199
+ }
200
+
201
+ return toVirtualId(resolved.id) + REL_SEPARATOR + clean.slice(DATA_PREFIX.length);
202
+ };
203
+
204
+ const loadInitModule = (state: PluginState): string => {
205
+ if (!state.isBuild) {
206
+ ensureStagingDir(state);
207
+ }
208
+
209
+ return renderInitModule({ isBuild: state.isBuild, devBundlePath: state.devBundlePath });
210
+ };
211
+
154
212
  const loadAssetModule = (state: PluginState, virtualId: string): string => {
155
213
  const rest = fromVirtualId(virtualId);
156
214
  const separatorIndex = rest.indexOf(REL_SEPARATOR);
@@ -165,7 +223,7 @@ const loadAssetModule = (state: PluginState, virtualId: string): string => {
165
223
 
166
224
  return [
167
225
  `import { ensureRegistered } from ${JSON.stringify(VIRTUAL_INIT)};`,
168
- `ensureRegistered();`,
226
+ "ensureRegistered();",
169
227
  `export default ${JSON.stringify(uri)};`,
170
228
  `export const path = ${JSON.stringify(entry.resourcePath)};`,
171
229
  ].join("\n");
@@ -175,42 +233,81 @@ const emitBuildBundle = (
175
233
  ctx: { emitFile: (asset: { type: "asset"; fileName: string; source: Buffer }) => string },
176
234
  state: PluginState,
177
235
  ): void => {
178
- if (!state.isBuild || state.entries.size === 0) return;
236
+ if (!state.isBuild || state.entries.size === 0) {
237
+ return;
238
+ }
239
+
179
240
  const compiled = withStagingDir("resources-out", (outDir) => compileBundle(state, join(outDir, BUNDLE_FILENAME)));
180
241
  ctx.emitFile({ type: "asset", fileName: BUNDLE_FILENAME, source: compiled });
181
- info(`Compiled ${state.entries.size} resource(s) into ${BUNDLE_FILENAME}`);
242
+ info(`Compiled ${String(state.entries.size)} resource(s) into ${BUNDLE_FILENAME}`);
182
243
  };
183
244
 
184
245
  const refreshDevRegistration = async (state: PluginState): Promise<void> => {
185
246
  compileDevBundle(state);
247
+
186
248
  try {
187
249
  await reregisterDevBundle(state);
188
- } catch (cause) {
189
- error("Failed to refresh GResource bundle:", cause);
250
+ } catch (error_) {
251
+ error("Failed to refresh GResource bundle:", error_);
190
252
  }
191
253
  };
192
254
 
193
255
  const resolveResourceConfig = async (state: PluginState, config: UserConfig, loadConfig: ConfigLoader) => {
194
256
  const { applicationId } = await loadConfig(config.root ?? process.cwd());
195
257
  state.prefix = deriveResourcePrefix(applicationId);
258
+
196
259
  return {
197
260
  assetsInclude: [ASSET_RE],
198
261
  };
199
262
  };
200
263
 
264
+ const refreshTrackedSource = async (state: PluginState, file: string): Promise<void> => {
265
+ if (!isTrackedSource(state, file)) {
266
+ return;
267
+ }
268
+
269
+ try {
270
+ await refreshDevRegistration(state);
271
+ } catch (error_) {
272
+ error("GResource refresh failed:", error_);
273
+ }
274
+ };
275
+
201
276
  const attachResourceWatcher = (state: PluginState, server: ViteDevServer): void => {
202
277
  state.server = server;
278
+
203
279
  const onFileEvent = (file: string): void => {
204
- if (!isTrackedSource(state, file)) return;
205
- refreshDevRegistration(state).catch((cause) => {
206
- error("GResource refresh failed:", cause);
207
- });
280
+ void refreshTrackedSource(state, file);
208
281
  };
282
+
209
283
  server.watcher.on("change", onFileEvent);
210
284
  server.watcher.on("add", onFileEvent);
211
285
  };
212
286
 
213
- export function gtkxResources(loadConfig: ConfigLoader = createConfigLoader()): Plugin {
287
+ const applyResolvedConfig = (state: PluginState, config: ResolvedConfig): void => {
288
+ state.isBuild = config.command === "build";
289
+
290
+ if (state.isBuild) {
291
+ return;
292
+ }
293
+
294
+ const relativeDataDir = resolveDataDir(config.root);
295
+ state.dataDir = relativeDataDir === null ? null : join(config.root, relativeDataDir);
296
+ };
297
+
298
+ const loadResourceModule = (state: PluginState, id: string): string | undefined => {
299
+ if (id === VIRTUAL_INIT) {
300
+ return loadInitModule(state);
301
+ }
302
+
303
+ if (!isVirtual(id)) {
304
+ return undefined;
305
+ }
306
+
307
+ return loadAssetModule(state, id);
308
+ };
309
+
310
+ function gtkxResources(loadConfig: ConfigLoader = createConfigLoader()): Plugin {
214
311
  const state: PluginState = {
215
312
  prefix: "",
216
313
  isBuild: false,
@@ -232,11 +329,7 @@ export function gtkxResources(loadConfig: ConfigLoader = createConfigLoader()):
232
329
  },
233
330
 
234
331
  configResolved(config: ResolvedConfig) {
235
- state.isBuild = config.command === "build";
236
- if (!state.isBuild) {
237
- const relativeDataDir = resolveDataDir(config.root);
238
- state.dataDir = relativeDataDir === null ? null : join(config.root, relativeDataDir);
239
- }
332
+ applyResolvedConfig(state, config);
240
333
  },
241
334
 
242
335
  configureServer(server) {
@@ -245,24 +338,23 @@ export function gtkxResources(loadConfig: ConfigLoader = createConfigLoader()):
245
338
  },
246
339
 
247
340
  async resolveId(source, importer, opts) {
248
- if (source === VIRTUAL_INIT) return VIRTUAL_INIT;
249
- const clean = stripQuery(source);
250
- if (!clean.startsWith(DATA_PREFIX) || !ASSET_PATH_RE.test(clean)) return;
341
+ if (source === VIRTUAL_INIT) {
342
+ return VIRTUAL_INIT;
343
+ }
344
+
345
+ const clean = dataAssetSource(source);
346
+
347
+ if (clean === null) {
348
+ return;
349
+ }
251
350
 
252
351
  const resolved = await this.resolve(clean, importer, { ...opts, skipSelf: true });
253
- if (!resolved || resolved.external) return;
254
352
 
255
- const rel = clean.slice(DATA_PREFIX.length);
256
- return toVirtualId(resolved.id) + REL_SEPARATOR + rel;
353
+ return resolvedAssetId(resolved, clean);
257
354
  },
258
355
 
259
356
  load(id) {
260
- if (id === VIRTUAL_INIT) {
261
- if (!state.isBuild) ensureStagingDir(state);
262
- return renderInitModule({ isBuild: state.isBuild, devBundlePath: state.devBundlePath });
263
- }
264
- if (!isVirtual(id)) return;
265
- return loadAssetModule(state, id);
357
+ return loadResourceModule(state, id);
266
358
  },
267
359
 
268
360
  buildEnd() {
@@ -270,3 +362,5 @@ export function gtkxResources(loadConfig: ConfigLoader = createConfigLoader()):
270
362
  },
271
363
  };
272
364
  }
365
+
366
+ export { gtkxResources };
@@ -3,7 +3,7 @@ import type { Plugin } from "vitest/config";
3
3
  import { resolveDataDir } from "../internal/data-dir.js";
4
4
  import { prependSchemaDir, stageAndCompileProjectSchemas } from "../settings/schema.js";
5
5
 
6
- export function gtkxSettingsWorkerEnv(): Plugin {
6
+ function gtkxSettingsWorkerEnv(): Plugin {
7
7
  return {
8
8
  name: "gtkx:settings-worker-env",
9
9
  enforce: "pre",
@@ -11,7 +11,10 @@ export function gtkxSettingsWorkerEnv(): Plugin {
11
11
  config(config: UserConfig) {
12
12
  const root = config.root ?? process.cwd();
13
13
  const dir = stageAndCompileProjectSchemas(root, resolveDataDir(root));
14
- if (dir === null) return;
14
+
15
+ if (dir === null) {
16
+ return;
17
+ }
15
18
 
16
19
  process.env.GTKX_DEV_SCHEMA_DIR = dir;
17
20
 
@@ -23,3 +26,5 @@ export function gtkxSettingsWorkerEnv(): Plugin {
23
26
  },
24
27
  };
25
28
  }
29
+
30
+ export { gtkxSettingsWorkerEnv };