@deck.gl-community/graph-layers 9.2.0-beta.5 → 9.2.0-beta.8

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 (44) hide show
  1. package/dist/core/graph-engine.d.ts +3 -2
  2. package/dist/core/graph-engine.d.ts.map +1 -1
  3. package/dist/core/graph-engine.js +1 -0
  4. package/dist/core/graph-engine.js.map +1 -1
  5. package/dist/graph-style-schema.cdn.js +1 -1
  6. package/dist/graph-style-schema.json +1 -1
  7. package/dist/index.cjs +307 -202
  8. package/dist/index.cjs.map +4 -4
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/layers/edge-attachment-helper.d.ts.map +1 -1
  13. package/dist/layers/edge-attachment-helper.js.map +1 -1
  14. package/dist/layers/graph-layer.d.ts +4 -3
  15. package/dist/layers/graph-layer.d.ts.map +1 -1
  16. package/dist/layers/graph-layer.js +11 -6
  17. package/dist/layers/graph-layer.js.map +1 -1
  18. package/dist/loaders/dot-graph-loader.js +1 -1
  19. package/dist/loaders/json-graph-loader.js +1 -1
  20. package/dist/style/graph-layer-stylesheet.d.ts +14 -5
  21. package/dist/style/graph-layer-stylesheet.d.ts.map +1 -1
  22. package/dist/style/graph-layer-stylesheet.js +9 -3
  23. package/dist/style/graph-layer-stylesheet.js.map +1 -1
  24. package/dist/style/graph-style-engine.d.ts +4 -4
  25. package/dist/style/graph-style-engine.d.ts.map +1 -1
  26. package/dist/style/graph-style-engine.js +4 -4
  27. package/dist/style/graph-style-engine.js.map +1 -1
  28. package/dist/style/graph-stylesheet-schema.d.ts +13211 -0
  29. package/dist/style/graph-stylesheet-schema.d.ts.map +1 -0
  30. package/dist/style/graph-stylesheet-schema.js +354 -0
  31. package/dist/style/graph-stylesheet-schema.js.map +1 -0
  32. package/package.json +2 -2
  33. package/src/core/graph-engine.ts +7 -2
  34. package/src/index.ts +2 -1
  35. package/src/layers/edge-attachment-helper.ts +2 -5
  36. package/src/layers/graph-layer.ts +25 -19
  37. package/src/style/graph-layer-stylesheet.ts +16 -9
  38. package/src/style/graph-style-engine.ts +21 -13
  39. package/src/style/graph-stylesheet-schema.ts +538 -0
  40. package/dist/style/graph-stylesheet.schema.d.ts +0 -311
  41. package/dist/style/graph-stylesheet.schema.d.ts.map +0 -1
  42. package/dist/style/graph-stylesheet.schema.js +0 -238
  43. package/dist/style/graph-stylesheet.schema.js.map +0 -1
  44. package/src/style/graph-stylesheet.schema.ts +0 -344
