# Architecture

> Internal design for contributors and curious readers.
> **v1.7.0** — Understanding this document is not required to use the library.

---

## Architecture Diagram

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                          xml-xsd-engine  v1.7.0                             │
│                        Public API Surface (index.ts)                        │
└───────┬──────────┬──────────┬───────────┬───────────┬──────────┬────────────┘
        │          │          │           │           │          │
        ▼          ▼          ▼           ▼           ▼          ▼
  ┌──────────┐ ┌───────┐ ┌────────┐ ┌─────────┐ ┌────────┐ ┌────────────┐
  │  Parser  │ │  XSD  │ │Schema  │ │Validator│ │ Utils  │ │  Pipeline  │
  │  Layer   │ │ Layer │ │ Model  │ │  Layer  │ │ Layer  │ │  Layer     │
  └──────────┘ └───────┘ └────────┘ └─────────┘ └────────┘ └────────────┘

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LAYER 1 — PARSING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌─────────────────────────────────────────────────────────────────────────┐
  │  XML Source String / Stream                                             │
  └────────────────────────┬────────────────────────────────────────────────┘
                           │
                           ▼
  ┌─────────────────────────────────────────────────────────────────────────┐
  │  StringReader (utils/StringReader.ts)                                   │
  │  • consumePattern(re: sticky RegExp) — single-pass SIMD-friendly scan  │
  │  • consumeWhile(pred) — character-by-character fallback                 │
  │  • consumeUntilStr(stop) — indexOf-based fast scan                      │
  │  • skipWhitespace() — pre-compiled /[ \t\r\n]*/y                        │
  └────────────────────────┬────────────────────────────────────────────────┘
                           │
               ┌───────────┴───────────┐
               ▼                       ▼
  ┌────────────────────┐   ┌────────────────────────────────────┐
  │  XmlLexer          │   │  SaxParser                         │
  │  (state machine)   │   │  (push events: startElement,       │
  │  Tokens: OPEN_TAG  │   │   endElement, text, comment, PI)   │
  │  CLOSE_TAG, TEXT   │   │  Zero DOM allocation               │
  │  CDATA, COMMENT    │   │  Used by: StreamingValidator,      │
  │  PI, DOCTYPE, ATTR │   │  SaxInstrumentation                │
  └─────────┬──────────┘   └────────────────────────────────────┘
            │
            ▼
  ┌──────────────────────────────────────────────────────────────┐
  │  XmlParser (stack-based DOM builder)                         │
  │  • Namespace resolution via NsContext (linked chain)         │
  │  • Entity decoding & CDATA expansion                         │
  │  • ParseBudget: maxDepth / maxNodes / maxTextLength          │
  │  • XXE blocking (SEC_EXTERNAL_ENTITY on SYSTEM refs)         │
  │  • Billion-laughs guard (maxEntityExpansion)                 │
  │  Output: XmlDocument                                         │
  └──────────────────────────────────────────────────────────────┘
            │
            ▼
  ┌──────────────────────────────────────────────────────────────┐
  │  XmlDocument / XmlElement / XmlText / XmlComment / ...       │
  │  (parser/XmlNodes.ts)                                        │
  │  • childElements[]  • getAttribute()  • textContent          │
  │  • localName / namespaceURI / prefix                         │
  │  • xmlId  • xmlBase  • line / col source maps                │
  └──────────────────────────────────────────────────────────────┘

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LAYER 2 — XSD PARSING & SCHEMA MODEL
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌─────────────────────────────────────────────────────────────────────────┐
  │  XSD Source String                                                      │
  └────────────────────────┬────────────────────────────────────────────────┘
                           │
                           ▼
  ┌──────────────────────────────────────────────────────────────────────────┐
  │  XsdParser (xsd/XsdParser.ts)                                            │
  │  • Parses XSD 1.0 large subset via XmlParser (DOM-based)                │
  │  • occ() helper: NaN-guarded minOccurs/maxOccurs parsing                │
  │  • xs:import / xs:include / xs:redefine → delegates to SchemaMerger     │
  │  • Produces SchemaModel                                                  │
  └────────────┬──────────────────────────────────────────────────────────-─┘
               │
               ▼
  ┌─────────────────────────────────────────────────────────────────────────┐
  │  SchemaMerger (xsd/SchemaMerger.ts)                                     │
  │  • Deduplicates imports via Set<logicalKey>                             │
  │  • SHA-256 content-hash parse cache (Map<hash, SchemaModel>)            │
  │  • handleImport / handleInclude / handleRedefine                        │
  │  • Shared cache across all sub-parsers in same parse() call             │
  └────────────┬────────────────────────────────────────────────────────────┘
               │
               ▼
  ┌─────────────────────────────────────────────────────────────────────────┐
  │  SchemaModel (schema/SchemaModel.ts)                                    │
  │  • elements: Map<string, ElementDeclaration>                            │
  │  • complexTypes: Map<string, ComplexTypeDefinition>                     │
  │  • simpleTypes:  Map<string, SimpleTypeDefinition>                      │
  │  • attributeGroups / modelGroups / notations                            │
  │  • identityConstraints: Map<string, IdentityConstraint[]>               │
  │  • substitutionGroups: Map<string, Set<string>>                         │
  │  • resolveType() / resolveComplexType() / resolveSimpleType()           │
  └─────────────────────────────────────────────────────────────────────────┘

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LAYER 3 — SCHEMA COMPILATION (SchemaCompilerLite / G27)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌─────────────────────────────────────────────────────────────────────────┐
  │  compileSchema(SchemaModel) → CompiledSchema                            │
  │  (pipeline/SchemaCompilerLite.ts)                                       │
  │                                                                         │
  │  _compileElements()   → elements: ReadonlyMap<key, ElementDeclaration> │
  │  _compileComplexTypes() → complexTypes with merged extension chains     │
  │  _compileDfas()    ─┐  → compiledDfas: ReadonlyMap<typeName, DfaModel> │
  │  _compileIdentityConstraints()                                          │
  │  _collectAbstractElements()                                             │
  │                     │                                                   │
  │  ┌──────────────────▼────────────────────────────────────────────────┐ │
  │  │  DfaEngine (validator/DfaEngine.ts)                               │ │
  │  │  buildDfa(particles, compositor) → DfaModel                       │ │
  │  │  • particleIndex: Map<name, NormalisedParticle>  ← O(1) lookup    │ │
  │  │  • sequence / choice / all  state machines                         │ │
  │  │  runDfa(dfa, elementNames[]) → DfaRunResult                       │ │
  │  │  { valid, unexpected[], missing[], tooMany[] }                    │ │
  │  └───────────────────────────────────────────────────────────────────┘ │
  └─────────────────────────────────────────────────────────────────────────┘

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LAYER 4 — VALIDATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌─────────────────────────────────────────────────────────────────────────┐
  │  ValidationEngine (validator/ValidationEngine.ts)                       │
  │  DOM-based validation — requires XmlDocument                            │
  │                                                                         │
  │  validate(doc, schema, opts?)        → ValidationResult                 │
  │  validateSubtree(elem, schema, opts?) → ValidationResult                │
  │  validateFragment(xml, schema, opts?) → ValidationResult                │
  │  revalidateSubtree(elem, schema, opts?) → ValidationResult  ← G38      │
  │                                                                         │
  │  Internal pipeline:                                                     │
  │  1. Root element lookup                                                 │
  │  2. _validateElement() — recursive DOM walk                             │
  │  3. TypeValidator — simple type + facet checking                        │
  │  4. DFA content-model check (uses compiledDfas when available)          │
  │  5. Attribute validation                                                │
  │  6. Identity constraints (IdentityConstraintEngine)                     │
  │  7. xs:assert evaluation (AssertionEvaluator)                           │
  │  8. PSVI annotation (optional, Map<XmlElement, PsviAnnotation>)         │
  └──────────────┬──────────────────────────────────────────────────────────┘
                 │                                                    │
                 ▼                                                    ▼
  ┌──────────────────────────────────┐   ┌─────────────────────────────────┐
  │  TypeValidator                   │   │  IdentityConstraintEngine       │
  │  (validator/TypeValidator.ts)    │   │  (validator/IdentityConstraint  │
  │  • 56 built-in XSD primitive     │   │   Engine.ts)                    │
  │    types (xs:string → xs:IDREFS) │   │  • xs:key / xs:unique / keyref  │
  │  • _wsCache: whitespace mode     │   │  • Iterative post-order walk    │
  │    per type (no chain rebuild)   │   │  • Pre-built constraintNames Set │
  │  • _patternCache: max 512 RegExp │   │  • O(1) skip for unconstrained  │
  │  • Single-pass _checkFacets      │   │    elements                     │
  │  • xs:date calendar validation   │   └─────────────────────────────────┘
  └──────────────────────────────────┘

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LAYER 4b — STREAMING VALIDATION (v1.7.0)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌─────────────────────────────────────────────────────────────────────────┐
  │  StreamingValidator (validator/StreamingValidator.ts)                   │
  │  SAX-driven — no DOM required                                           │
  │                                                                         │
  │  validateStreaming(xml, compiled, opts?) → StreamingValidationResult    │
  │  validateStream(stream, compiled, opts?) → Promise<Result>              │
  │  validateStreamingGenerator(xml, compiled, opts?)                       │
  │    → AsyncGenerator<StreamingIssue, StreamingValidationResult>  ← P2   │
  │                                                                         │
  │  Internal SAX loop:                                                     │
  │  startElement → push StackFrame                                         │
  │              → check xsi:type override → resolve typeDef               │
  │              → validate attributes                                      │
  │  endElement  → feed StreamingKeyrefTracker                             │
  │             → TypeValidator (simple type or user simpleDef)            │
  │             → _validateChildOrder() → compiledDfas lookup              │
  │  After parse → keyrefTracker.validate() → referential check            │
  └──────────────────┬──────────────────────────────────────────────────────┘
                     │
                     ▼
  ┌──────────────────────────────────────────────────────────────────────────┐
  │  StreamingKeyrefTracker                                                  │
  │  • _constraintsByElement: Map<elementName, IdentityConstraint[]>         │
  │    (O(1) per-element dispatch, built once in constructor)               │
  │  • Accumulates key/unique tuples and keyref tuples in SAX pass          │
  │  • validate() resolves keyref → key after parse completes               │
  └──────────────────────────────────────────────────────────────────────────┘

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LAYER 5 — PIPELINE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌─────────────────────────────────────────────────────────────────────────┐
  │  ValidationPipeline (pipeline/ValidationPipeline.ts)                    │
  │  7-stage orchestrator:                                                  │
  │                                                                         │
  │  Stage 1: Parse XML             (parseXml)                              │
  │  Stage 2: Parse XSD             (parseXsd)                              │
  │  Stage 3: Compile schema        (compileSchema → CompiledSchema)        │
  │  Stage 4: Preflight check       (SchemaPreflight)                       │
  │  Stage 5: Validate              (ValidationEngine)                      │
  │  Stage 6: Identity constraints  (IdentityConstraintEngine)              │
  │  Stage 7: PSVI annotation       (optional, Psvi.ts)                     │
  └─────────────────────────────────────────────────────────────────────────┘

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LAYER 6 — UTILITIES & CROSS-CUTTING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌───────────────────┐  ┌───────────────────┐  ┌───────────────────────────┐
  │  XmlCanonical     │  │  XmlDiff          │  │  XPathEngine              │
  │  C14N 1.0         │  │  diffXml()        │  │  XPath 1.0 + 22 XPath 2.0 │
  │  inclusive/excl.  │  │  WeakMap finger-  │  │  Two-tier LRU cache        │
  │  withComments     │  │  print cache      │  │  cold(512) + hot(128)      │
  │  Delta ns save    │  │  O(1) ref eq fast │  │  configureXPathCache()     │
  │  WeakMap memo     │  │  path             │  │  xpathCacheStats()         │
  └───────────────────┘  └───────────────────┘  └───────────────────────────┘

  ┌───────────────────┐  ┌───────────────────┐  ┌───────────────────────────┐
  │  SchemaCache      │  │  ParseBudget      │  │  PluginRegistry           │
  │  LRU eviction     │  │  maxDepth         │  │  registerTypeValidator()  │
  │  TTL expiry       │  │  maxNodes         │  │  registerEntityResolver() │
  │  Content-hash key │  │  maxTextLen       │  │  registerTransformer()    │
  │  maxVersionsPerKey│  │  maxEntityExp.    │  │                           │
  │  statFast (mtime) │  │  Early-abort      │  │                           │
  │  get() / has()    │  │                   │  │                           │
  └───────────────────┘  └───────────────────┘  └───────────────────────────┘

  ┌───────────────────┐  ┌───────────────────┐
  │  XmlSerializer    │  │  Transforms        │
  │  DOM → string     │  │  XmlToJson         │
  │  Round-trip safe  │  │  JsonToXml         │
  │  Mixed-content    │  │  XsltTransformer   │
  └───────────────────┘  └───────────────────┘

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CACHE ARCHITECTURE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌─────────────────────────────────────────────────────────────────────────┐
  │                         Cache Layers                                    │
  │                                                                         │
  │  ┌───────────────────────────────────────────────────────────────────┐ │
  │  │  SchemaCache (LRU, content-hash, TTL, statFast)                   │ │
  │  │  key@sha256hash → CacheEntry { schema, loadedAt, statFp, deps }   │ │
  │  │  maxVersionsPerKey = 2  (prevents OOM in watch mode)              │ │
  │  └───────────────────────────────────────────────────────────────────┘ │
  │                                                                         │
  │  ┌───────────────────────────────────────────────────────────────────┐ │
  │  │  XPath LRU Cache (two-tier)                                       │ │
  │  │  Cold tier: 512 slots — newly compiled XPath expressions          │ │
  │  │  Hot tier:  128 slots — frequently evaluated expressions           │ │
  │  │  Promotion: cold entry hit → move to hot                          │ │
  │  └───────────────────────────────────────────────────────────────────┘ │
  │                                                                         │
  │  ┌───────────────────────────────────────────────────────────────────┐ │
  │  │  TypeValidator Caches (module-level)                              │ │
  │  │  _patternCache: Map<xsdPattern, RegExp>  max 512 entries (LRU)   │ │
  │  │  _wsCache:      Map<typeName, wsMode>    unbounded (type names    │ │
  │  │                                          are a bounded set)       │ │
  │  └───────────────────────────────────────────────────────────────────┘ │
  │                                                                         │
  │  ┌───────────────────────────────────────────────────────────────────┐ │
  │  │  PSVI Annotation Pool (module-level in Psvi.ts)                   │ │
  │  │  Map<"validity|type", PsviAnnotation>  max 256 entries            │ │
  │  │  Avoids per-node heap allocation on null-value annotations        │ │
  │  └───────────────────────────────────────────────────────────────────┘ │
  │                                                                         │
  │  ┌───────────────────────────────────────────────────────────────────┐ │
  │  │  SchemaMerger Parse Cache (per parse() call, optionally shared)  │ │
  │  │  Map<sha256(src), SchemaModel>  — prevents duplicate sub-parsing  │ │
  │  └───────────────────────────────────────────────────────────────────┘ │
  └─────────────────────────────────────────────────────────────────────────┘

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DATA FLOW — VALIDATE AN XML FILE AGAINST AN XSD
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  xml string          xsd string
       │                   │
       ▼                   ▼
  parseXml()         parseXsd()
       │                   │
       ▼                   ▼
  XmlDocument        SchemaModel
       │                   │
       │              compileSchema()
       │                   │
       │              CompiledSchema
       │             { elements, complexTypes,
       │               simpleTypes, compiledDfas,
       │               identityConstraints }
       │                   │
       └─────────┬─────────┘
                 │
                 ▼
          validate(doc, schema, opts?)
                 │
          ValidationEngine
          ├── _validateElement(root)
          │     ├── TypeValidator.validate(text, typeName)
          │     ├── runDfa(compiledDfas.get(type), children)
          │     └── _validateAttributes(attrs, typeDef)
          ├── IdentityConstraintEngine.evaluate(doc)
          ├── AssertionEvaluator (if xs:assert)
          └── PSVI annotation (if opts.psvi)
                 │
                 ▼
          ValidationResult
          { valid, errors[], warnings[], psvi? }

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DATA FLOW — STREAMING VALIDATION (v1.7.0)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  xml string          xsd string
       │                   │
       │              parseXsd() + compileSchema()
       │                   │
       │              CompiledSchema
       │             { compiledDfas, elements, ... }
       │                   │
       └─────────┬─────────┘
                 │
                 ▼
  validateStreaming(xml, compiled, opts?)
                 │
  SaxParser (push events)
  ├── startElement → StackFrame push
  │     ├── resolveDecl(localName, ns)
  │     ├── xsi:type override check
  │     └── validateAttributes(attrs, typeDef)
  ├── text    → frame.textContent accumulate
  └── endElement → StackFrame pop
        ├── StreamingKeyrefTracker.onElement()
        ├── TypeValidator (simpleDef or xs: builtin)
        └── _validateChildOrder()
              └── compiledDfas.get(typeKey)
                  or buildDfa() (inline types)
                 │
  (after parse) keyrefTracker.validate()
                 │
                 ▼
  StreamingValidationResult
  { valid, issues[], errorCount, warningCount, durationMs }
