{"version":3,"sources":["../../../../src/shared/lib/segment-cache/output-export-prefetch-encoding.ts"],"sourcesContent":["// In output: export mode, the build id is added to the start of the HTML\n// document, directly after the doctype declaration. During a prefetch, the\n// client performs a range request to get the build id, so it can check whether\n// the target page belongs to the same build.\n//\n// The first 64 bytes of the document are requested. The exact number isn't\n// too important; it must be larger than the build id + doctype + closing and\n// ending comment markers, but it doesn't need to match the end of the\n// comment exactly.\n//\n// Build ids are 21 bytes long in the default implementation, though this\n// can be overridden in the Next.js config. For the purposes of this check,\n// it's OK to only match the start of the id, so we'll truncate it if exceeds\n// a certain length.\n\nconst DOCTYPE_PREFIX = '' // 15 bytes\nconst MAX_BUILD_ID_LENGTH = 24\n\n// Request the first 64 bytes. The Range header is inclusive of the end value.\nexport const DOC_PREFETCH_RANGE_HEADER_VALUE = 'bytes=0-63'\n\nfunction escapeBuildId(buildId: string) {\n // If the build id is longer than the given limit, it's OK for our purposes\n // to only match the beginning.\n const truncated = buildId.slice(0, MAX_BUILD_ID_LENGTH)\n // Replace hyphens with underscores so it doesn't break the HTML comment.\n // (Unlikely, but if this did happen it would break the whole document.)\n return truncated.replace(/-/g, '_')\n}\n\nexport function insertBuildIdComment(originalHtml: string, buildId: string) {\n if (\n // Skip if the build id contains a closing comment marker.\n buildId.includes('-->') ||\n // React always inserts a doctype at the start of the document. Skip if it\n // isn't present. Shouldn't happen; suggests an issue elsewhere.\n !originalHtml.startsWith(DOCTYPE_PREFIX)\n ) {\n // Return the original HTML unchanged. This means the document will not\n // be prefetched.\n // TODO: The build id comment is currently only used during prefetches, but\n // if we eventually use this mechanism for regular navigations, we may need\n // to error during build if we fail to insert it for some reason.\n return originalHtml\n }\n // The comment must be inserted after the doctype.\n return originalHtml.replace(\n DOCTYPE_PREFIX,\n DOCTYPE_PREFIX + ''\n )\n}\n\nexport function doesExportedHtmlMatchBuildId(\n partialHtmlDocument: string,\n buildId: string\n) {\n // Check whether the document starts with the expected buildId.\n return partialHtmlDocument.startsWith(\n DOCTYPE_PREFIX + ''\n )\n}\n"],"names":["DOC_PREFETCH_RANGE_HEADER_VALUE","doesExportedHtmlMatchBuildId","insertBuildIdComment","DOCTYPE_PREFIX","MAX_BUILD_ID_LENGTH","escapeBuildId","buildId","truncated","slice","replace","originalHtml","includes","startsWith","partialHtmlDocument"],"mappings":"AAAA,yEAAyE;AACzE,2EAA2E;AAC3E,+EAA+E;AAC/E,6CAA6C;AAC7C,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,sEAAsE;AACtE,mBAAmB;AACnB,EAAE;AACF,yEAAyE;AACzE,2EAA2E;AAC3E,6EAA6E;AAC7E,oBAAoB;;;;;;;;;;;;;;;;;IAMPA,+BAA+B;eAA/BA;;IAiCGC,4BAA4B;eAA5BA;;IAtBAC,oBAAoB;eAApBA;;;AAfhB,MAAMC,iBAAiB,kBAAkB,WAAW;;AACpD,MAAMC,sBAAsB;AAGrB,MAAMJ,kCAAkC;AAE/C,SAASK,cAAcC,OAAe;IACpC,2EAA2E;IAC3E,+BAA+B;IAC/B,MAAMC,YAAYD,QAAQE,KAAK,CAAC,GAAGJ;IACnC,yEAAyE;IACzE,wEAAwE;IACxE,OAAOG,UAAUE,OAAO,CAAC,MAAM;AACjC;AAEO,SAASP,qBAAqBQ,YAAoB,EAAEJ,OAAe;IACxE,IACE,0DAA0D;IAC1DA,QAAQK,QAAQ,CAAC,UACjB,0EAA0E;IAC1E,gEAAgE;IAChE,CAACD,aAAaE,UAAU,CAACT,iBACzB;QACA,uEAAuE;QACvE,iBAAiB;QACjB,2EAA2E;QAC3E,2EAA2E;QAC3E,iEAAiE;QACjE,OAAOO;IACT;IACA,kDAAkD;IAClD,OAAOA,aAAaD,OAAO,CACzBN,gBACAA,iBAAiB,SAASE,cAAcC,WAAW;AAEvD;AAEO,SAASL,6BACdY,mBAA2B,EAC3BP,OAAe;IAEf,+DAA+D;IAC/D,OAAOO,oBAAoBD,UAAU,CACnCT,iBAAiB,SAASE,cAAcC,WAAW;AAEvD","ignoreList":[0]}