@gtkx/cli 1.0.0-rc.1 → 1.0.0-rc.3

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 +10 -10
  18. package/dist/codegen/run-codegen.d.ts.map +1 -1
  19. package/dist/codegen/run-codegen.js +72 -47
  20. package/dist/codegen/run-codegen.js.map +1 -1
  21. package/dist/codegen/store-resolver.d.ts +9 -6
  22. package/dist/codegen/store-resolver.d.ts.map +1 -1
  23. package/dist/codegen/store-resolver.js +24 -7
  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 +25 -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 +4 -3
  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 +95 -55
  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 +3 -1
  218. package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
  219. package/dist/vite-plugins/undeclared-library.js +11 -8
  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 +39 -26
  233. package/src/codegen/report.ts +10 -2
  234. package/src/codegen/run-codegen.ts +131 -66
  235. package/src/codegen/store-resolver.ts +52 -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 +47 -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 +7 -4
  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 +154 -60
  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 +26 -16
  285. package/src/vite-plugins/virtual-module.ts +9 -2
  286. package/src/vitest-plugin.ts +1 -2
@@ -1,52 +1,65 @@
1
+ import type { Config } from "@gtkx/config";
2
+ import { resolveGirPath, resolveLibraries } from "@gtkx/codegen";
1
3
  import { existsSync } from "node:fs";
2
4
  import { join } from "node:path";
3
- import { resolveGirPath, resolveLibraries } from "@gtkx/codegen";
4
- import type { Config, ElementProp } from "@gtkx/config";
5
5
  import { type CodegenStore, resolveCodegenStore } from "./store-resolver.js";
6
6
 
