{"version":3,"file":"htmlBoundaryScanner.cjs","names":[],"sources":["../../../src/ssr/htmlBoundaryScanner.ts"],"sourcesContent":["const textEncoder = new TextEncoder()\n\nconst DOCUMENT_CLOSE = '</body></html>'\nexport const SCRIPT_CLOSE = '</script>'\nexport const DOCUMENT_CLOSE_ANCHOR_INDEX = DOCUMENT_CLOSE.indexOf('y')\nexport const SCRIPT_CLOSE_ANCHOR_INDEX = SCRIPT_CLOSE.indexOf('p')\n\nexport const DOCUMENT_CLOSE_BYTES = textEncoder.encode(DOCUMENT_CLOSE)\nexport const SCRIPT_CLOSE_BYTES = textEncoder.encode(SCRIPT_CLOSE)\n\nexport function encodeIntoBoundedChunk(\n  source: string,\n  sourceOffset: number,\n  output: Uint8Array,\n  outputOffset = 0,\n) {\n  // encodeInto() stops before a code point that does not fit, so it never\n  // splits a surrogate pair across chunks.\n  return textEncoder.encodeInto(\n    sourceOffset === 0 ? source : source.slice(sourceOffset),\n    outputOffset === 0 ? output : output.subarray(outputOffset),\n  )\n}\n\n/**\n * State for matching a fixed ASCII sequence across input chunks.\n *\n * The pattern must be non-empty, its first byte must be unique, and the anchor\n * index must point inside the pattern.\n */\nexport type ByteMatcherState = {\n  readonly pattern: Uint8Array\n  readonly anchorIndex: number\n  matched: number\n}\n\n/** Advance matcher state and return the local offset after a complete match. */\nexport function advanceByteMatcher(\n  matcher: ByteMatcherState,\n  value: Uint8Array,\n  startIndex = 0,\n  findLast = false,\n) {\n  const { pattern, anchorIndex } = matcher\n  let matched = matcher.matched\n  let lastMatchEnd: number | undefined\n  let index = startIndex\n  while (index < value.length) {\n    if (matched === 0) {\n      if (anchorIndex > 0 && index < value.length - anchorIndex) {\n        const anchor = value.indexOf(pattern[anchorIndex]!, index + anchorIndex)\n        if (anchor < 0) {\n          index = value.length - anchorIndex\n          continue\n        }\n        index = anchor - anchorIndex\n      } else {\n        index = value.indexOf(pattern[0]!, index)\n        if (index < 0) {\n          matcher.matched = matched\n          return lastMatchEnd\n        }\n      }\n    }\n\n    const byte = value[index]!\n    if (byte === pattern[matched]) {\n      matched++\n    } else {\n      matched = byte === pattern[0] ? 1 : 0\n    }\n    index++\n\n    if (matched === pattern.length) {\n      matched = 0\n      if (!findLast) {\n        matcher.matched = matched\n        return index\n      }\n      lastMatchEnd = index\n    }\n  }\n  matcher.matched = matched\n  return lastMatchEnd\n}\n\n/** Find a complete fixed sequence that is contained in one byte chunk. */\nexport function findExactBytes(\n  value: Uint8Array,\n  pattern: Uint8Array,\n  startIndex = 0,\n  anchorIndex = 0,\n) {\n  let anchor = value.indexOf(pattern[anchorIndex]!, startIndex + anchorIndex)\n  while (anchor >= 0) {\n    const candidate = anchor - anchorIndex\n    if (candidate + pattern.length > value.length) {\n      return -1\n    }\n    let patternIndex = 0\n    while (\n      patternIndex < pattern.length &&\n      value[candidate + patternIndex] === pattern[patternIndex]\n    ) {\n      patternIndex++\n    }\n    if (patternIndex === pattern.length) {\n      return candidate\n    }\n    anchor = value.indexOf(pattern[anchorIndex]!, anchor + 1)\n  }\n  return -1\n}\n\n/**\n * Find the longest suffix that can become the fixed sequence in the next\n * chunk. The returned index starts that suffix.\n */\nexport function getExactBytesPrefixAtEnd(\n  value: Uint8Array,\n  pattern: Uint8Array,\n  startIndex = 0,\n) {\n  candidate: for (\n    let length = Math.min(pattern.length - 1, value.length - startIndex);\n    length > 0;\n    length--\n  ) {\n    const candidateStart = value.length - length\n    for (let index = 0; index < length; index++) {\n      if (value[candidateStart + index] !== pattern[index]) {\n        continue candidate\n      }\n    }\n    return candidateStart\n  }\n  return undefined\n}\n"],"mappings":";AAAA,MAAM,cAAc,IAAI,YAAY;AAEpC,MAAM,iBAAiB;AACvB,MAAa,eAAe;AAC5B,MAAa,8BAA8B,eAAe,QAAQ,GAAG;AACrE,MAAa,4BAA4B,aAAa,QAAQ,GAAG;AAEjE,MAAa,uBAAuB,YAAY,OAAO,cAAc;AACrE,MAAa,qBAAqB,YAAY,OAAO,YAAY;AAEjE,SAAgB,uBACd,QACA,cACA,QACA,eAAe,GACf;CAGA,OAAO,YAAY,WACjB,iBAAiB,IAAI,SAAS,OAAO,MAAM,YAAY,GACvD,iBAAiB,IAAI,SAAS,OAAO,SAAS,YAAY,CAC5D;AACF;;AAeA,SAAgB,mBACd,SACA,OACA,aAAa,GACb,WAAW,OACX;CACA,MAAM,EAAE,SAAS,gBAAgB;CACjC,IAAI,UAAU,QAAQ;CACtB,IAAI;CACJ,IAAI,QAAQ;CACZ,OAAO,QAAQ,MAAM,QAAQ;EAC3B,IAAI,YAAY,GACd,IAAI,cAAc,KAAK,QAAQ,MAAM,SAAS,aAAa;GACzD,MAAM,SAAS,MAAM,QAAQ,QAAQ,cAAe,QAAQ,WAAW;GACvE,IAAI,SAAS,GAAG;IACd,QAAQ,MAAM,SAAS;IACvB;GACF;GACA,QAAQ,SAAS;EACnB,OAAO;GACL,QAAQ,MAAM,QAAQ,QAAQ,IAAK,KAAK;GACxC,IAAI,QAAQ,GAAG;IACb,QAAQ,UAAU;IAClB,OAAO;GACT;EACF;EAGF,MAAM,OAAO,MAAM;EACnB,IAAI,SAAS,QAAQ,UACnB;OAEA,UAAU,SAAS,QAAQ,KAAK,IAAI;EAEtC;EAEA,IAAI,YAAY,QAAQ,QAAQ;GAC9B,UAAU;GACV,IAAI,CAAC,UAAU;IACb,QAAQ,UAAU;IAClB,OAAO;GACT;GACA,eAAe;EACjB;CACF;CACA,QAAQ,UAAU;CAClB,OAAO;AACT;;AAGA,SAAgB,eACd,OACA,SACA,aAAa,GACb,cAAc,GACd;CACA,IAAI,SAAS,MAAM,QAAQ,QAAQ,cAAe,aAAa,WAAW;CAC1E,OAAO,UAAU,GAAG;EAClB,MAAM,YAAY,SAAS;EAC3B,IAAI,YAAY,QAAQ,SAAS,MAAM,QACrC,OAAO;EAET,IAAI,eAAe;EACnB,OACE,eAAe,QAAQ,UACvB,MAAM,YAAY,kBAAkB,QAAQ,eAE5C;EAEF,IAAI,iBAAiB,QAAQ,QAC3B,OAAO;EAET,SAAS,MAAM,QAAQ,QAAQ,cAAe,SAAS,CAAC;CAC1D;CACA,OAAO;AACT;;;;;AAMA,SAAgB,yBACd,OACA,SACA,aAAa,GACb;CACA,WAAW,KACT,IAAI,SAAS,KAAK,IAAI,QAAQ,SAAS,GAAG,MAAM,SAAS,UAAU,GACnE,SAAS,GACT,UACA;EACA,MAAM,iBAAiB,MAAM,SAAS;EACtC,KAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,SAClC,IAAI,MAAM,iBAAiB,WAAW,QAAQ,QAC5C,SAAS;EAGb,OAAO;CACT;AAEF"}