@gtkx/codegen 1.4.0 → 1.6.0
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 +1 -1
- package/dist/analysis/descriptor-render.d.ts +1 -0
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +56 -28
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +3 -1
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +10 -9
- package/dist/analysis/descriptor.js.map +1 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +24 -3
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts +2 -0
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +2 -1
- package/dist/docs/api-reference.js.map +1 -1
- package/dist/docs/pipeline.d.ts +3 -0
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +44 -12
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/fingerprint.d.ts +3 -0
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +4 -0
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +1 -0
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +4 -1
- package/dist/gi.js.map +1 -1
- package/dist/gir/libraries.d.ts +12 -5
- package/dist/gir/libraries.d.ts.map +1 -1
- package/dist/gir/libraries.js +50 -14
- package/dist/gir/libraries.js.map +1 -1
- package/dist/gir/library.d.ts +5 -0
- package/dist/gir/library.d.ts.map +1 -1
- package/dist/gir/library.js +6 -0
- package/dist/gir/library.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/dist/jsx.d.ts +1 -0
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +2 -0
- package/dist/jsx.js.map +1 -1
- package/dist/runner.d.ts +2 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +3 -1
- package/dist/runner.js.map +1 -1
- package/dist/store/gi/bootstrap.d.ts +4 -0
- package/dist/store/gi/bootstrap.d.ts.map +1 -0
- package/dist/store/gi/bootstrap.js +48 -0
- package/dist/store/gi/bootstrap.js.map +1 -0
- package/dist/store/gi/class.d.ts.map +1 -1
- package/dist/store/gi/class.js +75 -28
- package/dist/store/gi/class.js.map +1 -1
- package/dist/store/gi/constructor-props.d.ts.map +1 -1
- package/dist/store/gi/constructor-props.js +2 -1
- package/dist/store/gi/constructor-props.js.map +1 -1
- package/dist/store/gi/enum.js +3 -3
- package/dist/store/gi/enum.js.map +1 -1
- package/dist/store/gi/folded.d.ts +14 -0
- package/dist/store/gi/folded.d.ts.map +1 -0
- package/dist/store/gi/folded.js +35 -0
- package/dist/store/gi/folded.js.map +1 -0
- package/dist/store/gi/function.d.ts.map +1 -1
- package/dist/store/gi/function.js +22 -3
- package/dist/store/gi/function.js.map +1 -1
- package/dist/store/gi/gtype-binding.d.ts.map +1 -1
- package/dist/store/gi/gtype-binding.js +11 -1
- package/dist/store/gi/gtype-binding.js.map +1 -1
- package/dist/store/gi/interface.d.ts.map +1 -1
- package/dist/store/gi/interface.js +43 -4
- package/dist/store/gi/interface.js.map +1 -1
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +2 -0
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/pipeline.d.ts +5 -1
- package/dist/store/gi/pipeline.d.ts.map +1 -1
- package/dist/store/gi/pipeline.js +13 -1
- package/dist/store/gi/pipeline.js.map +1 -1
- package/dist/store/gi/property-accessor.js +1 -1
- package/dist/store/gi/property-accessor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +3 -3
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/record.d.ts.map +1 -1
- package/dist/store/gi/record.js +44 -12
- package/dist/store/gi/record.js.map +1 -1
- package/dist/store/gi/registration.js +2 -2
- package/dist/store/gi/registration.js.map +1 -1
- package/dist/store/gi/return-wrap.js +1 -1
- 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 +7 -3
- package/dist/store/gi/signal.js.map +1 -1
- package/dist/store/gi/vtable.d.ts.map +1 -1
- package/dist/store/gi/vtable.js +1 -1
- package/dist/store/gi/vtable.js.map +1 -1
- package/dist/store/gi-store.d.ts +1 -0
- package/dist/store/gi-store.d.ts.map +1 -1
- package/dist/store/gi-store.js +16 -7
- package/dist/store/gi-store.js.map +1 -1
- package/dist/store/jsx/element-components.d.ts.map +1 -1
- package/dist/store/jsx/element-components.js +64 -10
- package/dist/store/jsx/element-components.js.map +1 -1
- package/dist/store/jsx/element-prop-types.d.ts +2 -0
- package/dist/store/jsx/element-prop-types.d.ts.map +1 -1
- package/dist/store/jsx/element-prop-types.js +2 -0
- package/dist/store/jsx/element-prop-types.js.map +1 -1
- package/dist/store/jsx/metadata.d.ts.map +1 -1
- package/dist/store/jsx/metadata.js +28 -1
- package/dist/store/jsx/metadata.js.map +1 -1
- package/dist/store/jsx-store.d.ts +1 -0
- package/dist/store/jsx-store.d.ts.map +1 -1
- package/dist/store/jsx-store.js +7 -2
- package/dist/store/jsx-store.js.map +1 -1
- package/dist/store/resolve-store.d.ts.map +1 -1
- package/dist/store/resolve-store.js +2 -0
- package/dist/store/resolve-store.js.map +1 -1
- package/dist/store/store-fs.d.ts +2 -1
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +1 -1
- package/dist/store/store-fs.js.map +1 -1
- package/dist/writer/context.d.ts +17 -0
- package/dist/writer/context.d.ts.map +1 -1
- package/dist/writer/context.js +83 -11
- package/dist/writer/context.js.map +1 -1
- package/dist/writer/emit.d.ts +2 -1
- package/dist/writer/emit.d.ts.map +1 -1
- package/dist/writer/emit.js +2 -1
- package/dist/writer/emit.js.map +1 -1
- package/dist/writer/imports.d.ts.map +1 -1
- package/dist/writer/imports.js +6 -1
- package/dist/writer/imports.js.map +1 -1
- package/dist/writer/module.d.ts +1 -0
- package/dist/writer/module.d.ts.map +1 -1
- package/dist/writer/module.js +6 -1
- package/dist/writer/module.js.map +1 -1
- package/overrides/glib/regex.ts.ejs +2 -0
- package/package.json +4 -4
- package/src/analysis/descriptor-render.ts +79 -30
- package/src/analysis/descriptor.ts +19 -11
- package/src/compile.ts +42 -3
- package/src/docs/api-reference.ts +4 -1
- package/src/docs/pipeline.ts +64 -13
- package/src/fingerprint.ts +7 -0
- package/src/gi.ts +6 -1
- package/src/gir/libraries.ts +64 -16
- package/src/gir/library.ts +9 -0
- package/src/internal.ts +1 -0
- package/src/jsx.ts +3 -0
- package/src/runner.ts +5 -1
- package/src/store/gi/bootstrap.ts +64 -0
- package/src/store/gi/class.ts +100 -29
- package/src/store/gi/constructor-props.ts +2 -1
- package/src/store/gi/enum.ts +4 -4
- package/src/store/gi/folded.ts +57 -0
- package/src/store/gi/function.ts +22 -3
- package/src/store/gi/gtype-binding.ts +15 -2
- package/src/store/gi/interface.ts +64 -7
- package/src/store/gi/method.ts +2 -0
- package/src/store/gi/pipeline.ts +21 -2
- package/src/store/gi/property-accessor.ts +1 -1
- package/src/store/gi/record-field-accessor.ts +5 -3
- package/src/store/gi/record.ts +61 -14
- package/src/store/gi/registration.ts +2 -2
- package/src/store/gi/return-wrap.ts +1 -1
- package/src/store/gi/signal.ts +8 -3
- package/src/store/gi/vtable.ts +1 -0
- package/src/store/gi-store.ts +19 -7
- package/src/store/jsx/element-components.ts +107 -10
- package/src/store/jsx/element-prop-types.ts +4 -0
- package/src/store/jsx/metadata.ts +41 -0
- package/src/store/jsx-store.ts +10 -4
- package/src/store/resolve-store.ts +2 -0
- package/src/store/store-fs.ts +3 -2
- package/src/writer/context.ts +109 -16
- package/src/writer/emit.ts +3 -1
- package/src/writer/imports.ts +9 -1
- package/src/writer/module.ts +9 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { sourceStringLiteral } from "@gtkx/utils";
|
|
1
|
+
import { sanitizeTypeIdentifier, sourceStringLiteral } from "@gtkx/utils";
|
|
2
2
|
import type { Library } from "../../gir/library.js";
|
|
3
3
|
import type { GirNamespace } from "../../gir/namespace.js";
|
|
4
4
|
import type { ImportsBuilder } from "../../writer/imports.js";
|
|
5
5
|
import type { LazyElementSpec } from "./element-prop-types.js";
|
|
6
|
+
import { externalPackageFor } from "../../gir/external-namespaces.js";
|
|
6
7
|
import { getDoc } from "../gi/doc-spec.js";
|
|
7
8
|
import { ancestorGlibNames, type GlibNamedClass } from "./intrinsic-elements.js";
|
|
8
9
|
|
|
@@ -23,6 +24,13 @@ type CandidateExportOptions = {
|
|
|
23
24
|
components: Record<string, ElementComponent>;
|
|
24
25
|
};
|
|
25
26
|
|
|
27
|
+
type LazyMetadataOptions = {
|
|
28
|
+
isTreeShaken: boolean;
|
|
29
|
+
intrinsicNames: Set<string>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const METADATA_ALIAS = "Metadata$";
|
|
33
|
+
|
|
26
34
|
const generateElementComponentsSection = (
|
|
27
35
|
targetNamespace: GirNamespace,
|
|
28
36
|
library: Library,
|
|
@@ -45,7 +53,11 @@ const generateElementComponentsSection = (
|
|
|
45
53
|
components: options.components,
|
|
46
54
|
});
|
|
47
55
|
|
|
48
|
-
collectLazyElementExports(collector, lazyElements
|
|
56
|
+
collectLazyElementExports(collector, lazyElements, {
|
|
57
|
+
isTreeShaken: library.isTreeShaken,
|
|
58
|
+
intrinsicNames: new Set(options.intrinsicElements.map((entry) => entry.glibName)),
|
|
59
|
+
});
|
|
60
|
+
|
|
49
61
|
const source = collector.exportLines.join("\n\n");
|
|
50
62
|
|
|
51
63
|
return { source, exportedNames: collector.exportedNames };
|
|
@@ -81,18 +93,75 @@ const collectCandidateExports = (collector: ExportCollector, options: CandidateE
|
|
|
81
93
|
}
|
|
82
94
|
};
|
|
83
95
|
|
|
84
|
-
const collectLazyElementExports = (
|
|
96
|
+
const collectLazyElementExports = (
|
|
97
|
+
collector: ExportCollector,
|
|
98
|
+
lazyElements: LazyElementSpec[],
|
|
99
|
+
options: LazyMetadataOptions,
|
|
100
|
+
): void => {
|
|
85
101
|
for (const spec of lazyElements) {
|
|
86
102
|
collector.imports.addNamed("@gtkx/react/internal", "createElementComponent", false);
|
|
87
103
|
collector.imports.addNamed("react", "ReactNode", true);
|
|
88
|
-
|
|
104
|
+
|
|
105
|
+
const refs = {
|
|
106
|
+
classRef: lazyClassRef(collector, spec, options),
|
|
107
|
+
metadataRef: lazyMetadataRef(collector, spec, options),
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
collector.exportLines.push(renderLazyElementExport(spec, refs, options));
|
|
89
111
|
collector.exportedNames.add(spec.element);
|
|
90
112
|
}
|
|
91
113
|
};
|
|
92
114
|
|
|
93
|
-
const
|
|
115
|
+
const lazyMetadataRef = (
|
|
116
|
+
collector: ExportCollector,
|
|
117
|
+
spec: LazyElementSpec,
|
|
118
|
+
options: LazyMetadataOptions,
|
|
119
|
+
): string | undefined => {
|
|
120
|
+
if (!options.isTreeShaken || !options.intrinsicNames.has(spec.element)) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
collector.imports.addNamespace("../metadata.js", METADATA_ALIAS, false);
|
|
125
|
+
|
|
126
|
+
return `${METADATA_ALIAS}.${spec.element}`;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const lazyClassRef = (
|
|
130
|
+
collector: ExportCollector,
|
|
131
|
+
spec: LazyElementSpec,
|
|
132
|
+
options: LazyMetadataOptions,
|
|
133
|
+
): string | undefined => {
|
|
134
|
+
if (!options.isTreeShaken) {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const alias = `${spec.namespaceName}$`;
|
|
139
|
+
const specifier = externalPackageFor(spec.namespaceName) ?? `@gtkx/gi/${spec.namespaceName.toLowerCase()}`;
|
|
140
|
+
collector.imports.addNamespace(specifier, alias, false);
|
|
141
|
+
|
|
142
|
+
return `${alias}.${sanitizeTypeIdentifier(spec.className)}`;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const renderLazyElementExport = (
|
|
146
|
+
spec: LazyElementSpec,
|
|
147
|
+
refs: { classRef: string | undefined; metadataRef: string | undefined },
|
|
148
|
+
options: LazyMetadataOptions,
|
|
149
|
+
): string => {
|
|
94
150
|
const doc = getDoc(spec);
|
|
95
|
-
const
|
|
151
|
+
const args = [sourceStringLiteral(spec.element)];
|
|
152
|
+
|
|
153
|
+
if (refs.classRef !== undefined) {
|
|
154
|
+
args.push(refs.classRef);
|
|
155
|
+
} else if (refs.metadataRef !== undefined) {
|
|
156
|
+
args.push("undefined");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (refs.metadataRef !== undefined) {
|
|
160
|
+
args.push(refs.metadataRef);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const pure = options.isTreeShaken ? "/* @__PURE__ */ " : "";
|
|
164
|
+
const factory = `${pure}createElementComponent(${args.join(", ")})`;
|
|
96
165
|
const component = `${doc}export const ${spec.element}: (props: ${spec.typeName}) => ReactNode = ${factory};`;
|
|
97
166
|
|
|
98
167
|
return `${doc}${spec.typeSource}\n\n${component}`;
|
|
@@ -114,9 +183,21 @@ const renderCandidateExport = (
|
|
|
114
183
|
imports.addNamed(component.module, component.export, false);
|
|
115
184
|
}
|
|
116
185
|
|
|
186
|
+
let classRef: string | undefined;
|
|
187
|
+
let metadataRef: string | undefined;
|
|
188
|
+
|
|
189
|
+
if (library.isTreeShaken) {
|
|
190
|
+
const alias = `${namespace.name}$`;
|
|
191
|
+
const specifier = externalPackageFor(namespace.name) ?? `@gtkx/gi/${namespace.name.toLowerCase()}`;
|
|
192
|
+
imports.addNamespace(specifier, alias, false);
|
|
193
|
+
imports.addNamespace("../metadata.js", METADATA_ALIAS, false);
|
|
194
|
+
classRef = `${alias}.${sanitizeTypeIdentifier(klass.name)}`;
|
|
195
|
+
metadataRef = `${METADATA_ALIAS}.${glibName}`;
|
|
196
|
+
}
|
|
197
|
+
|
|
117
198
|
const doc = getDoc(klass);
|
|
118
199
|
|
|
119
|
-
return `${doc}${renderElementComponentExport(glibName, component)}`;
|
|
200
|
+
return `${doc}${renderElementComponentExport(glibName, component, classRef, metadataRef)}`;
|
|
120
201
|
};
|
|
121
202
|
|
|
122
203
|
const resolveElementComponent = (
|
|
@@ -134,16 +215,32 @@ const resolveElementComponent = (
|
|
|
134
215
|
return undefined;
|
|
135
216
|
};
|
|
136
217
|
|
|
137
|
-
const renderElementComponentExport = (
|
|
218
|
+
const renderElementComponentExport = (
|
|
219
|
+
glibName: string,
|
|
220
|
+
component: ElementComponent | undefined,
|
|
221
|
+
classRef: string | undefined,
|
|
222
|
+
metadataRef: string | undefined,
|
|
223
|
+
): string => {
|
|
138
224
|
const propsType = `${glibName}Props`;
|
|
139
225
|
const annotation = `(props: ${propsType}) => ReactNode`;
|
|
140
|
-
const
|
|
226
|
+
const args = [sourceStringLiteral(glibName)];
|
|
227
|
+
|
|
228
|
+
if (classRef !== undefined) {
|
|
229
|
+
args.push(classRef);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (metadataRef !== undefined) {
|
|
233
|
+
args.push(metadataRef);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const pure = classRef === undefined ? "" : "/* @__PURE__ */ ";
|
|
237
|
+
const factoryCall = `${pure}createElementComponent(${args.join(", ")})`;
|
|
141
238
|
|
|
142
239
|
if (component === undefined) {
|
|
143
240
|
return `export const ${glibName}: ${annotation} = ${factoryCall};`;
|
|
144
241
|
}
|
|
145
242
|
|
|
146
|
-
return `export const ${glibName}: ${annotation} = ${component.export}(${factoryCall});`;
|
|
243
|
+
return `export const ${glibName}: ${annotation} = ${pure}${component.export}(${factoryCall});`;
|
|
147
244
|
};
|
|
148
245
|
|
|
149
246
|
export { generateElementComponentsSection, type ElementComponentOverrides };
|
|
@@ -10,6 +10,8 @@ type LazyElementSpec = {
|
|
|
10
10
|
typeSource: string;
|
|
11
11
|
doc: string | undefined;
|
|
12
12
|
annotations: GirAnnotations;
|
|
13
|
+
namespaceName: string;
|
|
14
|
+
className: string;
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
const appendConstructOnlyNames = (klass: GirClass, names: string[]): void => {
|
|
@@ -43,6 +45,8 @@ const createLazyElementSpec = (context: GirIndex, element: string, entry: GirTyp
|
|
|
43
45
|
typeSource: `export type ${typeName} = ${base} & { children?: ReactNode };`,
|
|
44
46
|
doc: entry.klass.doc,
|
|
45
47
|
annotations: entry.klass.annotations,
|
|
48
|
+
namespaceName: entry.namespace.name,
|
|
49
|
+
className: entry.klass.name,
|
|
46
50
|
};
|
|
47
51
|
};
|
|
48
52
|
|
|
@@ -8,6 +8,7 @@ import type { GirType } from "../../gir/type.js";
|
|
|
8
8
|
import { inputParameters } from "../../analysis/param-structure.js";
|
|
9
9
|
import { type GirProperty, isConstructableProperty } from "../../gir/property.js";
|
|
10
10
|
import {
|
|
11
|
+
ancestorGlibNames,
|
|
11
12
|
implementedInterfaces,
|
|
12
13
|
isIntrinsicElementClass,
|
|
13
14
|
iterateClassesWithGlibName,
|
|
@@ -18,6 +19,7 @@ type IntrinsicElementEntry = {
|
|
|
18
19
|
glibName: string;
|
|
19
20
|
signals: [string, string][];
|
|
20
21
|
properties: [string, string][];
|
|
22
|
+
ancestors: string[];
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
const READABLE = 1;
|
|
@@ -35,6 +37,10 @@ const FLOAT_PATTERN = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i;
|
|
|
35
37
|
const generateMetadata = (library: Library): string => {
|
|
36
38
|
const intrinsicElements = collectIntrinsicElements(library);
|
|
37
39
|
|
|
40
|
+
if (library.isTreeShaken) {
|
|
41
|
+
return generateEntryMetadata(intrinsicElements);
|
|
42
|
+
}
|
|
43
|
+
|
|
38
44
|
const signalsEntries = intrinsicElements.map(
|
|
39
45
|
({ glibName, signals }) => ` "${glibName}": ${renderSignalsObject(signals)},`,
|
|
40
46
|
);
|
|
@@ -51,6 +57,40 @@ const generateMetadata = (library: Library): string => {
|
|
|
51
57
|
].join("\n\n")}\n`;
|
|
52
58
|
};
|
|
53
59
|
|
|
60
|
+
const entryAncestorsInSet = (entry: IntrinsicElementEntry, names: Set<string>): string[] =>
|
|
61
|
+
entry.ancestors.filter((name) => name !== entry.glibName && names.has(name));
|
|
62
|
+
|
|
63
|
+
const compareEntriesByDepth = (
|
|
64
|
+
names: Set<string>,
|
|
65
|
+
): ((first: IntrinsicElementEntry, second: IntrinsicElementEntry) => number) =>
|
|
66
|
+
(first, second) =>
|
|
67
|
+
entryAncestorsInSet(first, names).length - entryAncestorsInSet(second, names).length ||
|
|
68
|
+
first.glibName.localeCompare(second.glibName);
|
|
69
|
+
|
|
70
|
+
const renderEntryExport = (entry: IntrinsicElementEntry, names: Set<string>): string => {
|
|
71
|
+
const parent = entryAncestorsInSet(entry, names)[0] ?? "undefined";
|
|
72
|
+
const literal = sourceStringLiteral(entry.glibName);
|
|
73
|
+
const ownSignals = renderSignalsObject(entry.signals);
|
|
74
|
+
const ownProperties = renderPropertiesObject(entry.properties);
|
|
75
|
+
const call = `registerElementMetadata(${literal}, ${parent}, ${ownSignals}, ${ownProperties})`;
|
|
76
|
+
|
|
77
|
+
return `export const ${entry.glibName}: string = /* @__PURE__ */ ${call};`;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const generateEntryMetadata = (intrinsicElements: IntrinsicElementEntry[]): string => {
|
|
81
|
+
const names = new Set(intrinsicElements.map((entry) => entry.glibName));
|
|
82
|
+
const ordered = intrinsicElements.toSorted(compareEntriesByDepth(names));
|
|
83
|
+
const lines = ordered.map((entry) => renderEntryExport(entry, names));
|
|
84
|
+
|
|
85
|
+
return `${[
|
|
86
|
+
"import { registerElementMetadata } from \"@gtkx/runtime/internal\";",
|
|
87
|
+
PROPERTY_ENTRY_TYPE,
|
|
88
|
+
"export const signals: Record<string, Record<string, string>> = {};",
|
|
89
|
+
"export const properties: Record<string, Record<string, PropertyEntry>> = {};",
|
|
90
|
+
lines.join("\n\n"),
|
|
91
|
+
].join("\n\n")}\n`;
|
|
92
|
+
};
|
|
93
|
+
|
|
54
94
|
const collectIntrinsicElements = (library: Library): IntrinsicElementEntry[] => {
|
|
55
95
|
const entries: IntrinsicElementEntry[] = [];
|
|
56
96
|
const seen: Set<string> = new Set();
|
|
@@ -71,6 +111,7 @@ const collectIntrinsicElements = (library: Library): IntrinsicElementEntry[] =>
|
|
|
71
111
|
glibName,
|
|
72
112
|
signals: collectSignals(sources),
|
|
73
113
|
properties: collectProperties(library, sources),
|
|
114
|
+
ancestors: ancestorGlibNames(klass, namespace, library),
|
|
74
115
|
});
|
|
75
116
|
}
|
|
76
117
|
|
package/src/store/jsx-store.ts
CHANGED
|
@@ -9,12 +9,17 @@ type WriteJsxStoreParams = {
|
|
|
9
9
|
metadata: string;
|
|
10
10
|
externalPackages: string[];
|
|
11
11
|
rawFiles: RawFile[];
|
|
12
|
+
isTreeShaken?: boolean;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
const jsxPeerDependencies = (externalPackages: string[]): Record<string, string> =>
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const jsxPeerDependencies = (externalPackages: string[], isTreeShaken: boolean): Record<string, string> => {
|
|
16
|
+
const runtime = isTreeShaken ? ["@gtkx/runtime"] : [];
|
|
17
|
+
|
|
18
|
+
return Object.fromEntries(
|
|
19
|
+
sortStrings(["@gtkx/gi", "@gtkx/react", "react", ...runtime, ...externalPackages])
|
|
20
|
+
.map((name) => [name, "*"]),
|
|
17
21
|
);
|
|
22
|
+
};
|
|
18
23
|
|
|
19
24
|
const writeJsxStore = (params: WriteJsxStoreParams): void => {
|
|
20
25
|
const { options, namespaces, metadata, externalPackages, rawFiles } = params;
|
|
@@ -43,7 +48,8 @@ const writeJsxStore = (params: WriteJsxStoreParams): void => {
|
|
|
43
48
|
name: "@gtkx/jsx",
|
|
44
49
|
version: options.version,
|
|
45
50
|
exports: exportsMap,
|
|
46
|
-
|
|
51
|
+
sideEffects: params.isTreeShaken !== true,
|
|
52
|
+
peerDependencies: jsxPeerDependencies(externalPackages, params.isTreeShaken === true),
|
|
47
53
|
}),
|
|
48
54
|
rawFiles,
|
|
49
55
|
});
|
package/src/store/store-fs.ts
CHANGED
|
@@ -31,7 +31,7 @@ type Manifest = {
|
|
|
31
31
|
name: string;
|
|
32
32
|
type: "module";
|
|
33
33
|
version: string;
|
|
34
|
-
sideEffects:
|
|
34
|
+
sideEffects: boolean | string[];
|
|
35
35
|
exports: Record<string, unknown>;
|
|
36
36
|
peerDependencies?: Record<string, string>;
|
|
37
37
|
};
|
|
@@ -40,6 +40,7 @@ type ManifestInput = {
|
|
|
40
40
|
name: string;
|
|
41
41
|
version: string;
|
|
42
42
|
exports: Record<string, unknown>;
|
|
43
|
+
sideEffects?: boolean | string[];
|
|
43
44
|
peerDependencies?: Record<string, string>;
|
|
44
45
|
};
|
|
45
46
|
|
|
@@ -71,7 +72,7 @@ const buildManifest = (input: ManifestInput): Manifest => {
|
|
|
71
72
|
name: input.name,
|
|
72
73
|
type: "module",
|
|
73
74
|
version: input.version,
|
|
74
|
-
sideEffects: true,
|
|
75
|
+
sideEffects: input.sideEffects ?? true,
|
|
75
76
|
exports: { "./package.json": "./package.json", ...input.exports },
|
|
76
77
|
};
|
|
77
78
|
|
package/src/writer/context.ts
CHANGED
|
@@ -3,16 +3,56 @@ import type { GirNamespace } from "../gir/namespace.js";
|
|
|
3
3
|
import { externalPackageFor } from "../gir/external-namespaces.js";
|
|
4
4
|
import { type Declaration, ModuleBuilder } from "./module.js";
|
|
5
5
|
|
|
6
|
+
type BootstrapCallOptions = {
|
|
7
|
+
moduleExports?: string[];
|
|
8
|
+
runtimeImports?: string[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const addExternalNamespaceImport = (context: ModuleContext, packageName: string, namespaceName: string): void => {
|
|
12
|
+
if (context.isTreeShaken) {
|
|
13
|
+
context.externalDependencies.add(packageName);
|
|
14
|
+
} else {
|
|
15
|
+
context.module.imports.addSideEffect(packageName);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
context.module.imports.addNamespace(packageName, namespaceName);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const addInternalNamespaceImport = (context: ModuleContext, namespaceName: string): void => {
|
|
22
|
+
const directory = namespaceName.toLowerCase();
|
|
23
|
+
const isFoundational = directory === "gobject" || directory === "glib";
|
|
24
|
+
const path = isFoundational ? `../${directory}/${directory}.js` : `../${directory}/index.js`;
|
|
25
|
+
|
|
26
|
+
if (context.isTreeShaken) {
|
|
27
|
+
context.dependencies.add(directory);
|
|
28
|
+
} else if (!isFoundational) {
|
|
29
|
+
context.module.imports.addSideEffect(path);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
context.module.imports.addNamespace(path, namespaceName);
|
|
33
|
+
};
|
|
34
|
+
|
|
6
35
|
class ModuleContext {
|
|
36
|
+
private registrationSink: string[] | undefined;
|
|
37
|
+
private readonly hoistedBases: Map<string, string> = new Map();
|
|
7
38
|
public module: ModuleBuilder = new ModuleBuilder();
|
|
8
39
|
public namespace: GirNamespace;
|
|
9
40
|
public library: Library;
|
|
41
|
+
public dependencies: Set<string> = new Set();
|
|
42
|
+
public externalDependencies: Set<string> = new Set();
|
|
43
|
+
public bootstrapCalls: string[] = [];
|
|
44
|
+
public bootstrapModuleExports: Set<string> = new Set();
|
|
45
|
+
public bootstrapRuntimeImports: Set<string> = new Set();
|
|
10
46
|
|
|
11
47
|
constructor(namespace: GirNamespace, library: Library) {
|
|
12
48
|
this.namespace = namespace;
|
|
13
49
|
this.library = library;
|
|
14
50
|
}
|
|
15
51
|
|
|
52
|
+
get isTreeShaken(): boolean {
|
|
53
|
+
return this.library.isTreeShaken;
|
|
54
|
+
}
|
|
55
|
+
|
|
16
56
|
addRuntimeImport(name: string): void {
|
|
17
57
|
this.module.imports.addNamed("@gtkx/runtime", name);
|
|
18
58
|
}
|
|
@@ -25,7 +65,47 @@ class ModuleContext {
|
|
|
25
65
|
return this.module.hoistDescriptor(expression);
|
|
26
66
|
}
|
|
27
67
|
|
|
68
|
+
beginRegistrations(): void {
|
|
69
|
+
this.registrationSink = [];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
takeRegistrations(): string[] {
|
|
73
|
+
const collected = this.registrationSink ?? [];
|
|
74
|
+
this.registrationSink = undefined;
|
|
75
|
+
|
|
76
|
+
return collected;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
collectRegistration(code: string, requires: string[] = []): void {
|
|
80
|
+
if (this.registrationSink === undefined) {
|
|
81
|
+
this.module.appendRegistration(code, requires);
|
|
82
|
+
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.registrationSink.push(code);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
addBootstrapCall(code: string, options: BootstrapCallOptions = {}): void {
|
|
90
|
+
const moduleExports = options.moduleExports ?? [];
|
|
91
|
+
const runtimeImports = options.runtimeImports ?? [];
|
|
92
|
+
|
|
93
|
+
for (const name of moduleExports) {
|
|
94
|
+
this.bootstrapModuleExports.add(name);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const name of runtimeImports) {
|
|
98
|
+
this.bootstrapRuntimeImports.add(name);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.bootstrapCalls.push(code);
|
|
102
|
+
}
|
|
103
|
+
|
|
28
104
|
addGObjectBootstrapImports(): void {
|
|
105
|
+
if (this.isTreeShaken) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
29
109
|
if (this.namespace.name === "GObject") {
|
|
30
110
|
return;
|
|
31
111
|
}
|
|
@@ -46,33 +126,23 @@ class ModuleContext {
|
|
|
46
126
|
|
|
47
127
|
const packageName = externalPackageFor(namespaceName);
|
|
48
128
|
|
|
49
|
-
if (packageName
|
|
50
|
-
this
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return namespaceName;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const directory = namespaceName.toLowerCase();
|
|
57
|
-
const isFoundational = directory === "gobject" || directory === "glib";
|
|
58
|
-
const path = isFoundational ? `../${directory}/${directory}.js` : `../${directory}/index.js`;
|
|
59
|
-
|
|
60
|
-
if (!isFoundational) {
|
|
61
|
-
this.module.imports.addSideEffect(path);
|
|
129
|
+
if (packageName === undefined) {
|
|
130
|
+
addInternalNamespaceImport(this, namespaceName);
|
|
131
|
+
} else {
|
|
132
|
+
addExternalNamespaceImport(this, packageName, namespaceName);
|
|
62
133
|
}
|
|
63
134
|
|
|
64
|
-
this.module.imports.addNamespace(path, namespaceName);
|
|
65
|
-
|
|
66
135
|
return namespaceName;
|
|
67
136
|
}
|
|
68
137
|
|
|
69
138
|
declare(declaration: Declaration): void {
|
|
70
|
-
const { name, code, owner } = declaration;
|
|
139
|
+
const { name, code, owner, isLocal } = declaration;
|
|
71
140
|
|
|
72
141
|
this.module.appendDeclaration({
|
|
73
142
|
name,
|
|
74
143
|
code,
|
|
75
144
|
owner: owner === undefined ? undefined : `${this.namespace.name}.${owner}`,
|
|
145
|
+
isLocal,
|
|
76
146
|
});
|
|
77
147
|
}
|
|
78
148
|
|
|
@@ -83,6 +153,29 @@ class ModuleContext {
|
|
|
83
153
|
|
|
84
154
|
return `${this.addCrossNamespaceImport(namespaceName)}.${name}`;
|
|
85
155
|
}
|
|
156
|
+
|
|
157
|
+
hoistBaseRef(expression: string): string {
|
|
158
|
+
if (!expression.includes(".")) {
|
|
159
|
+
return expression;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const existing = this.hoistedBases.get(expression);
|
|
163
|
+
|
|
164
|
+
if (existing !== undefined) {
|
|
165
|
+
return existing;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const local = `_${expression.replaceAll(".", "_")}`;
|
|
169
|
+
this.hoistedBases.set(expression, local);
|
|
170
|
+
|
|
171
|
+
this.module.appendDeclaration({
|
|
172
|
+
name: local,
|
|
173
|
+
code: `const ${local}: typeof ${expression} = ${expression};`,
|
|
174
|
+
isLocal: true,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return local;
|
|
178
|
+
}
|
|
86
179
|
}
|
|
87
180
|
|
|
88
181
|
export { ModuleContext };
|
package/src/writer/emit.ts
CHANGED
|
@@ -32,4 +32,6 @@ const arrayLiteral = (elements: string[]): string => {
|
|
|
32
32
|
return `[\n${lines.join("\n")}\n]`;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
const pure = (expression: string): string => `/* @__PURE__ */ ${expression}`;
|
|
36
|
+
|
|
37
|
+
export { indent, renderBlock, renderBraced, renderBracedOrEmpty, indentMembers, joinArgs, arrayLiteral, pure };
|
package/src/writer/imports.ts
CHANGED
|
@@ -62,8 +62,16 @@ class ImportsBuilder {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
addNamespace(specifier: string, alias: string, isType = false): void {
|
|
65
|
-
|
|
65
|
+
const existing = this.namespaces.get(specifier);
|
|
66
|
+
|
|
67
|
+
if (existing === undefined) {
|
|
66
68
|
this.namespaces.set(specifier, { alias, isType });
|
|
69
|
+
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!isType && existing.isType) {
|
|
74
|
+
existing.isType = false;
|
|
67
75
|
}
|
|
68
76
|
}
|
|
69
77
|
|
package/src/writer/module.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { pure } from "./emit.js";
|
|
1
2
|
import { ImportsBuilder } from "./imports.js";
|
|
2
3
|
|
|
3
4
|
type Declaration = {
|
|
4
5
|
name: string;
|
|
5
6
|
code: string;
|
|
6
7
|
owner?: string | undefined;
|
|
8
|
+
isLocal?: boolean | undefined;
|
|
7
9
|
};
|
|
8
10
|
|
|
9
11
|
type ExportedDeclaration = {
|
|
@@ -127,12 +129,18 @@ class ModuleBuilder {
|
|
|
127
129
|
|
|
128
130
|
const name = `_desc${String(this.hoistedDescriptors.size)}`;
|
|
129
131
|
this.hoistedDescriptors.set(expression, name);
|
|
130
|
-
this.appendBinding(`const ${name} = ${expression};`, name);
|
|
132
|
+
this.appendBinding(`const ${name} = ${pure(expression)};`, name);
|
|
131
133
|
|
|
132
134
|
return name;
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
appendDeclaration(declaration: Declaration): void {
|
|
138
|
+
if (declaration.isLocal === true) {
|
|
139
|
+
this.declarations.push(declaration.code);
|
|
140
|
+
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
136
144
|
this.claimExportedName(declaration);
|
|
137
145
|
this.claimTypeName(declaration);
|
|
138
146
|
this.declaredNames.add(declaration.name);
|