@tbela99/css-parser 0.0.1-alpha5 → 0.0.1-rc2

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.
@@ -0,0 +1,454 @@
1
+ import { isWhiteSpace, isDigit, isNewLine } from './utils/syntax.js';
2
+
3
+ function* tokenize(iterator) {
4
+ let ind = -1;
5
+ let lin = 1;
6
+ let col = 0;
7
+ const position = {
8
+ ind: Math.max(ind, 0),
9
+ lin: lin,
10
+ col: Math.max(col, 1)
11
+ };
12
+ let value;
13
+ let buffer = '';
14
+ function consumeWhiteSpace() {
15
+ let count = 0;
16
+ while (isWhiteSpace(iterator.charAt(count + ind + 1).charCodeAt(0))) {
17
+ count++;
18
+ }
19
+ next(count);
20
+ return count;
21
+ }
22
+ function pushToken(token, hint) {
23
+ const result = { token, hint, position: { ...position }, bytesIn: ind };
24
+ position.ind = ind;
25
+ position.lin = lin;
26
+ position.col = col == 0 ? 1 : col;
27
+ return result;
28
+ }
29
+ function* consumeString(quoteStr) {
30
+ const quote = quoteStr;
31
+ let value;
32
+ let hasNewLine = false;
33
+ if (buffer.length > 0) {
34
+ yield pushToken(buffer);
35
+ buffer = '';
36
+ }
37
+ buffer += quoteStr;
38
+ while (value = peek()) {
39
+ // if (ind >= iterator.length) {
40
+ //
41
+ // yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string');
42
+ // break;
43
+ // }
44
+ if (value == '\\') {
45
+ const sequence = peek(6);
46
+ let escapeSequence = '';
47
+ let codepoint;
48
+ let i;
49
+ for (i = 1; i < sequence.length; i++) {
50
+ codepoint = sequence.charCodeAt(i);
51
+ if (codepoint == 0x20 ||
52
+ (codepoint >= 0x61 && codepoint <= 0x66) ||
53
+ (codepoint >= 0x41 && codepoint <= 0x46) ||
54
+ (codepoint >= 0x30 && codepoint <= 0x39)) {
55
+ escapeSequence += sequence[i];
56
+ if (codepoint == 0x20) {
57
+ break;
58
+ }
59
+ continue;
60
+ }
61
+ break;
62
+ }
63
+ // not hex or new line
64
+ // @ts-ignore
65
+ if (i == 1 && !isNewLine(codepoint)) {
66
+ buffer += value + sequence[i];
67
+ next(2);
68
+ continue;
69
+ }
70
+ if (escapeSequence.trimEnd().length > 0) {
71
+ const codepoint = Number(`0x${escapeSequence.trimEnd()}`);
72
+ if (codepoint == 0 ||
73
+ // leading surrogate
74
+ (0xD800 <= codepoint && codepoint <= 0xDBFF) ||
75
+ // trailing surrogate
76
+ (0xDC00 <= codepoint && codepoint <= 0xDFFF)) {
77
+ buffer += String.fromCodePoint(0xFFFD);
78
+ }
79
+ else {
80
+ buffer += String.fromCodePoint(codepoint);
81
+ }
82
+ next(escapeSequence.length + 1);
83
+ continue;
84
+ }
85
+ // buffer += value;
86
+ // if (ind >= iterator.length) {
87
+ //
88
+ // // drop '\\' at the end
89
+ // yield pushToken(buffer);
90
+ // break;
91
+ // }
92
+ buffer += next(2);
93
+ continue;
94
+ }
95
+ if (value == quote) {
96
+ buffer += value;
97
+ yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'String');
98
+ next();
99
+ // i += value.length;
100
+ buffer = '';
101
+ break;
102
+ }
103
+ if (isNewLine(value.charCodeAt(0))) {
104
+ hasNewLine = true;
105
+ }
106
+ if (hasNewLine && value == ';') {
107
+ yield pushToken(buffer, 'Bad-string');
108
+ buffer = '';
109
+ break;
110
+ }
111
+ buffer += value;
112
+ // i += value.length;
113
+ next();
114
+ }
115
+ }
116
+ function peek(count = 1) {
117
+ if (count == 1) {
118
+ return iterator.charAt(ind + 1);
119
+ }
120
+ return iterator.slice(ind + 1, ind + count + 1);
121
+ }
122
+ function prev(count = 1) {
123
+ if (count == 1) {
124
+ return ind == 0 ? '' : iterator.charAt(ind - 1);
125
+ }
126
+ return iterator.slice(ind - 1 - count, ind - 1);
127
+ }
128
+ function next(count = 1) {
129
+ let char = '';
130
+ while (count-- > 0 && ind < iterator.length) {
131
+ const codepoint = iterator.charCodeAt(++ind);
132
+ if (isNaN(codepoint)) {
133
+ return char;
134
+ }
135
+ char += iterator.charAt(ind);
136
+ if (isNewLine(codepoint)) {
137
+ lin++;
138
+ col = 0;
139
+ }
140
+ else {
141
+ col++;
142
+ }
143
+ }
144
+ return char;
145
+ }
146
+ while (value = next()) {
147
+ if (ind >= iterator.length) {
148
+ if (buffer.length > 0) {
149
+ yield pushToken(buffer);
150
+ buffer = '';
151
+ }
152
+ break;
153
+ }
154
+ if (isWhiteSpace(value.charCodeAt(0))) {
155
+ if (buffer.length > 0) {
156
+ yield pushToken(buffer);
157
+ buffer = '';
158
+ }
159
+ while (value = next()) {
160
+ if (ind >= iterator.length) {
161
+ break;
162
+ }
163
+ if (!isWhiteSpace(value.charCodeAt(0))) {
164
+ break;
165
+ }
166
+ }
167
+ yield pushToken('', 'Whitespace');
168
+ buffer = '';
169
+ if (ind >= iterator.length) {
170
+ break;
171
+ }
172
+ }
173
+ switch (value) {
174
+ case '/':
175
+ if (buffer.length > 0) {
176
+ yield pushToken(buffer);
177
+ buffer = '';
178
+ if (peek() != '*') {
179
+ yield pushToken(value);
180
+ break;
181
+ }
182
+ }
183
+ buffer += value;
184
+ if (peek() == '*') {
185
+ buffer += '*';
186
+ // i++;
187
+ next();
188
+ while (value = next()) {
189
+ if (ind >= iterator.length) {
190
+ yield pushToken(buffer, 'Bad-comment');
191
+ break;
192
+ }
193
+ if (value == '\\') {
194
+ buffer += value;
195
+ value = next();
196
+ if (ind >= iterator.length) {
197
+ yield pushToken(buffer, 'Bad-comment');
198
+ break;
199
+ }
200
+ buffer += value;
201
+ continue;
202
+ }
203
+ if (value == '*') {
204
+ buffer += value;
205
+ value = next();
206
+ if (ind >= iterator.length) {
207
+ yield pushToken(buffer, 'Bad-comment');
208
+ break;
209
+ }
210
+ buffer += value;
211
+ if (value == '/') {
212
+ yield pushToken(buffer, 'Comment');
213
+ buffer = '';
214
+ break;
215
+ }
216
+ }
217
+ else {
218
+ buffer += value;
219
+ }
220
+ }
221
+ }
222
+ break;
223
+ case '<':
224
+ if (buffer.length > 0) {
225
+ yield pushToken(buffer);
226
+ buffer = '';
227
+ }
228
+ buffer += value;
229
+ value = next();
230
+ if (ind >= iterator.length) {
231
+ break;
232
+ }
233
+ if (peek(3) == '!--') {
234
+ while (value = next()) {
235
+ if (ind >= iterator.length) {
236
+ break;
237
+ }
238
+ buffer += value;
239
+ if (value == '>' && prev(2) == '--') {
240
+ yield pushToken(buffer, 'CDOCOMM');
241
+ buffer = '';
242
+ break;
243
+ }
244
+ }
245
+ }
246
+ if (ind >= iterator.length) {
247
+ yield pushToken(buffer, 'BADCDO');
248
+ buffer = '';
249
+ }
250
+ break;
251
+ case '\\':
252
+ value = next();
253
+ // EOF
254
+ if (ind + 1 >= iterator.length) {
255
+ // end of stream ignore \\
256
+ yield pushToken(buffer);
257
+ buffer = '';
258
+ break;
259
+ }
260
+ buffer += prev() + value;
261
+ break;
262
+ case '"':
263
+ case "'":
264
+ yield* consumeString(value);
265
+ break;
266
+ case '~':
267
+ case '|':
268
+ if (buffer.length > 0) {
269
+ yield pushToken(buffer);
270
+ buffer = '';
271
+ }
272
+ buffer += value;
273
+ value = next();
274
+ if (ind >= iterator.length) {
275
+ yield pushToken(buffer);
276
+ buffer = '';
277
+ break;
278
+ }
279
+ if (value == '=') {
280
+ buffer += value;
281
+ yield pushToken(buffer, buffer[0] == '~' ? 'Includes' : 'Dash-matches');
282
+ buffer = '';
283
+ break;
284
+ }
285
+ yield pushToken(buffer);
286
+ while (isWhiteSpace(value.charCodeAt(0))) {
287
+ value = next();
288
+ }
289
+ buffer = value;
290
+ break;
291
+ case '>':
292
+ if (buffer !== '') {
293
+ yield pushToken(buffer);
294
+ buffer = '';
295
+ }
296
+ yield pushToken('', 'Gt');
297
+ consumeWhiteSpace();
298
+ break;
299
+ case '.':
300
+ const codepoint = peek().charCodeAt(0);
301
+ if (!isDigit(codepoint) && buffer !== '') {
302
+ yield pushToken(buffer);
303
+ buffer = value;
304
+ break;
305
+ }
306
+ buffer += value;
307
+ break;
308
+ case '+':
309
+ case ':':
310
+ case ',':
311
+ case '=':
312
+ if (buffer.length > 0) {
313
+ yield pushToken(buffer);
314
+ buffer = '';
315
+ }
316
+ if (value == ':' && ':' == peek()) {
317
+ buffer += value + next();
318
+ break;
319
+ }
320
+ yield pushToken(value);
321
+ buffer = '';
322
+ if (value == '+' && isWhiteSpace(peek().charCodeAt(0))) {
323
+ yield pushToken(next());
324
+ }
325
+ while (isWhiteSpace(peek().charCodeAt(0))) {
326
+ next();
327
+ }
328
+ break;
329
+ case ')':
330
+ if (buffer.length > 0) {
331
+ yield pushToken(buffer);
332
+ buffer = '';
333
+ }
334
+ yield pushToken('', 'End-parens');
335
+ break;
336
+ case '(':
337
+ if (buffer.length == 0) {
338
+ yield pushToken('', 'Start-parens');
339
+ break;
340
+ }
341
+ buffer += value;
342
+ // @ts-ignore
343
+ if (buffer == 'url(') {
344
+ yield pushToken(buffer);
345
+ buffer = '';
346
+ // consume either string or url token
347
+ let whitespace = '';
348
+ value = peek();
349
+ while (isWhiteSpace(value.charCodeAt(0))) {
350
+ whitespace += value;
351
+ }
352
+ if (whitespace.length > 0) {
353
+ next(whitespace.length);
354
+ }
355
+ value = peek();
356
+ if (value == '"' || value == "'") {
357
+ yield* consumeString(next());
358
+ break;
359
+ }
360
+ else {
361
+ buffer = '';
362
+ do {
363
+ let cp = value.charCodeAt(0);
364
+ // EOF -
365
+ if (cp == null) {
366
+ yield pushToken('', 'Bad-url-token');
367
+ break;
368
+ }
369
+ // ')'
370
+ if (cp == 0x29 || cp == null) {
371
+ if (buffer.length == 0) {
372
+ yield pushToken(buffer, 'Bad-url-token');
373
+ }
374
+ else {
375
+ yield pushToken(buffer, 'Url-token');
376
+ }
377
+ if (cp != null) {
378
+ yield pushToken(next());
379
+ }
380
+ break;
381
+ }
382
+ if (isWhiteSpace(cp)) {
383
+ whitespace = next();
384
+ while (true) {
385
+ value = peek();
386
+ cp = value.charCodeAt(0);
387
+ if (isWhiteSpace(cp)) {
388
+ whitespace += value;
389
+ continue;
390
+ }
391
+ break;
392
+ }
393
+ if (cp == null || cp == 0x29) {
394
+ continue;
395
+ }
396
+ // bad url token
397
+ buffer += next(whitespace.length);
398
+ do {
399
+ value = peek();
400
+ cp = value.charCodeAt(0);
401
+ if (cp == null || cp == 0x29) {
402
+ break;
403
+ }
404
+ buffer += next();
405
+ } while (true);
406
+ yield pushToken(buffer, 'Bad-url-token');
407
+ continue;
408
+ }
409
+ buffer += next();
410
+ value = peek();
411
+ } while (true);
412
+ buffer = '';
413
+ }
414
+ break;
415
+ }
416
+ yield pushToken(buffer);
417
+ buffer = '';
418
+ break;
419
+ case '[':
420
+ case ']':
421
+ case '{':
422
+ case '}':
423
+ case ';':
424
+ if (buffer.length > 0) {
425
+ yield pushToken(buffer);
426
+ buffer = '';
427
+ }
428
+ yield pushToken(value);
429
+ break;
430
+ case '!':
431
+ if (buffer.length > 0) {
432
+ yield pushToken(buffer);
433
+ buffer = '';
434
+ }
435
+ const important = peek(9);
436
+ if (important == 'important') {
437
+ yield pushToken('', 'Important');
438
+ next(9);
439
+ buffer = '';
440
+ break;
441
+ }
442
+ buffer = '!';
443
+ break;
444
+ default:
445
+ buffer += value;
446
+ break;
447
+ }
448
+ }
449
+ if (buffer.length > 0) {
450
+ yield pushToken(buffer);
451
+ }
452
+ }
453
+
454
+ export { tokenize };
@@ -1,13 +1,37 @@
1
1
  function eq(a, b) {
2
- if ((typeof a != 'object') || typeof b != 'object') {
2
+ if (a == null || b == null) {
3
+ return a == b;
4
+ }
5
+ if (typeof a != 'object' || typeof b != 'object') {
3
6
  return a === b;
4
7
  }
8
+ if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) {
9
+ return false;
10
+ }
11
+ if (Array.isArray(a)) {
12
+ if (a.length != b.length) {
13
+ return false;
14
+ }
15
+ let i = 0;
16
+ for (; i < a.length; i++) {
17
+ if (!eq(a[i], b[i])) {
18
+ return false;
19
+ }
20
+ }
21
+ return true;
22
+ }
5
23
  const k1 = Object.keys(a);
6
24
  const k2 = Object.keys(b);
7
- return k1.length == k2.length &&
8
- k1.every((key) => {
9
- return eq(a[key], b[key]);
10
- });
25
+ if (k1.length != k2.length) {
26
+ return false;
27
+ }
28
+ let key;
29
+ for (key of k1) {
30
+ if (!eq(a[key], b[key])) {
31
+ return false;
32
+ }
33
+ }
34
+ return true;
11
35
  }
