@gtkx/config 0.21.0 → 1.0.0-rc.1

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 (77) hide show
  1. package/README.md +137 -82
  2. package/dist/config.d.ts +76 -35
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +76 -83
  5. package/dist/config.js.map +1 -1
  6. package/dist/element-props.d.ts +180 -0
  7. package/dist/element-props.d.ts.map +1 -0
  8. package/dist/element-props.js +154 -0
  9. package/dist/element-props.js.map +1 -0
  10. package/dist/index.d.ts +3 -10
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -8
  13. package/dist/index.js.map +1 -1
  14. package/dist/internal.d.ts +3 -0
  15. package/dist/internal.d.ts.map +1 -0
  16. package/dist/internal.js +3 -0
  17. package/dist/internal.js.map +1 -0
  18. package/dist/loader.d.ts +19 -15
  19. package/dist/loader.d.ts.map +1 -1
  20. package/dist/loader.js +25 -39
  21. package/dist/loader.js.map +1 -1
  22. package/dist/virtual.d.ts +2 -4
  23. package/dist/virtual.d.ts.map +1 -1
  24. package/dist/virtual.js +2 -14
  25. package/dist/virtual.js.map +1 -1
  26. package/dist/vite-plugin.d.ts +16 -0
  27. package/dist/vite-plugin.d.ts.map +1 -0
  28. package/dist/vite-plugin.js +32 -0
  29. package/dist/vite-plugin.js.map +1 -0
  30. package/env.d.ts +4 -22
  31. package/package.json +20 -7
  32. package/src/config.ts +134 -144
  33. package/src/element-props.ts +248 -0
  34. package/src/index.ts +14 -82
  35. package/src/internal.ts +2 -0
  36. package/src/loader.ts +36 -56
  37. package/src/virtual.ts +3 -32
  38. package/src/vite-plugin.ts +37 -0
  39. package/dist/bundled-modules.d.ts +0 -2
  40. package/dist/bundled-modules.d.ts.map +0 -1
  41. package/dist/bundled-modules.js +0 -2
  42. package/dist/bundled-modules.js.map +0 -1
  43. package/dist/data-dir.d.ts +0 -4
  44. package/dist/data-dir.d.ts.map +0 -1
  45. package/dist/data-dir.js +0 -37
  46. package/dist/data-dir.js.map +0 -1
  47. package/dist/plugin.d.ts +0 -9
  48. package/dist/plugin.d.ts.map +0 -1
  49. package/dist/plugin.js +0 -24
  50. package/dist/plugin.js.map +0 -1
  51. package/dist/runtime.d.ts +0 -22
  52. package/dist/runtime.d.ts.map +0 -1
  53. package/dist/runtime.js +0 -22
  54. package/dist/runtime.js.map +0 -1
  55. package/dist/table-rules-ir.d.ts +0 -36
  56. package/dist/table-rules-ir.d.ts.map +0 -1
  57. package/dist/table-rules-ir.js +0 -2
  58. package/dist/table-rules-ir.js.map +0 -1
  59. package/dist/table-schema.d.ts +0 -107
  60. package/dist/table-schema.d.ts.map +0 -1
  61. package/dist/table-schema.js +0 -199
  62. package/dist/table-schema.js.map +0 -1
  63. package/dist/validators.d.ts +0 -4
  64. package/dist/validators.d.ts.map +0 -1
  65. package/dist/validators.js +0 -10
  66. package/dist/validators.js.map +0 -1
  67. package/dist/wrapper-protocol.d.ts +0 -12
  68. package/dist/wrapper-protocol.d.ts.map +0 -1
  69. package/dist/wrapper-protocol.js +0 -12
  70. package/dist/wrapper-protocol.js.map +0 -1
  71. package/src/bundled-modules.ts +0 -1
  72. package/src/data-dir.ts +0 -39
  73. package/src/plugin.ts +0 -30
  74. package/src/table-rules-ir.ts +0 -42
  75. package/src/table-schema.ts +0 -342
  76. package/src/validators.ts +0 -15
  77. package/src/wrapper-protocol.ts +0 -21
