@gtkx/codegen 1.0.0-rc.3 → 1.0.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/README.md +4 -5
  2. package/dist/analysis/descriptor-render.d.ts +1 -3
  3. package/dist/analysis/descriptor-render.d.ts.map +1 -1
  4. package/dist/analysis/descriptor-render.js +14 -37
  5. package/dist/analysis/descriptor-render.js.map +1 -1
  6. package/dist/analysis/descriptor.d.ts +6 -6
  7. package/dist/analysis/descriptor.d.ts.map +1 -1
  8. package/dist/analysis/descriptor.js +7 -7
  9. package/dist/analysis/descriptor.js.map +1 -1
  10. package/dist/analysis/param-structure.d.ts +2 -2
  11. package/dist/analysis/param-structure.d.ts.map +1 -1
  12. package/dist/analysis/param-structure.js +5 -7
  13. package/dist/analysis/param-structure.js.map +1 -1
  14. package/dist/analysis/ts-type.d.ts +1 -1
  15. package/dist/analysis/ts-type.d.ts.map +1 -1
  16. package/dist/analysis/ts-type.js +3 -5
  17. package/dist/analysis/ts-type.js.map +1 -1
  18. package/dist/compile.d.ts.map +1 -1
  19. package/dist/compile.js +2 -1
  20. package/dist/compile.js.map +1 -1
  21. package/dist/docs/api-reference.d.ts +77 -1
  22. package/dist/docs/api-reference.d.ts.map +1 -1
  23. package/dist/docs/api-reference.js +62 -0
  24. package/dist/docs/api-reference.js.map +1 -1
  25. package/dist/docs/pipeline.d.ts +4 -4
  26. package/dist/docs/pipeline.d.ts.map +1 -1
  27. package/dist/docs/pipeline.js +4 -4
  28. package/dist/docs/pipeline.js.map +1 -1
  29. package/dist/docs/render.js +6 -6
  30. package/dist/docs/render.js.map +1 -1
  31. package/dist/docs/symbol-page.d.ts +5 -0
  32. package/dist/docs/symbol-page.d.ts.map +1 -1
  33. package/dist/docs/symbol-page.js +2 -2
  34. package/dist/docs/symbol-page.js.map +1 -1
  35. package/dist/fingerprint.d.ts +2 -5
  36. package/dist/fingerprint.d.ts.map +1 -1
  37. package/dist/fingerprint.js +6 -8
  38. package/dist/fingerprint.js.map +1 -1
  39. package/dist/gi.d.ts +3 -11
  40. package/dist/gi.d.ts.map +1 -1
  41. package/dist/gi.js +0 -7
  42. package/dist/gi.js.map +1 -1
  43. package/dist/gir/field.d.ts +0 -1
  44. package/dist/gir/field.d.ts.map +1 -1
  45. package/dist/gir/field.js +0 -3
  46. package/dist/gir/field.js.map +1 -1
  47. package/dist/gir/gir-path.d.ts +7 -0
  48. package/dist/gir/gir-path.d.ts.map +1 -1
  49. package/dist/gir/gir-path.js +7 -0
  50. package/dist/gir/gir-path.js.map +1 -1
  51. package/dist/gir/libraries.d.ts +13 -0
  52. package/dist/gir/libraries.d.ts.map +1 -1
  53. package/dist/gir/libraries.js +12 -0
  54. package/dist/gir/libraries.js.map +1 -1
  55. package/dist/gir/parameter.d.ts.map +1 -1
  56. package/dist/gir/parameter.js +0 -4
  57. package/dist/gir/parameter.js.map +1 -1
  58. package/dist/gir/size.d.ts.map +1 -1
  59. package/dist/gir/size.js +0 -3
  60. package/dist/gir/size.js.map +1 -1
  61. package/dist/gir/type-id.d.ts +1 -1
  62. package/dist/gir/type-id.d.ts.map +1 -1
  63. package/dist/gir/type-id.js +1 -3
  64. package/dist/gir/type-id.js.map +1 -1
  65. package/dist/gir/type-ref.js +1 -1
  66. package/dist/gir/type-ref.js.map +1 -1
  67. package/dist/index.d.ts +18 -6
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +12 -3
  70. package/dist/index.js.map +1 -1
  71. package/dist/internal.d.ts +3 -0
  72. package/dist/internal.d.ts.map +1 -0
  73. package/dist/internal.js +3 -0
  74. package/dist/internal.js.map +1 -0
  75. package/dist/jsx.d.ts +7 -12
  76. package/dist/jsx.d.ts.map +1 -1
  77. package/dist/jsx.js +18 -19
  78. package/dist/jsx.js.map +1 -1
  79. package/dist/khronos/args.d.ts.map +1 -1
  80. package/dist/khronos/args.js +1 -1
  81. package/dist/khronos/args.js.map +1 -1
  82. package/dist/khronos/pipeline.js +1 -1
  83. package/dist/khronos/pipeline.js.map +1 -1
  84. package/dist/khronos/plan.d.ts +2 -2
  85. package/dist/khronos/plan.d.ts.map +1 -1
  86. package/dist/khronos/plan.js +6 -6
  87. package/dist/khronos/plan.js.map +1 -1
  88. package/dist/react/element-config.d.ts +17 -11
  89. package/dist/react/element-config.d.ts.map +1 -1
  90. package/dist/react/element-config.js +22 -15
  91. package/dist/react/element-config.js.map +1 -1
  92. package/dist/runner.d.ts +35 -17
  93. package/dist/runner.d.ts.map +1 -1
  94. package/dist/runner.js +19 -20
  95. package/dist/runner.js.map +1 -1
  96. package/dist/store/compile-store.d.ts +1 -2
  97. package/dist/store/compile-store.d.ts.map +1 -1
  98. package/dist/store/compile-store.js +2 -2
  99. package/dist/store/compile-store.js.map +1 -1
  100. package/dist/store/gi/callables.js +4 -4
  101. package/dist/store/gi/callables.js.map +1 -1
  102. package/dist/store/gi/constant.d.ts.map +1 -1
  103. package/dist/store/gi/constant.js +0 -2
  104. package/dist/store/gi/constant.js.map +1 -1
  105. package/dist/store/gi/function.d.ts.map +1 -1
  106. package/dist/store/gi/function.js +1 -5
  107. package/dist/store/gi/function.js.map +1 -1
  108. package/dist/store/gi/method.d.ts.map +1 -1
  109. package/dist/store/gi/method.js +25 -23
  110. package/dist/store/gi/method.js.map +1 -1
  111. package/dist/store/gi/property-accessor.d.ts +1 -1
  112. package/dist/store/gi/property-accessor.d.ts.map +1 -1
  113. package/dist/store/gi/property-accessor.js +5 -7
  114. package/dist/store/gi/property-accessor.js.map +1 -1
  115. package/dist/store/gi/record-field-accessor.d.ts +1 -1
  116. package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
  117. package/dist/store/gi/record-field-accessor.js +3 -9
  118. package/dist/store/gi/record-field-accessor.js.map +1 -1
  119. package/dist/store/gi/record-layout.d.ts.map +1 -1
  120. package/dist/store/gi/record-layout.js +0 -4
  121. package/dist/store/gi/record-layout.js.map +1 -1
  122. package/dist/store/gi/return-wrap.d.ts +1 -1
  123. package/dist/store/gi/return-wrap.d.ts.map +1 -1
  124. package/dist/store/gi/return-wrap.js +4 -4
  125. package/dist/store/gi/return-wrap.js.map +1 -1
  126. package/dist/store/gi/signal.d.ts.map +1 -1
  127. package/dist/store/gi/signal.js +13 -16
  128. package/dist/store/gi/signal.js.map +1 -1
  129. package/dist/store/gi/value-marshalable.d.ts +0 -8
  130. package/dist/store/gi/value-marshalable.d.ts.map +1 -1
  131. package/dist/store/gi/value-marshalable.js +0 -9
  132. package/dist/store/gi/value-marshalable.js.map +1 -1
  133. package/dist/store/gi-store.d.ts +2 -3
  134. package/dist/store/gi-store.d.ts.map +1 -1
  135. package/dist/store/gi-store.js.map +1 -1
  136. package/dist/store/jsx/element-components.d.ts +0 -2
  137. package/dist/store/jsx/element-components.d.ts.map +1 -1
  138. package/dist/store/jsx/element-components.js +0 -4
  139. package/dist/store/jsx/element-components.js.map +1 -1
  140. package/dist/store/jsx/element-prop-imports.d.ts +2 -3
  141. package/dist/store/jsx/element-prop-imports.d.ts.map +1 -1
  142. package/dist/store/jsx/element-prop-imports.js +0 -2
  143. package/dist/store/jsx/element-prop-imports.js.map +1 -1
  144. package/dist/store/jsx/element-prop-types.d.ts +0 -1
  145. package/dist/store/jsx/element-prop-types.d.ts.map +1 -1
  146. package/dist/store/jsx/element-prop-types.js +0 -1
  147. package/dist/store/jsx/element-prop-types.js.map +1 -1
  148. package/dist/store/jsx/generated-elements.d.ts +29 -0
  149. package/dist/store/jsx/generated-elements.d.ts.map +1 -0
  150. package/dist/store/jsx/generated-elements.js +30 -0
  151. package/dist/store/jsx/generated-elements.js.map +1 -0
  152. package/dist/store/jsx/jsx.js +6 -6
  153. package/dist/store/jsx/jsx.js.map +1 -1
  154. package/dist/store/jsx/metadata.js +7 -7
  155. package/dist/store/jsx/metadata.js.map +1 -1
  156. package/dist/store/jsx/omitted-props.d.ts +2 -4
  157. package/dist/store/jsx/omitted-props.d.ts.map +1 -1
  158. package/dist/store/jsx/omitted-props.js +2 -4
  159. package/dist/store/jsx/omitted-props.js.map +1 -1
  160. package/dist/store/jsx/pipeline.d.ts +3 -1
  161. package/dist/store/jsx/pipeline.d.ts.map +1 -1
  162. package/dist/store/jsx/pipeline.js +3 -2
  163. package/dist/store/jsx/pipeline.js.map +1 -1
  164. package/dist/store/jsx/props.js +2 -2
  165. package/dist/store/jsx/props.js.map +1 -1
  166. package/dist/store/jsx-store.d.ts +2 -3
  167. package/dist/store/jsx-store.d.ts.map +1 -1
  168. package/dist/store/jsx-store.js +3 -3
  169. package/dist/store/jsx-store.js.map +1 -1
  170. package/dist/store/resolve-store.d.ts +28 -0
  171. package/dist/store/resolve-store.d.ts.map +1 -0
  172. package/dist/store/resolve-store.js +65 -0
  173. package/dist/store/resolve-store.js.map +1 -0
  174. package/dist/store/store-fs.d.ts +5 -1
  175. package/dist/store/store-fs.d.ts.map +1 -1
  176. package/dist/store/store-fs.js +6 -4
  177. package/dist/store/store-fs.js.map +1 -1
  178. package/overrides/gobject/object.ts.ejs +8 -8
  179. package/package.json +6 -10
  180. package/src/analysis/descriptor-render.ts +20 -45
  181. package/src/analysis/descriptor.ts +13 -13
  182. package/src/analysis/param-structure.ts +8 -10
  183. package/src/analysis/ts-type.ts +4 -6
  184. package/src/compile.ts +2 -1
  185. package/src/docs/api-reference.ts +127 -4
  186. package/src/docs/pipeline.ts +8 -8
  187. package/src/docs/render.ts +7 -7
  188. package/src/docs/symbol-page.ts +7 -2
  189. package/src/fingerprint.ts +8 -13
  190. package/src/gi.ts +4 -11
  191. package/src/gir/field.ts +0 -4
  192. package/src/gir/gir-path.ts +7 -0
  193. package/src/gir/libraries.ts +13 -0
  194. package/src/gir/parameter.ts +0 -4
  195. package/src/gir/size.ts +0 -3
  196. package/src/gir/type-id.ts +2 -4
  197. package/src/gir/type-ref.ts +1 -1
  198. package/src/index.ts +18 -16
  199. package/src/internal.ts +2 -0
  200. package/src/jsx.ts +26 -26
  201. package/src/khronos/args.ts +1 -1
  202. package/src/khronos/pipeline.ts +1 -1
  203. package/src/khronos/plan.ts +8 -8
  204. package/src/react/element-config.ts +22 -19
  205. package/src/runner.ts +57 -39
  206. package/src/store/compile-store.ts +3 -4
  207. package/src/store/gi/callables.ts +5 -5
  208. package/src/store/gi/constant.ts +0 -2
  209. package/src/store/gi/function.ts +1 -5
  210. package/src/store/gi/method.ts +30 -28
  211. package/src/store/gi/property-accessor.ts +6 -8
  212. package/src/store/gi/record-field-accessor.ts +4 -10
  213. package/src/store/gi/record-layout.ts +0 -4
  214. package/src/store/gi/return-wrap.ts +5 -5
  215. package/src/store/gi/signal.ts +17 -17
  216. package/src/store/gi/value-marshalable.ts +0 -9
  217. package/src/store/gi-store.ts +2 -4
  218. package/src/store/jsx/element-components.ts +0 -6
  219. package/src/store/jsx/element-prop-imports.ts +7 -4
  220. package/src/store/jsx/element-prop-types.ts +0 -1
  221. package/src/store/jsx/generated-elements.ts +60 -0
  222. package/src/store/jsx/jsx.ts +7 -7
  223. package/src/store/jsx/metadata.ts +8 -8
  224. package/src/store/jsx/omitted-props.ts +2 -4
  225. package/src/store/jsx/pipeline.ts +5 -3
  226. package/src/store/jsx/props.ts +2 -2
  227. package/src/store/jsx-store.ts +5 -7
  228. package/src/store/resolve-store.ts +100 -0
  229. package/src/store/store-fs.ts +12 -5
