UNPKG

@tanstack/router-core

Version:

Modern and scalable routing for React applications

1 lines 5.61 kB
{"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"}