@@ -1,342 +0,0 @@
1
- import { CAMEL_CASE_NAME_PATTERN, PASCAL_CASE_NAME_PATTERN, validateArrayOf } from "./validators.js";
2
-
3
- export type VerbArgs = "child" | "childName" | "null" | "prefixChild" | "prefixNull";
4
-
5
- export type DetachGuard = { side: "child" | "parent"; getter: string };
6
-
7
- export type MethodVerb = {
8
- kind: "method";
9
- attach: string;
10
- attachArgs: VerbArgs;
11
- detach: string;
12
- detachArgs: VerbArgs;
13
- detachGuard?: DetachGuard;
14
- };
15
-
16
- export type ContainerPropRow = {
17
- attach: string;
18
- attachArgs?: VerbArgs;
19
- detach?: string;
20
- detachArgs?: VerbArgs;
21
- detachGuard?: DetachGuard;
22
- };
23
-
24
- export type OrderedInsertVerb = {
25
- kind: "orderedInsert";
26
- attach: string;
27
- detach: string;
28
- collection: string;
29
- };
30
-
31
- export type AttachVerb = MethodVerb | OrderedInsertVerb;
32
-
33
- export type ElementMapRule = {
34
- child: string;
35
- parentType?: string;
36
- parentMethod?: string;
37
- verb: AttachVerb;
38
- };
39
-
40
- export type PresenceCondition = "defined" | "nonNull";
41
-
42
- export type CallArg = { kind: "item"; path?: string; fallback?: unknown } | { kind: "value"; value: unknown };
43
-
44
- export type CallStep = {
45
- method: string;
46
- args: CallArg[];
47
- when?: { path: string; is: PresenceCondition };
48
- };
49
-
50
- export type ConstructSetter = {
51
- method: string;
52
- path: string;
53
- when: PresenceCondition;
54
- };
55
-
56
- export type ConstructStep = {
57
- type: string;
58
- setters: ConstructSetter[];
59
- attach: string;
60
- };
61
-
62
- export type ArrayPropRow = {
63
- itemType: string;
64
- clear?: string;
65
- remove?: CallStep;
66
- add?: CallStep[];
67
- construct?: ConstructStep;
68
- set?: string;
69
- appendOnce?: boolean;
70
- };
71
-
72
- export type ObjectPropRow = {
73
- itemType: string;
74
- set: CallStep[];
75
- unset?: CallStep[];
76
- };
77
-
78
- export type VirtualPropRow = {
79
- type: string;
80
- setter: string;
81
- after?: string;
82
- };
83
-
84
- export type PerElementPropRows<Row> = Record<string, Record<string, Row>>;
85
-
86
- /**
87
- * Names of the child-attachment method shapes a GObject type can satisfy. Each
88
- * shape corresponds to a runtime method whose presence *and* signature (argument
89
- * arity, parameter types, nullability) `@gtkx/codegen` verifies against the GIR
90
- * model, so the reconciler can rely on the call shape instead of duck-typing the
91
- * method name alone.
92
- */
93
- export type AttachShape =
94
- | "append"
95
- | "add"
96
- | "setContent"
97
- | "setChild"
98
- | "getChild"
99
- | "remove"
100
- | "reorderChildAfter"
101
- | "insertChildAfter"
102
- | "insert"
103
- | "getFirstChild";
104
-
105
- /**
106
- * Maps a GLib type name to the verified {@link AttachShape}s its own methods
107
- * introduce. The reconciler resolves an instance's full shape set by unioning
108
- * the entries across its type-name chain and implemented interfaces.
109
- */
110
- export type AttachShapeTable = Record<string, AttachShape[]>;
111
-
112
- export type UserTableRows = {
113
- containerProps?: PerElementPropRows<ContainerPropRow> | undefined;
114
-
115
- arrayProps?: PerElementPropRows<ArrayPropRow> | undefined;
116
-
117
- objectProps?: PerElementPropRows<ObjectPropRow> | undefined;
118
-
119
- virtualProps?: PerElementPropRows<VirtualPropRow> | undefined;
120
-
121
- elementMap?: ElementMapRule[] | undefined;
122
- };
123
-
124
- const VERB_ARGS: VerbArgs[] = ["child", "childName", "null", "prefixChild", "prefixNull"];
125
- const PRESENCE_CONDITIONS: PresenceCondition[] = ["defined", "nonNull"];
126
-
127
- const fail = (path: string, message: string): never => {
128
- throw new Error(`gtkx.config.ts: invalid \`${path}\` — ${message}`);
129
- };
130
-
131
- const requireRecord = (value: unknown, path: string): Record<string, unknown> => {
132
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
133
- fail(path, "must be an object");
134
- }
135
- return value as Record<string, unknown>;
136
- };
137
-
138
- const requireTypeName = (value: unknown, path: string): void => {
139
- if (typeof value !== "string" || !PASCAL_CASE_NAME_PATTERN.test(value)) {
140
- fail(path, `must be a PascalCase GLib type name (e.g. "GtkWidget"), got "${String(value)}"`);
141
- }
142
- };
143
-
144
- const requireMethodName = (value: unknown, path: string): void => {
145
- if (typeof value !== "string" || !CAMEL_CASE_NAME_PATTERN.test(value)) {
146
- fail(path, `must be a camelCase method name (e.g. "addController"), got "${String(value)}"`);
147
- }
148
- };
149
-
150
- const requireFieldName = (value: unknown, path: string): void => {
151
- if (typeof value !== "string" || !CAMEL_CASE_NAME_PATTERN.test(value)) {
152
- fail(path, `must be a camelCase item field name (e.g. "iconName"), got "${String(value)}"`);
153
- }
154
- };
155
-
156
- const requireReactMemberName = (value: unknown, path: string, example: string): void => {
157
- if (typeof value !== "string" || !PASCAL_CASE_NAME_PATTERN.test(value)) {
158
- fail(path, `must be a PascalCase exported member of @gtkx/react (e.g. "${example}")`);
159
- }
160
- };
161
-
162
- const validateVerbArgs = (value: unknown, path: string): void => {
163
- if (!VERB_ARGS.includes(value as VerbArgs)) {
164
- fail(path, `must be one of ${VERB_ARGS.join(", ")}`);
165
- }
166
- };
167
-
168
- const validateDetachGuard = (value: unknown, path: string): void => {
169
- const guard = requireRecord(value, path);
170
- if (guard["side"] !== "child" && guard["side"] !== "parent") {
171
- fail(`${path}.side`, 'must be "child" or "parent"');
172
- }
173
- requireMethodName(guard["getter"], `${path}.getter`);
174
- };
175
-
176
- const validateMethodVerb = (verb: Record<string, unknown>, path: string): void => {
177
- requireMethodName(verb["attach"], `${path}.attach`);
178
- requireMethodName(verb["detach"], `${path}.detach`);
179
- validateVerbArgs(verb["attachArgs"], `${path}.attachArgs`);
180
- validateVerbArgs(verb["detachArgs"], `${path}.detachArgs`);
181
- if (verb["detachGuard"] !== undefined) validateDetachGuard(verb["detachGuard"], `${path}.detachGuard`);
182
- };
183
-
184
- const validateContainerPropRow = (value: unknown, path: string): void => {
185
- const row = requireRecord(value, path);
186
- requireMethodName(row["attach"], `${path}.attach`);
187
- if (row["attachArgs"] !== undefined) validateVerbArgs(row["attachArgs"], `${path}.attachArgs`);
188
- if (row["detach"] !== undefined) requireMethodName(row["detach"], `${path}.detach`);
189
- if (row["detachArgs"] !== undefined) validateVerbArgs(row["detachArgs"], `${path}.detachArgs`);
190
- if (row["detachGuard"] !== undefined) validateDetachGuard(row["detachGuard"], `${path}.detachGuard`);
191
- };
192
-
193
- export const validateContainerPropRows = (containerProps: unknown): void => {
194
- validatePropRowMap(containerProps, "containerProps", validateContainerPropRow);
195
- };
196
-
197
- const validateOrderedInsertVerb = (verb: Record<string, unknown>, path: string): void => {
198
- requireMethodName(verb["attach"], `${path}.attach`);
199
- requireMethodName(verb["detach"], `${path}.detach`);
200
- requireMethodName(verb["collection"], `${path}.collection`);
201
- };
202
-
203
- const validateVerb = (value: unknown, path: string): void => {
204
- const verb = requireRecord(value, path);
205
- if (verb["kind"] === "method") validateMethodVerb(verb, path);
206
- else if (verb["kind"] === "orderedInsert") validateOrderedInsertVerb(verb, path);
207
- else fail(`${path}.kind`, 'must be "method" or "orderedInsert"');
208
- };
209
-
210
- const validateElementMapRule = (value: unknown, path: string): void => {
211
- const rule = requireRecord(value, path);
212
- requireTypeName(rule["child"], `${path}.child`);
213
- if (rule["parentType"] === undefined && rule["parentMethod"] === undefined) {
214
- fail(path, "must declare `parentType` or `parentMethod`");
215
- }
216
- if (rule["parentType"] !== undefined) requireTypeName(rule["parentType"], `${path}.parentType`);
217
- if (rule["parentMethod"] !== undefined) requireMethodName(rule["parentMethod"], `${path}.parentMethod`);
218
- validateVerb(rule["verb"], `${path}.verb`);
219
- };
220
-
221
- export const validateElementMap = (elementMap: unknown): void => {
222
- if (elementMap === undefined) return;
223
- validateArrayOf(elementMap, "elementMap", validateElementMapRule, (path) =>
224
- fail(path, "must be an array of attach rules"),
225
- );
226
- };
227
-
228
- const validateWhen = (when: unknown, path: string): void => {
229
- if (when === undefined) return;
230
- const condition = requireRecord(when, path);
231
- requireFieldName(condition["path"], `${path}.path`);
232
- if (!PRESENCE_CONDITIONS.includes(condition["is"] as PresenceCondition)) {
233
- fail(`${path}.is`, `must be one of ${PRESENCE_CONDITIONS.join(", ")}`);
234
- }
235
- };
236
-
237
- const validateCallArg = (value: unknown, path: string): void => {
238
- const arg = requireRecord(value, path);
239
- if (arg["kind"] === "item") {
240
- if (arg["path"] !== undefined) requireFieldName(arg["path"], `${path}.path`);
241
- return;
242
- }
243
- if (arg["kind"] !== "value") fail(`${path}.kind`, 'must be "item" or "value"');
244
- };
245
-
246
- const validateCallStep = (value: unknown, path: string): void => {
247
- const step = requireRecord(value, path);
248
- requireMethodName(step["method"], `${path}.method`);
249
- validateArrayOf(step["args"], `${path}.args`, validateCallArg, (argsPath) => fail(argsPath, "must be an array"));
250
- validateWhen(step["when"], `${path}.when`);
251
- };
252
-
253
- const validateConstructSetter = (setter: unknown, setterPath: string): void => {
254
- const record = requireRecord(setter, setterPath);
255
- requireMethodName(record["method"], `${setterPath}.method`);
256
- requireFieldName(record["path"], `${setterPath}.path`);
257
- if (!PRESENCE_CONDITIONS.includes(record["when"] as PresenceCondition)) {
258
- fail(`${setterPath}.when`, `must be one of ${PRESENCE_CONDITIONS.join(", ")}`);
259
- }
260
- };
261
-
262
- const validateConstructStep = (value: unknown, path: string): void => {
263
- const step = requireRecord(value, path);
264
- requireTypeName(step["type"], `${path}.type`);
265
- requireMethodName(step["attach"], `${path}.attach`);
266
- validateArrayOf(step["setters"], `${path}.setters`, validateConstructSetter, (settersPath) =>
267
- fail(settersPath, "must be an array"),
268
- );
269
- };
270
-
271
- const validateArrayPropRow = (value: unknown, path: string): void => {
272
- const row = requireRecord(value, path);
273
- requireReactMemberName(row["itemType"], `${path}.itemType`, "ScaleMark");
274
- if (row["clear"] !== undefined) requireMethodName(row["clear"], `${path}.clear`);
275
- if (row["set"] !== undefined) requireMethodName(row["set"], `${path}.set`);
276
- if (row["appendOnce"] !== undefined && typeof row["appendOnce"] !== "boolean") {
277
- fail(`${path}.appendOnce`, "must be a boolean");
278
- }
279
- if (row["remove"] !== undefined) validateCallStep(row["remove"], `${path}.remove`);
280
- if (row["add"] !== undefined) {
281
- validateArrayOf(row["add"], `${path}.add`, validateCallStep, (addPath) =>
282
- fail(addPath, "must be an array of call steps"),
283
- );
284
- }
285
- if (row["construct"] !== undefined) validateConstructStep(row["construct"], `${path}.construct`);
286
- };
287
-
288
- export const validateArrayPropRows = (arrayProps: unknown): void => {
289
- validatePropRowMap(arrayProps, "arrayProps", validateArrayPropRow);
290
- };
291
-
292
- const validateObjectPropRow = (value: unknown, path: string): void => {
293
- const row = requireRecord(value, path);
294
- requireReactMemberName(row["itemType"], `${path}.itemType`, "DragSourceIcon");
295
- validateArrayOf(row["set"], `${path}.set`, validateCallStep, (setPath) =>
296
- fail(setPath, "must be an array of call steps"),
297
- );
298
- if (row["unset"] !== undefined) {
299
- validateArrayOf(row["unset"], `${path}.unset`, validateCallStep, (unsetPath) =>
300
- fail(unsetPath, "must be an array of call steps"),
301
- );
302
- }
303
- };
304
-
305
- export const validateObjectPropRows = (objectProps: unknown): void => {
306
- validatePropRowMap(objectProps, "objectProps", validateObjectPropRow);
307
- };
308
-
309
- const QUALIFIED_TYPE_PATTERN = /^[A-Z][A-Za-z0-9]*\.[A-Z][A-Za-z0-9]*$/;
310
-
311
- const validateVirtualPropRow = (value: unknown, path: string): void => {
312
- const row = requireRecord(value, path);
313
- if (typeof row["type"] !== "string" || !QUALIFIED_TYPE_PATTERN.test(row["type"])) {
314
- fail(`${path}.type`, `must be a qualified GIR type (e.g. "Gtk.DrawingAreaDrawFunc")`);
315
- }
316
- requireMethodName(row["setter"], `${path}.setter`);
317
- if (row["after"] !== undefined) requireMethodName(row["after"], `${path}.after`);
318
- };
319
-
320
- export const validateVirtualPropRows = (virtualProps: unknown): void => {
321
- validatePropRowMap(virtualProps, "virtualProps", validateVirtualPropRow);
322
- };
323
-
324
- const validatePropRowMap = (
325
- value: unknown,
326
- tableName: string,
327
- validateRow: (row: unknown, path: string) => void,
328
- ): void => {
329
- if (value === undefined) return;
330
- const map = requireRecord(value, tableName);
331
- for (const [jsxName, props] of Object.entries(map)) {
332
- requireTypeName(jsxName, `${tableName} key "${jsxName}"`);
333
- const propMap = requireRecord(props, `${tableName}.${jsxName}`);
334
- if (Object.keys(propMap).length === 0) {
335
- fail(`${tableName}.${jsxName}`, "must declare at least one prop");
336
- }
337
- for (const [propName, row] of Object.entries(propMap)) {
338
- requireMethodName(propName, `${tableName}.${jsxName} prop "${propName}"`);
339
- validateRow(row, `${tableName}.${jsxName}.${propName}`);
340
- }
341
- }
342
- };
package/src/validators.ts DELETED
@@ -1,15 +0,0 @@
1
- export const PASCAL_CASE_NAME_PATTERN: RegExp = /^[A-Z][A-Za-z0-9]*$/;
2
-
3
- export const CAMEL_CASE_NAME_PATTERN: RegExp = /^[a-z][A-Za-z0-9]*$/;
4
-
5
- export const validateArrayOf = (
6
- value: unknown,
7
- path: string,
8
- validateElement: (element: unknown, elementPath: string) => void,
9
- onNotArray: (path: string) => never,
10
- ): void => {
11
- if (!Array.isArray(value)) onNotArray(path);
12
- value.forEach((element, index) => {
13
- validateElement(element, `${path}[${index}]`);
14
- });
15
- };
@@ -1,21 +0,0 @@
1
- export const WRAPPER_NODE_ELEMENT = "__GTKX_WRAPPER_NODE__";
2
-
3
- export const META_OBJECT_KIND = "meta-object";
4
-
5
- export const LAYOUT_CHILD_KIND = "layout-child";
6
-
7
- export const OVERLAY_KIND = "overlay";
8
-
9
- export const TAB_LABEL_KIND = "tab-label";
10
-
11
- export const SLOT_KIND = "slot";
12
-
13
- export const CONTAINER_PROP_KIND = "container-slot";
14
-
15
- export const TEXT_ANCHOR_KIND = "text-anchor";
16
-
17
- export const TEXT_PAINTABLE_KIND = "text-paintable";
18
-
19
- export const BUFFER_TEXT_KIND = "text";
20
-
21
- export const LABEL_TEXT_KIND = "label-text";