@@ -1,16 +1,19 @@
1
- import type { ModuleExport } from "@gtkx/react/config";
1
+ import type { ModuleExport } from "@gtkx/react/internal";
2
2
  import { readdirSync } from "node:fs";
3
3
  import type { OmittedProps } from "../store/jsx/omitted-props.js";
4
4
 
5
- /** The codegen-relevant subset of a React element config; behaviors are ignored at codegen time. */
6
- type BuiltinElement = { component?: ModuleExport; lazy?: boolean; props?: ModuleExport; omitProps?: string[] };
5
+ type BuiltinElement = { component?: ModuleExport; isLazy?: boolean; props?: ModuleExport; omittedProps?: string[] };
7
6
 
8
7
  /** The framework's built-in element config, split into the maps codegen consumes. */
9
8
  type BuiltinElements = {
9
+ /** Component wrappers keyed by GLib type name; an element without one inherits its nearest ancestor's. */
10
10
  components: Record<string, ModuleExport>;
11
+ /** GLib type names with no GObject of their own, exported as elements that drop their construct-only props. */
11
12
  lazyElements: string[];
13
+ /** Base props interfaces the generated element props extend, keyed by GLib type name. */
12
14
  props: Record<string, ModuleExport>;
13
- omitProps: OmittedProps;
15
+ /** Props left out of the generated element props, keyed by GLib type name. */
16
+ omittedProps: OmittedProps;
14
17
  };