```

---

## Module Map

```
xml-xsd-engine
├── parser/
│   ├── XmlLexer.ts           Single-pass state-machine tokenizer (_XML_NAME_RE sticky)
│   ├── XmlParser.ts          Stack-based DOM builder (consumePattern hot path)
│   ├── XmlNodes.ts           XmlDocument, XmlElement, XmlText, XmlComment, XmlPI, ...
│   ├── XmlSerializer.ts      DOM → XML string (mixed-content aware)
│   ├── SaxParser.ts          Push SAX parser, zero DOM allocation
│   ├── SaxInstrumentation.ts Structured instrumentation wrapper (zero-cost when disabled)
│   ├── XPathEngine.ts        XPath 1.0 subset + two-tier LRU cache
│   └── XPath2Functions.ts    22 XPath 2.0 functions
├── xsd/
│   ├── XsdParser.ts          XSD 1.0 large subset → SchemaModel (NaN-guarded occ())
│   └── SchemaMerger.ts       xs:import/include/redefine + SHA-256 content-hash cache
├── schema/
│   └── SchemaModel.ts        Typed schema graph (elements, complexTypes, simpleTypes, ...)
├── namespace/
│   └── NamespaceEngine.ts    Scoped prefix→URI, linked chain, O(decls) push
├── pipeline/
│   ├── ValidationPipeline.ts 7-stage formal pipeline
│   └── SchemaCompilerLite.ts SchemaModel → CompiledSchema + compiledDfas (G27)
├── validator/
│   ├── ValidationEngine.ts   DOM-based validator; validate/validateSubtree/revalidateSubtree
│   ├── StreamingValidator.ts SAX-driven validator; G28b keyref; async generator (P2)
│   ├── DfaEngine.ts          DFA build/run; particleIndex for O(1) lookup
│   ├── TypeValidator.ts      56 XSD types; _wsCache; _patternCache(512); single-pass facets
│   ├── Psvi.ts               PsviAnnotation, PsviMap (Map-based with .size), extractPsvi
│   ├── ValidationResult.ts   ValidationIssue, ValidationResult, severity, merge()
│   ├── AssertionEvaluator.ts xs:assert with XPath; deterministic ordering
│   ├── IdentityConstraintEngine.ts xs:key/unique/keyref; iterative walk; O(1) skip
│   ├── SchemaPreflight.ts    Pre-validation schema consistency check
│   ├── BatchValidator.ts     Parallel multi-file validation
│   ├── XsdTypeSystem.ts      XSD type hierarchy and derivation queries
│   └── formatters.ts         text / compact / json / github / junit output
├── cache/
│   └── SchemaCache.ts        LRU+TTL+hash+stat cache; get()/has(); statFast option
├── utils/
│   ├── StringReader.ts       Streaming char reader; consumePattern (sticky regex)
│   ├── XmlCanonical.ts       C14N 1.0 inclusive/exclusive; delta ns; WeakMap memo
│   ├── XmlDiff.ts            diffXml(); WeakMap fingerprint; ref-eq fast path
│   ├── SchemaInference.ts    inferSchema(); ParseBudget-aware
│   ├── ParseBudget.ts        Depth/node/text/entity limits; XXE blocking
│   ├── sha256.ts             sha256Hex / sha256Short (pure TypeScript + Node.js)
│   └── xmlUtils.ts           decodeEntities, normalizeAttrValue, splitQName, ...
├── io/
│   ├── fileUtils.ts          readXmlFile / readXsdFile / validateFiles
│   └── XmlStreamParser.ts    Node.js Transform stream; chunk accumulation
├── codegen/
│   ├── XsdToJsonSchema.ts    XSD → JSON Schema Draft-07 (stream + sync)
│   ├── XsdToTypeScript.ts    XSD → TypeScript interfaces (stream + sync)
│   └── index.ts              barrel
├── transform/
│   ├── XmlToJson.ts          DOM → JSON object
│   ├── JsonToXml.ts          JSON → XmlDocument
│   ├── XsltTransformer.ts    XSLT 1.0 subset
│   └── index.ts              barrel
├── cli/
│   ├── cli.ts                xml-validate CLI; --watch with debounce
│   └── format.ts             --format helpers
├── plugins/
│   └── PluginRegistry.ts     Type validators, entity resolvers, transformers
├── browser.ts                Browser entry (no fs/path)
├── bun.ts                    Bun entry
├── deno.ts                   Deno entry
└── index.ts                  Main Node.js entry (all public exports)
```

---

## Layer Dependency Rules

```
┌─────────────────────────────────────────────────────────┐
│  Allowed dependency directions (→ = may import):        │
│                                                         │
│  cli          → validator, pipeline, utils, io          │
│  pipeline     → validator, schema, xsd, utils           │
│  validator    → schema, parser, utils                   │
│  xsd          → parser, schema, utils                   │
│  parser       → utils                                   │
│  schema       → (none — pure data types)                │
│  utils        → (none — standalone)                     │
│  cache        → xsd, validator, utils                   │
│  io           → parser, validator, utils                │
│  codegen      → schema, xsd                             │
│  transform    → parser, utils                           │
│  plugins      → validator, utils                        │
│                                                         │
│  ✗ parser must NOT import validator                     │
│  ✗ schema must NOT import parser or validator           │
│  ✗ utils must NOT import any domain layer               │
└─────────────────────────────────────────────────────────┘
```

---

## Security Model Summary

```
Untrusted XML Input
       │
       ▼  ParseBudget gates:
  ┌────────────────────────────────────────────────┐
  │  maxDepth          (default: 512)               │
  │  maxNodeCount      (default: 100,000)           │
  │  maxTextLength     (default: 10 MB)             │
  │  maxEntityExpansion(default: 10,000) ←  Billion │
  │  External entities → SEC_EXTERNAL_ENTITY thrown │  Laughs
  │  DOCTYPE SYSTEM    → blocked by default         │  protection
  └────────────────────────────────────────────────┘
       │ safe XmlDocument
       ▼
  ValidationEngine / StreamingValidator
  (no eval, no network, no file I/O in hot path)
```

---

## Key Design Decisions

| Decision | Rationale |
|----------|-----------|
| Zero runtime dependencies | Browser + Deno + Bun without polyfills; no transitive CVEs |
| DOM-first for v1.x | XPath, PSVI, identity constraints require random access |
| Streaming-first for v2.0 | Large-document scalability; DOM becomes optional overlay |
| DFA per complex type (G27) | Content-model validation compiled once, executed O(n) per element |
| Two-tier XPath LRU | Cold=512 for unique expressions; hot=128 for frequently reused |
| `Map` instead of `WeakMap` for PSVI | `.size` property needed for memory monitoring; GC acceptable |
| `consumePattern` sticky regex | V8 can SIMD-scan sticky regexes — faster than per-char callbacks |
| `statFast` for SchemaCache | Skip file read on cache hit in watch-mode servers (opt-in) |
| `_wsCache` in TypeValidator | Whitespace derivation chains computed once per named type |
| `particleIndex` on DfaModel | Avoids O(n) `Array.find` in xs:all/choice validation hot path |