@@ -0,0 +1,538 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ /* eslint-disable no-continue */
6
+
7
+ import {z, type ZodTypeAny} from 'zod';
8
+
9
+ import {GRAPH_DECKGL_ACCESSOR_MAP} from './graph-style-accessor-map';
10
+ export {GRAPH_DECKGL_ACCESSOR_MAP};
11
+
12
+ const GraphStylePrimitiveSchema = z.union([
13
+ z.string(),
14
+ z.number(),
15
+ z.boolean(),
16
+ z.null(),
17
+ z.array(z.union([z.string(), z.number(), z.boolean(), z.null()]))
18
+ ]);
19
+
20
+ const GraphStyleFunctionSchema = z.custom<(...args: unknown[]) => unknown>(
21
+ (value) => typeof value === 'function',
22
+ {
23
+ message: 'Style functions must be callable.'
24
+ }
25
+ );
26
+
27
+ /**
28
+ * Supported scale identifiers for mapping data values to visual encodings.
29
+ */
30
+ export const GraphStyleScaleTypeEnum = z.enum([
31
+ 'linear',
32
+ 'log',
33
+ 'pow',
34
+ 'sqrt',
35
+ 'quantize',
36
+ 'quantile',
37
+ 'ordinal'
38
+ ]);
39
+
40
+ /**
41
+ * TypeScript union of {@link GraphStyleScaleTypeEnum} values.
42
+ */
43
+ export type GraphStyleScaleType = z.infer<typeof GraphStyleScaleTypeEnum>;
44
+
45
+ /**
46
+ * Configuration for data-driven style scaling. Supports deck.gl compatible numeric and
47
+ * categorical scaling with optional d3-scale like parameters.
48
+ */
49
+ export const GraphStyleScaleSchema = z
50
+ .object({
51
+ type: GraphStyleScaleTypeEnum.optional(),
52
+ domain: z.array(z.union([z.number(), z.string()])).optional(),
53
+ range: z.array(z.any()).optional(),
54
+ clamp: z.boolean().optional(),
55
+ nice: z.union([z.boolean(), z.number()]).optional(),
56
+ base: z.number().optional(),
57
+ exponent: z.number().optional(),
58
+ unknown: z.any().optional()
59
+ })
60
+ .strict();
61
+
62
+ /**
63
+ * TypeScript view of {@link GraphStyleScaleSchema} after parsing.
64
+ */
65
+ export type GraphStyleScale = z.infer<typeof GraphStyleScaleSchema>;
66
+
67
+ /**
68
+ * Reference to node/edge attributes, optionally including fallback values and scale
69
+ * configuration for data-driven styling.
70
+ */
71
+ export const GraphStyleAttributeReferenceSchema = z.union([
72
+ z
73
+ .string()
74
+ .regex(/^@.+/, 'Attribute reference strings must start with "@" and include an attribute name.'),
75
+ z
76
+ .object({
77
+ attribute: z.string().min(1, 'Attribute name is required.'),
78
+ fallback: GraphStylePrimitiveSchema.optional(),
79
+ scale: z.union([GraphStyleScaleSchema, GraphStyleFunctionSchema]).optional()
80
+ })
81
+ .strict()
82
+ ]);
83
+
84
+ /**
85
+ * Parsed value produced by {@link GraphStyleAttributeReferenceSchema}.
86
+ */
87
+ export type GraphStyleAttributeReference = z.infer<typeof GraphStyleAttributeReferenceSchema>;
88
+
89
+ /**
90
+ * Primitive value allowed in stylesheet definitions. Supports literal values, attribute
91
+ * references and imperative resolver functions.
92
+ */
93
+ export const GraphStyleLeafValueSchema = z.union([
94
+ GraphStylePrimitiveSchema,
95
+ GraphStyleAttributeReferenceSchema,
96
+ GraphStyleFunctionSchema
97
+ ]);
98
+
99
+ /**
100
+ * Union of literal, attribute-driven and functional style values.
101
+ */
102
+ export type GraphStyleLeafValue = z.infer<typeof GraphStyleLeafValueSchema>;
103
+
104
+ const RESERVED_STATE_KEYS = new Set(['attribute', 'fallback', 'scale']);
105
+
106
+ /**
107
+ * Mapping of interaction or application state keys to leaf style values.
108
+ */
109
+ export const GraphStyleStateMapSchema = z.record(
110
+ z
111
+ .string()
112
+ .refine((key) => !RESERVED_STATE_KEYS.has(key), 'State overrides must not use reserved keys.'),
113
+ GraphStyleLeafValueSchema
114
+ );
115
+
116
+ /**
117
+ * Style value that may be either a simple leaf value or a keyed map of overrides.
118
+ */
119
+ export const GraphStyleValueSchema = z.union([
120
+ GraphStyleLeafValueSchema,
121
+ GraphStyleStateMapSchema
122
+ ]);
123
+
124
+ /**
125
+ * Parsed style property value that may include state overrides.
126
+ */
127
+ export type GraphStyleValue = z.infer<typeof GraphStyleValueSchema>;
128
+
129
+
130
+ export type GraphStyleType = keyof typeof GRAPH_DECKGL_ACCESSOR_MAP;
131
+
132
+ /**
133
+ * CSS-like pseudo selector supported by the stylesheet for state overrides.
134
+ */
135
+ export type GraphStyleSelector = `:${string}`;
136
+
137
+ const GraphStyleSelectorKeySchema = z.string().regex(/^:[^\s]+/, 'Selectors must start with ":".');
138
+
139
+ function createSelectorRefinement(
140
+ allowedKeys: readonly string[],
141
+ propertiesSchema: ZodTypeAny
142
+ ) {
143
+ const allowedKeySet = new Set<string>(allowedKeys);
144
+
145
+ return (value: unknown, ctx: z.RefinementCtx) => {
146
+ if (typeof value !== 'object' || value === null) {
147
+ return;
148
+ }
149
+
150
+ const record = value as Record<string, unknown>;
151
+
152
+ for (const key of Object.keys(record)) {
153
+ if (key === 'type') continue;
154
+ if (allowedKeySet.has(key)) continue;
155
+
156
+ if (!key.startsWith(':')) {
157
+ ctx.addIssue({
158
+ code: z.ZodIssueCode.custom,
159
+ path: [key],
160
+ message: `Unknown style property "${key}".`
161
+ });
162
+ continue;
163
+ }
164
+
165
+ if (!GraphStyleSelectorKeySchema.safeParse(key).success) {
166
+ ctx.addIssue({
167
+ code: z.ZodIssueCode.custom,
168
+ path: [key],
169
+ message: 'Selectors must start with ":".'
170
+ });
171
+ continue;
172
+ }
173
+
174
+ const selectorResult = propertiesSchema.safeParse(record[key]);
175
+ if (!selectorResult.success) {
176
+ for (const issue of selectorResult.error.issues) {
177
+ ctx.addIssue({
178
+ ...issue,
179
+ path: [key, ...(issue.path ?? [])]
180
+ });
181
+ }
182
+ }
183
+ }
184
+ };
185
+ }
186
+
187
+ const CircleShape = {
188
+ offset: GraphStyleValueSchema.optional(),
189
+ opacity: GraphStyleValueSchema.optional(),
190
+ fill: GraphStyleValueSchema.optional(),
191
+ stroke: GraphStyleValueSchema.optional(),
192
+ strokeWidth: GraphStyleValueSchema.optional(),
193
+ radius: GraphStyleValueSchema.optional()
194
+ } as const;
195
+
196
+ const CirclePropertiesSchema = z.object(CircleShape).partial().strict();
197
+
198
+ const CircleStylesheetSchema = z
199
+ .object({
200
+ type: z.literal('circle'),
201
+ ...CircleShape
202
+ })
203
+ .catchall(z.unknown())
204
+ .superRefine(
205
+ createSelectorRefinement(Object.keys(CircleShape), CirclePropertiesSchema)
206
+ );
207
+
208
+ const RectangleShape = {
209
+ offset: GraphStyleValueSchema.optional(),
210
+ opacity: GraphStyleValueSchema.optional(),
211
+ width: GraphStyleValueSchema.optional(),
212
+ height: GraphStyleValueSchema.optional(),
213
+ fill: GraphStyleValueSchema.optional(),
214
+ stroke: GraphStyleValueSchema.optional(),
215
+ strokeWidth: GraphStyleValueSchema.optional()
216
+ } as const;
217
+
218
+ const RectanglePropertiesSchema = z.object(RectangleShape).partial().strict();
219
+
220
+ const RectangleStylesheetSchema = z
221
+ .object({
222
+ type: z.literal('rectangle'),
223
+ ...RectangleShape
224
+ })
225
+ .catchall(z.unknown())
226
+ .superRefine(
227
+ createSelectorRefinement(
228
+ Object.keys(RectangleShape),
229
+ RectanglePropertiesSchema
230
+ )
231
+ );
232
+
233
+ const RoundedRectangleShape = {
234
+ offset: GraphStyleValueSchema.optional(),
235
+ opacity: GraphStyleValueSchema.optional(),
236
+ cornerRadius: GraphStyleValueSchema.optional(),
237
+ radius: GraphStyleValueSchema.optional(),
238
+ width: GraphStyleValueSchema.optional(),
239
+ height: GraphStyleValueSchema.optional(),
240
+ fill: GraphStyleValueSchema.optional(),
241
+ stroke: GraphStyleValueSchema.optional(),
242
+ strokeWidth: GraphStyleValueSchema.optional()
243
+ } as const;
244
+
245
+ const RoundedRectanglePropertiesSchema = z
246
+ .object(RoundedRectangleShape)
247
+ .partial()
248
+ .strict();
249
+
250
+ const RoundedRectangleStylesheetSchema = z
251
+ .object({
252
+ type: z.literal('rounded-rectangle'),
253
+ ...RoundedRectangleShape
254
+ })
255
+ .catchall(z.unknown())
256
+ .superRefine(
257
+ createSelectorRefinement(
258
+ Object.keys(RoundedRectangleShape),
259
+ RoundedRectanglePropertiesSchema
260
+ )
261
+ );
262
+
263
+ const PathRoundedRectangleShape = {
264
+ offset: GraphStyleValueSchema.optional(),
265
+ opacity: GraphStyleValueSchema.optional(),
266
+ width: GraphStyleValueSchema.optional(),
267
+ height: GraphStyleValueSchema.optional(),
268
+ fill: GraphStyleValueSchema.optional(),
269
+ stroke: GraphStyleValueSchema.optional(),
270
+ strokeWidth: GraphStyleValueSchema.optional(),
271
+ cornerRadius: GraphStyleValueSchema.optional()
272
+ } as const;
273
+
274
+ const PathRoundedRectanglePropertiesSchema = z
275
+ .object(PathRoundedRectangleShape)
276
+ .partial()
277
+ .strict();
278
+
279
+ const PathRoundedRectangleStylesheetSchema = z
280
+ .object({
281
+ type: z.literal('path-rounded-rectangle'),
282
+ ...PathRoundedRectangleShape
283
+ })
284
+ .catchall(z.unknown())
285
+ .superRefine(
286
+ createSelectorRefinement(
287
+ Object.keys(PathRoundedRectangleShape),
288
+ PathRoundedRectanglePropertiesSchema
289
+ )
290
+ );
291
+
292
+ const LabelShape = {
293
+ offset: GraphStyleValueSchema.optional(),
294
+ opacity: GraphStyleValueSchema.optional(),
295
+ color: GraphStyleValueSchema.optional(),
296
+ text: GraphStyleValueSchema.optional(),
297
+ fontSize: GraphStyleValueSchema.optional(),
298
+ textAnchor: GraphStyleValueSchema.optional(),
299
+ alignmentBaseline: GraphStyleValueSchema.optional(),
300
+ angle: GraphStyleValueSchema.optional(),
301
+ scaleWithZoom: GraphStyleValueSchema.optional(),
302
+ textMaxWidth: GraphStyleValueSchema.optional(),
303
+ textWordBreak: GraphStyleValueSchema.optional(),
304
+ textSizeMinPixels: GraphStyleValueSchema.optional()
305
+ } as const;
306
+
307
+ const LabelPropertiesSchema = z.object(LabelShape).partial().strict();
308
+
309
+ const LabelStylesheetSchema = z
310
+ .object({
311
+ type: z.literal('label'),
312
+ ...LabelShape
313
+ })
314
+ .catchall(z.unknown())
315
+ .superRefine(
316
+ createSelectorRefinement(Object.keys(LabelShape), LabelPropertiesSchema)
317
+ );
318
+
319
+ const MarkerShape = {
320
+ offset: GraphStyleValueSchema.optional(),
321
+ opacity: GraphStyleValueSchema.optional(),
322
+ fill: GraphStyleValueSchema.optional(),
323
+ size: GraphStyleValueSchema.optional(),
324
+ marker: GraphStyleValueSchema.optional(),
325
+ scaleWithZoom: GraphStyleValueSchema.optional()
326
+ } as const;
327
+
328
+ const MarkerPropertiesSchema = z.object(MarkerShape).partial().strict();
329
+
330
+ const MarkerStylesheetSchema = z
331
+ .object({
332
+ type: z.literal('marker'),
333
+ ...MarkerShape
334
+ })
335
+ .catchall(z.unknown())
336
+ .superRefine(
337
+ createSelectorRefinement(Object.keys(MarkerShape), MarkerPropertiesSchema)
338
+ );
339
+
340
+ const EdgeUpperShape = {
341
+ stroke: GraphStyleValueSchema.optional(),
342
+ strokeWidth: GraphStyleValueSchema.optional()
343
+ } as const;
344
+
345
+ const EdgeUpperPropertiesSchema = z.object(EdgeUpperShape).partial().strict();
346
+
347
+ const EdgeUpperStylesheetSchema = z
348
+ .object({
349
+ type: z.literal('Edge'),
350
+ ...EdgeUpperShape
351
+ })
352
+ .catchall(z.unknown())
353
+ .superRefine(
354
+ createSelectorRefinement(
355
+ Object.keys(EdgeUpperShape),
356
+ EdgeUpperPropertiesSchema
357
+ )
358
+ );
359
+
360
+ const EdgeLowerShape = {
361
+ stroke: GraphStyleValueSchema.optional(),
362
+ strokeWidth: GraphStyleValueSchema.optional()
363
+ } as const;
364
+
365
+ const EdgeLowerPropertiesSchema = z.object(EdgeLowerShape).partial().strict();
366
+
367
+ const EdgeLowerStylesheetSchema = z
368
+ .object({
369
+ type: z.literal('edge'),
370
+ ...EdgeLowerShape
371
+ })
372
+ .catchall(z.unknown())
373
+ .superRefine(
374
+ createSelectorRefinement(
375
+ Object.keys(EdgeLowerShape),
376
+ EdgeLowerPropertiesSchema
377
+ )
378
+ );
379
+
380
+ const EdgeLabelShape = {
381
+ color: GraphStyleValueSchema.optional(),
382
+ text: GraphStyleValueSchema.optional(),
383
+ fontSize: GraphStyleValueSchema.optional(),
384
+ textAnchor: GraphStyleValueSchema.optional(),
385
+ alignmentBaseline: GraphStyleValueSchema.optional(),
386
+ scaleWithZoom: GraphStyleValueSchema.optional(),
387
+ textMaxWidth: GraphStyleValueSchema.optional(),
388
+ textWordBreak: GraphStyleValueSchema.optional(),
389
+ textSizeMinPixels: GraphStyleValueSchema.optional()
390
+ } as const;
391
+
392
+ const EdgeLabelPropertiesSchema = z.object(EdgeLabelShape).partial().strict();
393
+
394
+ const EdgeLabelStylesheetSchema = z
395
+ .object({
396
+ type: z.literal('edge-label'),
397
+ ...EdgeLabelShape
398
+ })
399
+ .catchall(z.unknown())
400
+ .superRefine(
401
+ createSelectorRefinement(
402
+ Object.keys(EdgeLabelShape),
403
+ EdgeLabelPropertiesSchema
404
+ )
405
+ );
406
+
407
+ const FlowShape = {
408
+ color: GraphStyleValueSchema.optional(),
409
+ width: GraphStyleValueSchema.optional(),
410
+ speed: GraphStyleValueSchema.optional(),
411
+ tailLength: GraphStyleValueSchema.optional()
412
+ } as const;
413
+
414
+ const FlowPropertiesSchema = z.object(FlowShape).partial().strict();
415
+
416
+ const FlowStylesheetSchema = z
417
+ .object({
418
+ type: z.literal('flow'),
419
+ ...FlowShape
420
+ })
421
+ .catchall(z.unknown())
422
+ .superRefine(
423
+ createSelectorRefinement(Object.keys(FlowShape), FlowPropertiesSchema)
424
+ );
425
+
426
+ const ArrowShape = {
427
+ color: GraphStyleValueSchema.optional(),
428
+ size: GraphStyleValueSchema.optional(),
429
+ offset: GraphStyleValueSchema.optional()
430
+ } as const;
431
+
432
+ const ArrowPropertiesSchema = z.object(ArrowShape).partial().strict();
433
+
434
+ const ArrowStylesheetSchema = z
435
+ .object({
436
+ type: z.literal('arrow'),
437
+ ...ArrowShape
438
+ })
439
+ .catchall(z.unknown())
440
+ .superRefine(
441
+ createSelectorRefinement(Object.keys(ArrowShape), ArrowPropertiesSchema)
442
+ );
443
+
444
+ const GraphNodeStylesheetVariants = [
445
+ CircleStylesheetSchema,
446
+ RectangleStylesheetSchema,
447
+ RoundedRectangleStylesheetSchema,
448
+ PathRoundedRectangleStylesheetSchema,
449
+ LabelStylesheetSchema,
450
+ MarkerStylesheetSchema
451
+ ];
452
+
453
+ const GraphEdgeStylesheetVariants = [
454
+ EdgeUpperStylesheetSchema,
455
+ EdgeLowerStylesheetSchema,
456
+ EdgeLabelStylesheetSchema,
457
+ FlowStylesheetSchema,
458
+ ArrowStylesheetSchema
459
+ ];
460
+
461
+ const GraphStyleRuleVariants = [
462
+ ...GraphNodeStylesheetVariants,
463
+ ...GraphEdgeStylesheetVariants
464
+ ];
465
+
466
+ type GraphStyleRuleVariantSchema = (typeof GraphStyleRuleVariants)[number];
467
+
468
+ /**
469
+ * Schema that validates stylesheet definitions for all graph style primitives.
470
+ */
471
+ export const GraphStyleRuleSchema = z.discriminatedUnion(
472
+ 'type',
473
+ GraphStyleRuleVariants as [
474
+ GraphStyleRuleVariantSchema,
475
+ ...GraphStyleRuleVariantSchema[]
476
+ ]
477
+ );
478
+
479
+ /**
480
+ * Runtime type accepted by {@link GraphStyleRuleSchema} before validation.
481
+ */
482
+ export type GraphStyleRule = z.input<typeof GraphStyleRuleSchema>;
483
+ /**
484
+ * Type returned by {@link GraphStyleRuleSchema} after successful parsing.
485
+ */
486
+ export type GraphStyleRuleParsed = z.infer<typeof GraphStyleRuleSchema>;
487
+
488
+ const GraphNodeStyleRuleSchema = z.discriminatedUnion(
489
+ 'type',
490
+ GraphNodeStylesheetVariants as [
491
+ (typeof GraphNodeStylesheetVariants)[number],
492
+ ...(typeof GraphNodeStylesheetVariants)[number][]
493
+ ]
494
+ );
495
+
496
+ const GraphEdgeDecoratorRuleSchema = z.discriminatedUnion(
497
+ 'type',
498
+ [EdgeLabelStylesheetSchema, FlowStylesheetSchema, ArrowStylesheetSchema] as [
499
+ typeof EdgeLabelStylesheetSchema,
500
+ typeof FlowStylesheetSchema,
501
+ typeof ArrowStylesheetSchema,
502
+ ...Array<
503
+ typeof EdgeLabelStylesheetSchema | typeof FlowStylesheetSchema | typeof ArrowStylesheetSchema
504
+ >
505
+ ]
506
+ );
507
+
508
+ const EdgeUpperWithDecoratorsSchema = EdgeUpperStylesheetSchema.safeExtend({
509
+ decorators: z.array(GraphEdgeDecoratorRuleSchema).optional()
510
+ });
511
+
512
+ const EdgeLowerWithDecoratorsSchema = EdgeLowerStylesheetSchema.safeExtend({
513
+ decorators: z.array(GraphEdgeDecoratorRuleSchema).optional()
514
+ });
515
+
516
+ const GraphEdgeRuleWithDecoratorsSchema = z.discriminatedUnion('type', [
517
+ EdgeUpperWithDecoratorsSchema,
518
+ EdgeLowerWithDecoratorsSchema
519
+ ] as [typeof EdgeUpperWithDecoratorsSchema, typeof EdgeLowerWithDecoratorsSchema]);
520
+
521
+ /**
522
+ * Schema that validates a full graph stylesheet including nodes, edges, and decorators.
523
+ */
524
+ export const GraphStylesheetSchema = z
525
+ .object({
526
+ nodes: z.array(GraphNodeStyleRuleSchema).optional(),
527
+ edges: z.array(GraphEdgeRuleWithDecoratorsSchema).optional()
528
+ })
529
+ .strict();
530
+
531
+ /**
532
+ * Runtime type accepted by {@link GraphStylesheetSchema} before validation.
533
+ */
534
+ export type GraphStylesheet = z.input<typeof GraphStylesheetSchema>;
535
+ /**
536
+ * Type returned by {@link GraphStylesheetSchema} after successful parsing.
537
+ */
538
+ export type GraphStylesheetParsed = z.infer<typeof GraphStylesheetSchema>;