@ismail-elkorchi/css-parser 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # @ismail-elkorchi/css-parser
2
2
 
3
- Deterministic CSS parsing and selector evaluation for automation pipelines that need stable output across Node, Deno, Bun, and modern browsers.
3
+ Deterministic CSS parsing and selector utilities for automation across Node, Deno, Bun, and modern browsers.
4
+
5
+ No runtime dependencies: this package ships with zero runtime dependencies.
6
+
7
+ ## When To Use
8
+
9
+ - You need deterministic CSS parse/serialize output.
10
+ - You need selector querying without browser-engine side effects.
11
+ - You need explicit resource budgets for untrusted stylesheets.
12
+
13
+ ## When Not To Use
14
+
15
+ - You need browser layout/cascade computation.
16
+ - You need stylesheet sanitization and policy enforcement in one step.
17
+ - You need script or DOM runtime semantics.
4
18
 
5
19
  ## Install
6
20
 
@@ -12,25 +26,31 @@ npm install @ismail-elkorchi/css-parser
12
26
  deno add jsr:@ismail-elkorchi/css-parser
13
27
  ```
14
28
 
29
+ ## Import
30
+
31
+ ```ts
32
+ import { parse } from "@ismail-elkorchi/css-parser";
33
+ ```
34
+
15
35
  ```txt
16
36
  import { parse } from "jsr:@ismail-elkorchi/css-parser";
17
37
  ```
18
38
 
19
- ## Success Path
39
+ ## Copy/Paste Examples
40
+
41
+ ### Example 1: Parse CSS
20
42
 
21
43
  ```ts
22
- import {
23
- compileSelectorList,
24
- parse,
25
- parseStream,
26
- querySelectorAll,
27
- serialize
28
- } from "@ismail-elkorchi/css-parser";
29
-
30
- const css = ".card { color: red; } #content .card { margin: 1px; }";
31
- const parsed = parse(css, {
32
- budgets: { maxInputBytes: 4096, maxNodes: 256, maxDepth: 32 }
33
- });
44
+ import { parse } from "@ismail-elkorchi/css-parser";
45
+
46
+ const tree = parse(".card { color: red; }");
47
+ console.log(tree.kind);
48
+ ```
49
+
50
+ ### Example 2: Parse streaming input
51
+
52
+ ```ts
53
+ import { parseStream } from "@ismail-elkorchi/css-parser";
34
54
 