15
18
 
16
19
  const CONFIG_ENTRYPOINT = "config";
@@ -29,10 +32,6 @@ const presentNamespaceDirs = (giStoreDir: string): Set<string> => {
29
32
  return dirs;
30
33
  };
31
34
 
32
- /**
33
- * The clean, reconciler-free `@gtkx/react` config entrypoints to import: the base `config` entry plus
34
- * each namespace's `<ns>/config` entry whose GIR namespace is present in the gi store.
35
- */
36
35
  const configEntrypoints = (reactSubexports: string[], present: Set<string>): string[] =>
37
36
  reactSubexports.filter((sub) => {
38
37
  if (sub === CONFIG_ENTRYPOINT) {
@@ -61,30 +60,34 @@ const applyBuiltinElement = (target: BuiltinElements, type: string, config: Buil
61
60
  target.props[type] = config.props;
62
61
  }
63
62
 
64
- if (config.omitProps !== undefined) {
65
- target.omitProps[type] = [...(target.omitProps[type] ?? []), ...config.omitProps];
63
+ if (config.omittedProps !== undefined) {
64
+ target.omittedProps[type] = [...(target.omittedProps[type] ?? []), ...config.omittedProps];
66
65
  }
67
66
 
68
- if (config.lazy === true) {
67
+ if (config.isLazy === true) {
69
68
  target.lazyElements.push(type);
70
69
  }
71
70
  };
72
71
 
73
- /**
74
- * Reads the framework's built-in element config by importing the freshly linked `@gtkx/react` config
75
- * entrypoints. These are reconciler-free, so importing them resolves `@gtkx/gi` but never `virtual:gtkx-config`;
76
- * it must run only after the gi store has been linked.
77
- */
78
72
  const collectBuiltinElements = (target: BuiltinElements, elements: Record<string, BuiltinElement>): void => {
79
73
  for (const [type, config] of Object.entries(elements)) {
80
74
  applyBuiltinElement(target, type, config);
81
75
  }
82
76
  };
83
77
 
78
+ /**
79
+ * Reads the framework's built-in element config by importing the `config` entrypoints of the installed
80
+ * `@gtkx/react`, skipping the per-namespace ones whose namespace the gi store does not carry. Those
81
+ * entrypoints are reconciler-free, so importing them resolves `@gtkx/gi` but never `virtual:gtkx-config`,
82
+ * which means this must run only after the gi store has been written and linked.
83
+ *
84
+ * @param reactSubexports Subexport names of the installed `@gtkx/react`, as `resolveStore` reports them.
85
+ * @param giStoreDir The gi store directory, whose subdirectories name the generated namespaces.
86
+ */
84
87
  const readBuiltinElements = async (reactSubexports: string[], giStoreDir: string): Promise<BuiltinElements> => {
85
88
  const present = presentNamespaceDirs(giStoreDir);
86
89
  const entrypoints = configEntrypoints(reactSubexports, present);
87
- const result: BuiltinElements = { components: {}, lazyElements: [], props: {}, omitProps: {} };
90
+ const result: BuiltinElements = { components: {}, lazyElements: [], props: {}, omittedProps: {} };
88
91
 
89
92
  for (const entrypoint of entrypoints) {
90
93
  collectBuiltinElements(result, await importBuiltinElements(entrypoint));
@@ -93,5 +96,5 @@ const readBuiltinElements = async (reactSubexports: string[], giStoreDir: string
93
96
  return result;
94
97
  };
95
98
 
96
- export { type ModuleExport } from "@gtkx/react/config";
97
- export { readBuiltinElements, type BuiltinElement, type BuiltinElements };
99
+ export type { ModuleExport } from "@gtkx/react/internal";
100
+ export { readBuiltinElements, type BuiltinElements };
package/src/runner.ts CHANGED
@@ -1,15 +1,20 @@
1
1
  import { mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import type { GiStoreOptions } from "./store/gi-store.js";
4
- import type { JsxStoreOptions } from "./store/jsx-store.js";
5
3
  import type { OmittedProps } from "./store/jsx/omitted-props.js";
4
+ import type { StoreOptions } from "./store/store-fs.js";
6
5
  import { checkModules } from "./compile.js";
7
6
  import { isGiStoreFresh } from "./fingerprint.js";
8
7
  import { runGiCodegen } from "./gi.js";
9
8
  import { Library } from "./gir/library.js";
10
9
  import { generateGlModules, type GlGenerationReport } from "./khronos/pipeline.js";
11
10
 
12
- type ModuleExport = { module: string; export: string };
11
+ /** A named export in a module, referenced as plain data (the module is never imported at runtime). */
12
+ type ModuleExport = {
13
+ /** Specifier the export is imported from. */
14
+ module: string;
15
+ /** Identifier the module exports it under. */
16
+ export: string;
17
+ };
13
18
 
14
19
  type GlCodegenOptions = {
15
20
  registryPath: string;
@@ -18,58 +23,71 @@ type GlCodegenOptions = {
18
23
  resolveFrom: string;
19
24
  };
20
25
 
26
+ /** What to generate and where to write it. */
21
27
  type CodegenRunnerOptions = {
22
- libraries?: string[];
23
- girPath?: string[];
24
- gi?: GiStoreOptions;
25
- jsx?: JsxStoreOptions | undefined;
28
+ /** GIR library identifiers such as `"Gtk-4.0"`; a `"*"` selection must be expanded before it gets here. */
29
+ libraries: string[];
30
+ /** Directories to search for `.gir` files. */
31
+ girPath: string[];
32
+ /** Where to write and link the `@gtkx/gi` store. */
33
+ gi: StoreOptions;
34
+ /** Where to write and link the `@gtkx/jsx` store; omit to generate the gi store alone. */
35
+ jsx?: StoreOptions | undefined;
36
+ /** Subexport names of the installed `@gtkx/react`, whose element config shapes the jsx store. */
26
37
  reactSubexports?: string[];
38
+ /** Component wrappers the project layers over the built-ins, keyed by GLib type name. */
27
39
  userComponents?: Record<string, ModuleExport>;
40
+ /** GLib type names whose GObject their parent container creates, added to the framework's own. */
28
41
  userLazyElements?: string[];
42
+ /** Base props interfaces the project's elements extend, keyed by GLib type name. */
29
43
  userProps?: Record<string, ModuleExport>;
30
- userOmitProps?: OmittedProps;
31
- gl?: GlCodegenOptions;
32
- force?: boolean;
44
+ /** Props the project drops from the generated element props, keyed by GLib type name. */
45
+ userOmittedProps?: OmittedProps;
46
+ /** Regenerates both stores even when their fingerprints are fresh. */
47
+ isForced?: boolean;
33
48
  };
34
49
 
50
+ /** What a `runCodegen` run produced. */
35
51
  type CodegenRunnerResult = {
36
- regenerated: boolean;
52
+ /** Whether either store was rewritten; false means both were already fresh. */
53
+ isRegenerated: boolean;
54
+ /** How many namespaces the gi store was written with, zero when it was already fresh. */
37
55
  namespaces: number;
56
+ /** How many JSX elements the jsx store binds, zero when no jsx store was requested. */
38
57
  intrinsicElements: number;
58
+ /** Wall-clock duration of the run, in milliseconds. */
39
59
  duration: number;
40
- gl?: GlGenerationReport | undefined;
41
60
  };
42
61
 
43
62
  type StoreResult = {
44
- regenerated: boolean;
63
+ isRegenerated: boolean;
45
64
  namespaces: number;
46
65
  intrinsicElements: number;
47
66
  };
48
67
 
49
68
  /**
50
- * Runs the `@gtkx` code generators, producing the `@gtkx/gi`, `@gtkx/jsx`, and `@gtkx/gl` bindings from the
51
- * configured GObject-introspection libraries and OpenGL registry. The gi store is regenerated only when its
52
- * fingerprint is stale unless `options.force` is set, then the jsx store is regenerated when the gi store or
53
- * the React element config changed; the OpenGL modules are regenerated whenever `options.gl` is provided.
69
+ * Writes and links a project's `@gtkx/gi` and `@gtkx/jsx` stores from the given GObject-Introspection
70
+ * libraries. The gi store is rewritten only when its GIR inputs changed, and the jsx store only when the gi
71
+ * store or the React element config changed, unless `options.isForced` is set. Pass the spread of
72
+ * `resolveStore(projectRoot)` for everything but `libraries` and `girPath`.
54
73
  *
55
- * @param options - What to generate and where to write it.
74
+ * @param options What to generate and where to write it.
56
75
  * @returns A summary of what was regenerated and how long the run took.
76
+ * @throws If `girPath` is empty, which would otherwise generate nothing and report success.
57
77
  */
58
78
  const runCodegen = async (options: CodegenRunnerOptions): Promise<CodegenRunnerResult> => {
59
79
  const start = Date.now();
60
- const gl = options.gl === undefined ? undefined : emitGlModules(options.gl);
61
80
  const store = await emitStores(options);
62
81
 
63
82
  return {
64
- regenerated: store.regenerated,
83
+ isRegenerated: store.isRegenerated,
65
84
  namespaces: store.namespaces,
66
85
  intrinsicElements: store.intrinsicElements,
67
86
  duration: Date.now() - start,
68
- gl,
69
87
  };
70
88
  };
71
89
 
72
- const emitGlModules = (options: GlCodegenOptions): GlGenerationReport => {
90
+ const runGlCodegen = (options: GlCodegenOptions): GlGenerationReport => {
73
91
  const { files, report } = generateGlModules({
74
92
  registryPath: options.registryPath,
75
93
  overrideExports: options.overrideExports,
@@ -97,24 +115,24 @@ const jsxUserOptions = (
97
115
  userComponents: Record<string, ModuleExport>;
98
116
  userLazyElements: string[];
99
117
  userProps: Record<string, ModuleExport>;
100
- userOmitProps: OmittedProps;
118
+ userOmittedProps: OmittedProps;
101
119
  } => ({
102
120
  reactSubexports: options.reactSubexports ?? [],
103
121
  userComponents: options.userComponents ?? {},
104
122
  userLazyElements: options.userLazyElements ?? [],
105
123
  userProps: options.userProps ?? {},
106
- userOmitProps: options.userOmitProps ?? {},
124
+ userOmittedProps: options.userOmittedProps ?? {},
107
125
  });
108
126
 
109
127
  const emitJsxStore = async (input: {
110
128
  options: CodegenRunnerOptions;
111
- jsx: JsxStoreOptions;
112
- gi: GiStoreOptions;
129
+ jsx: StoreOptions;
130
+ gi: StoreOptions;
113
131
  loadLibrary: () => Library;
114
- giRegenerated: boolean;
132
+ isGiRegenerated: boolean;
115
133
  namespaces: number;
116
134
  }): Promise<StoreResult> => {
117
- const { options, jsx, gi, loadLibrary, giRegenerated, namespaces } = input;
135
+ const { options, jsx, gi, loadLibrary, isGiRegenerated, namespaces } = input;
118
136
  const { runJsxCodegen } = await import("./jsx.js");
119
137
 
120
138
  const jsxResult = await runJsxCodegen({
@@ -122,12 +140,12 @@ const emitJsxStore = async (input: {
122
140
  jsx,
123
141
  giStoreDir: gi.storeDir,
124
142
  ...jsxUserOptions(options),
125
- giRegenerated,
126
- force: options.force === true,
143
+ isGiRegenerated,
144
+ isForced: options.isForced === true,
127
145
  });
128
146
 
129
147
  return {
130
- regenerated: giRegenerated || jsxResult.regenerated,
148
+ isRegenerated: isGiRegenerated || jsxResult.isRegenerated,
131
149
  namespaces,
132
150
  intrinsicElements: jsxResult.intrinsicElementCount,
133
151
  };
@@ -135,35 +153,35 @@ const emitJsxStore = async (input: {
135
153
 
136
154
  const emitStoresWithConfig = async (config: {
137
155
  options: CodegenRunnerOptions;
138
- gi: GiStoreOptions;
139
- jsx: JsxStoreOptions | undefined;
156
+ gi: StoreOptions;
157
+ jsx: StoreOptions | undefined;
140
158
  libraries: string[];
141
159
  girPath: string[];
142
160
  }): Promise<StoreResult> => {
143
161
  const { options, gi, jsx, libraries, girPath } = config;
144
162
  let library: Library | undefined;
145
163
  const loadLibrary = (): Library => (library ??= Library.load(libraries, girPath));
146
- const isGiRegenerated = options.force === true || !isGiStoreFresh(gi.storeDir, libraries, girPath);
164
+ const isGiRegenerated = options.isForced === true || !isGiStoreFresh(gi.storeDir, libraries, girPath);
147
165
 
148
166
  const namespaces = isGiRegenerated
149
167
  ? runGiCodegen(loadLibrary(), { gi, libraries, girPath })
150
168
  : 0;
151
169
 
152
170
  if (jsx === undefined) {
153
- return { regenerated: isGiRegenerated, namespaces, intrinsicElements: 0 };
171
+ return { isRegenerated: isGiRegenerated, namespaces, intrinsicElements: 0 };
154
172
  }
155
173
 
156
- return emitJsxStore({ options, jsx, gi, loadLibrary, giRegenerated: isGiRegenerated, namespaces });
174
+ return emitJsxStore({ options, jsx, gi, loadLibrary, isGiRegenerated, namespaces });
157
175
  };
158
176
 
159
177
  const emitStores = async (options: CodegenRunnerOptions): Promise<StoreResult> => {
160
178
  const { gi, jsx, libraries, girPath } = options;
161
179
 
162
- if (gi === undefined || libraries === undefined || girPath === undefined) {
163
- return { regenerated: false, namespaces: 0, intrinsicElements: 0 };
180
+ if (girPath.length === 0) {
181
+ throw new Error("codegen needs at least one GIR search path; pass the result of resolveGirPath");
164
182
  }
165
183
 
166
184
  return emitStoresWithConfig({ options, gi, jsx, libraries, girPath });
167
185
  };
168
186
 
169
- export { runCodegen, type GlCodegenOptions, type CodegenRunnerOptions, type CodegenRunnerResult };
187
+ export { runCodegen, runGlCodegen, type CodegenRunnerOptions, type CodegenRunnerResult };
@@ -6,8 +6,7 @@ type CompileStoreParams = {
6
6
  storeDir: string;
7
7
  files: SourceModule[];
8
8
  packageName: string;
9
- /** Declare `virtual:gtkx-config` for the typecheck, needed when it follows imports into `@gtkx/react` source. */
10
- configEnv?: boolean;
9
+ requiresEnvReference?: boolean;
11
10
  };
12
11
 
13
12
  const EMIT_OPTIONS = {
@@ -32,14 +31,14 @@ const writeEnvReference = (storeDir: string): (() => void) => {
32
31
  const compileStore = (params: CompileStoreParams): void => {
33
32
  const fileNames = params.files.map((file) => file.fileName);
34
33
 
35
- const removeEnvReference = params.configEnv === true
34
+ const removeEnvReference = params.requiresEnvReference === true
36
35
  ? writeEnvReference(params.storeDir)
37
36
  : (): void => undefined;
38
37
 
39
38
  try {
40
39
  compileProject({
41
40
  projectDir: params.storeDir,
42
- fileNames: params.configEnv === true ? [ENV_REFERENCE_FILE, ...fileNames] : fileNames,
41
+ fileNames: params.requiresEnvReference === true ? [ENV_REFERENCE_FILE, ...fileNames] : fileNames,
43
42
  compilerOptions: EMIT_OPTIONS,
44
43
  label: `the generated ${params.packageName} store`,
45
44
  });
@@ -34,7 +34,7 @@ type CallableMemberOptions = {
34
34
  resolveName: (callable: GirFunction) => string | undefined;
35
35
  isStatic: boolean;
36
36
  returnTypeOverride?: string | undefined;
37
- allowRuntimeOverride?: boolean;
37
+ canUseRuntimeOverride?: boolean;
38
38
  };
39
39
 
40
40
  type StaticEntryOptions = {
@@ -159,9 +159,9 @@ const runtimeOverrideMember = (
159
159
  callable: GirFunction,
160
160
  name: string,
161
161
  doc: string,
162
- allow: boolean | undefined,
162
+ canUseRuntimeOverride: boolean | undefined,
163
163
  ): string | undefined => {
164
- if (allow !== true) {
164
+ if (canUseRuntimeOverride !== true) {
165
165
  return undefined;
166
166
  }
167
167
 
@@ -183,7 +183,7 @@ const renderCallableMember = (
183
183
 
184
184
  const { cIdentifier, name } = resolved;
185
185
  const doc = renderJsDoc(callable.doc);
186
- const override = runtimeOverrideMember(callable, name, doc, options.allowRuntimeOverride);
186
+ const override = runtimeOverrideMember(callable, name, doc, options.canUseRuntimeOverride);
187
187
 
188
188
  if (override !== undefined) {
189
189
  return override;
@@ -240,7 +240,7 @@ const renderInstanceMethod = (
240
240
  renderCallableMember(context, callable, {
241
241
  resolveName: (member) => nameOverride ?? methodExportName(member),
242
242
  isStatic: false,
243
- allowRuntimeOverride: true,
243
+ canUseRuntimeOverride: true,
244
244
  });
245
245
 
246
246
  const resolveInstanceMember = (
@@ -6,8 +6,6 @@ import type { ModuleContext } from "../../writer/context.js";
6
6
  import { renderJsDoc } from "../../writer/doc.js";
7
7
 
8
8
  const TRUE_VALUES: Set<string> = new Set(["true", "1"]);
9
- // A `gint64`/`guint64` constant is typed `bigint`, and its decimal text does not survive a double:
10
- // G_MAXINT64 rounds to 2^63. The literal has to carry the BigInt suffix the type promises.
11
9
  const BIGINT_CATEGORIES: Set<PrimitiveCategory> = new Set(["bigint64", "biguint64", "gtype"]);
12
10
 
13
11
  const generateConstant = (context: ModuleContext, constant: GirConstant): void => {
@@ -32,13 +32,9 @@ const renderFnExpression = (context: ModuleContext, fn: GirFunction): string | u
32
32
  const params = planCallArgs(context, fn).map((arg) => arg.paramLiteral);
33
33
  const ret = renderReturnDescriptor(context, fn);
34
34
 
35
- return tFn(library, fn.cIdentifier, { args: arrayLiteral(params), returns: ret, throws: fn.throws });
35
+ return tFn(library, fn.cIdentifier, { args: arrayLiteral(params), returns: ret, canThrow: fn.throws });
36
36
  };
37
37
 
38
- // `moved-to` names the type member this function is also reachable as, so the namespace-level copy
39
- // is a second export of one binding. Suppressing it is only right when that member is really
40
- // emitted: 15 of Gtk-4.0's 28 `moved-to` targets are enum or error-domain members codegen emits no
41
- // static for, and dropping those would delete API with nothing to replace it.
42
38
  const isMovedOntoEmittedMember = (context: ModuleContext, fn: GirFunction): boolean => {
43
39
  const [typeName, memberName] = fn.movedTo?.split(".") ?? [];
44
40
 
@@ -23,7 +23,7 @@ import { hasUnknownArrayLength, type TypeId } from "../../gir/type-id.js";
23
23
  import { itemComparatorArgDescriptors, itemComparatorTsType } from "./item-comparators.js";
24
24
  import { isCollectibleCallerOut, isHandlePassedInPlace, isHandlePassing } from "./param-marshal.js";
25
25
 
26
- type PromisifiedStep = { sawOptional: boolean; expression: string | undefined };
26
+ type PromisifiedStep = { hasSeenOptional: boolean; expression: string | undefined };
27
27
 
28
28
  type PromisifyContext = {
29
29
  context: ModuleContext;
@@ -44,8 +44,8 @@ type CallArgPlan = {
44
44
 
45
45
  type ParamDescriptorOptions = {
46
46
  direction?: "out" | "inout";
47
- callerAllocated?: boolean;
48
- consumed?: boolean;
47
+ isCallerAllocated?: boolean;
48
+ isConsumed?: boolean;
49
49
  };
50
50
 
51
51
  type ArgIndexOptions = {
@@ -94,7 +94,7 @@ const renderInputParameters = (
94
94
  isOptionalExtra: (parameter: GirParameter) => boolean,
95
95
  ): string => {
96
96
  const parts: string[] = [];
97
- let isSawOptional = false;
97
+ let hasSeenOptional = false;
98
98
 
99
99
  for (const { parameter, index } of inputParameters(context.library, fn)) {
100
100
  if (shouldSkip(parameter)) {
@@ -104,10 +104,10 @@ const renderInputParameters = (
104
104
  const name = parameterIdentifier(parameter, index);
105
105
 
106
106
  if (isParameterOptional(parameter, isOptionalExtra)) {
107
- isSawOptional = true;
107
+ hasSeenOptional = true;
108
108
  }
109
109
 
110
- parts.push(formatParameterPart(name, parameterAnnotation(context, fn, parameter), isSawOptional));
110
+ parts.push(formatParameterPart(name, parameterAnnotation(context, fn, parameter), hasSeenOptional));
111
111
  }
112
112
 
113
113
  return parts.join(", ");
@@ -139,36 +139,36 @@ const classifyPromisifiedParameter = (
139
139
  promisify: PromisifyContext,
140
140
  parameter: GirParameter,
141
141
  index: number,
142
- state: { cancellableIndex: number; sawOptional: boolean },
142
+ state: { cancellableIndex: number; hasSeenOptional: boolean },
143
143
  ): PromisifiedStep => {
144
144
  if (parameter.isVarargs) {
145
- return { sawOptional: state.sawOptional, expression: undefined };
145
+ return { hasSeenOptional: state.hasSeenOptional, expression: undefined };
146
146
  }
147
147
 
148
148
  if (index === state.cancellableIndex) {
149
- return { sawOptional: true, expression: undefined };
149
+ return { hasSeenOptional: true, expression: undefined };
150
150
  }
151
151
 
152
152
  if (shouldSkipPromisifiedParameter(promisify, parameter, index)) {
153
- return { sawOptional: state.sawOptional, expression: undefined };
153
+ return { hasSeenOptional: state.hasSeenOptional, expression: undefined };
154
154
  }
155
155
 
156
- const isSawOptional = state.sawOptional || parameter.optional;
156
+ const hasSeenOptional = state.hasSeenOptional || parameter.optional;
157
157
 
158
- return { sawOptional: isSawOptional, expression: promisifiedArgument(promisify, parameter, index, isSawOptional) };
158
+ return { hasSeenOptional, expression: promisifiedArgument(promisify, parameter, index, hasSeenOptional) };
159
159
  };
160
160
 
161
161
  const collectPromisifiedArguments = (promisify: PromisifyContext, cancellableIndex: number): string[] => {
162
162
  const expressions: string[] = [];
163
- let isSawOptional = false;
163
+ let hasSeenOptional = false;
164
164
 
165
165
  for (const [index, parameter] of promisify.asyncFn.parameters.entries()) {
166
166
  const step = classifyPromisifiedParameter(promisify, parameter, index, {
167
167
  cancellableIndex,
168
- sawOptional: isSawOptional,
168
+ hasSeenOptional,
169
169
  });
170
170
 
171
- isSawOptional = step.sawOptional;
171
+ hasSeenOptional = step.hasSeenOptional;
172
172
 
173
173
  if (step.expression !== undefined) {
174
174
  expressions.push(step.expression);
@@ -298,12 +298,12 @@ const paramDescriptorLiteral = (descriptor: string, options: ParamDescriptorOpti
298
298
  parts.push(`direction: ${sourceStringLiteral(options.direction)}`);
299
299
  }
300
300
 
301
- if (options.callerAllocated === true) {
302
- parts.push("callerAllocated: true");
301
+ if (options.isCallerAllocated === true) {
302
+ parts.push("isCallerAllocated: true");
303
303
  }
304
304
 
305
- if (options.consumed === true) {
306
- parts.push("consumed: true");
305
+ if (options.isConsumed === true) {
306
+ parts.push("isConsumed: true");
307
307
  }
308
308
 
309
309
  return `{ ${parts.join(", ")} }`;
@@ -407,7 +407,7 @@ const planInoutArgument = (
407
407
  return planInoutParam(context, parameter, {
408
408
  index,
409
409
  argIndex: planContext.argIndex,
410
- consumed: folded.has(index),
410
+ isConsumed: folded.has(index),
411
411
  lengthSource,
412
412
  });
413
413
  };
@@ -436,7 +436,7 @@ const planOutParam = (
436
436
  const descriptor = renderDescriptor(context, parameter.type, parameter.transferOwnership, argIndex);
437
437
 
438
438
  return {
439
- paramLiteral: paramDescriptorLiteral(descriptor, { direction: "out", consumed: isConsumed }),
439
+ paramLiteral: paramDescriptorLiteral(descriptor, { direction: "out", isConsumed }),
440
440
  inputExpr: undefined,
441
441
  };
442
442
  };
@@ -474,7 +474,7 @@ const planCallerOut = (
474
474
  const classExpression = context.qualify(name.namespaceName, name.typeName);
475
475
 
476
476
  return {
477
- paramLiteral: paramDescriptorLiteral(descriptor, { direction: "out", callerAllocated: true }),
477
+ paramLiteral: paramDescriptorLiteral(descriptor, { direction: "out", isCallerAllocated: true }),
478
478
  inputExpr: `new ${classExpression}()`,
479
479
  };
480
480
  }
@@ -488,17 +488,21 @@ const planInoutParam = (
488
488
  options: {
489
489
  index: number;
490
490
  argIndex: ArgIndexOptions;
491
- consumed: boolean;
491
+ isConsumed: boolean;
492
492
  lengthSource?: { source: GirParameter; index: number } | undefined;
493
493
  },
494
494
  ): CallArgPlan => {
495
- const { index, argIndex, consumed, lengthSource } = options;
495
+ const { index, argIndex, isConsumed, lengthSource } = options;
496
496
 
497
497
  if (isHandlePassedInPlace(context, parameter)) {
498
498
  const descriptor = renderDescriptor(context, parameter.type, "none", argIndex);
499
499
 
500
500
  return {
501
- paramLiteral: paramDescriptorLiteral(descriptor, { direction: "inout", callerAllocated: true, consumed }),
501
+ paramLiteral: paramDescriptorLiteral(descriptor, {
502
+ direction: "inout",
503
+ isCallerAllocated: true,
504
+ isConsumed,
505
+ }),
502
506
  inputExpr: parameterIdentifier(parameter, index),
503
507
  };
504
508
  }
@@ -506,7 +510,7 @@ const planInoutParam = (
506
510
  const descriptor = renderDescriptor(context, parameter.type, parameter.transferOwnership, argIndex);
507
511
 
508
512
  return {
509
- paramLiteral: paramDescriptorLiteral(descriptor, { direction: "inout", consumed }),
513
+ paramLiteral: paramDescriptorLiteral(descriptor, { direction: "inout", isConsumed }),
510
514
  inputExpr:
511
515
  lengthSource === undefined
512
516
  ? parameterCallExpression(context, parameter, index)
@@ -588,8 +592,6 @@ const collectionArgument = (
588
592
  return mapHandleExpression(name, isNullable);
589
593
  };
590
594
 
591
- // An array whose length nothing states is marshalled as the bare pointer it is, so there is nothing
592
- // to map over.
593
595
  const isMappableSequence = (context: ModuleContext, type: GirType | undefined): boolean => {
594
596
  if (type?.kind === "carray") {
595
597
  return !hasUnknownArrayLength(type) && isHandlePassing(context, type.element);
@@ -15,7 +15,7 @@ type ResolvedAccessor = {
15
15
  jsName: string;
16
16
  tsType: string;
17
17
  hasGetter: boolean;
18
- writable: boolean;
18
+ isWritable: boolean;
19
19
  getterMember: string | undefined;
20
20
  getterMethod: GirFunction | undefined;
21
21
  setterMember: string | undefined;
@@ -136,8 +136,6 @@ const resolveAccessor = (args: PropertyAccessorArgs): ResolvedAccessor | undefin
136
136
  return undefined;
137
137
  }
138
138
 
139
- // `g_object_set_property` rejects a construct-only pspec with a critical and drops the write, so
140
- // the property is settable at construction time only and must not advertise a setter.
141
139
  const isWritable = isConstructableProperty(property) && !property.constructOnly;
142
140
  const { member: getterMember, method: getterMethod } = resolveGetterDelegate(args, jsName);
143
141
  const { member: setterMember, method: setterMethod } = resolveSetterDelegate(args, jsName, isWritable);
@@ -150,7 +148,7 @@ const resolveAccessor = (args: PropertyAccessorArgs): ResolvedAccessor | undefin
150
148
  const ownType = resolveOwnType(context, property, getterMethod, setterMethod);
151
149
  const tsType = resolveTsType(args.inheritedType, ownType);
152
150
 
153
- return { jsName, tsType, hasGetter, writable: isWritable, getterMember, getterMethod, setterMember };
151
+ return { jsName, tsType, hasGetter, isWritable, getterMember, getterMethod, setterMember };
154
152
  };
155
153
 
156
154
  const resolveOwnerAccessor = (
@@ -197,7 +195,7 @@ const renderResolvedPropertyAccessor = (
197
195
  property: GirProperty,
198
196
  accessor: ResolvedAccessor,
199
197
  ): string => {
200
- const { jsName, tsType, hasGetter, writable, getterMember, getterMethod, setterMember } = accessor;
198
+ const { jsName, tsType, hasGetter, isWritable, getterMember, getterMethod, setterMember } = accessor;
201
199
  const blocks: string[] = [];
202
200
 
203
201
  if (hasGetter) {
@@ -205,7 +203,7 @@ const renderResolvedPropertyAccessor = (
205
203
  blocks.push(renderBlock(`get ${jsName}(): ${tsType}`, getterBody));
206
204
  }
207
205
 
208
- if (writable) {
206
+ if (isWritable) {
209
207
  const setterBody =
210
208
  setterMember === undefined ? renderGenericSetBody(context, property) : `this.${setterMember}(value);`;
211
209
 
@@ -219,10 +217,10 @@ const renderPropertyAccessor = (args: PropertyAccessorArgs): string | undefined
219
217
  withAccessor(args, (accessor) => renderResolvedPropertyAccessor(args.context, args.property, accessor));
220
218
 
221
219
  const renderPropertyAccessorSignature = (args: PropertyAccessorArgs): string | undefined =>
222
- withAccessor(args, ({ jsName, tsType, hasGetter, writable }) => {
220
+ withAccessor(args, ({ jsName, tsType, hasGetter, isWritable }) => {
223
221
  const doc = renderJsDoc(args.property.doc);
224
222
 
225
- if (hasGetter && writable) {
223
+ if (hasGetter && isWritable) {
226
224
  return `${doc}${jsName}: ${tsType};`;
227
225
  }
228
226