@navita/engine 0.0.0-main-20230917201540

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 (4) hide show
  1. package/index.d.ts +51 -0
  2. package/index.js +870 -0
  3. package/index.mjs +866 -0
  4. package/package.json +19 -0
package/index.js ADDED
@@ -0,0 +1,870 @@
1
+ 'use strict';
2
+
3
+ var path = require('node:path');
4
+ var hash = require('@emotion/hash');
5
+ var sourceMap = require('source-map');
6
+ var createSort = require('sort-css-media-queries/lib/create-sort.js');
7
+
8
+ class Cache {
9
+ constructor(_idGenerator){
10
+ this._idGenerator = _idGenerator;
11
+ this._items = {};
12
+ }
13
+ getOrStore(value) {
14
+ const cacheKey = JSON.stringify(value);
15
+ if (this._items[cacheKey]) {
16
+ return this._items[cacheKey];
17
+ }
18
+ return this._items[cacheKey] = {
19
+ id: this._idGenerator.next(value),
20
+ ...value
21
+ };
22
+ }
23
+ items(ids = undefined) {
24
+ const items = Object.values(this._items);
25
+ if (ids === undefined) {
26
+ return items;
27
+ }
28
+ return items.filter((item)=>ids.includes(item.id));
29
+ }
30
+ }
31
+
32
+ function isObject(val) {
33
+ return val != null && typeof val === 'object' && Array.isArray(val) === false;
34
+ }
35
+
36
+ function splitStyleBlocks(blocks) {
37
+ const atRules = [];
38
+ const rules = [];
39
+ for (const block of blocks){
40
+ if (block.media || block.support) {
41
+ atRules.push(block);
42
+ } else {
43
+ rules.push(block);
44
+ }
45
+ }
46
+ return {
47
+ atRules,
48
+ rules
49
+ };
50
+ }
51
+
52
+ class IDGenerator {
53
+ counter = 1;
54
+ next() {
55
+ return this.counter++;
56
+ }
57
+ }
58
+
59
+ const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
60
+ const charLength = chars.length;
61
+ class AlphaIDGenerator {
62
+ constructor(blacklist = [
63
+ 'ad'
64
+ ]){
65
+ this.blacklist = blacklist;
66
+ this.counter = 1;
67
+ }
68
+ next() {
69
+ const nextString = (id, className = '')=>{
70
+ if (id <= charLength) {
71
+ return chars[id - 1] + className;
72
+ }
73
+ return nextString(id / charLength | 0, chars[(id - 1) % charLength] + className);
74
+ };
75
+ let className;
76
+ do {
77
+ className = nextString(this.counter++);
78
+ }while (this.blacklist.includes(className.toLowerCase()))
79
+ return className;
80
+ }
81
+ }
82
+
83
+ class PropertyValueIDGenerator {
84
+ property = new AlphaIDGenerator();
85
+ cache = {};
86
+ next({ property , media ='' , support ='' , pseudo ='' , value }) {
87
+ const propertyKey = `${media}${support}${pseudo}${property}`;
88
+ if (this.cache[propertyKey] === undefined) {
89
+ this.cache[propertyKey] = {
90
+ key: this.property.next(),
91
+ cache: {}
92
+ };
93
+ }
94
+ const entry = this.cache[propertyKey];
95
+ if (entry.cache[value] === undefined) {
96
+ entry.cache[value] = Object.keys(entry.cache).length + 1;
97
+ }
98
+ return `${entry.key}${entry.cache[value]}`;
99
+ }
100
+ }
101
+
102
+ // https://github.com/styletron/styletron/blob/b552ddc5050a8cc5eec84a46a299d937d3bb0112/packages/styletron-engine-atomic/src/hyphenate-style-name.ts
103
+ const uppercasePattern = /[A-Z]/g;
104
+ const msPattern = /^ms-/;
105
+ const cache = {};
106
+ function hyphenateProperty(property) {
107
+ return property in cache ? cache[property] : cache[property] = property.replace(uppercasePattern, "-$&").toLowerCase().replace(msPattern, "-ms-");
108
+ }
109
+
110
+ // https://github.com/styletron/styletron/blob/b552ddc5050a8cc5eec84a46a299d937d3bb0112/packages/styletron-engine-atomic/src/css.ts#L36
111
+ function declarationsToBlock(style) {
112
+ let css = "";
113
+ for(const prop in style){
114
+ const val = style[prop];
115
+ if (typeof val === "string" || typeof val === "number") {
116
+ css += `${hyphenateProperty(prop)}:${val};`;
117
+ }
118
+ }
119
+ return css.slice(0, -1);
120
+ }
121
+
122
+ function printFontFaces(blocks) {
123
+ let fontFaces = '';
124
+ for (const block of blocks){
125
+ for (const rule of block.rule){
126
+ fontFaces += `@font-face{font-family:${block.id};${declarationsToBlock(rule)}}`;
127
+ }
128
+ }
129
+ return fontFaces;
130
+ }
131
+
132
+ // https://github.com/styletron/styletron/blob/master/packages/styletron-engine-atomic/src/css.ts#L48
133
+ function keyframesToBlock(keyframes) {
134
+ let result = "";
135
+ for(const animationState in keyframes){
136
+ result += `${animationState}{${declarationsToBlock(keyframes[animationState])}}`;
137
+ }
138
+ return result;
139
+ }
140
+ function printKeyFrames(blocks) {
141
+ let keyframes = '';
142
+ for (const block of blocks){
143
+ keyframes += `@keyframes ${block.id}{${keyframesToBlock(block.rule)}}`;
144
+ }
145
+ return keyframes;
146
+ }
147
+
148
+ function printSourceMap(sourceMapReferences, content) {
149
+ if (content.length === 0) {
150
+ return content;
151
+ }
152
+ const entries = Object.entries(sourceMapReferences);
153
+ if (entries.length === 0) {
154
+ return content;
155
+ }
156
+ const sourceMap$1 = new sourceMap.SourceMapGenerator({
157
+ file: "navita.css"
158
+ });
159
+ const references = entries.flatMap(([filePath, references])=>references.map((reference)=>({
160
+ filePath,
161
+ ...reference
162
+ })));
163
+ for (const reference of references){
164
+ const { filePath , selector , line , column } = reference;
165
+ const generatedColumn = content.length - 1;
166
+ content += `${selector}{/* Only used for sourceMap */}`;
167
+ sourceMap$1.addMapping({
168
+ source: filePath,
169
+ original: {
170
+ line,
171
+ column
172
+ },
173
+ generated: {
174
+ line: 1,
175
+ column: generatedColumn
176
+ }
177
+ });
178
+ }
179
+ const sourceMapContent = Buffer.from(sourceMap$1.toString()).toString('base64');
180
+ content += `\n/*# sourceMappingURL=data:application/json;base64,${sourceMapContent} */`;
181
+ return content;
182
+ }
183
+
184
+ /**
185
+ * This list comes from:
186
+ * https://github.com/callstack/linaria/blob/master/packages/atomic/src/processors/helpers/propertyPriority.ts
187
+ */ const shorthandProperties = {
188
+ // The `all` property resets everything, and should effectively have priority zero.
189
+ // In practice, this can be achieved by using: div { all: ... } to have even less specificity, but to avoid duplicating all selectors, we just let it be
190
+ // 'all': []
191
+ animation: [
192
+ 'animation-name',
193
+ 'animation-duration',
194
+ 'animation-timing-function',
195
+ 'animation-delay',
196
+ 'animation-iteration-count',
197
+ 'animation-direction',
198
+ 'animation-fill-mode',
199
+ 'animation-play-state'
200
+ ],
201
+ background: [
202
+ 'background-attachment',
203
+ 'background-clip',
204
+ 'background-color',
205
+ 'background-image',
206
+ 'background-origin',
207
+ 'background-position',
208
+ 'background-repeat',
209
+ 'background-size'
210
+ ],
211
+ border: [
212
+ 'border-color',
213
+ 'border-style',
214
+ 'border-width'
215
+ ],
216
+ 'border-block-end': [
217
+ 'border-block-end-color',
218
+ 'border-block-end-style',
219
+ 'border-block-end-width'
220
+ ],
221
+ 'border-block-start': [
222
+ 'border-block-start-color',
223
+ 'border-block-start-style',
224
+ 'border-block-start-width'
225
+ ],
226
+ 'border-bottom': [
227
+ 'border-bottom-color',
228
+ 'border-bottom-style',
229
+ 'border-bottom-width'
230
+ ],
231
+ 'border-color': [
232
+ 'border-bottom-color',
233
+ 'border-left-color',
234
+ 'border-right-color',
235
+ 'border-top-color'
236
+ ],
237
+ 'border-image': [
238
+ 'border-image-outset',
239
+ 'border-image-repeat',
240
+ 'border-image-slice',
241
+ 'border-image-source',
242
+ 'border-image-width'
243
+ ],
244
+ 'border-inline-end': [
245
+ 'border-inline-end-color',
246
+ 'border-inline-end-style',
247
+ 'border-inline-end-width'
248
+ ],
249
+ 'border-inline-start': [
250
+ 'border-inline-start-color',
251
+ 'border-inline-start-style',
252
+ 'border-inline-start-width'
253
+ ],
254
+ 'border-left': [
255
+ 'border-left-color',
256
+ 'border-left-style',
257
+ 'border-left-width'
258
+ ],
259
+ 'border-radius': [
260
+ 'border-top-left-radius',
261
+ 'border-top-right-radius',
262
+ 'border-bottom-right-radius',
263
+ 'border-bottom-left-radius'
264
+ ],
265
+ 'border-right': [
266
+ 'border-right-color',
267
+ 'border-right-style',
268
+ 'border-right-width'
269
+ ],
270
+ 'border-style': [
271
+ 'border-bottom-style',
272
+ 'border-left-style',
273
+ 'border-right-style',
274
+ 'border-top-style'
275
+ ],
276
+ 'border-top': [
277
+ 'border-top-color',
278
+ 'border-top-style',
279
+ 'border-top-width'
280
+ ],
281
+ 'border-width': [
282
+ 'border-bottom-width',
283
+ 'border-left-width',
284
+ 'border-right-width',
285
+ 'border-top-width'
286
+ ],
287
+ 'column-rule': [
288
+ 'column-rule-width',
289
+ 'column-rule-style',
290
+ 'column-rule-color'
291
+ ],
292
+ columns: [
293
+ 'column-count',
294
+ 'column-width'
295
+ ],
296
+ flex: [
297
+ 'flex-grow',
298
+ 'flex-shrink',
299
+ 'flex-basis'
300
+ ],
301
+ 'flex-flow': [
302
+ 'flex-direction',
303
+ 'flex-wrap'
304
+ ],
305
+ font: [
306
+ 'font-family',
307
+ 'font-size',
308
+ 'font-stretch',
309
+ 'font-style',
310
+ 'font-variant',
311
+ 'font-weight',
312
+ 'line-height'
313
+ ],
314
+ gap: [
315
+ 'row-gap',
316
+ 'column-gap'
317
+ ],
318
+ grid: [
319
+ 'grid-auto-columns',
320
+ 'grid-auto-flow',
321
+ 'grid-auto-rows',
322
+ 'grid-template-areas',
323
+ 'grid-template-columns',
324
+ 'grid-template-rows'
325
+ ],
326
+ 'grid-area': [
327
+ 'grid-row-start',
328
+ 'grid-column-start',
329
+ 'grid-row-end',
330
+ 'grid-column-end'
331
+ ],
332
+ 'grid-column': [
333
+ 'grid-column-end',
334
+ 'grid-column-start'
335
+ ],
336
+ 'grid-row': [
337
+ 'grid-row-end',
338
+ 'grid-row-start'
339
+ ],
340
+ 'grid-template': [
341
+ 'grid-template-areas',
342
+ 'grid-template-columns',
343
+ 'grid-template-rows'
344
+ ],
345
+ 'list-style': [
346
+ 'list-style-image',
347
+ 'list-style-position',
348
+ 'list-style-type'
349
+ ],
350
+ margin: [
351
+ 'margin-bottom',
352
+ 'margin-left',
353
+ 'margin-right',
354
+ 'margin-top'
355
+ ],
356
+ mask: [
357
+ 'mask-clip',
358
+ 'mask-composite',
359
+ 'mask-image',
360
+ 'mask-mode',
361
+ 'mask-origin',
362
+ 'mask-position',
363
+ 'mask-repeat',
364
+ 'mask-size'
365
+ ],
366
+ offset: [
367
+ 'offset-anchor',
368
+ 'offset-distance',
369
+ 'offset-path',
370
+ 'offset-position',
371
+ 'offset-rotate'
372
+ ],
373
+ outline: [
374
+ 'outline-color',
375
+ 'outline-style',
376
+ 'outline-width'
377
+ ],
378
+ overflow: [
379
+ 'overflow-x',
380
+ 'overflow-y'
381
+ ],
382
+ padding: [
383
+ 'padding-bottom',
384
+ 'padding-left',
385
+ 'padding-right',
386
+ 'padding-top'
387
+ ],
388
+ 'place-content': [
389
+ 'align-content',
390
+ 'justify-content'
391
+ ],
392
+ 'place-items': [
393
+ 'align-items',
394
+ 'justify-items'
395
+ ],
396
+ 'place-self': [
397
+ 'align-self',
398
+ 'justify-self'
399
+ ],
400
+ 'scroll-margin': [
401
+ 'scroll-margin-bottom',
402
+ 'scroll-margin-left',
403
+ 'scroll-margin-right',
404
+ 'scroll-margin-top'
405
+ ],
406
+ 'scroll-padding': [
407
+ 'scroll-padding-bottom',
408
+ 'scroll-padding-left',
409
+ 'scroll-padding-right',
410
+ 'scroll-padding-top'
411
+ ],
412
+ 'text-decoration': [
413
+ 'text-decoration-color',
414
+ 'text-decoration-line',
415
+ 'text-decoration-style',
416
+ 'text-decoration-thickness'
417
+ ],
418
+ 'text-emphasis': [
419
+ 'text-emphasis-color',
420
+ 'text-emphasis-style'
421
+ ],
422
+ transition: [
423
+ 'transition-delay',
424
+ 'transition-duration',
425
+ 'transition-property',
426
+ 'transition-timing-function'
427
+ ]
428
+ };
429
+ const longhands = Object.values(shorthandProperties).reduce((a, b)=>[
430
+ ...a,
431
+ ...b
432
+ ], []);
433
+ /**
434
+ * The concept here is that shorthand properties, such as "border" gets
435
+ * a priority of one, while longhand properties, such as "border-color" gets
436
+ * a priority of 2.
437
+ *
438
+ * Read more:
439
+ * @see https://weser.io/blog/the-shorthand-longhand-problem-in-atomic-css
440
+ * @see https://www.w3.org/TR/selectors-3/#specificity
441
+ */ const getPropertyPriority = (property)=>longhands.includes(property) ? 2 : 1;
442
+
443
+ function printStyleBlocks(blocks) {
444
+ let stylesheet = '';
445
+ let previousStyle;
446
+ for (const style of blocks){
447
+ if (style.type === 'static' && previousStyle && (previousStyle.selector !== style.selector || previousStyle.pseudo !== style.pseudo || previousStyle.media !== style.media || previousStyle.support !== style.support)) {
448
+ stylesheet += '}';
449
+ }
450
+ // Close support queries:
451
+ // 1. When the current style is not a support query, and the previous style was support query
452
+ // 2. When the current style is a support query and the previous style was a support query with a different support query
453
+ if (previousStyle && previousStyle.support && (!style.support || style.support !== previousStyle.support)) {
454
+ stylesheet += '}';
455
+ }
456
+ // Close media queries:
457
+ // 1. When the current style is not a media query, and the previous style was media query
458
+ // 2. When the current style is a media query and the previous style was a media query with a different media query
459
+ if (previousStyle && previousStyle.media && (!style.media || style.media !== previousStyle.media)) {
460
+ stylesheet += '}';
461
+ }
462
+ // Only add media queries if the previous style was not the same media query
463
+ if (style.media && previousStyle?.media !== style.media) {
464
+ stylesheet += `@media ${style.media}{`;
465
+ }
466
+ // Only add support queries if the previous style was not the same support query
467
+ if (style.support && previousStyle?.support !== style.support) {
468
+ stylesheet += `@supports ${style.support}{`;
469
+ }
470
+ if (style.type === 'rule') {
471
+ const className = `.${style.id}`.repeat(getPropertyPriority(style.property));
472
+ stylesheet += `${className}${style.pseudo}{`;
473
+ } else if (style.type === 'static' && (previousStyle?.selector !== style.selector || previousStyle?.pseudo !== style.pseudo || previousStyle?.media !== style.media || previousStyle?.support !== style.support)) {
474
+ // If static, we don't add pseudo selectors currently
475
+ stylesheet += `${style.selector}${style.pseudo}{`;
476
+ }
477
+ stylesheet += `${style.property}:${style.value}`;
478
+ if (style.type === 'static') {
479
+ stylesheet += ';';
480
+ }
481
+ if (style.type === 'rule') {
482
+ stylesheet += '}';
483
+ }
484
+ previousStyle = style;
485
+ }
486
+ if (previousStyle?.support) {
487
+ stylesheet += '}';
488
+ }
489
+ if (previousStyle?.media) {
490
+ stylesheet += '}';
491
+ }
492
+ if (previousStyle?.type === 'static') {
493
+ stylesheet += '}';
494
+ }
495
+ return stylesheet;
496
+ }
497
+
498
+ const sortCSSMediaQueries = createSort();
499
+ function sortAtRules(blocks) {
500
+ return blocks.sort((a, b)=>sortCSSMediaQueries(a.media, b.media) || a.support.localeCompare(b.support));
501
+ }
502
+
503
+ function generateCombinedAtRules(currentMediaQuery, nestedMediaQuery) {
504
+ if (currentMediaQuery.length === 0) {
505
+ return nestedMediaQuery;
506
+ }
507
+ return `${currentMediaQuery} and ${nestedMediaQuery}`;
508
+ }
509
+
510
+ function isMediaQuery(property) {
511
+ return property.startsWith('@media');
512
+ }
513
+
514
+ const regex$1 = /^([:\[>&])/;
515
+ function isNestedSelector(property) {
516
+ return regex$1.test(property);
517
+ }
518
+
519
+ function isSupportsQuery(property) {
520
+ return property.startsWith("@supports");
521
+ }
522
+
523
+ const regex = /var\(([^,]+).*\)/;
524
+ function normalizeCSSVarsProperty(property) {
525
+ if (!property.startsWith('var(')) {
526
+ return property;
527
+ }
528
+ const matches = property.match(regex);
529
+ if (!matches) {
530
+ return property;
531
+ }
532
+ return matches[1];
533
+ }
534
+
535
+ function normalizeNestedProperty(nestedProperty) {
536
+ if (nestedProperty.charAt(0) === '&') {
537
+ return nestedProperty.slice(1);
538
+ }
539
+ return nestedProperty;
540
+ }
541
+
542
+ const UNITLESS = {
543
+ animationIterationCount: true,
544
+ borderImage: true,
545
+ borderImageOutset: true,
546
+ borderImageSlice: true,
547
+ borderImageWidth: true,
548
+ boxFlex: true,
549
+ boxFlexGroup: true,
550
+ columnCount: true,
551
+ columns: true,
552
+ flex: true,
553
+ flexGrow: true,
554
+ flexShrink: true,
555
+ fontWeight: true,
556
+ gridArea: true,
557
+ gridColumn: true,
558
+ gridColumnEnd: true,
559
+ gridColumnStart: true,
560
+ gridRow: true,
561
+ gridRowEnd: true,
562
+ gridRowStart: true,
563
+ initialLetter: true,
564
+ lineClamp: true,
565
+ lineHeight: true,
566
+ maxLines: true,
567
+ opacity: true,
568
+ order: true,
569
+ orphans: true,
570
+ scale: true,
571
+ tabSize: true,
572
+ WebkitLineClamp: true,
573
+ widows: true,
574
+ zIndex: true,
575
+ zoom: true,
576
+ // svg properties
577
+ fillOpacity: true,
578
+ floodOpacity: true,
579
+ maskBorder: true,
580
+ maskBorderOutset: true,
581
+ maskBorderSlice: true,
582
+ maskBorderWidth: true,
583
+ shapeImageThreshold: true,
584
+ stopOpacity: true,
585
+ strokeDashoffset: true,
586
+ strokeMiterlimit: true,
587
+ strokeOpacity: true,
588
+ strokeWidth: true
589
+ };
590
+ function pixelifyProperties(property, value) {
591
+ if (value !== 0 && !UNITLESS[property]) {
592
+ return `${value}px`;
593
+ }
594
+ return value;
595
+ }
596
+
597
+ // https://github.com/vanilla-extract-css/vanilla-extract/blob/40d7e72c041989a4dc847dc66b94a4c680b5536e/packages/css/src/transformCss.ts#L277
598
+ function transformContentProperty(value) {
599
+ return value && (value.includes('"') || value.includes("'") || /^([A-Za-z\-]+\([^]*|[^]*-quote|inherit|initial|none|normal|revert|unset)(\s|$)/.test(value)) ? value : `"${value}"`;
600
+ }
601
+
602
+ const transformValuePropertyMap = {
603
+ content: transformContentProperty
604
+ };
605
+ function processStyles({ cache , type }) {
606
+ return function process({ styles , pseudo ="" , media ="" , support ="" , selector ="" }) {
607
+ const result = [];
608
+ for (const [property, value] of Object.entries(styles)){
609
+ if (isObject(value)) {
610
+ if (isMediaQuery(property)) {
611
+ const combinedMedia = generateCombinedAtRules(media, property.slice(6).trim());
612
+ result.push(...process({
613
+ styles: value,
614
+ pseudo,
615
+ media: combinedMedia,
616
+ support,
617
+ selector
618
+ }));
619
+ } else if (isSupportsQuery(property)) {
620
+ const combinedSupport = generateCombinedAtRules(support, property.slice(9).trim());
621
+ result.push(...process({
622
+ styles: value,
623
+ pseudo,
624
+ media,
625
+ support: combinedSupport,
626
+ selector
627
+ }));
628
+ } else if (isNestedSelector(property)) {
629
+ // This is only allowed in simple pseudos currently.
630
+ const copies = property.split(',').map((p)=>p.trim());
631
+ for (const copy of copies){
632
+ result.push(...process({
633
+ styles: value,
634
+ pseudo: pseudo + normalizeNestedProperty(copy),
635
+ media,
636
+ support,
637
+ selector
638
+ }));
639
+ }
640
+ } else {
641
+ console.warn("Unknown property", property);
642
+ }
643
+ } else {
644
+ let newProperty = normalizeCSSVarsProperty(property);
645
+ let newValue = value;
646
+ if (typeof value === "string") {
647
+ newValue = value.trim().replace(/;[\n\s]*$/, "");
648
+ }
649
+ if (typeof value === "number") {
650
+ newValue = pixelifyProperties(newProperty, value);
651
+ }
652
+ if (transformValuePropertyMap[newProperty]) {
653
+ newValue = transformValuePropertyMap[newProperty](value);
654
+ }
655
+ newProperty = hyphenateProperty(newProperty);
656
+ // Remove trailing semicolon and new lines with regex
657
+ result.push(cache.getOrStore({
658
+ type,
659
+ selector,
660
+ property: newProperty,
661
+ value: newValue,
662
+ pseudo,
663
+ media,
664
+ support
665
+ }));
666
+ }
667
+ }
668
+ return result;
669
+ };
670
+ }
671
+
672
+ class ClassList extends String {
673
+ }
674
+
675
+ class Static {
676
+ }
677
+
678
+ const defaultOptions = {
679
+ enableSourceMaps: false,
680
+ enableDebugIdentifiers: false
681
+ };
682
+ class Engine {
683
+ caches = {
684
+ rule: new Cache(new PropertyValueIDGenerator()),
685
+ static: new Cache(new IDGenerator()),
686
+ keyframes: new Cache(new AlphaIDGenerator()),
687
+ fontFace: new Cache(new AlphaIDGenerator()),
688
+ identifiers: new Cache(new AlphaIDGenerator())
689
+ };
690
+ usedIds = {};
691
+ identifierCount = 0;
692
+ options = {};
693
+ sourceMapReferences = {};
694
+ constructor(options = {}){
695
+ this.options = {
696
+ ...defaultOptions,
697
+ ...Object.keys(options).reduce((acc, key)=>{
698
+ if (options[key] !== undefined) {
699
+ acc[key] = options[key];
700
+ }
701
+ return acc;
702
+ }, {})
703
+ };
704
+ }
705
+ addStatic(selector, styles) {
706
+ this.addUsedIds("static", processStyles({
707
+ type: "static",
708
+ cache: this.caches.static
709
+ })({
710
+ styles,
711
+ selector
712
+ }).map((style)=>style.id));
713
+ return new Static();
714
+ }
715
+ addStyle(styles) {
716
+ const rules = processStyles({
717
+ type: "rule",
718
+ cache: this.caches.rule
719
+ })({
720
+ styles
721
+ });
722
+ const ids = rules.map((rule)=>rule.id);
723
+ this.addUsedIds("rule", ids);
724
+ return new ClassList(ids.join(" "));
725
+ }
726
+ addFontFace(fontFace) {
727
+ const { id } = this.caches.fontFace.getOrStore({
728
+ type: "fontFace",
729
+ rule: Array.isArray(fontFace) ? fontFace : [
730
+ fontFace
731
+ ]
732
+ });
733
+ this.addUsedIds("fontFace", [
734
+ id
735
+ ]);
736
+ return id;
737
+ }
738
+ addKeyframes(keyframes) {
739
+ const { id } = this.caches.keyframes.getOrStore({
740
+ type: "keyframes",
741
+ rule: keyframes
742
+ });
743
+ this.addUsedIds("keyframes", [
744
+ id
745
+ ]);
746
+ return id;
747
+ }
748
+ addSourceMapReference({ filePath , identifier , classList , line , column , index }) {
749
+ if (!this.options.enableSourceMaps) {
750
+ return false;
751
+ }
752
+ const { name } = path.parse(filePath);
753
+ const extraClass = this.options.enableDebugIdentifiers ? `${name}_${identifier}` : '';
754
+ const selector = '.' + classList.toString().split(' ').concat(extraClass).filter(Boolean).join('.');
755
+ if (index === 0 || !this.sourceMapReferences[filePath]) {
756
+ this.sourceMapReferences[filePath] = [];
757
+ }
758
+ this.sourceMapReferences[filePath][index] = {
759
+ selector,
760
+ line,
761
+ column
762
+ };
763
+ return extraClass;
764
+ }
765
+ generateIdentifier(value) {
766
+ if (typeof value === 'undefined') {
767
+ let identifier = hash((this.identifierCount++).toString(36));
768
+ if (identifier.match(/^\d/)) {
769
+ identifier = `_${identifier}`;
770
+ }
771
+ return identifier;
772
+ }
773
+ const newValue = JSON.stringify(value);
774
+ const { id } = this.caches.identifiers.getOrStore({
775
+ value: newValue
776
+ });
777
+ this.addUsedIds("identifiers", [
778
+ id
779
+ ]);
780
+ return `_${id}`;
781
+ }
782
+ renderCssToString(options) {
783
+ const { filePaths , usedIds , opinionatedLayers =false } = options || {};
784
+ // We prioritize ids over filePaths. If neither are provided, we use all the used filePaths.
785
+ const { keyframes: keyframesCache , fontFace: fontFaceCache , static: staticCache , rule: ruleCache } = usedIds ?? this.getUsedCacheIds(filePaths ?? Object.keys(this.usedIds));
786
+ const { atRules , rules } = splitStyleBlocks(this.caches.rule.items(ruleCache));
787
+ const keyFrameCss = printKeyFrames(this.caches.keyframes.items(keyframesCache));
788
+ const fontFaceCss = printFontFaces(this.caches.fontFace.items(fontFaceCache));
789
+ const staticCss = printStyleBlocks(this.caches.static.items(staticCache));
790
+ const atRulesCss = printStyleBlocks(sortAtRules(atRules));
791
+ const rulesCss = printStyleBlocks(rules);
792
+ if (opinionatedLayers) {
793
+ const result = `${keyFrameCss}${fontFaceCss}` + (staticCss.length > 0 ? `@layer static{${staticCss}}` : '') + (rulesCss.length > 0 ? `@layer rules{${rulesCss}}` : '') + (atRulesCss.length > 0 ? `@layer at{${atRulesCss}}` : '');
794
+ if (result.length > 0) {
795
+ return `@layer static,rules,at;${result}`;
796
+ }
797
+ return '';
798
+ }
799
+ return printSourceMap(this.sourceMapReferences, keyFrameCss + fontFaceCss + staticCss + rulesCss + atRulesCss);
800
+ }
801
+ serialize() {
802
+ const { caches , usedIds , identifierCount , sourceMapReferences } = this;
803
+ return JSON.stringify({
804
+ caches,
805
+ usedIds,
806
+ identifierCount,
807
+ sourceMapReferences
808
+ });
809
+ }
810
+ async deserialize(buffer) {
811
+ const data = JSON.parse(buffer.toString());
812
+ function assign(target, source) {
813
+ for(const key in source){
814
+ if (isObject(target[key]) && isObject(source[key])) {
815
+ assign(target[key], source[key]);
816
+ } else {
817
+ target[key] = source[key];
818
+ }
819
+ }
820
+ return target;
821
+ }
822
+ assign(this, data);
823
+ }
824
+ setFilePath(filePath) {
825
+ this.filePath = filePath;
826
+ }
827
+ clearUsedIds(filePath) {
828
+ if (filePath === undefined) {
829
+ return;
830
+ }
831
+ this.usedIds[filePath] = {};
832
+ }
833
+ addUsedIds(cacheType, identifiers) {
834
+ const { filePath } = this;
835
+ if (filePath === undefined) {
836
+ return;
837
+ }
838
+ if (this.usedIds[filePath] === undefined) {
839
+ this.usedIds[filePath] = {};
840
+ }
841
+ if (this.usedIds[filePath][cacheType] === undefined) {
842
+ this.usedIds[filePath][cacheType] = [];
843
+ }
844
+ this.usedIds[filePath][cacheType] = [
845
+ ...new Set([
846
+ ...this.usedIds[filePath][cacheType],
847
+ ...identifiers
848
+ ])
849
+ ];
850
+ }
851
+ getUsedCacheIds(filePaths = []) {
852
+ return filePaths.reduce((acc, filePath)=>({
853
+ ...acc,
854
+ ...Object.keys(this.usedIds[filePath] || []).reduce((cache, key)=>({
855
+ ...cache,
856
+ [key]: [
857
+ ...acc[key] || [],
858
+ ...this.usedIds[filePath][key] || []
859
+ ]
860
+ }), {})
861
+ }), Object.keys(this.caches).reduce((acc, key)=>({
862
+ ...acc,
863
+ [key]: []
864
+ }), {}));
865
+ }
866
+ }
867
+
868
+ exports.ClassList = ClassList;
869
+ exports.Engine = Engine;
870
+ exports.Static = Static;