@gtkx/codegen 1.0.0-rc.2 → 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.
- package/README.md +4 -5
- package/dist/analysis/descriptor-render.d.ts +2 -2
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +30 -32
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +6 -6
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +7 -7
- package/dist/analysis/descriptor.js.map +1 -1
- package/dist/analysis/param-structure.d.ts +2 -2
- package/dist/analysis/param-structure.d.ts.map +1 -1
- package/dist/analysis/param-structure.js +5 -7
- package/dist/analysis/param-structure.js.map +1 -1
- package/dist/analysis/ts-type.d.ts +1 -1
- package/dist/analysis/ts-type.d.ts.map +1 -1
- package/dist/analysis/ts-type.js +7 -13
- package/dist/analysis/ts-type.js.map +1 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +2 -1
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts +77 -1
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +66 -8
- package/dist/docs/api-reference.js.map +1 -1
- package/dist/docs/element-page.d.ts.map +1 -1
- package/dist/docs/element-page.js +5 -4
- package/dist/docs/element-page.js.map +1 -1
- package/dist/docs/pipeline.d.ts +5 -3
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +5 -3
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/docs/render.js +6 -6
- package/dist/docs/render.js.map +1 -1
- package/dist/docs/symbol-page.d.ts +5 -0
- package/dist/docs/symbol-page.d.ts.map +1 -1
- package/dist/docs/symbol-page.js +2 -2
- package/dist/docs/symbol-page.js.map +1 -1
- package/dist/fingerprint.d.ts +2 -4
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +7 -6
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +7 -10
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +4 -9
- package/dist/gi.js.map +1 -1
- package/dist/gir/field.d.ts +0 -1
- package/dist/gir/field.d.ts.map +1 -1
- package/dist/gir/field.js +0 -3
- package/dist/gir/field.js.map +1 -1
- package/dist/gir/gir-path.d.ts +7 -0
- package/dist/gir/gir-path.d.ts.map +1 -1
- package/dist/gir/gir-path.js +7 -0
- package/dist/gir/gir-path.js.map +1 -1
- package/dist/gir/libraries.d.ts +17 -3
- package/dist/gir/libraries.d.ts.map +1 -1
- package/dist/gir/libraries.js +14 -1
- package/dist/gir/libraries.js.map +1 -1
- package/dist/gir/parameter.d.ts.map +1 -1
- package/dist/gir/parameter.js +0 -4
- package/dist/gir/parameter.js.map +1 -1
- package/dist/gir/size.d.ts.map +1 -1
- package/dist/gir/size.js +0 -3
- package/dist/gir/size.js.map +1 -1
- package/dist/gir/type-id.d.ts +1 -1
- package/dist/gir/type-id.d.ts.map +1 -1
- package/dist/gir/type-id.js +1 -3
- package/dist/gir/type-id.js.map +1 -1
- package/dist/gir/type-ref.js +1 -1
- package/dist/gir/type-ref.js.map +1 -1
- package/dist/index.d.ts +18 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +3 -0
- package/dist/internal.js.map +1 -0
- package/dist/jsx.d.ts +8 -11
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +18 -15
- package/dist/jsx.js.map +1 -1
- package/dist/khronos/args.d.ts.map +1 -1
- package/dist/khronos/args.js +1 -1
- package/dist/khronos/args.js.map +1 -1
- package/dist/khronos/pipeline.js +1 -1
- package/dist/khronos/pipeline.js.map +1 -1
- package/dist/khronos/plan.d.ts +2 -2
- package/dist/khronos/plan.d.ts.map +1 -1
- package/dist/khronos/plan.js +6 -6
- package/dist/khronos/plan.js.map +1 -1
- package/dist/react/element-config.d.ts +18 -9
- package/dist/react/element-config.d.ts.map +1 -1
- package/dist/react/element-config.js +23 -13
- package/dist/react/element-config.js.map +1 -1
- package/dist/runner.d.ts +36 -16
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +22 -20
- package/dist/runner.js.map +1 -1
- package/dist/store/compile-store.d.ts +1 -2
- package/dist/store/compile-store.d.ts.map +1 -1
- package/dist/store/compile-store.js +2 -2
- package/dist/store/compile-store.js.map +1 -1
- package/dist/store/gi/callables.d.ts.map +1 -1
- package/dist/store/gi/callables.js +4 -9
- package/dist/store/gi/callables.js.map +1 -1
- package/dist/store/gi/constant.d.ts.map +1 -1
- package/dist/store/gi/constant.js +0 -2
- package/dist/store/gi/constant.js.map +1 -1
- package/dist/store/gi/function.d.ts.map +1 -1
- package/dist/store/gi/function.js +1 -7
- package/dist/store/gi/function.js.map +1 -1
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +26 -23
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/property-accessor.d.ts +1 -1
- package/dist/store/gi/property-accessor.d.ts.map +1 -1
- package/dist/store/gi/property-accessor.js +5 -7
- package/dist/store/gi/property-accessor.js.map +1 -1
- package/dist/store/gi/record-constructor.d.ts.map +1 -1
- package/dist/store/gi/record-constructor.js +5 -4
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts +3 -2
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +21 -11
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/record-layout.d.ts.map +1 -1
- package/dist/store/gi/record-layout.js +0 -4
- package/dist/store/gi/record-layout.js.map +1 -1
- package/dist/store/gi/record.d.ts.map +1 -1
- package/dist/store/gi/record.js +0 -7
- package/dist/store/gi/record.js.map +1 -1
- package/dist/store/gi/return-wrap.d.ts +1 -1
- package/dist/store/gi/return-wrap.d.ts.map +1 -1
- package/dist/store/gi/return-wrap.js +4 -4
- package/dist/store/gi/return-wrap.js.map +1 -1
- package/dist/store/gi/signal.d.ts.map +1 -1
- package/dist/store/gi/signal.js +13 -16
- package/dist/store/gi/signal.js.map +1 -1
- package/dist/store/gi/value-marshalable.d.ts +7 -0
- package/dist/store/gi/value-marshalable.d.ts.map +1 -0
- package/dist/store/gi/value-marshalable.js +57 -0
- package/dist/store/gi/value-marshalable.js.map +1 -0
- package/dist/store/gi-store.d.ts +2 -3
- package/dist/store/gi-store.d.ts.map +1 -1
- package/dist/store/gi-store.js.map +1 -1
- package/dist/store/jsx/element-components.d.ts +0 -2
- package/dist/store/jsx/element-components.d.ts.map +1 -1
- package/dist/store/jsx/element-components.js +0 -4
- package/dist/store/jsx/element-components.js.map +1 -1
- package/dist/store/jsx/element-prop-imports.d.ts +2 -3
- package/dist/store/jsx/element-prop-imports.d.ts.map +1 -1
- package/dist/store/jsx/element-prop-imports.js +0 -2
- package/dist/store/jsx/element-prop-imports.js.map +1 -1
- package/dist/store/jsx/element-prop-types.d.ts +0 -1
- package/dist/store/jsx/element-prop-types.d.ts.map +1 -1
- package/dist/store/jsx/element-prop-types.js +0 -1
- package/dist/store/jsx/element-prop-types.js.map +1 -1
- package/dist/store/jsx/generated-elements.d.ts +29 -0
- package/dist/store/jsx/generated-elements.d.ts.map +1 -0
- package/dist/store/jsx/generated-elements.js +30 -0
- package/dist/store/jsx/generated-elements.js.map +1 -0
- package/dist/store/jsx/intrinsic-elements.d.ts +1 -2
- package/dist/store/jsx/intrinsic-elements.d.ts.map +1 -1
- package/dist/store/jsx/intrinsic-elements.js +1 -2
- package/dist/store/jsx/intrinsic-elements.js.map +1 -1
- package/dist/store/jsx/jsx.js +6 -6
- package/dist/store/jsx/jsx.js.map +1 -1
- package/dist/store/jsx/metadata.js +7 -7
- package/dist/store/jsx/metadata.js.map +1 -1
- package/dist/store/jsx/omitted-props.d.ts +8 -0
- package/dist/store/jsx/omitted-props.d.ts.map +1 -0
- package/dist/store/jsx/omitted-props.js +20 -0
- package/dist/store/jsx/omitted-props.js.map +1 -0
- package/dist/store/jsx/pipeline.d.ts +4 -0
- package/dist/store/jsx/pipeline.d.ts.map +1 -1
- package/dist/store/jsx/pipeline.js +4 -1
- package/dist/store/jsx/pipeline.js.map +1 -1
- package/dist/store/jsx/props.d.ts +1 -1
- package/dist/store/jsx/props.d.ts.map +1 -1
- package/dist/store/jsx/props.js +8 -13
- package/dist/store/jsx/props.js.map +1 -1
- package/dist/store/jsx-store.d.ts +2 -3
- package/dist/store/jsx-store.d.ts.map +1 -1
- package/dist/store/jsx-store.js +3 -3
- package/dist/store/jsx-store.js.map +1 -1
- package/dist/store/resolve-store.d.ts +28 -0
- package/dist/store/resolve-store.d.ts.map +1 -0
- package/dist/store/resolve-store.js +65 -0
- package/dist/store/resolve-store.js.map +1 -0
- package/dist/store/store-fs.d.ts +5 -1
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +6 -4
- package/dist/store/store-fs.js.map +1 -1
- package/overrides/gobject/object.ts.ejs +8 -8
- package/package.json +6 -11
- package/src/analysis/descriptor-render.ts +45 -38
- package/src/analysis/descriptor.ts +13 -13
- package/src/analysis/param-structure.ts +8 -10
- package/src/analysis/ts-type.ts +8 -17
- package/src/compile.ts +2 -1
- package/src/docs/api-reference.ts +131 -13
- package/src/docs/element-page.ts +5 -9
- package/src/docs/pipeline.ts +9 -6
- package/src/docs/render.ts +7 -7
- package/src/docs/symbol-page.ts +7 -2
- package/src/fingerprint.ts +21 -12
- package/src/gi.ts +13 -11
- package/src/gir/field.ts +0 -4
- package/src/gir/gir-path.ts +7 -0
- package/src/gir/libraries.ts +18 -4
- package/src/gir/parameter.ts +0 -4
- package/src/gir/size.ts +0 -3
- package/src/gir/type-id.ts +2 -4
- package/src/gir/type-ref.ts +1 -1
- package/src/index.ts +18 -15
- package/src/internal.ts +2 -0
- package/src/jsx.ts +26 -21
- package/src/khronos/args.ts +1 -1
- package/src/khronos/pipeline.ts +1 -1
- package/src/khronos/plan.ts +8 -8
- package/src/react/element-config.ts +25 -16
- package/src/runner.ts +62 -37
- package/src/store/compile-store.ts +3 -4
- package/src/store/gi/callables.ts +5 -11
- package/src/store/gi/constant.ts +0 -2
- package/src/store/gi/function.ts +1 -7
- package/src/store/gi/method.ts +31 -28
- package/src/store/gi/property-accessor.ts +6 -8
- package/src/store/gi/record-constructor.ts +9 -4
- package/src/store/gi/record-field-accessor.ts +41 -12
- package/src/store/gi/record-layout.ts +0 -4
- package/src/store/gi/record.ts +0 -9
- package/src/store/gi/return-wrap.ts +5 -5
- package/src/store/gi/signal.ts +17 -17
- package/src/store/gi/value-marshalable.ts +87 -0
- package/src/store/gi-store.ts +2 -4
- package/src/store/jsx/element-components.ts +0 -6
- package/src/store/jsx/element-prop-imports.ts +7 -4
- package/src/store/jsx/element-prop-types.ts +0 -1
- package/src/store/jsx/generated-elements.ts +60 -0
- package/src/store/jsx/intrinsic-elements.ts +0 -9
- package/src/store/jsx/jsx.ts +7 -7
- package/src/store/jsx/metadata.ts +8 -8
- package/src/store/jsx/omitted-props.ts +30 -0
- package/src/store/jsx/pipeline.ts +6 -1
- package/src/store/jsx/props.ts +8 -20
- package/src/store/jsx-store.ts +5 -7
- package/src/store/resolve-store.ts +100 -0
- package/src/store/store-fs.ts +12 -5
- package/dist/store/gi/class-struct-record.d.ts +0 -10
- package/dist/store/gi/class-struct-record.d.ts.map +0 -1
- package/dist/store/gi/class-struct-record.js +0 -52
- package/dist/store/gi/class-struct-record.js.map +0 -1
- package/src/store/gi/class-struct-record.ts +0 -72
|
@@ -5,43 +5,91 @@ import type { GirRecord } from "../gir/record.js";
|
|
|
5
5
|
import { Library } from "../gir/library.js";
|
|
6
6
|
import { type GirNamespace, namespaceDirectory } from "../gir/namespace.js";
|
|
7
7
|
import { dedupeCallables, isEmittableCallable } from "../store/gi/callables.js";
|
|
8
|
-
import { isClassStructRecord } from "../store/gi/class-struct-record.js";
|
|
9
8
|
import { namespaceFunctionExportName } from "../store/gi/function.js";
|
|
9
|
+
import { type ElementProps, setElementProps } from "../store/jsx/element-prop-imports.js";
|
|
10
10
|
import { collectIntrinsicElementClasses, type GlibNamedClass } from "../store/jsx/intrinsic-elements.js";
|
|
11
|
+
import { type OmittedProps, setOmittedProps } from "../store/jsx/omitted-props.js";
|
|
11
12
|
import { createElementPageContext, type ElementPageContext, renderElementPage } from "./element-page.js";
|
|
12
13
|
import { docsSignatureContext, firstSentence, namespaceOrder } from "./render.js";
|
|
13
14
|
import { type GiSymbolEntry, renderSymbolPage, type SymbolPageOptions } from "./symbol-page.js";
|
|
14
15
|
|
|
16
|
+
/** What to index and the element config the rendered pages reflect. */
|
|
15
17
|
type ApiReferenceOptions = {
|
|
18
|
+
/** GIR library identifiers to load, such as `"Gtk-4.0"`; their dependencies are pulled in too. */
|
|
16
19
|
libraries: string[];
|
|
20
|
+
/** Directories to search for `.gir` files. */
|
|
17
21
|
girPath: string[];
|
|
22
|
+
/** Base props interfaces per element, as read by `readBuiltinElements`; without it pages miss them. */
|
|
23
|
+
props?: ElementProps;
|
|
24
|
+
/** GObject properties the project omits from generated props; without it pages show props that do not exist. */
|
|
25
|
+
omittedProps?: OmittedProps;
|
|
18
26
|
};
|
|
19
27
|
|
|
28
|
+
/** Narrows an `ApiReference.symbols` enumeration. */
|
|
29
|
+
type ApiSymbolQuery = {
|
|
30
|
+
/** GIR namespace to keep, matched case-insensitively; every namespace when omitted. */
|
|
31
|
+
namespace?: string;
|
|
32
|
+
/** Symbol kinds to keep; every kind when omitted. */
|
|
33
|
+
kinds?: ApiSymbolKind[];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** What an indexed symbol is: one of the GIR symbol kinds, or a JSX element. */
|
|
20
37
|
type ApiSymbolKind = GiSymbolEntry["kind"] | "element";
|
|
21
38
|
|
|
39
|
+
/** An indexed symbol, without its reference page. */
|
|
22
40
|
type ApiSymbol = {
|
|
41
|
+
/** GIR namespace declaring the symbol, such as `"Gtk"`. */
|
|
23
42
|
namespace: string;
|
|
43
|
+
/** Name within the namespace, which for an element is its GLib type name. */
|
|
24
44
|
name: string;
|
|
45
|
+
/** Kind the reference groups and filters the symbol by, `"element"` for a JSX tag. */
|
|
25
46
|
kind: ApiSymbolKind;
|
|
47
|
+
/** First sentence of the symbol's GIR documentation, elided past 220 characters and empty when it has none. */
|
|
26
48
|
summary: string;
|
|
27
49
|
};
|
|
28
50
|
|
|
51
|
+
/** How much of one namespace the reference indexes. */
|
|
29
52
|
type ApiNamespaceSummary = {
|
|
53
|
+
/** GIR namespace name, such as `"Gtk"`. */
|
|
30
54
|
name: string;
|
|
55
|
+
/** The `@gtkx/gi` subpath the namespace's symbols are imported from. */
|
|
31
56
|
importPath: string;
|
|
57
|
+
/** How many symbols other than JSX elements the namespace contributes. */
|
|
32
58
|
symbols: number;
|
|
59
|
+
/** How many JSX elements the namespace contributes. */
|
|
33
60
|
elements: number;
|
|
34
61
|
};
|
|
35
62
|
|
|
63
|
+
/** What an `ApiReference.lookup` found: a rendered page, several candidates for the name, or nothing. */
|
|
36
64
|
type ApiLookupResult =
|
|
37
|
-
| {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
65
|
+
| {
|
|
66
|
+
/** Discriminant selecting the variant. */
|
|
67
|
+
outcome: "page";
|
|
68
|
+
/** Index entry for the symbol the query resolved to. */
|
|
69
|
+
symbol: ApiSymbol;
|
|
70
|
+
/** The symbol's complete reference page, rendered as Markdown. */
|
|
71
|
+
markdown: string;
|
|
72
|
+
} |
|
|
73
|
+
{
|
|
74
|
+
/** Discriminant selecting the variant. */
|
|
75
|
+
outcome: "ambiguous";
|
|
76
|
+
/** Every symbol the name answers to, to be narrowed by namespace or kind. */
|
|
77
|
+
candidates: ApiSymbol[];
|
|
78
|
+
} |
|
|
79
|
+
{
|
|
80
|
+
/** Discriminant selecting the variant. */
|
|
81
|
+
outcome: "notFound";
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/** A fuzzy search over indexed symbol names. */
|
|
41
85
|
type ApiSearchOptions = {
|
|
86
|
+
/** Text matched case-insensitively against each symbol's name and its qualified `Namespace.Name` form. */
|
|
42
87
|
query: string;
|
|
88
|
+
/** GIR namespace to keep, matched case-insensitively; every namespace when omitted. */
|
|
43
89
|
namespace?: string;
|
|
90
|
+
/** Symbol kinds to keep; every kind when omitted. */
|
|
44
91
|
kinds?: ApiSymbolKind[];
|
|
92
|
+
/** Maximum number of results, 20 by default. */
|
|
45
93
|
limit?: number;
|
|
46
94
|
};
|
|
47
95
|
|
|
@@ -56,6 +104,7 @@ type ElementEntry = {
|
|
|
56
104
|
type SymbolEntry = GiSymbolEntry | ElementEntry;
|
|
57
105
|
type ScoredEntry = { score: number; entry: SymbolEntry };
|
|
58
106
|
|
|
107
|
+
/** Every kind the reference indexes, in the order a namespace overview groups its symbols. */
|
|
59
108
|
const API_SYMBOL_KINDS: ApiSymbolKind[] = [
|
|
60
109
|
"element",
|
|
61
110
|
"class",
|
|
@@ -90,6 +139,32 @@ const compareNames = (a: string, b: string): number => {
|
|
|
90
139
|
return a > b ? 1 : 0;
|
|
91
140
|
};
|
|
92
141
|
|
|
142
|
+
const isQueriedEntry = (
|
|
143
|
+
entry: SymbolEntry,
|
|
144
|
+
namespaceFilter: string | undefined,
|
|
145
|
+
kinds: Set<ApiSymbolKind> | undefined,
|
|
146
|
+
): boolean => {
|
|
147
|
+
if (namespaceFilter !== undefined && entry.namespace.name.toLowerCase() !== namespaceFilter) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return kinds === undefined || kinds.has(entry.kind);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const compareApiSymbols = (a: ApiSymbol, b: ApiSymbol): number => {
|
|
155
|
+
const byNamespace = namespaceOrder(a.namespace).localeCompare(namespaceOrder(b.namespace));
|
|
156
|
+
|
|
157
|
+
return byNamespace === 0 ? a.name.localeCompare(b.name) : byNamespace;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Loads the GIR data for the given libraries and indexes every symbol and JSX element in it. The result is
|
|
162
|
+
* a read-only view: it generates no store and needs none, so a tool can explore the bindings a project would
|
|
163
|
+
* get without running codegen.
|
|
164
|
+
*
|
|
165
|
+
* @param options Which libraries to index, where to find them, and the project's element config.
|
|
166
|
+
* @returns The indexed reference.
|
|
167
|
+
*/
|
|
93
168
|
const loadApiReference = (options: ApiReferenceOptions): ApiReference => new ApiReference(options);
|
|
94
169
|
|
|
95
170
|
const functionEntry = (
|
|
@@ -136,23 +211,19 @@ const classEntries = (namespace: GirNamespace): GiSymbolEntry[] => {
|
|
|
136
211
|
return entries;
|
|
137
212
|
};
|
|
138
213
|
|
|
139
|
-
const recordEntry = (
|
|
214
|
+
const recordEntry = (namespace: GirNamespace, record: GirRecord): GiSymbolEntry | undefined => {
|
|
140
215
|
if (!record.introspectable || record.isVtable || record.name.length === 0) {
|
|
141
216
|
return undefined;
|
|
142
217
|
}
|
|
143
218
|
|
|
144
|
-
if (isClassStructRecord(library, namespace.name, record)) {
|
|
145
|
-
return undefined;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
219
|
return { kind: "record", namespace, name: record.name, doc: record.doc, record };
|
|
149
220
|
};
|
|
150
221
|
|
|
151
|
-
const recordEntries = (
|
|
222
|
+
const recordEntries = (namespace: GirNamespace): GiSymbolEntry[] => {
|
|
152
223
|
const entries: GiSymbolEntry[] = [];
|
|
153
224
|
|
|
154
225
|
for (const record of namespace.records) {
|
|
155
|
-
const entry = recordEntry(
|
|
226
|
+
const entry = recordEntry(namespace, record);
|
|
156
227
|
|
|
157
228
|
if (entry !== undefined) {
|
|
158
229
|
entries.push(entry);
|
|
@@ -270,6 +341,7 @@ const searchScore = (entry: SymbolEntry, query: string): number => {
|
|
|
270
341
|
return 0;
|
|
271
342
|
};
|
|
272
343
|
|
|
344
|
+
/** An index over the GIR data a project's bindings are generated from, queryable and renderable as Markdown. */
|
|
273
345
|
class ApiReference {
|
|
274
346
|
private library: Library;
|
|
275
347
|
private libraries: string[];
|
|
@@ -280,13 +352,23 @@ class ApiReference {
|
|
|
280
352
|
private byNamespace: Map<string, SymbolEntry[]> = new Map();
|
|
281
353
|
private elementsByClass: Map<string, string> = new Map();
|
|
282
354
|
|
|
355
|
+
private props: ElementProps;
|
|
356
|
+
private omittedProps: OmittedProps;
|
|
357
|
+
|
|
283
358
|
constructor(options: ApiReferenceOptions) {
|
|
284
359
|
this.libraries = options.libraries;
|
|
360
|
+
this.props = options.props ?? {};
|
|
361
|
+
this.omittedProps = options.omittedProps ?? {};
|
|
285
362
|
this.library = Library.load(options.libraries, options.girPath);
|
|
286
363
|
this.elementContext = createElementPageContext(this.library, (): string | undefined => undefined);
|
|
287
364
|
this.buildIndex();
|
|
288
365
|
}
|
|
289
366
|
|
|
367
|
+
private applyElementConfig(): void {
|
|
368
|
+
setElementProps(this.props);
|
|
369
|
+
setOmittedProps(this.omittedProps);
|
|
370
|
+
}
|
|
371
|
+
|
|
290
372
|
private add(entry: SymbolEntry): void {
|
|
291
373
|
this.entries.push(entry);
|
|
292
374
|
|
|
@@ -322,7 +404,7 @@ class ApiReference {
|
|
|
322
404
|
private indexNamespace(namespace: GirNamespace): void {
|
|
323
405
|
const entries = [
|
|
324
406
|
...classEntries(namespace),
|
|
325
|
-
...recordEntries(
|
|
407
|
+
...recordEntries(namespace),
|
|
326
408
|
...valueEntries(namespace),
|
|
327
409
|
];
|
|
328
410
|
|
|
@@ -367,6 +449,8 @@ class ApiReference {
|
|
|
367
449
|
|
|
368
450
|
private renderPage(entry: SymbolEntry): string {
|
|
369
451
|
if (entry.kind === "element") {
|
|
452
|
+
this.applyElementConfig();
|
|
453
|
+
|
|
370
454
|
return renderElementPage(entry.element, this.elementContext);
|
|
371
455
|
}
|
|
372
456
|
|
|
@@ -415,10 +499,18 @@ class ApiReference {
|
|
|
415
499
|
return scored;
|
|
416
500
|
}
|
|
417
501
|
|
|
502
|
+
/** Paths of the `.gir` files the index was built from, including the ones pulled in as dependencies. */
|
|
418
503
|
get girFiles(): string[] {
|
|
419
504
|
return this.library.girFiles;
|
|
420
505
|
}
|
|
421
506
|
|
|
507
|
+
/**
|
|
508
|
+
* Resolves a name to a single symbol and renders its reference page. The name may be bare (`Button`) or
|
|
509
|
+
* qualified (`Gtk.Button`), and is matched case-insensitively; a name several symbols answer to is
|
|
510
|
+
* reported as ambiguous rather than picked between.
|
|
511
|
+
*
|
|
512
|
+
* @param kind Restricts the match to one kind, which is how a class and its JSX element are told apart.
|
|
513
|
+
*/
|
|
422
514
|
lookup(query: string, kind?: ApiSymbolKind): ApiLookupResult {
|
|
423
515
|
const trimmed = query.trim();
|
|
424
516
|
|
|
@@ -440,6 +532,21 @@ class ApiReference {
|
|
|
440
532
|
return { outcome: "page", symbol: this.toApiSymbol(entry), markdown: this.renderPage(entry) };
|
|
441
533
|
}
|
|
442
534
|
|
|
535
|
+
/** Every indexed symbol the query keeps, ordered by namespace (Gtk, then Adw, then alphabetically) and name. */
|
|
536
|
+
symbols(query: ApiSymbolQuery = {}): ApiSymbol[] {
|
|
537
|
+
const namespaceFilter = query.namespace?.toLowerCase();
|
|
538
|
+
const kinds = query.kinds === undefined ? undefined : new Set(query.kinds);
|
|
539
|
+
|
|
540
|
+
return this.entries
|
|
541
|
+
.filter((entry) => isQueriedEntry(entry, namespaceFilter, kinds))
|
|
542
|
+
.map((entry) => this.toApiSymbol(entry))
|
|
543
|
+
.toSorted(compareApiSymbols);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Symbols whose name matches the query, best first: an exact name beats a prefix, which beats a
|
|
548
|
+
* substring, and shorter names win ties. An empty query matches nothing.
|
|
549
|
+
*/
|
|
443
550
|
search(options: ApiSearchOptions): ApiSymbol[] {
|
|
444
551
|
const query = options.query.trim().toLowerCase();
|
|
445
552
|
|
|
@@ -455,6 +562,7 @@ class ApiReference {
|
|
|
455
562
|
return scored.slice(0, limit).map((item) => this.toApiSymbol(item.entry));
|
|
456
563
|
}
|
|
457
564
|
|
|
565
|
+
/** A summary of every indexed namespace, ordered Gtk, Adw, then alphabetically. */
|
|
458
566
|
namespaces(): ApiNamespaceSummary[] {
|
|
459
567
|
const summaries = [...this.byNamespace].map(([name, entries]) => ({
|
|
460
568
|
name,
|
|
@@ -466,6 +574,10 @@ class ApiReference {
|
|
|
466
574
|
return sortStringsBy(summaries, (summary) => namespaceOrder(summary.name));
|
|
467
575
|
}
|
|
468
576
|
|
|
577
|
+
/**
|
|
578
|
+
* Sorted names of everything a namespace contributes, JSX elements included. The namespace is matched
|
|
579
|
+
* case-insensitively, and an unindexed one yields an empty array.
|
|
580
|
+
*/
|
|
469
581
|
symbolNames(namespaceName: string): string[] {
|
|
470
582
|
const namespace = this.findNamespace(namespaceName);
|
|
471
583
|
|
|
@@ -478,6 +590,7 @@ class ApiReference {
|
|
|
478
590
|
return sortStrings(entries.map((entry) => entry.name));
|
|
479
591
|
}
|
|
480
592
|
|
|
593
|
+
/** Renders the reference's Markdown landing page: every namespace, its import path, and its totals. */
|
|
481
594
|
overview(): string {
|
|
482
595
|
const rows = this.namespaces().map(
|
|
483
596
|
(summary) =>
|
|
@@ -505,6 +618,10 @@ class ApiReference {
|
|
|
505
618
|
].join("\n");
|
|
506
619
|
}
|
|
507
620
|
|
|
621
|
+
/**
|
|
622
|
+
* Renders one namespace's Markdown page: its import line and its symbol names grouped by kind. The
|
|
623
|
+
* namespace is matched case-insensitively, and an unindexed one yields undefined.
|
|
624
|
+
*/
|
|
508
625
|
namespaceOverview(name: string): string | undefined {
|
|
509
626
|
const namespace = this.findNamespace(name);
|
|
510
627
|
|
|
@@ -554,4 +671,5 @@ export {
|
|
|
554
671
|
type ApiNamespaceSummary,
|
|
555
672
|
type ApiLookupResult,
|
|
556
673
|
type ApiSearchOptions,
|
|
674
|
+
type ApiSymbolQuery,
|
|
557
675
|
};
|
package/src/docs/element-page.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
newlyImplementedInterfaces,
|
|
14
14
|
signalHandlerName,
|
|
15
15
|
} from "../store/jsx/intrinsic-elements.js";
|
|
16
|
+
import { isOmittedProp } from "../store/jsx/omitted-props.js";
|
|
16
17
|
import { isObjectProp } from "../store/jsx/props.js";
|
|
17
18
|
import {
|
|
18
19
|
classMethodEntries,
|
|
@@ -120,12 +121,7 @@ const propertyEntry = (
|
|
|
120
121
|
property: GirProperty,
|
|
121
122
|
jsName: string,
|
|
122
123
|
): PropEntry => {
|
|
123
|
-
const isObject = isObjectProp(
|
|
124
|
-
{ library: context.library, klass: owner.klass, namespace: owner.namespace },
|
|
125
|
-
property,
|
|
126
|
-
jsName,
|
|
127
|
-
);
|
|
128
|
-
|
|
124
|
+
const isObject = isObjectProp(context.library, property);
|
|
129
125
|
const baseType = renderDocsType(context.library, property.type, false);
|
|
130
126
|
const type = isObject ? `${baseType} | ReactElement` : baseType;
|
|
131
127
|
const meta: string[] = [`\`${type}\``];
|
|
@@ -149,14 +145,14 @@ const propertyEntry = (
|
|
|
149
145
|
return { name: jsName, meta: meta.join(" · "), doc: docMarkdown(property.doc) };
|
|
150
146
|
};
|
|
151
147
|
|
|
152
|
-
const propJsName = (property: GirProperty, seen: Set<string>): string | undefined => {
|
|
148
|
+
const propJsName = (property: GirProperty, owner: MemberOwner, seen: Set<string>): string | undefined => {
|
|
153
149
|
if (!property.introspectable) {
|
|
154
150
|
return undefined;
|
|
155
151
|
}
|
|
156
152
|
|
|
157
153
|
const jsName = toCamelIdentifier(property.name);
|
|
158
154
|
|
|
159
|
-
if (seen.has(jsName)) {
|
|
155
|
+
if (seen.has(jsName) || isOmittedProp(owner.glibName, jsName)) {
|
|
160
156
|
return undefined;
|
|
161
157
|
}
|
|
162
158
|
|
|
@@ -169,7 +165,7 @@ const ownerPropEntries = (context: ElementPageContext, owner: MemberOwner, seen:
|
|
|
169
165
|
const entries: PropEntry[] = [];
|
|
170
166
|
|
|
171
167
|
for (const property of owner.klass.properties) {
|
|
172
|
-
const jsName = propJsName(property, seen);
|
|
168
|
+
const jsName = propJsName(property, owner, seen);
|
|
173
169
|
|
|
174
170
|
if (jsName !== undefined) {
|
|
175
171
|
entries.push(propertyEntry(context, owner, property, jsName));
|
package/src/docs/pipeline.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { Library } from "../gir/library.js";
|
|
|
6
6
|
import { namespaceDirectory } from "../gir/namespace.js";
|
|
7
7
|
import { type ElementProps, setElementProps } from "../store/jsx/element-prop-imports.js";
|
|
8
8
|
import { collectIntrinsicElementClasses, type GlibNamedClass } from "../store/jsx/intrinsic-elements.js";
|
|
9
|
+
import { type OmittedProps, setOmittedProps } from "../store/jsx/omitted-props.js";
|
|
9
10
|
import { createElementPageContext, type ElementPageContext, renderElementPage } from "./element-page.js";
|
|
10
11
|
import { elementSlug, firstSentence, namespaceOrder } from "./render.js";
|
|
11
12
|
|
|
@@ -27,7 +28,8 @@ type DocsOptions = {
|
|
|
27
28
|
outDir: string;
|
|
28
29
|
basePath?: string;
|
|
29
30
|
props?: ElementProps;
|
|
30
|
-
|
|
31
|
+
omittedProps?: OmittedProps;
|
|
32
|
+
isForced?: boolean;
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
type DocsManifest = {
|
|
@@ -43,7 +45,7 @@ type Page = { path: string; content: string };
|
|
|
43
45
|
type NamespacePages = { docs: DocsNamespace; pages: Page[] };
|
|
44
46
|
|
|
45
47
|
type DocsResult = {
|
|
46
|
-
|
|
48
|
+
isRegenerated: boolean;
|
|
47
49
|
namespaces: DocsNamespace[];
|
|
48
50
|
};
|
|
49
51
|
|
|
@@ -191,7 +193,7 @@ const generatePages = (options: DocsOptions, basePath: string, library: Library)
|
|
|
191
193
|
};
|
|
192
194
|
|
|
193
195
|
const cachedDocsResult = (options: DocsOptions, manifestPath: string): DocsResult | undefined => {
|
|
194
|
-
if (options.
|
|
196
|
+
if (options.isForced === true || !isGiStoreFresh(options.outDir, options.libraries, options.girPath)) {
|
|
195
197
|
return undefined;
|
|
196
198
|
}
|
|
197
199
|
|
|
@@ -201,7 +203,7 @@ const cachedDocsResult = (options: DocsOptions, manifestPath: string): DocsResul
|
|
|
201
203
|
|
|
202
204
|
const manifest = JSON.parse(readFileSync(manifestPath, "utf8")) as DocsManifest;
|
|
203
205
|
|
|
204
|
-
return {
|
|
206
|
+
return { isRegenerated: false, namespaces: manifest.namespaces };
|
|
205
207
|
};
|
|
206
208
|
|
|
207
209
|
const writePages = (outDir: string, pages: Page[]): void => {
|
|
@@ -214,6 +216,7 @@ const writePages = (outDir: string, pages: Page[]): void => {
|
|
|
214
216
|
|
|
215
217
|
const writeDocs = (options: DocsOptions): DocsResult => {
|
|
216
218
|
setElementProps(options.props ?? {});
|
|
219
|
+
setOmittedProps(options.omittedProps ?? {});
|
|
217
220
|
const basePath = options.basePath ?? "/reference";
|
|
218
221
|
const manifestPath = join(options.outDir, MANIFEST_FILENAME);
|
|
219
222
|
const cached = cachedDocsResult(options, manifestPath);
|
|
@@ -235,7 +238,7 @@ const writeDocs = (options: DocsOptions): DocsResult => {
|
|
|
235
238
|
JSON.stringify(computeGiFingerprint(library.girFiles, options.libraries, options.girPath)),
|
|
236
239
|
);
|
|
237
240
|
|
|
238
|
-
return {
|
|
241
|
+
return { isRegenerated: true, namespaces };
|
|
239
242
|
};
|
|
240
243
|
|
|
241
|
-
export { writeDocs
|
|
244
|
+
export { writeDocs };
|
package/src/docs/render.ts
CHANGED
|
@@ -45,8 +45,8 @@ const renderDocsHandlerResultType = (library: Library, signal: GirCallable): str
|
|
|
45
45
|
library,
|
|
46
46
|
signal,
|
|
47
47
|
renderType: (ref, nullable) => renderDocsType(library, ref, nullable),
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
shouldIncludeCallerAllocated: false,
|
|
49
|
+
isOptOut: true,
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
const renderDocsHandlerParameters = (library: Library, signal: GirCallable): string[] =>
|
|
@@ -69,16 +69,16 @@ const stripDocMedia = (markdown: string): string =>
|
|
|
69
69
|
.replaceAll(/<video[\s\S]*?(?:<\/video>|\/>)/g, "")
|
|
70
70
|
.replaceAll(/<img[^>]*>/g, "");
|
|
71
71
|
|
|
72
|
-
const demoteLine = (line: string, isInFence: boolean): { text: string;
|
|
72
|
+
const demoteLine = (line: string, isInFence: boolean): { text: string; isInFence: boolean } => {
|
|
73
73
|
if (FENCE_LINE.test(line)) {
|
|
74
|
-
return { text: line,
|
|
74
|
+
return { text: line, isInFence: !isInFence };
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
if (isInFence) {
|
|
78
|
-
return { text: line,
|
|
78
|
+
return { text: line, isInFence };
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
return { text: HEADING_LINE.test(line) ? `#${line}` : line,
|
|
81
|
+
return { text: HEADING_LINE.test(line) ? `#${line}` : line, isInFence };
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
const demoteHeadings = (markdown: string): string => {
|
|
@@ -87,7 +87,7 @@ const demoteHeadings = (markdown: string): string => {
|
|
|
87
87
|
|
|
88
88
|
for (const line of markdown.split("\n")) {
|
|
89
89
|
const result = demoteLine(line, isInFence);
|
|
90
|
-
isInFence = result.
|
|
90
|
+
isInFence = result.isInFence;
|
|
91
91
|
lines.push(result.text);
|
|
92
92
|
}
|
|
93
93
|
|
package/src/docs/symbol-page.ts
CHANGED
|
@@ -49,12 +49,17 @@ import {
|
|
|
49
49
|
type SignatureEntry,
|
|
50
50
|
} from "./render.js";
|
|
51
51
|
|
|
52
|
+
/** What every indexed GIR symbol carries, whatever its kind. */
|
|
52
53
|
type GiSymbolBase = {
|
|
54
|
+
/** GIR namespace declaring the symbol. */
|
|
53
55
|
namespace: GirNamespace;
|
|
56
|
+
/** Name the bindings export it under: camelCase for functions, PascalCase for classes, the GIR name otherwise. */
|
|
54
57
|
name: string;
|
|
58
|
+
/** Raw gtk-doc text from the GIR, undefined when the symbol is undocumented. */
|
|
55
59
|
doc: string | undefined;
|
|
56
60
|
};
|
|
57
61
|
|
|
62
|
+
/** A GIR symbol the reference indexes, discriminated by `kind` and carrying the GIR node its page renders from. */
|
|
58
63
|
type GiSymbolEntry =
|
|
59
64
|
| (GiSymbolBase & { kind: "class" | "interface"; klass: GirClass }) |
|
|
60
65
|
(GiSymbolBase & { kind: "record"; record: GirRecord }) |
|
|
@@ -270,7 +275,7 @@ const propertyMeta = (property: GirProperty, accessor: ResolvedAccessor, origin:
|
|
|
270
275
|
meta.push("construct-only");
|
|
271
276
|
}
|
|
272
277
|
|
|
273
|
-
if (!accessor.
|
|
278
|
+
if (!accessor.isWritable) {
|
|
274
279
|
meta.push("read-only");
|
|
275
280
|
} else if (!accessor.hasGetter) {
|
|
276
281
|
meta.push("write-only");
|
|
@@ -495,7 +500,7 @@ const recordPage = (entry: GiSymbolBase & { kind: "record"; record: GirRecord },
|
|
|
495
500
|
};
|
|
496
501
|
|
|
497
502
|
const fieldMeta = (field: ResolvedRecordField): string =>
|
|
498
|
-
[`\`${field.tsType}\``, ...(field.
|
|
503
|
+
[`\`${field.tsType}\``, ...(field.isWritable ? [] : ["read-only"])].join(" · ");
|
|
499
504
|
|
|
500
505
|
const fieldsSection = (record: GirRecord, context: ModuleContext, claimedNames: Set<string>): string[] => {
|
|
501
506
|
const { slots } = computeRecordFieldSlots(context, record.fields, record.isUnion);
|
package/src/fingerprint.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { createRequire } from "node:module";
|
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
|
-
/** The freshness sentinel of the `@gtkx/gi` store, derived purely from the GIR inputs. */
|
|
9
8
|
type GiFingerprint = {
|
|
10
9
|
value: string;
|
|
11
10
|
girFiles: string[];
|
|
@@ -15,15 +14,14 @@ type GiFingerprint = {
|
|
|
15
14
|
|
|
16
15
|
type ModuleExport = { module: string; export: string };
|
|
17
16
|
|
|
18
|
-
/** The `@gtkx/react` element config that shapes the generated `@gtkx/jsx` store. */
|
|
19
17
|
type JsxFingerprintInput = {
|
|
20
18
|
reactVersion: string;
|
|
21
19
|
components: Record<string, ModuleExport>;
|
|
22
20
|
lazyElements: string[];
|
|
23
21
|
props: Record<string, ModuleExport>;
|
|
22
|
+
omittedProps: Record<string, string[]>;
|
|
24
23
|
};
|
|
25
24
|
|
|
26
|
-
/** The freshness sentinel of the `@gtkx/jsx` store, derived from the React element config. */
|
|
27
25
|
type JsxFingerprint = {
|
|
28
26
|
value: string;
|
|
29
27
|
intrinsicElementCount: number;
|
|
@@ -36,8 +34,6 @@ const OVERRIDES_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..", "o
|
|
|
36
34
|
|
|
37
35
|
const sortAlpha = (values: string[]): string => sortStrings(values).join(",");
|
|
38
36
|
|
|
39
|
-
// The overrides are copied verbatim into the store, so editing one changes the output even though no
|
|
40
|
-
// GIR file moved. Without them in the hash a stale override survives every non-forced run.
|
|
41
37
|
const overrideFiles = (): string[] => {
|
|
42
38
|
if (!existsSync(OVERRIDES_ROOT)) {
|
|
43
39
|
return [];
|
|
@@ -55,6 +51,7 @@ const hashGi = (girFiles: string[], libraries: string[], girPath: string[]): str
|
|
|
55
51
|
hash.update(sortAlpha(libraries));
|
|
56
52
|
hash.update("\n");
|
|
57
53
|
hash.update(sortAlpha(girPath));
|
|
54
|
+
hash.update("\n");
|
|
58
55
|
const hashedFiles = sortStrings([...girFiles, ...overrideFiles()]);
|
|
59
56
|
|
|
60
57
|
for (const file of hashedFiles) {
|
|
@@ -67,14 +64,22 @@ const hashGi = (girFiles: string[], libraries: string[], girPath: string[]): str
|
|
|
67
64
|
return hash.digest("hex");
|
|
68
65
|
};
|
|
69
66
|
|
|
70
|
-
const computeGiFingerprint = (
|
|
67
|
+
const computeGiFingerprint = (
|
|
68
|
+
girFiles: string[],
|
|
69
|
+
libraries: string[],
|
|
70
|
+
girPath: string[],
|
|
71
|
+
): GiFingerprint => ({
|
|
71
72
|
value: hashGi(girFiles, libraries, girPath),
|
|
72
73
|
girFiles,
|
|
73
74
|
libraries,
|
|
74
75
|
girPath,
|
|
75
76
|
});
|
|
76
77
|
|
|
77
|
-
const isGiStoreFresh = (
|
|
78
|
+
const isGiStoreFresh = (
|
|
79
|
+
giStoreDir: string,
|
|
80
|
+
libraries: string[],
|
|
81
|
+
girPath: string[],
|
|
82
|
+
): boolean => {
|
|
78
83
|
const sentinelPath = join(giStoreDir, FINGERPRINT_FILENAME);
|
|
79
84
|
|
|
80
85
|
if (!existsSync(sentinelPath)) {
|
|
@@ -106,6 +111,9 @@ const hasMatchingRecordedInputs = (sentinel: GiFingerprint, libraries: string[],
|
|
|
106
111
|
const serializeModuleExports = (map: Record<string, ModuleExport>): [string, string, string][] =>
|
|
107
112
|
sortStrings(Object.keys(map)).map((type) => [type, map[type]?.module ?? "", map[type]?.export ?? ""]);
|
|
108
113
|
|
|
114
|
+
const serializeOmittedProps = (map: Record<string, string[]>): [string, string][] =>
|
|
115
|
+
sortStrings(Object.keys(map)).map((type) => [type, sortAlpha(map[type] ?? [])]);
|
|
116
|
+
|
|
109
117
|
const hashJsx = (input: JsxFingerprintInput): string =>
|
|
110
118
|
createHash("sha256")
|
|
111
119
|
.update(
|
|
@@ -115,6 +123,7 @@ const hashJsx = (input: JsxFingerprintInput): string =>
|
|
|
115
123
|
serializeModuleExports(input.components),
|
|
116
124
|
sortStrings(input.lazyElements),
|
|
117
125
|
serializeModuleExports(input.props),
|
|
126
|
+
serializeOmittedProps(input.omittedProps),
|
|
118
127
|
]),
|
|
119
128
|
)
|
|
120
129
|
.digest("hex");
|
|
@@ -127,11 +136,11 @@ const computeJsxFingerprint = (input: JsxFingerprintInput, intrinsicElementCount
|
|
|
127
136
|
const jsxStoreFreshness = (
|
|
128
137
|
jsxStoreDir: string,
|
|
129
138
|
input: JsxFingerprintInput,
|
|
130
|
-
): {
|
|
139
|
+
): { isFresh: boolean; intrinsicElementCount: number } => {
|
|
131
140
|
const sentinelPath = join(jsxStoreDir, FINGERPRINT_FILENAME);
|
|
132
141
|
|
|
133
142
|
if (!existsSync(sentinelPath)) {
|
|
134
|
-
return {
|
|
143
|
+
return { isFresh: false, intrinsicElementCount: 0 };
|
|
135
144
|
}
|
|
136
145
|
|
|
137
146
|
let sentinel: JsxFingerprint;
|
|
@@ -139,12 +148,12 @@ const jsxStoreFreshness = (
|
|
|
139
148
|
try {
|
|
140
149
|
sentinel = JSON.parse(readFileSync(sentinelPath, "utf8")) as JsxFingerprint;
|
|
141
150
|
} catch {
|
|
142
|
-
return {
|
|
151
|
+
return { isFresh: false, intrinsicElementCount: 0 };
|
|
143
152
|
}
|
|
144
153
|
|
|
145
154
|
return sentinel.value === hashJsx(input)
|
|
146
|
-
? {
|
|
147
|
-
: {
|
|
155
|
+
? { isFresh: true, intrinsicElementCount: sentinel.intrinsicElementCount }
|
|
156
|
+
: { isFresh: false, intrinsicElementCount: 0 };
|
|
148
157
|
};
|
|
149
158
|
|
|
150
159
|
export {
|
package/src/gi.ts
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import type { Library } from "./gir/library.js";
|
|
2
|
+
import type { StoreOptions } from "./store/store-fs.js";
|
|
2
3
|
import { computeGiFingerprint } from "./fingerprint.js";
|
|
3
4
|
import { namespaceDirectory } from "./gir/namespace.js";
|
|
4
|
-
import { type GiNamespaceInput,
|
|
5
|
+
import { type GiNamespaceInput, writeGiStore } from "./store/gi-store.js";
|
|
5
6
|
import { generateNamespaceModule } from "./store/gi/pipeline.js";
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const runGiCodegen = (library: Library,
|
|
8
|
+
type GiCodegenOptions = {
|
|
9
|
+
gi: StoreOptions;
|
|
10
|
+
libraries: string[];
|
|
11
|
+
girPath: string[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const runGiCodegen = (library: Library, options: GiCodegenOptions): number => {
|
|
15
|
+
const { gi, libraries, girPath } = options;
|
|
16
|
+
|
|
14
17
|
const namespaces: GiNamespaceInput[] = Array.from(library.namespaces.values(), (namespace) => ({
|
|
15
18
|
directory: namespaceDirectory(namespace),
|
|
16
19
|
rawSource: generateNamespaceModule(namespace, library),
|
|
17
20
|
}));
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
const fingerprint = computeGiFingerprint(library.girFiles, [...libraries], [...girPath]);
|
|
23
|
+
writeGiStore(gi, namespaces, fingerprint);
|
|
20
24
|
|
|
21
25
|
return library.namespaces.size;
|
|
22
26
|
};
|
|
23
27
|
|
|
24
|
-
export { isGiStoreFresh } from "./fingerprint.js";
|
|
25
|
-
export type { GiStoreOptions } from "./store/gi-store.js";
|
|
26
28
|
export { runGiCodegen };
|
package/src/gir/field.ts
CHANGED
|
@@ -11,7 +11,6 @@ type GirField = {
|
|
|
11
11
|
writable: boolean;
|
|
12
12
|
private: boolean;
|
|
13
13
|
bits: number | undefined;
|
|
14
|
-
/** Members of an anonymous nested `<union>`/`<record>`, which occupies a slot but has no type. */
|
|
15
14
|
inlineMembers: GirField[] | undefined;
|
|
16
15
|
inlineIsUnion: boolean;
|
|
17
16
|
};
|
|
@@ -29,9 +28,6 @@ const fieldFromNode = (node: RawNode, context: ParseContext): GirField => ({
|
|
|
29
28
|
inlineIsUnion: false,
|
|
30
29
|
});
|
|
31
30
|
|
|
32
|
-
// A record may embed an anonymous `<union>` or `<record>` instead of naming a type for it. The
|
|
33
|
-
// member occupies a real slot and contributes its own size and alignment, but carries no `<type>`,
|
|
34
|
-
// so it has to be admitted as a field whose layout comes from its own children.
|
|
35
31
|
const anonymousMemberFromNode = (node: RawNode, isUnion: boolean, context: ParseContext): GirField => ({
|
|
36
32
|
name: nameAttr(node),
|
|
37
33
|
doc: getDoc(node),
|
package/src/gir/gir-path.ts
CHANGED
|
@@ -4,6 +4,13 @@ import { existsSync } from "node:fs";
|
|
|
4
4
|
|
|
5
5
|
const SYSTEM_GIR_PATH = "/usr/share/gir-1.0";
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* The directories to search for `.gir` files, in precedence order: the config's own `girPath`, then
|
|
9
|
+
* `GTKX_GIR_PATH`, then `/usr/share/gir-1.0`, then the girdir pkg-config reports for
|
|
10
|
+
* gobject-introspection-1.0. Duplicates are dropped, and the last two are included only when they exist.
|
|
11
|
+
*
|
|
12
|
+
* @throws If pkg-config is installed but fails while being queried.
|
|
13
|
+
*/
|
|
7
14
|
const resolveGirPath = (configGirPath: string[] | undefined): string[] => {
|
|
8
15
|
const paths: string[] = [];
|
|
9
16
|
|