12
36
 
13
37
  export { eq };
@@ -2,13 +2,14 @@
2
2
  // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
3
3
  // '\\'
4
4
  const REVERSE_SOLIDUS = 0x5c;
5
+ const dimensionUnits = [
6
+ 'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
7
+ 'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
8
+ 'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
9
+ 'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
10
+ ];
5
11
  function isLength(dimension) {
6
- return 'unit' in dimension && [
7
- 'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
8
- 'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
9
- 'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
10
- 'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
11
- ].includes(dimension.unit.toLowerCase());
12
+ return 'unit' in dimension && dimensionUnits.includes(dimension.unit.toLowerCase());
12
13
  }
13
14
  function isResolution(dimension) {
14
15
  return 'unit' in dimension && ['dpi', 'dpcm', 'dppx', 'x'].includes(dimension.unit.toLowerCase());
@@ -86,10 +87,7 @@ function isHash(name) {
86
87
  if (name.charAt(0) != '#') {
87
88
  return false;
88
89
  }
89
- if (isIdent(name.charAt(1))) {
90
- return true;
91
- }
92
- return true;
90
+ return isIdent(name.charAt(1));
93
91
  }
94
92
  function isNumber(name) {
95
93
  if (name.length == 0) {
@@ -233,6 +231,22 @@ function isHexColor(name) {
233
231
  }
234
232
  return true;
235
233
  }
234
+ function isHexDigit(name) {
235
+ if (name.length || name.length > 6) {
236
+ return false;
237
+ }
238
+ for (let chr of name) {
239
+ let codepoint = chr.charCodeAt(0);
240
+ if (!isDigit(codepoint) &&
241
+ // A F
242
+ !(codepoint >= 0x41 && codepoint <= 0x46) &&
243
+ // a f
244
+ !(codepoint >= 0x61 && codepoint <= 0x66)) {
245
+ return false;
246
+ }
247
+ }
248
+ return true;
249
+ }
236
250
  function isFunction(name) {
237
251
  return name.endsWith('(') && isIdent(name.slice(0, -1));
238
252
  }
@@ -249,4 +263,4 @@ function isWhiteSpace(codepoint) {
249
263
  codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
250
264
  }
251
265
 
252
- export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
266
+ export { isAngle, isAtKeyword, isDigit, isDimension, isFrequency, isFunction, isHash, isHexColor, isHexDigit, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
@@ -1,7 +1,8 @@
1
- import { rgb2Hex, hsl2Hex, hwb2hex, cmyk2hex, NAMES_COLORS } from './utils/color.js';
1
+ import { COLORS_NAMES, rgb2Hex, hsl2Hex, hwb2hex, cmyk2hex, NAMES_COLORS } from './utils/color.js';
2
2
 
3
3
  function render(data, opt = {}) {
4
- const options = Object.assign(opt.compress ? {
4
+ const startTime = performance.now();
5
+ const options = Object.assign(opt.minify ?? true ? {
5
6
  indent: '',
6
7
  newLine: '',
7
8
  removeComments: true
@@ -19,7 +20,9 @@ function render(data, opt = {}) {
19
20
  }
20
21
  return acc + renderToken(curr, options);
21
22
  }
22
- return { code: doRender(data, options, reducer, 0) };
23
+ return { code: doRender(data, options, reducer, 0), stats: {
24
+ total: `${(performance.now() - startTime).toFixed(2)}ms`
25
+ } };
23
26
  }
24
27
  // @ts-ignore
25
28
  function doRender(data, options, reducer, level = 0, indents = []) {
@@ -48,7 +51,7 @@ function doRender(data, options, reducer, level = 0, indents = []) {
48
51
  case 'AtRule':
49
52
  case 'Rule':
50
53
  if (data.typ == 'AtRule' && !('chi' in data)) {
51
- return `${indent}@${data.nam} ${data.val};`;
54
+ return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`;
52
55
  }
53
56
  // @ts-ignore
54
57
  let children = data.chi.reduce((css, node) => {
@@ -60,7 +63,7 @@ function doRender(data, options, reducer, level = 0, indents = []) {
60
63
  str = `${node.nam}:${options.indent}${node.val.reduce(reducer, '').trimEnd()};`;
61
64
  }
62
65
  else if (node.typ == 'AtRule' && !('chi' in node)) {
63
- str = `@${node.nam} ${node.val};`;
66
+ str = `${data.val === '' ? '' : options.indent || ' '}${data.val};`;
64
67
  }
65
68
  else {
66
69
  str = doRender(node, options, reducer, level + 1, indents);
@@ -77,7 +80,7 @@ function doRender(data, options, reducer, level = 0, indents = []) {
77
80
  children = children.slice(0, -1);
78
81
  }
79
82
  if (data.typ == 'AtRule') {
80
- return `@${data.nam}${data.val ? ' ' + data.val + options.indent : ''}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
83
+ return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
81
84
  }
82
85
  return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
83
86
  }
@@ -86,8 +89,11 @@ function doRender(data, options, reducer, level = 0, indents = []) {
86
89
  function renderToken(token, options = {}) {
87
90
  switch (token.typ) {
88
91
  case 'Color':
89
- if (options.compress || options.colorConvert) {
90
- let value = token.kin == 'hex' ? token.val.toLowerCase() : '';
92
+ if (options.minify || options.colorConvert) {
93
+ if (token.kin == 'lit' && token.val.toLowerCase() == 'currentcolor') {
94
+ return 'currentcolor';
95
+ }
96
+ let value = token.kin == 'hex' ? token.val.toLowerCase() : (token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : '');
91
97
  if (token.val == 'rgb' || token.val == 'rgba') {
92
98
  value = rgb2Hex(token);
93
99
  }
@@ -131,7 +137,7 @@ function renderToken(token, options = {}) {
131
137
  case 'UrlFunc':
132
138
  case 'Pseudo-class-func':
133
139
  // @ts-ignore
134
- return ( /* options.compress && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
140
+ return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce((acc, curr) => {
135
141
  if (options.removeComments && curr.typ == 'Comment') {
136
142
  if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
137
143
  return acc;
@@ -222,9 +228,11 @@ function renderToken(token, options = {}) {
222
228
  case 'String':
223
229
  case 'Iden':
224
230
  case 'Delim':
225
- return /* options.compress && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
231
+ return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
226
232
  }
227
- throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
233
+ console.error(`unexpected token ${JSON.stringify(token, null, 1)}`);
234
+ // throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`);
235
+ return '';
228
236
  }
229
237
 
230
238
  export { render, renderToken };
@@ -2,21 +2,19 @@ import { parse } from './parser/parse.js';
2
2
  import { render } from './renderer/render.js';
3
3
 
4
4
  async function transform(css, options = {}) {
5
- options = { compress: true, removeEmpty: true, ...options };
5
+ options = { minify: true, removeEmpty: true, ...options };
6
6
  const startTime = performance.now();
7
- const parseResult = await parse(css, options);
8
- const renderTime = performance.now();
9
- const rendered = render(parseResult.ast, options);
10
- const endTime = performance.now();
11
- return {
12
- ...parseResult, ...rendered, stats: {
13
- bytesIn: parseResult.bytesIn,
14
- bytesOut: rendered.code.length,
15
- parse: `${(renderTime - startTime).toFixed(2)}ms`,
16
- render: `${(endTime - renderTime).toFixed(2)}ms`,
17
- total: `${(endTime - startTime).toFixed(2)}ms`
18
- }
19
- };
7
+ return parse(css, options).then((parseResult) => {
8
+ const rendered = render(parseResult.ast, options);
9
+ return {
10
+ ...parseResult, ...rendered, stats: {
11
+ bytesOut: rendered.code.length,
12
+ ...parseResult.stats,
13
+ render: rendered.stats.total,
14
+ total: `${(performance.now() - startTime).toFixed(2)}ms`
15
+ }
16
+ };
17
+ });
20
18
  }
21
19
 
22
20
  export { transform };
@@ -1,4 +1,5 @@
1
1
  import { parse as parse$1 } from '../lib/parser/parse.js';
2
+ export { parseString, urlTokenMatcher } from '../lib/parser/parse.js';
2
3
  import '../lib/renderer/utils/color.js';
3
4
  import { transform as transform$1 } from '../lib/transform.js';
4
5
  import { load } from './load.js';