7
- export type CodegenInputs = {
7
+ type CodegenInputs = {
8
8
  girPath: string[];
9
9
  libraries: string[];
10
- elementProps: Record<string, ElementProp[]>;
11
10
  store: CodegenStore;
12
11
  };
13
12
 
14
- export const resolveCodegenInputs = (cwd: string, config: Config): CodegenInputs => {
13
+ const REACT_GENERATED_MODULES: string[] = ["metadata.js", join("gtk", "gtk.js")];
14
+
15
+ const resolveCodegenInputs = (cwd: string, config: Config): CodegenInputs => {
15
16
  const girPath = resolveGirPath(config.girPath);
16
17
  const libraries = resolveLibraries(config.libraries, girPath);
17
18
  const store = resolveCodegenStore(cwd);
18
- return { girPath, libraries, elementProps: config.elementProps ?? {}, store };
19
- };
20
19
 
21
- const REACT_GENERATED_MODULES: string[] = ["metadata.js", join("gtk", "gtk.js")];
20
+ return { girPath, libraries, store };
21
+ };
22
22
 
23
23
  const namespaceBarrelPath = (giStoreDir: string, library: string): string => {
24
24
  const separator = library.indexOf("-");
25
25
  const namespace = (separator === -1 ? library : library.slice(0, separator)).toLowerCase();
26
+
26
27
  return join(giStoreDir, namespace, "index.js");
27
28
  };
28
29
 
29
- const giStoreLinksResolve = (giStoreDir: string): boolean =>
30
- existsSync(join(giStoreDir, "node_modules", "@gtkx", "gi", "package.json"));
30
+ const isStoreResolvable = (storeDir: string, packageName: string): boolean =>
31
+ existsSync(join(storeDir, "node_modules", "@gtkx", packageName, "package.json"));
31
32
 
32
- export const isCodegenStale = (inputs: CodegenInputs): boolean => {
33
- try {
34
- const { store, libraries } = inputs;
35
- if (!existsSync(store.giLinkDir) || !existsSync(store.giStoreDir)) {
36
- return true;
37
- }
38
- if (!giStoreLinksResolve(store.giStoreDir)) {
39
- return true;
40
- }
41
- if (libraries.some((library) => !existsSync(namespaceBarrelPath(store.giStoreDir, library)))) {
42
- return true;
43
- }
44
- if (store.react !== null) {
45
- if (!existsSync(store.jsxLinkDir)) return true;
46
- if (REACT_GENERATED_MODULES.some((module) => !existsSync(join(store.jsxStoreDir, module)))) return true;
47
- }
33
+ const isGiStoreStale = (store: CodegenStore, libraries: string[]): boolean => {
34
+ if (!existsSync(store.giLinkDir) || !existsSync(store.giStoreDir)) {
35
+ return true;
36
+ }
37
+
38
+ if (!isStoreResolvable(store.giStoreDir, "gi")) {
39
+ return true;
40
+ }
41
+
42
+ return libraries.some((library) => !existsSync(namespaceBarrelPath(store.giStoreDir, library)));
43
+ };
44
+
45
+ const isReactStoreStale = (store: CodegenStore): boolean => {
46
+ if (store.react === null) {
48
47
  return false;
48
+ }
49
+
50
+ if (!existsSync(store.jsxLinkDir) || !isStoreResolvable(store.jsxStoreDir, "jsx")) {
51
+ return true;
52
+ }
53
+
54
+ return REACT_GENERATED_MODULES.some((module) => !existsSync(join(store.jsxStoreDir, module)));
55
+ };
56
+
57
+ const isCodegenStale = (inputs: CodegenInputs): boolean => {
58
+ try {
59
+ return isGiStoreStale(inputs.store, inputs.libraries) || isReactStoreStale(inputs.store);
49
60
  } catch {
50
61
  return true;
51
62
  }
52
63
  };
64
+
65
+ export { resolveCodegenInputs, isCodegenStale, type CodegenInputs };
@@ -2,19 +2,27 @@ import type { RunCodegenResult } from "./run-codegen.js";
2
2
 
3
3
  const PREFIX = "codegen: ";
4
4
 
5
- export const formatCodegenResult = (result: RunCodegenResult, totalMs: number): string[] => {
5
+ const formatCodegenResult = (result: RunCodegenResult, totalMs: number): string[] => {
6
6
  const details: string[] = [];
7
+
7
8
  if (result.configFile) {
8
9
  details.push(`config=${result.configFile}`);
9
10
  }
11
+
10
12
  if (result.libraries) {
11
13
  details.push(`libraries=${result.libraries.join(", ")}`);
12
14
  }
15
+
13
16
  if (result.girPath) {
14
17
  details.push(`girPath=${result.girPath.join(":")}`);
15
18
  }
19
+
16
20
  details.push(
17
- `${result.namespaces} namespaces, ${result.intrinsicElements} intrinsic elements in ${result.duration}ms (total ${totalMs}ms)`,
21
+ `${String(result.namespaces)} namespaces, ${String(result.intrinsicElements)} intrinsic elements ` +
22
+ `in ${String(result.duration)}ms (total ${String(totalMs)}ms)`,
18
23
  );
24
+
19
25
  return details.map((detail) => PREFIX + detail);
20
26
  };
27
+
28
+ export { formatCodegenResult };
@@ -1,14 +1,20 @@
1
- import { rmSync } from "node:fs";
2
- import { resolve } from "node:path";
3
1
  import { runCodegen as runCodegenCore } from "@gtkx/codegen";
4
- import { type Config, type ElementProp, loadConfig } from "@gtkx/config";
2
+ import { type Config, loadConfig } from "@gtkx/config";
3
+ import {
4
+ resolveElementComponents,
5
+ resolveElementProps,
6
+ resolveLazyElements,
7
+ resolveOmitProps,
8
+ } from "@gtkx/config/internal";
5
9
  import { info } from "@gtkx/utils";
10
+ import { rmSync } from "node:fs";
11
+ import { resolve } from "node:path";
6
12
  import { resolveDataDir } from "../internal/data-dir.js";
7
13
  import { emitSchemaEnv } from "../settings/schema.js";
8
14
  import { type CodegenInputs, isCodegenStale, resolveCodegenInputs } from "./freshness.js";
9
15
  import { type CodegenStore, resolveCodegenContext } from "./store-resolver.js";
10
16
 
11
- export type RunCodegenOptions = {
17
+ type RunCodegenOptions = {
12
18
  cwd?: string;
13
19
  mode?: string | undefined;
14
20
  force?: boolean;
@@ -18,10 +24,10 @@ export type RunCodegenOptions = {
18
24
 
19
25
  type LoadedConfig = {
20
26
  config: Config;
21
- configFile: string | undefined;
27
+ configFile: string;
22
28
  };
23
29
 
24
- export type RunCodegenResult = {
30
+ type RunCodegenResult = {
25
31
  regenerated: boolean;
26
32
  namespaces: number;
27
33
  intrinsicElements: number;
@@ -31,6 +37,27 @@ export type RunCodegenResult = {
31
37
  libraries?: string[] | undefined;
32
38
  };
33
39
 
40
+ type CodegenOptionsInput = {
41
+ store: CodegenStore;
42
+ libraries: string[];
43
+ girPath: string[];
44
+ elements: Config["elements"];
45
+ };
46
+
47
+ type PreparedCodegen = CodegenInputs & { force: boolean };
48
+
49
+ type RunOptionsInput = {
50
+ root: string;
51
+ mode: string | undefined;
52
+ inputs: CodegenInputs | null;
53
+ resolved: LoadedConfig;
54
+ };
55
+
56
+ const GIR_PATH_MISSING_MESSAGE =
57
+ "No GIR search paths available. Install gobject-introspection " +
58
+ "(Linux: `sudo dnf install gobject-introspection-devel` or `sudo apt install libgirepository1.0-dev`), " +
59
+ "or set `girPath` in gtkx.config.ts.";
60
+
34
61
  const removeSharedStoreShadow = (cwd: string): void => {
35
62
  for (const path of [
36
63
  resolve(cwd, "node_modules/.gtkx/gi"),
@@ -42,67 +69,83 @@ const removeSharedStoreShadow = (cwd: string): void => {
42
69
  }
43
70
  };
44
71
 
45
- type CodegenOptionsInput = {
46
- store: CodegenStore;
47
- libraries: string[];
48
- girPath: string[];
49
- elementProps: Record<string, ElementProp[]>;
50
- };
51
-
52
- const codegenOptions = ({ store, libraries, girPath, elementProps }: CodegenOptionsInput) => ({
72
+ const codegenOptions = ({ store, libraries, girPath, elements }: CodegenOptionsInput) => ({
53
73
  libraries,
54
74
  girPath,
55
- elementProps,
56
75
  gi: {
57
76
  storeDir: store.giStoreDir,
58
77
  linkDir: store.giLinkDir,
59
78
  version: store.runtimeVersion,
60
79
  },
61
80
  jsx:
62
- store.react !== null
63
- ? {
64
- storeDir: store.jsxStoreDir,
65
- linkDir: store.jsxLinkDir,
66
- version: store.react.version,
67
- }
68
- : undefined,
81
+ store.react === null
82
+ ? undefined
83
+ : {
84
+ storeDir: store.jsxStoreDir,
85
+ linkDir: store.jsxLinkDir,
86
+ version: store.react.version,
87
+ },
88
+ reactSubexports: store.react?.subexports ?? [],
89
+ userComponents: resolveElementComponents(elements),
90
+ userProps: resolveElementProps(elements),
91
+ userLazyElements: resolveLazyElements(elements),
92
+ userOmitProps: resolveOmitProps(elements),
69
93
  });
70
94
 
71
- export const runCodegen = async (options: RunCodegenOptions = {}): Promise<RunCodegenResult> => {
72
- const cwd = options.cwd ?? process.cwd();
73
-
74
- const { config, configFile } = options.resolved ?? (await loadConfig(cwd, { mode: options.mode }));
95
+ const disabledCodegenResult = (configFile: string): RunCodegenResult => ({
96
+ regenerated: false,
97
+ namespaces: 0,
98
+ intrinsicElements: 0,
99
+ duration: 0,
100
+ girPath: [],
101
+ configFile,
102
+ libraries: [],
103
+ });
75
104
 
76
- if (config.codegen === false) {
77
- removeSharedStoreShadow(cwd);
78
- return {
79
- regenerated: false,
80
- namespaces: 0,
81
- intrinsicElements: 0,
82
- duration: 0,
83
- girPath: [],
84
- configFile,
85
- libraries: [],
86
- };
105
+ const clearGeneratedStores = (store: CodegenStore): void => {
106
+ for (const path of [store.giStoreDir, store.giLinkDir, store.jsxStoreDir, store.jsxLinkDir]) {
107
+ rmSync(path, { recursive: true, force: true });
87
108
  }
109
+ };
110
+
111
+ const resolveLoadedConfig = async (options: RunCodegenOptions, cwd: string): Promise<LoadedConfig> =>
112
+ options.resolved ?? (await loadConfig(cwd, { mode: options.mode }));
88
113
 
89
- const { girPath, libraries, elementProps, store } = options.inputs ?? resolveCodegenInputs(cwd, config);
114
+ const prepareCodegen = (options: RunCodegenOptions, cwd: string, config: Config): PreparedCodegen => {
115
+ const { girPath, libraries, store } = options.inputs ?? resolveCodegenInputs(cwd, config);
90
116
 
91
117
  if (girPath.length === 0) {
92
- throw new Error(
93
- "No GIR search paths available. Install gobject-introspection (Linux: `sudo dnf install gobject-introspection-devel` or `sudo apt install libgirepository1.0-dev`), or set `girPath` in gtkx.config.ts.",
94
- );
118
+ throw new Error(GIR_PATH_MISSING_MESSAGE);
95
119
  }
96
120
 
97
- const force = options.force === true || isCodegenStale({ girPath, libraries, elementProps, store });
121
+ const isForce = options.force === true || isCodegenStale({ girPath, libraries, store });
122
+
123
+ return { girPath, libraries, store, force: isForce };
124
+ };
125
+
126
+ const runCodegen = async (options: RunCodegenOptions = {}): Promise<RunCodegenResult> => {
127
+ const cwd = options.cwd ?? process.cwd();
128
+ const { config, configFile } = await resolveLoadedConfig(options, cwd);
129
+
130
+ if (config.codegen === false) {
131
+ removeSharedStoreShadow(cwd);
132
+
133
+ return disabledCodegenResult(configFile);
134
+ }
135
+
136
+ const { girPath, libraries, store, force } = prepareCodegen(options, cwd, config);
137
+
98
138
  if (options.force) {
99
- for (const path of [store.giStoreDir, store.giLinkDir, store.jsxStoreDir, store.jsxLinkDir]) {
100
- rmSync(path, { recursive: true, force: true });
101
- }
139
+ clearGeneratedStores(store);
102
140
  }
103
141
 
104
142
  const result = await runCodegenCore({
105
- ...codegenOptions({ store, libraries, girPath, elementProps }),
143
+ ...codegenOptions({
144
+ store,
145
+ libraries,
146
+ girPath,
147
+ elements: config.elements,
148
+ }),
106
149
  force,
107
150
  });
108
151
 
@@ -117,19 +160,18 @@ export const runCodegen = async (options: RunCodegenOptions = {}): Promise<RunCo
117
160
  };
118
161
  };
119
162
 
120
- export const isCodegenDisabled = async (cwd: string, mode?: string): Promise<boolean> => {
163
+ const isCodegenDisabled = async (cwd: string, mode?: string): Promise<boolean> => {
121
164
  try {
122
165
  const { config } = await loadConfig(cwd, { mode });
166
+
123
167
  return config.codegen === false;
124
168
  } catch {
125
169
  return false;
126
170
  }
127
171
  };
128
172
 
129
- export const syncSchemaEnv = (cwd: string): void => {
130
- const dataDir = resolveDataDir(cwd);
131
- if (dataDir === null) return;
132
- emitSchemaEnv(cwd, dataDir);
173
+ const syncSchemaEnv = (cwd: string): void => {
174
+ emitSchemaEnv(cwd, resolveDataDir(cwd));
133
175
  };
134
176
 
135
177
  const resolveInputsOrNull = (cwd: string, config: Config): CodegenInputs | null => {
@@ -140,7 +182,25 @@ const resolveInputsOrNull = (cwd: string, config: Config): CodegenInputs | null
140
182
  }
141
183
  };
142
184
 
143
- export const ensureGenerated = async (
185
+ const maybeAnnounceStale = (announce: boolean | undefined, inputs: CodegenInputs | null): void => {
186
+ if (!announce) {
187
+ return;
188
+ }
189
+
190
+ if (inputs === null || isCodegenStale(inputs)) {
191
+ info("generated bindings missing; running codegen...");
192
+ }
193
+ };
194
+
195
+ const getRunOptions = ({ root, mode, inputs, resolved }: RunOptionsInput): RunCodegenOptions => {
196
+ if (inputs === null) {
197
+ return { cwd: root, mode, resolved };
198
+ }
199
+
200
+ return { cwd: root, mode, inputs, resolved };
201
+ };
202
+
203
+ const ensureGenerated = async (
144
204
  cwd: string,
145
205
  options: { announce?: boolean; mode?: string } = {},
146
206
  ): Promise<boolean> => {
@@ -149,33 +209,28 @@ export const ensureGenerated = async (
149
209
  }
150
210
 
151
211
  const context = await resolveCodegenContext(cwd, options.mode);
152
- if (!context) {
153
- return false;
154
- }
155
212
  syncSchemaEnv(cwd);
213
+
156
214
  if (context.config.codegen === false) {
157
215
  removeSharedStoreShadow(context.root);
216
+
158
217
  return false;
159
218
  }
219
+
160
220
  const inputs = resolveInputsOrNull(context.root, context.config);
161
- if (options.announce && (inputs === null || isCodegenStale(inputs))) {
162
- info("generated bindings missing; running codegen...");
163
- }
221
+ maybeAnnounceStale(options.announce, inputs);
164
222
  const resolved = { config: context.config, configFile: context.configFile };
165
- const result = await runCodegen(
166
- inputs === null
167
- ? { cwd: context.root, mode: options.mode, resolved }
168
- : { cwd: context.root, mode: options.mode, inputs, resolved },
169
- );
223
+ const result = await runCodegen(getRunOptions({ root: context.root, mode: options.mode, inputs, resolved }));
224
+
170
225
  return result.regenerated;
171
226
  };
172
227
 
173
- export const resolveConfigWatch = async (
228
+ const resolveConfigWatch = async (
174
229
  cwd: string,
175
230
  mode?: string,
176
- ): Promise<{ paths: string[]; regenerate: () => Promise<void> } | undefined> => {
231
+ ): Promise<{ paths: string[]; regenerate: () => Promise<void> }> => {
177
232
  const { configFile, root } = await loadConfig(cwd, { mode });
178
- if (configFile === undefined) return undefined;
233
+
179
234
  return {
180
235
  paths: [resolve(root, configFile)],
181
236
  regenerate: async () => {
@@ -183,3 +238,13 @@ export const resolveConfigWatch = async (
183
238
  },
184
239
  };
185
240
  };
241
+
242
+ export {
243
+ runCodegen,
244
+ isCodegenDisabled,
245
+ syncSchemaEnv,
246
+ ensureGenerated,
247
+ resolveConfigWatch,
248
+ type RunCodegenOptions,
249
+ type RunCodegenResult,
250
+ };
@@ -1,10 +1,10 @@
1
+ import { type Config, loadConfig } from "@gtkx/config";
1
2
  import { existsSync, readFileSync, realpathSync } from "node:fs";
2
3
  import { createRequire } from "node:module";
3
4
  import { dirname, join } from "node:path";
4
5
  import { pathToFileURL } from "node:url";
5
- import { type Config, loadConfig } from "@gtkx/config";
6
6
 
7
- export type CodegenStore = {
7
+ type CodegenStore = {
8
8
  giStoreDir: string;
9
9
  giLinkDir: string;
10
10
  jsxStoreDir: string;
@@ -15,61 +15,98 @@ export type CodegenStore = {
15
15
 
16
16
  type CodegenReactPackage = {
17
17
  version: string;
18
+ subexports: string[];
18
19
  };
19
20
 
20
21
  type ResolvedPackage = { dir: string; version: string };
21
22
 
23
+ type CodegenContext = {
24
+ root: string;
25
+ config: Config;
26
+ configFile: string;
27
+ };
28
+
22
29
  const readVersion = (packageJsonPath: string): string => {
23
30
  const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8")) as { version?: string };
31
+
24
32
  return parsed.version ?? "0.0.0";
25
33
  };
26
34
 
35
+ const readSubexports = (packageDir: string): string[] => {
36
+ const parsed = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8")) as {
37
+ exports?: Record<string, unknown>;
38
+ };
39
+
40
+ return Object.keys(parsed.exports ?? {})
41
+ .filter((key) => key.startsWith("./") && key !== "./package.json")
42
+ .map((key) => key.slice(2));
43
+ };
44
+
45
+ /** Resolves the `@gtkx/react` subexport names for a project without requiring runtime/native to be installed. */
46
+ const resolveReactSubexports = (dir: string): string[] => {
47
+ const require = createRequire(pathToFileURL(join(dir, "__gtkx_resolver__.js")).href);
48
+ const react = resolvePackage(require, dir, "@gtkx/react");
49
+
50
+ return react === null ? [] : readSubexports(react.dir);
51
+ };
52
+
27
53
  const resolvePackage = (require: NodeJS.Require, dir: string, packageName: string): ResolvedPackage | null => {
28
54
  try {
29
55
  const real = realpathSync(require.resolve(`${packageName}/package.json`));
56
+
30
57
  return { dir: dirname(real), version: readVersion(real) };
31
58
  } catch {
32
59
  const unscoped = packageName.replace(/^@[^/]+\//, "");
33
60
  const workspacePkg = join(dir, "packages", unscoped, "package.json");
34
- if (!existsSync(workspacePkg)) return null;
61
+
62
+ if (!existsSync(workspacePkg)) {
63
+ return null;
64
+ }
65
+
35
66
  const real = realpathSync(workspacePkg);
67
+
36
68
  return { dir: dirname(real), version: readVersion(real) };
37
69
  }
38
70
  };
39
71
 
40
- export const resolveCodegenStore = (dir: string): CodegenStore => {
72
+ const resolveCodegenStore = (dir: string): CodegenStore => {
41
73
  const require = createRequire(pathToFileURL(join(dir, "__gtkx_resolver__.js")).href);
42
-
43
74
  const runtime = resolvePackage(require, dir, "@gtkx/runtime");
75
+
44
76
  if (runtime === null) {
45
77
  throw new Error("Cannot resolve @gtkx/runtime from the project; is it installed?");
46
78
  }
79
+
47
80
  const native = resolvePackage(require, dir, "@gtkx/native");
81
+
48
82
  if (native === null) {
49
83
  throw new Error("Cannot resolve @gtkx/native from the project; is it installed?");
50
84
  }
85
+
51
86
  const react = resolvePackage(require, dir, "@gtkx/react");
52
87
  const reactRuntime = resolvePackage(require, dir, "react");
53
-
54
88
  const nodeModules = join(dir, "node_modules");
89
+
55
90
  return {
56
91
  giStoreDir: join(nodeModules, ".gtkx", "gi"),
57
92
  giLinkDir: join(nodeModules, "@gtkx", "gi"),
58
93
  jsxStoreDir: join(nodeModules, ".gtkx", "jsx"),
59
94
  jsxLinkDir: join(nodeModules, "@gtkx", "jsx"),
60
95
  runtimeVersion: runtime.version,
61
- react: react !== null && reactRuntime !== null ? { version: react.version } : null,
96
+ react:
97
+ react !== null && reactRuntime !== null
98
+ ? {
99
+ version: react.version,
100
+ subexports: readSubexports(react.dir),
101
+ }
102
+ : null,
62
103
  };
63
104
  };
64
105
 
65
- export type CodegenContext = {
66
- root: string;
67
- config: Config;
68
- configFile: string | undefined;
69
- };
70
-
71
- export const resolveCodegenContext = async (cwd: string, mode?: string): Promise<CodegenContext | null> => {
106
+ const resolveCodegenContext = async (cwd: string, mode?: string): Promise<CodegenContext> => {
72
107
  const { config, configFile } = await loadConfig(cwd, { mode });
73
- if (configFile === undefined) return null;
108
+
74
109
  return { root: cwd, config, configFile };
75
110
  };
111
+
112
+ export { resolveReactSubexports, resolveCodegenStore, resolveCodegenContext, type CodegenStore, type CodegenContext };
@@ -6,7 +6,7 @@ import { entryArg, resolveEntry } from "../internal/entry-arg.js";
6
6
 
7
7
  const BUILD_MODE = "production";
8
8
 
9
- export const build = defineCommand({
9
+ const build = defineCommand({
10
10
  meta: {
11
11
  name: "build",
12
12
  description: "Build application for production",
@@ -21,7 +21,6 @@ export const build = defineCommand({
21
21
  async run({ args }) {
22
22
  const { cwd, entry } = resolveEntry(args);
23
23
  info(`Building ${entry}`);
24
-
25
24
  await ensureGenerated(cwd, { announce: true, mode: BUILD_MODE });
26
25
 
27
26
  await buildApp({
@@ -35,3 +34,5 @@ export const build = defineCommand({
35
34
  info("Build complete: dist/bundle.js");
36
35
  },
37
36
  });
37
+
38
+ export { build };
@@ -4,7 +4,7 @@ import { formatCodegenResult } from "../codegen/report.js";
4
4
  import { ensureGenerated, isCodegenDisabled, runCodegen, syncSchemaEnv } from "../codegen/run-codegen.js";
5
5
  import { cwdArg, resolveCwd } from "../internal/entry-arg.js";
6
6
 
7
- export const codegen = defineCommand({
7
+ const codegen = defineCommand({
8
8
  meta: {
9
9
  name: "codegen",
10
10
  description: "Generate TypeScript bindings for the GIR libraries declared in gtkx.config.ts",
@@ -24,21 +24,26 @@ export const codegen = defineCommand({
24
24
  await runCodegen({ cwd });
25
25
  syncSchemaEnv(cwd);
26
26
  info("codegen: disabled for this project; reusing an installed binding store");
27
+
27
28
  return;
28
29
  }
29
30
 
30
31
  if (!args.force) {
31
- const ran = await ensureGenerated(cwd);
32
- info(ran ? "codegen: regenerated stale bindings" : "codegen: bindings up to date");
32
+ const isRan = await ensureGenerated(cwd);
33
+ info(isRan ? "codegen: regenerated stale bindings" : "codegen: bindings up to date");
34
+
33
35
  return;
34
36
  }
35
37
 
36
38
  const startedAt = Date.now();
37
39
  const result = await runCodegen({ cwd, force: true });
38
40
  syncSchemaEnv(cwd);
41
+ const lines = formatCodegenResult(result, Date.now() - startedAt);
39
42
 
40
- for (const line of formatCodegenResult(result, Date.now() - startedAt)) {
43
+ for (const line of lines) {
41
44
  info(line);
42
45
  }
43
46
  },
44
47
  });
48
+
49
+ export { codegen };
@@ -5,7 +5,7 @@ import { entryArg, resolveEntry } from "../internal/entry-arg.js";
5
5
 
6
6
  const DEV_MODE = "development";
7
7
 
8
- export const dev = defineCommand({
8
+ const dev = defineCommand({
9
9
  meta: {
10
10
  name: "dev",
11
11
  description: "Start development server with HMR",
@@ -15,11 +15,10 @@ export const dev = defineCommand({
15
15
  },
16
16
  async run({ args }) {
17
17
  const { cwd, entry: entryPath } = resolveEntry(args);
18
-
19
18
  await ensureGenerated(cwd, { announce: true, mode: DEV_MODE });
20
-
21
19
  const watch: DevWatch | undefined = await resolveConfigWatch(cwd, DEV_MODE);
22
-
23
20
  await runDevSupervisor(entryPath, cwd, watch);
24
21
  },
25
22
  });
23
+
24
+ export { dev };