@mapsight/vector-style-compiler 8.0.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.
Files changed (94) hide show
  1. package/README.md +366 -0
  2. package/bin/vector-style-compiler.js +2 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +83 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/cssToRules/mapDeclaration.d.ts +16 -0
  8. package/dist/cssToRules/mapDeclaration.d.ts.map +1 -0
  9. package/dist/cssToRules/mapDeclaration.js +24 -0
  10. package/dist/cssToRules/mapDeclaration.js.map +1 -0
  11. package/dist/cssToRules/mapRule.d.ts +41 -0
  12. package/dist/cssToRules/mapRule.d.ts.map +1 -0
  13. package/dist/cssToRules/mapRule.js +60 -0
  14. package/dist/cssToRules/mapRule.js.map +1 -0
  15. package/dist/cssToRules/mapSelector.d.ts +27 -0
  16. package/dist/cssToRules/mapSelector.d.ts.map +1 -0
  17. package/dist/cssToRules/mapSelector.js +61 -0
  18. package/dist/cssToRules/mapSelector.js.map +1 -0
  19. package/dist/cssToRules/mapSelectorPart.d.ts +48 -0
  20. package/dist/cssToRules/mapSelectorPart.d.ts.map +1 -0
  21. package/dist/cssToRules/mapSelectorPart.js +106 -0
  22. package/dist/cssToRules/mapSelectorPart.js.map +1 -0
  23. package/dist/cssToRules/mapValue.d.ts +20 -0
  24. package/dist/cssToRules/mapValue.d.ts.map +1 -0
  25. package/dist/cssToRules/mapValue.js +67 -0
  26. package/dist/cssToRules/mapValue.js.map +1 -0
  27. package/dist/cssToRules.d.ts +50 -0
  28. package/dist/cssToRules.d.ts.map +1 -0
  29. package/dist/cssToRules.js +32 -0
  30. package/dist/cssToRules.js.map +1 -0
  31. package/dist/helpers/Replacer.d.ts +11 -0
  32. package/dist/helpers/Replacer.d.ts.map +1 -0
  33. package/dist/helpers/Replacer.js +28 -0
  34. package/dist/helpers/Replacer.js.map +1 -0
  35. package/dist/helpers/compileDeclarationBlock.d.ts +14 -0
  36. package/dist/helpers/compileDeclarationBlock.d.ts.map +1 -0
  37. package/dist/helpers/compileDeclarationBlock.js +38 -0
  38. package/dist/helpers/compileDeclarationBlock.js.map +1 -0
  39. package/dist/helpers/createModulesMapFromDependencies.d.ts +5 -0
  40. package/dist/helpers/createModulesMapFromDependencies.d.ts.map +1 -0
  41. package/dist/helpers/createModulesMapFromDependencies.js +31 -0
  42. package/dist/helpers/createModulesMapFromDependencies.js.map +1 -0
  43. package/dist/helpers/ensureObject.d.ts +3 -0
  44. package/dist/helpers/ensureObject.d.ts.map +1 -0
  45. package/dist/helpers/ensureObject.js +12 -0
  46. package/dist/helpers/ensureObject.js.map +1 -0
  47. package/dist/helpers/pathToExpression.d.ts +2 -0
  48. package/dist/helpers/pathToExpression.d.ts.map +1 -0
  49. package/dist/helpers/pathToExpression.js +6 -0
  50. package/dist/helpers/pathToExpression.js.map +1 -0
  51. package/dist/helpers/uniqueSerialized.d.ts +2 -0
  52. package/dist/helpers/uniqueSerialized.d.ts.map +1 -0
  53. package/dist/helpers/uniqueSerialized.js +5 -0
  54. package/dist/helpers/uniqueSerialized.js.map +1 -0
  55. package/dist/index.d.ts +8 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +15 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/rulesToTree.d.ts +20 -0
  60. package/dist/rulesToTree.d.ts.map +1 -0
  61. package/dist/rulesToTree.js +43 -0
  62. package/dist/rulesToTree.js.map +1 -0
  63. package/dist/template.d.ts +16 -0
  64. package/dist/template.d.ts.map +1 -0
  65. package/dist/template.js +22 -0
  66. package/dist/template.js.map +1 -0
  67. package/dist/template.source.d.ts +3 -0
  68. package/dist/template.source.d.ts.map +1 -0
  69. package/dist/template.source.js +50 -0
  70. package/dist/template.source.js.map +1 -0
  71. package/dist/treeToProgram.d.ts +3 -0
  72. package/dist/treeToProgram.d.ts.map +1 -0
  73. package/dist/treeToProgram.js +158 -0
  74. package/dist/treeToProgram.js.map +1 -0
  75. package/package.json +67 -0
  76. package/src/data/custom-css-properties.json +200 -0
  77. package/src/js/cli.ts +98 -0
  78. package/src/js/cssToRules/mapDeclaration.ts +45 -0
  79. package/src/js/cssToRules/mapRule.ts +98 -0
  80. package/src/js/cssToRules/mapSelector.ts +78 -0
  81. package/src/js/cssToRules/mapSelectorPart.ts +161 -0
  82. package/src/js/cssToRules/mapValue.ts +84 -0
  83. package/src/js/cssToRules.ts +49 -0
  84. package/src/js/helpers/Replacer.ts +50 -0
  85. package/src/js/helpers/compileDeclarationBlock.ts +60 -0
  86. package/src/js/helpers/createModulesMapFromDependencies.ts +40 -0
  87. package/src/js/helpers/ensureObject.ts +17 -0
  88. package/src/js/helpers/pathToExpression.ts +5 -0
  89. package/src/js/helpers/uniqueSerialized.ts +7 -0
  90. package/src/js/index.ts +28 -0
  91. package/src/js/rulesToTree.ts +83 -0
  92. package/src/js/template.source.js +56 -0
  93. package/src/js/template.ts +50 -0
  94. package/src/js/treeToProgram.ts +220 -0