35
55
  const stream = new ReadableStream({
36
56
  start(controller) {
@@ -39,62 +59,54 @@ const stream = new ReadableStream({
39
59
  }
40
60
  });
41
61
 
42
- const streamed = await parseStream(stream, {
43
- budgets: { maxInputBytes: 4096, maxBufferedBytes: 256, maxNodes: 256 }
44
- });
45
-
46
- const selector = compileSelectorList("#content .card");
47
- const root = {
48
- kind: "document",
49
- children: [{ kind: "element", tagName: "main", attributes: [{ name: "id", value: "content" }], children: [] }]
50
- };
51
-
52
- console.log(querySelectorAll(selector, root).length);
53
- console.log(serialize(parsed));
54
- console.log(serialize(streamed));
62
+ const tree = await parseStream(stream, { budgets: { maxInputBytes: 4096, maxBufferedBytes: 512 } });
63
+ console.log(tree.kind);
55
64
  ```
56
65
 
57
- Runnable examples:
58
-
59
- ```bash
60
- npm run examples:run
61
- ```
62
-
63
- ## Options / API Reference
64
-
65
- - [Options and API reference](./docs/reference/options.md)
66
+ ### Example 3: Query selectors
66
67
 
67
- ## When To Use
68
+ ```ts
69
+ import { compileSelectorList, querySelectorAll } from "@ismail-elkorchi/css-parser";
68
70
 
69
- - You need deterministic CSS parse/serialize behavior for repeatable tooling.
70
- - You need parse budgets to bound runtime work and memory growth.
71
- - You need selector matching utilities in the same package as parsing.
71
+ const selector = compileSelectorList(".card");
72
+ console.log(selector.supported, querySelectorAll(selector, { kind: "document", children: [] }).length);
73
+ ```
72
74
 
73
- ## When Not To Use
75
+ ### Example 4: Extract render signals
74
76
 
75
- - You need a browser layout engine.
76
- - You need CSS sanitization or policy enforcement beyond parsing.
77
- - You need runtime execution of scripts or DOM behavior.
77
+ ```ts
78
+ import { extractRenderSignals, parse } from "@ismail-elkorchi/css-parser";
78
79
 
79
- ## Security Note
80
+ const tree = parse(".card { color: red; }");
81
+ console.log(extractRenderSignals(tree).length >= 0);
82
+ ```
80
83
 
81
- Use explicit budgets for untrusted input and fail closed on `BudgetExceededError`. Parsing validates syntax structure, not trust or safety policy. See [SECURITY.md](./SECURITY.md).
84
+ Run packaged examples:
82
85
 
83
- ## Runtime Compatibility
86
+ ```bash
87
+ npm run examples:run
88
+ ```
84
89
 
85
- - Node.js (current LTS and current stable)
86
- - Deno (stable)
87
- - Bun (stable)
88
- - Modern evergreen browsers (smoke-tested)
90
+ ## Compatibility
89
91
 
90
- ## No Runtime Dependencies
92
+ Runtime compatibility matrix:
91
93
 
92
- No runtime dependencies are used by production parser code.
94
+ | Runtime | Status |
95
+ | --- | --- |
96
+ | Node.js | Supported |
97
+ | Deno | Supported |
98
+ | Bun | Supported |
99
+ | Browser (evergreen) | Supported |
93
100
 
94
- ## Docs Map
101
+ ## Security and Safety Notes
95
102
 
96
- - [Documentation index](./docs/index.md)
103
+ Parsing is not sanitization. For untrusted input:
104
+ - configure strict budgets,
105
+ - handle `BudgetExceededError` explicitly,
106
+ - apply separate policy checks before execution or rendering.
97
107
 
98
- ## Release Trigger
108
+ ## Documentation
99
109
 
100
- See [RELEASING.md](./RELEASING.md) for required secrets, trigger methods, and post-publish checks.
110
+ - [Docs index](./docs/index.md)
111
+ - [First parse success tutorial](./docs/tutorial/first-parse.md)
112
+ - [Options reference](./docs/reference/options.md)
@@ -3,33 +3,67 @@ export type { BudgetExceededPayload, BudgetOptions, CompiledSelector, CompiledSe
3
3
  export declare class BudgetExceededError extends Error {
4
4
  readonly payload: BudgetExceededPayload;
5
5
  constructor(payload: BudgetExceededPayload);
6
- }
6
+ } /**
7
+ * Represents a structured public error for `PatchPlanningError` failure cases.
8
+ */
7
9
  export declare class PatchPlanningError extends Error {
8
10
  readonly payload: PatchPlanningErrorPayload;
9
11
  constructor(payload: PatchPlanningErrorPayload);
10
12
  }
11
- export declare function parse(css: string, options?: ParseOptions): StyleSheetTree;
12
- export declare function parseFragment(css: string, contextTagName: string, options?: ParseOptions): FragmentTree;
13
- export declare function parseRuleList(css: string, options?: ParseOptions): FragmentTree;
14
- export declare function parseDeclarationList(css: string, options?: ParseOptions): FragmentTree;
13
+ export declare function parse(css: string, options?: ParseOptions): StyleSheetTree; /**
14
+ * Parses input deterministically for the `parseFragment` public API.
15
+ */
16
+ export declare function parseFragment(css: string, contextTagName: string, options?: ParseOptions): FragmentTree; /**
17
+ * Parses input deterministically for the `parseRuleList` public API.
18
+ */
19
+ export declare function parseRuleList(css: string, options?: ParseOptions): FragmentTree; /**
20
+ * Parses input deterministically for the `parseDeclarationList` public API.
21
+ */
22
+ export declare function parseDeclarationList(css: string, options?: ParseOptions): FragmentTree; /**
23
+ * Returns deterministic public metadata for `getParseErrorSpecRef`.
24
+ */
15
25
  export declare function getParseErrorSpecRef(parseErrorId: string): string;
16
- export declare function tokenize(css: string, options?: TokenizeOptions): readonly Token[];
17
- export declare function tokenizeStream(stream: ReadableStream<Uint8Array>, options?: TokenizeOptions): AsyncIterable<Token>;
18
- export declare function parseBytes(bytes: Uint8Array, options?: ParseOptions): StyleSheetTree;
26
+ export declare function tokenize(css: string, options?: TokenizeOptions): readonly Token[]; /**
27
+ * Tokenizes input deterministically for the `tokenizeStream` public API.
28
+ */
29
+ export declare function tokenizeStream(stream: ReadableStream<Uint8Array>, options?: TokenizeOptions): AsyncIterable<Token>; /**
30
+ * Parses input deterministically for the `parseBytes` public API.
31
+ */
32
+ export declare function parseBytes(bytes: Uint8Array, options?: ParseOptions): StyleSheetTree; /**
33
+ * Parses input deterministically for the `parseStream` public API.
34
+ */
19
35
  export declare function parseStream(stream: ReadableStream<Uint8Array>, options?: ParseOptions): Promise<StyleSheetTree>;
20
36
  export declare function serialize(treeOrNode: StyleSheetTree | FragmentTree | CssNode): string;
21
- export declare function walk(tree: StyleSheetTree | FragmentTree, visitor: NodeVisitor): void;
22
- export declare function walkByType(tree: StyleSheetTree | FragmentTree, type: string, visitor: NodeVisitor): void;
23
- export declare function findById(tree: StyleSheetTree | FragmentTree, id: NodeId): CssNode | null;
24
- export declare function findAllByType(tree: StyleSheetTree | FragmentTree, type: string): IterableIterator<CssNode>;
37
+ export declare function walk(tree: StyleSheetTree | FragmentTree, visitor: NodeVisitor): void; /**
38
+ * Traverses parsed data deterministically for the `walkByType` public API.
39
+ */
40
+ export declare function walkByType(tree: StyleSheetTree | FragmentTree, type: string, visitor: NodeVisitor): void; /**
41
+ * Traverses parsed data deterministically for the `findById` public API.
42
+ */
43
+ export declare function findById(tree: StyleSheetTree | FragmentTree, id: NodeId): CssNode | null; /**
44
+ * Traverses parsed data deterministically for the `findAllByType` public API.
45
+ */
46
+ export declare function findAllByType(tree: StyleSheetTree | FragmentTree, type: string): IterableIterator<CssNode>; /**
47
+ * Provides deterministic public behavior for `outline`.
48
+ */
25
49
  export declare function outline(tree: StyleSheetTree | FragmentTree): Outline;
26
50
  export declare function chunk(tree: StyleSheetTree | FragmentTree, options?: ChunkOptions): Chunk[];
27
- export declare function applyPatchPlan(originalCss: string, plan: PatchPlan): string;
51
+ export declare function applyPatchPlan(originalCss: string, plan: PatchPlan): string; /**
52
+ * Computes deterministic public output for `computePatch`.
53
+ */
28
54
  export declare function computePatch(originalCss: string, edits: readonly Edit[]): PatchPlan;
29
55
  export declare function compileSelectorList(selectorText: string): CompiledSelectorList;
30
- export declare function extractStyleRuleSignals(cssOrTree: string | StyleSheetTree, options?: StyleSignalOptions): readonly StyleRuleSignal[];
31
- export declare function extractInlineStyleSignals(styleText: string): readonly StyleDeclarationSignal[];
32
- export declare function extractRenderSignals(cssOrTree: string | StyleSheetTree, options?: RenderSignalOptions): readonly RenderSignal[];
56
+ export declare function extractStyleRuleSignals(cssOrTree: string | StyleSheetTree, options?: StyleSignalOptions): readonly StyleRuleSignal[]; /**
57
+ * Extracts deterministic public data for `extractInlineStyleSignals`.
58
+ */
59
+ export declare function extractInlineStyleSignals(styleText: string): readonly StyleDeclarationSignal[]; /**
60
+ * Extracts deterministic public data for `extractRenderSignals`.
61
+ */
62
+ export declare function extractRenderSignals(cssOrTree: string | StyleSheetTree, options?: RenderSignalOptions): readonly RenderSignal[]; /**
63
+ * Extracts deterministic public data for `extractInlineRenderSignals`.
64
+ */
33
65
  export declare function extractInlineRenderSignals(styleText: string, options?: RenderSignalOptions): readonly RenderSignal[];
34
- export declare function matchesSelector<TNode extends SelectorNodeLike>(selector: string | CompiledSelectorList, node: TNode, root: TNode, options?: SelectorQueryOptions): boolean;
66
+ export declare function matchesSelector<TNode extends SelectorNodeLike>(selector: string | CompiledSelectorList, node: TNode, root: TNode, options?: SelectorQueryOptions): boolean; /**
67
+ * Traverses parsed data deterministically for the `querySelectorAll` public API.
68
+ */
35
69
  export declare function querySelectorAll<TNode extends SelectorNodeLike>(selector: string | CompiledSelectorList, root: TNode, options?: SelectorQueryOptions): readonly TNode[];
@@ -18,7 +18,9 @@ const SUPPORTED_PARSE_CONTEXTS = new Set([
18
18
  "declarationList",
19
19
  "declaration",
20
20
  "value"
21
- ]);
21
+ ]); /**
22
+ * Represents a structured public error for `BudgetExceededError` failure cases.
23
+ */
22
24
  export class BudgetExceededError extends Error {
23
25
  payload;
24
26
  constructor(payload) {
@@ -26,7 +28,9 @@ export class BudgetExceededError extends Error {
26
28
  this.name = "BudgetExceededError";
27
29
  this.payload = payload;
28
30
  }
29
- }
31
+ } /**
32
+ * Represents a structured public error for `PatchPlanningError` failure cases.
33
+ */
30
34
  export class PatchPlanningError extends Error {
31
35
  payload;
32
36
  constructor(payload) {
@@ -418,7 +422,9 @@ function parseInternal(css, context, options = {}) {
418
422
  errors: publicErrors,
419
423
  ...(trace ? { trace } : {})
420
424
  };
421
- }
425
+ } /**
426
+ * Parses input deterministically for the `parse` public API.
427
+ */
422
428
  export function parse(css, options = {}) {
423
429
  if (options.context !== undefined && options.context !== "stylesheet") {
424
430
  throw new Error("parse() only supports context \"stylesheet\"; use parseFragment() for other contexts");
@@ -433,7 +439,9 @@ export function parse(css, options = {}) {
433
439
  errors: parsed.errors,
434
440
  ...(parsed.trace ? { trace: parsed.trace } : {})
435
441
  };
436
- }
442
+ } /**
443
+ * Parses input deterministically for the `parseFragment` public API.
444
+ */
437
445
  export function parseFragment(css, contextTagName, options = {}) {
438
446
  const context = normalizeFragmentContext(contextTagName);
439
447
  if (!SUPPORTED_PARSE_CONTEXTS.has(context)) {
@@ -449,13 +457,19 @@ export function parseFragment(css, contextTagName, options = {}) {
449
457
  errors: parsed.errors,
450
458
  ...(parsed.trace ? { trace: parsed.trace } : {})
451
459
  };
452
- }
460
+ } /**
461
+ * Parses input deterministically for the `parseRuleList` public API.
462
+ */
453
463
  export function parseRuleList(css, options = {}) {
454
464
  return parseFragment(css, "rule", options);
455
- }
465
+ } /**
466
+ * Parses input deterministically for the `parseDeclarationList` public API.
467
+ */
456
468
  export function parseDeclarationList(css, options = {}) {
457
469
  return parseFragment(css, "declarationList", options);
458
- }
470
+ } /**
471
+ * Returns deterministic public metadata for `getParseErrorSpecRef`.
472
+ */
459
473
  export function getParseErrorSpecRef(parseErrorId) {
460
474
  void parseErrorId;
461
475
  return CSS_PARSE_ERRORS_SECTION_URL;
@@ -568,7 +582,9 @@ async function decodeStreamToText(stream, options) {
568
582
  totalBytes: total,
569
583
  maxBufferedObserved
570
584
  };
571
- }
585
+ } /**
586
+ * Tokenizes input deterministically for the `tokenize` public API.
587
+ */
572
588
  export function tokenize(css, options = {}) {
573
589
  enforceBudget("maxInputBytes", options.budgets?.maxInputBytes, css.length);
574
590
  const tokenized = tokenizeInternal(css, {
@@ -579,14 +595,18 @@ export function tokenize(css, options = {}) {
579
595
  });
580
596
  enforceBudget("maxTokens", options.budgets?.maxTokens, tokenized.tokens.length);
581
597
  return tokenized.tokens.map((token) => toPublicToken(token));
582
- }
598
+ } /**
599
+ * Tokenizes input deterministically for the `tokenizeStream` public API.
600
+ */
583
601
  export async function* tokenizeStream(stream, options = {}) {
584
602
  const decoded = await decodeStreamToText(stream, options);
585
603
  const tokens = tokenize(decoded.text, options);
586
604
  for (const token of tokens) {
587
605
  yield token;
588
606
  }
589
- }
607
+ } /**
608
+ * Parses input deterministically for the `parseBytes` public API.
609
+ */
590
610
  export function parseBytes(bytes, options = {}) {
591
611
  enforceBudget("maxInputBytes", options.budgets?.maxInputBytes, bytes.byteLength);
592
612
  const decoded = decodeCssBytes(bytes, {
@@ -609,7 +629,9 @@ export function parseBytes(bytes, options = {}) {
609
629
  ...parsed,
610
630
  trace: withDecodeTrace
611
631
  };
612
- }
632
+ } /**
633
+ * Parses input deterministically for the `parseStream` public API.
634
+ */
613
635
  export async function parseStream(stream, options = {}) {
614
636
  const budgets = options.budgets;
615
637
  const decoded = await decodeStreamToText(stream, options);
@@ -645,7 +667,9 @@ function nodeFromTree(treeOrNode) {
645
667
  return treeOrNode.root;
646
668
  }
647
669
  return treeOrNode;
648
- }
670
+ } /**
671
+ * Serializes data deterministically for the `serialize` public API.
672
+ */
649
673
  export function serialize(treeOrNode) {
650
674
  const node = nodeFromTree(treeOrNode);
651
675
  const sanitized = sanitizeCssNode(node);
@@ -656,10 +680,14 @@ function walkNode(node, depth, visitor) {
656
680
  for (const child of childNodes(node)) {
657
681
  walkNode(child, depth + 1, visitor);
658
682
  }
659
- }
683
+ } /**
684
+ * Traverses parsed data deterministically for the `walk` public API.
685
+ */
660
686
  export function walk(tree, visitor) {
661
687
  walkNode(tree.root, 0, visitor);
662
- }
688
+ } /**
689
+ * Traverses parsed data deterministically for the `walkByType` public API.
690
+ */
663
691
  export function walkByType(tree, type, visitor) {
664
692
  const normalizedType = type.toLowerCase();
665
693
  walk(tree, (node, depth) => {
@@ -667,7 +695,9 @@ export function walkByType(tree, type, visitor) {
667
695
  visitor(node, depth);
668
696
  }
669
697
  });
670
- }
698
+ } /**
699
+ * Traverses parsed data deterministically for the `findById` public API.
700
+ */
671
701
  export function findById(tree, id) {
672
702
  let matched = null;
673
703
  walk(tree, (node) => {
@@ -676,7 +706,9 @@ export function findById(tree, id) {
676
706
  }
677
707
  });
678
708
  return matched;
679
- }
709
+ } /**
710
+ * Traverses parsed data deterministically for the `findAllByType` public API.
711
+ */
680
712
  export function* findAllByType(tree, type) {
681
713
  const normalizedType = type.toLowerCase();
682
714
  const found = [];
@@ -688,7 +720,9 @@ export function* findAllByType(tree, type) {
688
720
  for (const node of found) {
689
721
  yield node;
690
722
  }
691
- }
723
+ } /**
724
+ * Provides deterministic public behavior for `outline`.
725
+ */
692
726
  export function outline(tree) {
693
727
  const entries = [];
694
728
  walk(tree, (node, depth) => {
@@ -717,7 +751,9 @@ function countNodes(node) {
717
751
  }
718
752
  function topLevelNodes(tree) {
719
753
  return tree.children.length > 0 ? tree.children : [tree.root];
720
- }
754
+ } /**
755
+ * Provides deterministic public behavior for `chunk`.
756
+ */
721
757
  export function chunk(tree, options = {}) {
722
758
  const maxChars = options.maxChars ?? 8192;
723
759
  const maxNodes = options.maxNodes ?? 256;
@@ -845,7 +881,9 @@ function buildReplacement(spanByNode, nodeById, edit, sourceIndex) {
845
881
  end: span.end,
846
882
  replacementCss: edit.css
847
883
  };
848
- }
884
+ } /**
885
+ * Provides deterministic public behavior for `applyPatchPlan`.
886
+ */
849
887
  export function applyPatchPlan(originalCss, plan) {
850
888
  let cursor = 0;
851
889
  let output = "";
@@ -864,7 +902,9 @@ export function applyPatchPlan(originalCss, plan) {
864
902
  output += step.text;
865
903
  }
866
904
  return output;
867
- }
905
+ } /**
906
+ * Computes deterministic public output for `computePatch`.
907
+ */
868
908
  export function computePatch(originalCss, edits) {
869
909
  if (edits.length === 0) {
870
910
  const steps = [
@@ -1400,7 +1440,9 @@ function compileSingleSelector(selectorNode, selectorIndex) {
1400
1440
  supported: unsupported.length === 0,
1401
1441
  unsupportedParts: unsupported
1402
1442
  };
1403
- }
1443
+ } /**
1444
+ * Provides deterministic public behavior for `compileSelectorList`.
1445
+ */
1404
1446
  export function compileSelectorList(selectorText) {
1405
1447
  const parsed = parseFragment(selectorText, "selectorList");
1406
1448
  const selectorNodes = Array.isArray(parsed.root.children)
@@ -1536,7 +1578,9 @@ function classifyRenderSignalClass(declaration, options) {
1536
1578
  }
1537
1579
  }
1538
1580
  return null;
1539
- }
1581
+ } /**
1582
+ * Extracts deterministic public data for `extractStyleRuleSignals`.
1583
+ */
1540
1584
  export function extractStyleRuleSignals(cssOrTree, options = {}) {
1541
1585
  const includeUnsupportedSelectors = options.includeUnsupportedSelectors === true;
1542
1586
  const strictSelectors = options.strictSelectors === true;
@@ -1580,7 +1624,9 @@ export function extractStyleRuleSignals(cssOrTree, options = {}) {
1580
1624
  });
1581
1625
  });
1582
1626
  return signals;
1583
- }
1627
+ } /**
1628
+ * Extracts deterministic public data for `extractInlineStyleSignals`.
1629
+ */
1584
1630
  export function extractInlineStyleSignals(styleText) {
1585
1631
  const fragment = parseDeclarationList(styleText);
1586
1632
  const signals = [];
@@ -1594,7 +1640,9 @@ export function extractInlineStyleSignals(styleText) {
1594
1640
  declarationOrder += 1;
1595
1641
  }
1596
1642
  return signals;
1597
- }
1643
+ } /**
1644
+ * Extracts deterministic public data for `extractRenderSignals`.
1645
+ */
1598
1646
  export function extractRenderSignals(cssOrTree, options = {}) {
1599
1647
  const ruleSignals = extractStyleRuleSignals(cssOrTree, options);
1600
1648
  const renderSignals = [];
@@ -1619,7 +1667,9 @@ export function extractRenderSignals(cssOrTree, options = {}) {
1619
1667
  }
1620
1668
  }
1621
1669
  return renderSignals;
1622
- }
1670
+ } /**
1671
+ * Extracts deterministic public data for `extractInlineRenderSignals`.
1672
+ */
1623
1673
  export function extractInlineRenderSignals(styleText, options = {}) {
1624
1674
  const declarations = extractInlineStyleSignals(styleText);
1625
1675
  const renderSignals = [];
@@ -1664,7 +1714,9 @@ function resolveCompiledSelectorList(selector) {
1664
1714
  }
1665
1715
  }
1666
1716
  return compiled;
1667
- }
1717
+ } /**
1718
+ * Provides deterministic public behavior for `matchesSelector`.
1719
+ */
1668
1720
  export function matchesSelector(selector, node, root, options = {}) {
1669
1721
  const compiled = resolveCompiledSelectorList(selector);
1670
1722
  assertSelectorStrict(compiled, options.strict === true);
@@ -1681,7 +1733,9 @@ export function matchesSelector(selector, node, root, options = {}) {
1681
1733
  }
1682
1734
  }
1683
1735
  return false;
1684
- }
1736
+ } /**
1737
+ * Traverses parsed data deterministically for the `querySelectorAll` public API.
1738
+ */
1685
1739
  export function querySelectorAll(selector, root, options = {}) {
1686
1740
  const compiled = resolveCompiledSelectorList(selector);
1687
1741
  assertSelectorStrict(compiled, options.strict === true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ismail-elkorchi/css-parser",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Deterministic CSS parser for automation workflows across Node, Deno, Bun, and modern browsers.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -48,7 +48,7 @@
48
48
  "test:bench": "npm run build && node --expose-gc scripts/bench/run-bench.mjs",
49
49
  "test:bench:stability": "npm run build && node --expose-gc scripts/bench/run-bench-stability.mjs",
50
50
  "examples:run": "npm run build && node examples/run-all.mjs",
51
- "check:fast": "npm run lint && npm run typecheck && npm run test:control && npm run examples:run",
51
+ "check:fast": "npm run lint && npm run typecheck && npm run test:control && npm run docs:required && npm run examples:run",
52
52
  "docs:lint:jsr": "deno doc --lint --sloppy-imports jsr/mod.ts",
53
53
  "docs:test:jsr": "deno test --doc --no-check --sloppy-imports jsr/mod.ts",
54
54
  "smoke:node": "npm run build && node scripts/smoke/control.mjs --runtime=node --report=reports/smoke-node.json",
@@ -65,10 +65,13 @@
65
65
  "realworld:bench:selectors:stability": "npm run build && node scripts/bench/run-selector-bench-stability.mjs",
66
66
  "realworld:check": "node scripts/realworld/check-realworld-targets.mjs",
67
67
  "eval:realworld": "npm run realworld:bench && npm run realworld:signals && npm run realworld:bench:selectors && npm run realworld:bench:selectors:stability && npm run realworld:check && node scripts/realworld/eval-realworld.mjs",
68
- "mutation:pilot": "npm run build && node scripts/mutation/run-pilot.mjs --config=scripts/mutation/pilot-config.json --out=docs/reference/mutation-pilot-report.json",
68
+ "mutation:pilot": "npm run build && node scripts/mutation/run-pilot.mjs --config=scripts/mutation/pilot-config.json --out=docs/maintainers/mutation-pilot-report.json",
69
69
  "eval:ci": "node scripts/eval/run-eval.mjs --profile=ci",
70
70
  "eval:release": "node scripts/eval/run-eval.mjs --profile=release",
71
- "eval:hard-gate": "node scripts/eval/run-eval.mjs --profile=hard-gate"
71
+ "eval:hard-gate": "node scripts/eval/run-eval.mjs --profile=hard-gate",
72
+ "docs:required": "node scripts/quality/doc-required.mjs",
73
+ "release:notes:dry-run": "node scripts/release/render-notes.mjs --dry-run",
74
+ "changelog:update:dry-run": "node scripts/release/update-changelog.mjs --dry-run"
72
75
  },
73
76
  "dependencies": {},
74
77
  "overrides": {