package/README.md ADDED
@@ -0,0 +1,366 @@
1
+ # Mapsight vector styles
2
+
3
+ Creates JavaScript-Code that can be used as a styleFunction in mapsight by
4
+ transforming a subset of CSS.
5
+
6
+ ## How it Works
7
+
8
+ The package compiles a CSS subset into a JavaScript module providing an efficient OpenLayers `styleFunction` with built-in caching.
9
+
10
+ ```
11
+ ┌─────────────────────────────────────────────────────────────────┐
12
+ │ DEVELOPER WORKFLOW │
13
+ ├─────────────────────────────────────────────────────────────────┤
14
+ │ │
15
+ │ Define styles in CSS subset (supports custom properties): │
16
+ │ │
17
+ │ * { fill-color: red; } │
18
+ │ #myStyle { circle-radius: 5; } │
19
+ │ :selected { stroke-color: green; } │
20
+ │ [state="hover"] { fill-color: orange; } │
21
+ │ │
22
+ └─────────────────────────────────────────────────────────────────┘
23
+
24
+ ┌─────────────────────────────────────────────────────────────────┐
25
+ │ COMPILE TIME (CSS → JavaScript) │
26
+ ├─────────────────────────────────────────────────────────────────┤
27
+ │ │
28
+ │ Input: CSS string │
29
+ │ Output: JavaScript function that renders to OL Styles │
30
+ │ │
31
+ │ Pipeline: │
32
+ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
33
+ │ │CSS String│→ │Parse to │→ │Build │→ │Generate │ │
34
+ │ │ │ │Rules │ │Tree │ │Code │ │
35
+ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
36
+ │ ↓ │
37
+ │ ┌──────────────┐ │
38
+ │ │Wrap in │ │
39
+ │ │Template: │ │
40
+ │ │ import OL │ │
41
+ │ │ import cache │ │
42
+ │ │ export fn │ │
43
+ │ └──────────────┘ │
44
+ │ ↓ │
45
+ │ Pre-compiled │
46
+ │ JavaScript Module │
47
+ │ │
48
+ └─────────────────────────────────────────────────────────────────┘
49
+
50
+ ┌─────────────────────────────────────────────────────────────────┐
51
+ │ RUNTIME (Features → OL Styles) │
52
+ ├─────────────────────────────────────────────────────────────────┤
53
+ │ │
54
+ │ Input: Feature (geometry + properties), Environment │
55
+ │ Output: Array of OL Style objects │
56
+ │ │
57
+ │ For each feature: │
58
+ │ │
59
+ │ 1. Filter feature properties │
60
+ │ 2. Compute hashes (env, props, geometry type) │
61
+ │ 3. Check 3-level LRU cache │
62
+ │ 4. Execute declarationFunction if cache miss │
63
+ │ 5. Build OL Style objects │
64
+ │ 6. Return styles │
65
+ │ │
66
+ └─────────────────────────────────────────────────────────────────┘
67
+ ```
68
+
69
+ ## Supported CSS Syntax
70
+
71
+ ### Supported Selector Types
72
+
73
+ ```css
74
+ /* Universal selector (any feature) */
75
+ * { ... }
76
+
77
+ /* Style selector (ID) */
78
+ #myStyleName { ... }
79
+
80
+ /* State selector (pseudo-class) */
81
+ ::selected { ... }
82
+ ::highlighted { ... }
83
+
84
+ /* Props selector (attribute) */
85
+ [state="hover"] { ... } /* Simple equality */
86
+ [props|name="Road"] { ... } /* Access nested props */
87
+ [geometry|type="Point"] { ... } /* Check geometry type */
88
+ [env|zoom="5"] { ... } /* Access environment */
89
+ [|js="props['id'] > 100"] { ... } /* JavaScript expression */
90
+
91
+ /* Negation */
92
+ :not([state="hover"]) { ... }
93
+ :not([geometry|type="LineString"]) { ... }
94
+
95
+ /* Combinations (space = AND) */
96
+ #myStyle [state="hover"] { ... } /* myStyle AND state==hover */
97
+ [geometry|type="Point"] .icon { ... } /* Geometry AND group */
98
+ ```
99
+
100
+ ### Property Examples
101
+
102
+ ```css
103
+ /* MapBox-like custom properties */
104
+ fill-color: red;
105
+ fill-color: attr(color); /* From props['color'] */
106
+ fill-color: attr(--env-primaryColor); /* From env['primaryColor'] */
107
+
108
+ circle-radius: 5;
109
+ circle-radius: calc(zoom * 2 + 3); /* JavaScript expression */
110
+
111
+ stroke-color: replace("pattern", "X", "attr(id)"); /* String replace */
112
+
113
+ text-text: attr(--env-title); /* Dynamic text */
114
+
115
+ /* Complex nested properties */
116
+ icon-src: "path/to/icon.png";
117
+ icon-sizex: 32;
118
+ icon-sizey: 32;
119
+ icon-offsetx: attr(offsetX);
120
+ ```
121
+
122
+ See full list of supported properties in [Custom CSS properties](#custom-css-properties).
123
+
124
+ ## Caching
125
+
126
+ High-level 3-level LRU caching strategy:
127
+
128
+ - **Level 1 (Coarse)**: env + geometry type + props (~95% hit, size 100)
129
+ - **Level 2 (Fine)**: declaration hashes (~92% hit, size 100)
130
+ - **Level 3**: OL Style objects (clone, ~98% hit, size 100)
131
+
132
+ **Example** (10k features, 50 styles, 10 zooms):
133
+
134
+ - 9500 L1 hits: instant
135
+ - 400 L1 miss → L2 hit: fast clone/construct
136
+ - 100 full execution
137
+
138
+ Average <1μs/feature, configurable sizes.
139
+
140
+ ## Docs
141
+
142
+ ### Custom CSS properties
143
+
144
+ <!-- CUSTOM_CSS_PROPERTIES_DOCS: -->
145
+
146
+ #### circle-fill-color
147
+
148
+ Description:
149
+
150
+ Since version: v0.0.0
151
+
152
+ #### circle-radius
153
+
154
+ Description:
155
+
156
+ Since version: v0.0.0
157
+
158
+ #### circle-stroke-color
159
+
160
+ Description:
161
+
162
+ Since version: v0.0.0
163
+
164
+ #### circle-stroke-width
165
+
166
+ Description:
167
+
168
+ Since version: v0.0.0
169
+
170
+ #### fill-color
171
+
172
+ Description:
173
+
174
+ Since version: v0.0.0
175
+
176
+ #### icon-anchorx
177
+
178
+ Description:
179
+
180
+ Since version: v0.0.0
181
+
182
+ #### icon-anchory
183
+
184
+ Description:
185
+
186
+ Since version: v0.0.0
187
+
188
+ #### icon-offsetx
189
+
190
+ Description:
191
+
192
+ Since version: v0.0.0
193
+
194
+ #### icon-offsety
195
+
196
+ Description:
197
+
198
+ Since version: v0.0.0
199
+
200
+ #### icon-opacity
201
+
202
+ Description:
203
+
204
+ Since version: v0.0.0
205
+
206
+ #### icon-scale
207
+
208
+ Description:
209
+
210
+ Since version: v0.0.0
211
+
212
+ #### icon-sizex
213
+
214
+ Description:
215
+
216
+ Since version: v0.0.0
217
+
218
+ #### icon-sizey
219
+
220
+ Description:
221
+
222
+ Since version: v0.0.0
223
+
224
+ #### icon-snaptopixel
225
+
226
+ Description:
227
+
228
+ Since version: v0.0.0
229
+
230
+ #### icon-src
231
+
232
+ Description:
233
+
234
+ Since version: v0.0.0
235
+
236
+ #### image-circle-fill-color
237
+
238
+ Description:
239
+
240
+ Since version: v0.0.0
241
+
242
+ #### image-circle-radius
243
+
244
+ Description:
245
+
246
+ Since version: v0.0.0
247
+
248
+ #### image-type
249
+
250
+ Description:
251
+
252
+ Since version: v0.0.0
253
+
254
+ #### stroke-color
255
+
256
+ Description:
257
+
258
+ Since version: v0.0.0
259
+
260
+ #### stroke-linedash
261
+
262
+ Description:
263
+
264
+ Since version: v0.0.0
265
+
266
+ #### text-alignment
267
+
268
+ Description:
269
+
270
+ Since version: v0.0.0
271
+
272
+ #### text-fill-color
273
+
274
+ Description:
275
+
276
+ Since version: v0.0.0
277
+
278
+ #### text-font
279
+
280
+ Description:
281
+
282
+ Since version: v0.0.0
283
+
284
+ #### text-offsetx
285
+
286
+ Description:
287
+
288
+ Since version: v0.0.0
289
+
290
+ #### text-offsety
291
+
292
+ Description:
293
+
294
+ Since version: v0.0.0
295
+
296
+ #### text-placement
297
+
298
+ Description:
299
+
300
+ Since version: v0.0.0
301
+
302
+ #### text-stroke-color
303
+
304
+ Description:
305
+
306
+ Since version: v0.0.0
307
+
308
+ #### text-stroke-width
309
+
310
+ Description:
311
+
312
+ Since version: v0.0.0
313
+
314
+ #### text-testalign
315
+
316
+ Description:
317
+
318
+ Since version: v0.0.0
319
+
320
+ #### text-text
321
+
322
+ Description:
323
+
324
+ Since version: v0.0.0
325
+
326
+ #### text-textalign
327
+
328
+ Description:
329
+
330
+ Since version: v0.0.0
331
+
332
+ #### text-textbaseline
333
+
334
+ Description:
335
+
336
+ Since version: v0.0.0
337
+
338
+ #### zindex
339
+
340
+ Description:
341
+
342
+ Since version: v0.0.0
343
+
344
+ <!-- :CUSTOM_CSS_PROPERTIES_DOCS -->
345
+
346
+ #### Adding the custom properties to WebStorm/PHPStorm/IntelliJ
347
+
348
+ Go to `Settings -> Editor -> Inspections` and search for `Unknown CSS property`. Then add the following string under `Options -> Custom CSS Properties`:
349
+
350
+ <code>
351
+
352
+ <!-- CUSTOM_CSS_PROPERTIES_LIST: -->
353
+
354
+ circle-fill-color,circle-radius,circle-stroke-color,circle-stroke-width,fill-color,icon-anchorx,icon-anchory,icon-offsetx,icon-offsety,icon-opacity,icon-scale,icon-sizex,icon-sizey,icon-snaptopixel,icon-src,image-circle-fill-color,image-circle-radius,image-type,stroke-color,stroke-linedash,text-alignment,text-fill-color,text-font,text-offsetx,text-offsety,text-placement,text-stroke-color,text-stroke-width,text-testalign,text-text,text-textalign,text-textbaseline,zindex<!-- :CUSTOM_CSS_PROPERTIES_LIST -->
355
+ </code>
356
+
357
+ ## Benchmarking
358
+
359
+ - `pnpm bench`
360
+ - Runs the canonical workload simulation benchmark across `nodejs`, `chromium`, `firefox`, and `webkit` via headless Playwright.
361
+ - Includes memory output for all engines (`nodejs` heap usage; browser memory via OS RSS sampling on the Playwright browser process using `pidusage`).
362
+ - Browser RSS is process-level memory (not JS-heap-only), so use it for trend/comparison signals.
363
+ - For stronger GC signal in Node, run with exposed GC:
364
+ - `NODE_OPTIONS=--expose-gc pnpm bench`
365
+ - You can increase run length / repeat count for more stable memory trends:
366
+ - `BENCH_WORKLOAD_ROUNDS=30 BENCH_WORKLOAD_TICKS=500 pnpm bench`
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "../dist/cli.js";
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/js/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,83 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parseArgs } from "node:util";
4
+ import { watch } from "chokidar";
5
+ import * as sass from "sass";
6
+ import vectorStyleCompiler from "./index.js";
7
+ const debounceAsync = (fn, delay) => {
8
+ let timer;
9
+ return () => {
10
+ clearTimeout(timer);
11
+ timer = setTimeout(() => {
12
+ fn().catch(console.error);
13
+ }, delay);
14
+ };
15
+ };
16
+ async function compile(input, opts) {
17
+ let css;
18
+ if (input.endsWith(".scss") || input.endsWith(".sass")) {
19
+ const result = sass.compile(input, {
20
+ loadPaths: [
21
+ "node_modules",
22
+ ...opts.include.map((p) => path.resolve(p)),
23
+ ],
24
+ style: "expanded",
25
+ quietDeps: true,
26
+ silenceDeprecations: ["legacy-js-api"],
27
+ sourceMap: false,
28
+ });
29
+ css = result.css.toString();
30
+ }
31
+ else {
32
+ css = await fs.readFile(input, "utf8");
33
+ }
34
+ const outDir = path.resolve(opts.output);
35
+ const cssPath = path.join(outDir, `${opts.name}.css`);
36
+ const jsPath = path.join(outDir, `${opts.name}.js`);
37
+ await fs.mkdir(outDir, { recursive: true });
38
+ await fs.writeFile(cssPath, css);
39
+ const js = vectorStyleCompiler(css);
40
+ await fs.writeFile(jsPath, js);
41
+ console.log(`Updated: ${cssPath}, ${jsPath}`);
42
+ }
43
+ const { values, positionals } = parseArgs({
44
+ options: {
45
+ output: {
46
+ type: "string",
47
+ short: "o",
48
+ default: "tmp/mapsight-vector-styles",
49
+ },
50
+ name: {
51
+ type: "string",
52
+ short: "n",
53
+ default: "default",
54
+ },
55
+ include: {
56
+ type: "string",
57
+ short: "i",
58
+ default: "node_modules",
59
+ },
60
+ watch: {
61
+ type: "boolean",
62
+ default: false,
63
+ },
64
+ },
65
+ allowPositionals: true,
66
+ });
67
+ const input = positionals[0];
68
+ if (!input) {
69
+ throw new Error("input SCSS or CSS file is required");
70
+ }
71
+ const options = {
72
+ output: values.output,
73
+ name: values.name,
74
+ include: values.include.split(","),
75
+ watch: values.watch,
76
+ };
77
+ await compile(input, options);
78
+ if (options.watch) {
79
+ const debouncedCompile = debounceAsync(() => compile(input, options), 300);
80
+ watch(input).on("change", debouncedCompile);
81
+ console.log(`Watching ${input}...`);
82
+ }
83
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/js/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Declaration as CssDeclaration } from "css";
2
+ import mapValue from "./mapValue.ts";
3
+ export type DeclarationLeaf = {
4
+ value: string | number | null;
5
+ };
6
+ export interface DeclarationNode {
7
+ [key: string]: DeclarationNode | DeclarationLeaf;
8
+ }
9
+ export type Declaration = {
10
+ declaration: DeclarationNode;
11
+ __meta: ReturnType<typeof mapValue>["__meta"] & {
12
+ name: string;
13
+ };
14
+ };
15
+ export default function mapDeclaration(declaration: CssDeclaration): Declaration;
16
+ //# sourceMappingURL=mapDeclaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapDeclaration.d.ts","sourceRoot":"","sources":["../../src/js/cssToRules/mapDeclaration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,IAAI,cAAc,EAAC,MAAM,KAAK,CAAC;AAEvD,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,MAAM,eAAe,GAAG;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAC,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,eAAe,CAAC;CACjD;AAED,MAAM,MAAM,WAAW,GAAG;IACzB,WAAW,EAAE,eAAe,CAAC;IAC7B,MAAM,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG;QAC/C,IAAI,EAAE,MAAM,CAAC;KACb,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,cAAc,CACrC,WAAW,EAAE,cAAc,GACzB,WAAW,CAyBb"}
@@ -0,0 +1,24 @@
1
+ import mapValue from "./mapValue.js";
2
+ export default function mapDeclaration(declaration) {
3
+ const { value, __meta: valueMeta } = mapValue(declaration.value);
4
+ if (!declaration.property) {
5
+ throw new Error("Declaration is lacking property");
6
+ }
7
+ const keyParts = declaration.property.split("-");
8
+ // build deep object
9
+ const result = {};
10
+ let current = result;
11
+ for (let i = 0; i < keyParts.length - 1; i++) {
12
+ const part = keyParts[i];
13
+ const next = {};
14
+ current[part] = next;
15
+ current = next;
16
+ }
17
+ const lastPart = keyParts[keyParts.length - 1];
18
+ current[lastPart] = { value };
19
+ return {
20
+ declaration: result,
21
+ __meta: { name: keyParts[0], ...valueMeta },
22
+ };
23
+ }
24
+ //# sourceMappingURL=mapDeclaration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapDeclaration.js","sourceRoot":"","sources":["../../src/js/cssToRules/mapDeclaration.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAerC,MAAM,CAAC,OAAO,UAAU,cAAc,CACrC,WAA2B;IAE3B,MAAM,EAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAE/D,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEjD,oBAAoB;IACpB,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,IAAI,OAAO,GAAoB,MAAM,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;QAC1B,MAAM,IAAI,GAAoB,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACrB,OAAO,GAAG,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;IAChD,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAC,KAAK,EAAC,CAAC;IAE5B,OAAO;QACN,WAAW,EAAE,MAAM;QACnB,MAAM,EAAE,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAE,EAAE,GAAG,SAAS,EAAC;KAC1C,CAAC;AACH,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type css from "css";
2
+ import type { DeclarationNode } from "./mapDeclaration.ts";
3
+ export default function mapRule(rule: css.Rule): {
4
+ conditions: {
5
+ style: string | undefined;
6
+ state: string | undefined;
7
+ group: string;
8
+ checks: ({
9
+ type: "js";
10
+ expression: string;
11
+ negate: boolean;
12
+ } | {
13
+ type: "geometryType";
14
+ value: string;
15
+ negate: boolean;
16
+ } | {
17
+ type: "value";
18
+ target: "props" | "env";
19
+ path: string[];
20
+ value?: string | number | null;
21
+ negate: boolean;
22
+ })[] | undefined;
23
+ __meta: {
24
+ stateNames: string[];
25
+ styleProps: string[];
26
+ stylePropExpressions: string[];
27
+ };
28
+ }[];
29
+ declarations: {
30
+ [x: string]: DeclarationNode;
31
+ };
32
+ __meta: {
33
+ styleNames: string[];
34
+ stateNames: string[];
35
+ groupNames: string[];
36
+ declarationNames: string[];
37
+ styleProps: string[];
38
+ stylePropExpressions: string[];
39
+ };
40
+ }[];
41
+ //# sourceMappingURL=mapRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapRule.d.ts","sourceRoot":"","sources":["../../src/js/cssToRules/mapRule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAO3B,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,qBAAqB,CAAC;AAQzD,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkF7C"}
@@ -0,0 +1,60 @@
1
+ import unique from "@mapsight/lib-js/array/unique";
2
+ import { isTruthy } from "@mapsight/lib-js/boolean";
3
+ import deepMerge from "@mapsight/lib-js/object/deep-extend";
4
+ import uniqueSerialized from "../helpers/uniqueSerialized.js";
5
+ import mapDeclaration from "./mapDeclaration.js";
6
+ import mapSelector from "./mapSelector.js";
7
+ const isDeclaration = (val) => val.type === "declaration";
8
+ export default function mapRule(rule) {
9
+ const declarations = rule.declarations
10
+ ?.filter(isDeclaration)
11
+ .map(mapDeclaration)
12
+ .filter((a) => !!a) ?? [];
13
+ const mergedDeclaration = deepMerge({}, ...declarations.map((a) => a.declaration));
14
+ // meta data
15
+ const mergedDeclarationNames = unique(declarations.map((declaration) => declaration.__meta.name));
16
+ const mergedStyleProps = unique(declarations.flatMap((declaration) => declaration.__meta.styleProps));
17
+ const mergedStylePropExpressions = unique(declarations.flatMap((declaration) => declaration.__meta.stylePropExpressions));
18
+ const selectors = uniqueSerialized(rule.selectors?.map(mapSelector) ?? []);
19
+ const groupedSelectors = {};
20
+ selectors.forEach((selector) => {
21
+ const existing = groupedSelectors[selector.group];
22
+ if (Array.isArray(existing)) {
23
+ existing.push(selector);
24
+ }
25
+ else {
26
+ groupedSelectors[selector.group] = [selector];
27
+ }
28
+ });
29
+ return Object.keys(groupedSelectors).map((group) => {
30
+ const conditions = uniqueSerialized(groupedSelectors[group]);
31
+ const mergedStateNames = unique(conditions.flatMap((condition) => condition.__meta.stateNames));
32
+ const mergedConditionStyleProps = unique(conditions.flatMap((condition) => condition.__meta.styleProps));
33
+ const mergedConditionStylePropExpressions = unique(conditions.flatMap((condition) => condition.__meta.stylePropExpressions));
34
+ return {
35
+ conditions: conditions,
36
+ declarations: {
37
+ [group]: mergedDeclaration,
38
+ },
39
+ __meta: {
40
+ styleNames: unique(conditions
41
+ .map((condition) => condition.style)
42
+ .filter(isTruthy)),
43
+ stateNames: [
44
+ ...unique(conditions
45
+ .map((condition) => condition.state)
46
+ .filter(isTruthy)),
47
+ ...mergedStateNames,
48
+ ],
49
+ groupNames: unique(conditions.map((condition) => condition.group)),
50
+ declarationNames: mergedDeclarationNames,
51
+ styleProps: [...mergedConditionStyleProps, ...mergedStyleProps],
52
+ stylePropExpressions: [
53
+ ...mergedConditionStylePropExpressions,
54
+ ...mergedStylePropExpressions,
55
+ ],
56
+ },
57
+ };
58
+ });
59
+ }
60
+ //# sourceMappingURL=mapRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapRule.js","sourceRoot":"","sources":["../../src/js/cssToRules/mapRule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export type Selector = ReturnType<typeof mapSelector>;
2
+ export default function mapSelector(selector: string): {
3
+ style: string | undefined;
4
+ state: string | undefined;
5
+ group: string;
6
+ checks: ({
7
+ type: "js";
8
+ expression: string;
9
+ negate: boolean;
10
+ } | {
11
+ type: "geometryType";
12
+ value: string;
13
+ negate: boolean;
14
+ } | {
15
+ type: "value";
16
+ target: "props" | "env";
17
+ path: string[];
18
+ value?: string | number | null;
19
+ negate: boolean;
20
+ })[] | undefined;
21
+ __meta: {
22
+ stateNames: string[];
23
+ styleProps: string[];
24
+ stylePropExpressions: string[];
25
+ };
26
+ };
27
+ //# sourceMappingURL=mapSelector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapSelector.d.ts","sourceRoot":"","sources":["../../src/js/cssToRules/mapSelector.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;EA4DnD"}