1;!function(){try { var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof global?global:"undefined"!=typeof window?window:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&((e._debugIds|| (e._debugIds={}))[n]="095e860a-bcdb-ea77-2495-6325388fa85d")}catch(e){}}(); 2(globalThis["TURBOPACK"] || (globalThis["TURBOPACK"] = [])).push([typeof document === "object" ? document.currentScript : undefined, 3964893, ((__turbopack_context__, module, exports) => { 4"use strict"; 5 6/** 7 * @license React 8 * react-server-dom-turbopack-client.browser.production.js 9 * 10 * Copyright (c) Meta Platforms, Inc. and affiliates. 11 * 12 * This source code is licensed under the MIT license found in the 13 * LICENSE file in the root directory of this source tree. 14 */ var ReactDOM = __turbopack_context__.r(174080), decoderOptions = { 15 stream: !0 16}, hasOwnProperty = Object.prototype.hasOwnProperty; 17function resolveClientReference(bundlerConfig, metadata) { 18 if (bundlerConfig) { 19 var moduleExports = bundlerConfig[metadata[0]]; 20 if (bundlerConfig = moduleExports && moduleExports[metadata[2]]) moduleExports = bundlerConfig.name; 21 else { 22 bundlerConfig = moduleExports && moduleExports["*"]; 23 if (!bundlerConfig) throw Error('Could not find the module "' + metadata[0] + '" in the React Server Consumer Manifest. This is probably a bug in the React Server Components bundler.'); 24 moduleExports = metadata[2]; 25 } 26 return 4 === metadata.length ? [ 27 bundlerConfig.id, 28 bundlerConfig.chunks, 29 moduleExports, 30 1 31 ] : [ 32 bundlerConfig.id, 33 bundlerConfig.chunks, 34 moduleExports 35 ]; 36 } 37 return metadata; 38} 39function resolveServerReference(bundlerConfig, id) { 40 var name = "", resolvedModuleData = bundlerConfig[id]; 41 if (resolvedModuleData) name = resolvedModuleData.name; 42 else { 43 var idx = id.lastIndexOf("#"); 44 -1 !== idx && (name = id.slice(idx + 1), resolvedModuleData = bundlerConfig[id.slice(0, idx)]); 45 if (!resolvedModuleData) throw Error('Could not find the module "' + id + '" in the React Server Manifest. This is probably a bug in the React Server Components bundler.'); 46 } 47 return resolvedModuleData.async ? [ 48 resolvedModuleData.id, 49 resolvedModuleData.chunks, 50 name, 51 1 52 ] : [ 53 resolvedModuleData.id, 54 resolvedModuleData.chunks, 55 name 56 ]; 57} 58function requireAsyncModule(id) { 59 var promise = /*TURBOPACK member replacement*/ __turbopack_context__.r(id); 60 if ("function" !== typeof promise.then || "fulfilled" === promise.status) return null; 61 promise.then(function(value) { 62 promise.status = "fulfilled"; 63 promise.value = value; 64 }, function(reason) { 65 promise.status = "rejected"; 66 promise.reason = reason; 67 }); 68 return promise; 69} 70var instrumentedChunks = new WeakSet(), loadedChunks = new WeakSet(); 71function ignoreReject() {} 72function preloadModule(metadata) { 73 for(var chunks = metadata[1], promises = [], i = 0; i < chunks.length; i++){ 74 var thenable = /*TURBOPACK member replacement*/ __turbopack_context__.L(chunks[i]); 75 loadedChunks.has(thenable) || promises.push(thenable); 76 if (!instrumentedChunks.has(thenable)) { 77 var resolve = loadedChunks.add.bind(loadedChunks, thenable); 78 thenable.then(resolve, ignoreReject); 79 instrumentedChunks.add(thenable); 80 } 81 } 82 return 4 === metadata.length ? 0 === promises.length ? requireAsyncModule(metadata[0]) : Promise.all(promises).then(function() { 83 return requireAsyncModule(metadata[0]); 84 }) : 0 < promises.length ? Promise.all(promises) : null; 85} 86function requireModule(metadata) { 87 var moduleExports = /*TURBOPACK member replacement*/ __turbopack_context__.r(metadata[0]); 88 if (4 === metadata.length && "function" === typeof moduleExports.then) if ("fulfilled" === moduleExports.status) moduleExports = moduleExports.value; 89 else throw moduleExports.reason; 90 if ("*" === metadata[2]) return moduleExports; 91 if ("" === metadata[2]) return moduleExports.__esModule ? moduleExports.default : moduleExports; 92 if (hasOwnProperty.call(moduleExports, metadata[2])) return moduleExports[metadata[2]]; 93} 94var ReactDOMSharedInternals = ReactDOM.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), MAYBE_ITERATOR_SYMBOL = Symbol.iterator; 95function getIteratorFn(maybeIterable) { 96 if (null === maybeIterable || "object" !== typeof maybeIterable) return null; 97 maybeIterable = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable["@@iterator"]; 98 return "function" === typeof maybeIterable ? maybeIterable : null; 99} 100var ASYNC_ITERATOR = Symbol.asyncIterator, isArrayImpl = Array.isArray, getPrototypeOf = Object.getPrototypeOf, ObjectPrototype = Object.prototype, knownServerReferences = new WeakMap(); 101function serializeNumber(number) { 102 return Number.isFinite(number) ? 0 === number && -Infinity === 1 / number ? "$-0" : number : Infinity === number ? "$Infinity" : -Infinity === number ? "$-Infinity" : "$NaN"; 103} 104function processReply(root, formFieldPrefix, temporaryReferences, resolve, reject) { 105 function serializeTypedArray(tag, typedArray) { 106 typedArray = new Blob([ 107 new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength) 108 ]); 109 var blobId = nextPartId++; 110 null === formData && (formData = new FormData()); 111 formData.append(formFieldPrefix + blobId, typedArray); 112 return "$" + tag + blobId.toString(16); 113 } 114 function serializeBinaryReader(reader) { 115 function progress(entry) { 116 entry.done ? (entry = nextPartId++, data.append(formFieldPrefix + entry, new Blob(buffer)), data.append(formFieldPrefix + streamId, '"$o' + entry.toString(16) + '"'), data.append(formFieldPrefix + streamId, "C"), pendingParts--, 0 === pendingParts && resolve(data)) : (buffer.push(entry.value), reader.read(new Uint8Array(1024)).then(progress, reject)); 117 } 118 null === formData && (formData = new FormData()); 119 var data = formData; 120 pendingParts++; 121 var streamId = nextPartId++, buffer = []; 122 reader.read(new Uint8Array(1024)).then(progress, reject); 123 return "$r" + streamId.toString(16); 124 } 125 function serializeReader(reader) { 126 function progress(entry) { 127 if (entry.done) data.append(formFieldPrefix + streamId, "C"), pendingParts--, 0 === pendingParts && resolve(data); 128 else try { 129 var partJSON = JSON.stringify(entry.value, resolveToJSON); 130 data.append(formFieldPrefix + streamId, partJSON); 131 reader.read().then(progress, reject); 132 } catch (x) { 133 reject(x); 134 } 135 } 136 null === formData && (formData = new FormData()); 137 var data = formData; 138 pendingParts++; 139 var streamId = nextPartId++; 140 reader.read().then(progress, reject); 141 return "$R" + streamId.toString(16); 142 } 143 function serializeReadableStream(stream) { 144 try { 145 var binaryReader = stream.getReader({ 146 mode: "byob" 147 }); 148 } catch (x) { 149 return serializeReader(stream.getReader()); 150 } 151 return serializeBinaryReader(binaryReader); 152 } 153 function serializeAsyncIterable(iterable, iterator) { 154 function progress(entry) { 155 if (entry.done) { 156 if (void 0 === entry.value) data.append(formFieldPrefix + streamId, "C"); 157 else try { 158 var partJSON = JSON.stringify(entry.value, resolveToJSON); 159 data.append(formFieldPrefix + streamId, "C" + partJSON); 160 } catch (x) { 161 reject(x); 162 return; 163 } 164 pendingParts--; 165 0 === pendingParts && resolve(data); 166 } else try { 167 var partJSON$21 = JSON.stringify(entry.value, resolveToJSON); 168 data.append(formFieldPrefix + streamId, partJSON$21); 169 iterator.next().then(progress, reject); 170 } catch (x$22) { 171 reject(x$22); 172 } 173 } 174 null === formData && (formData = new FormData()); 175 var data = formData; 176 pendingParts++; 177 var streamId = nextPartId++; 178 iterable = iterable === iterator; 179 iterator.next().then(progress, reject); 180 return "$" + (iterable ? "x" : "X") + streamId.toString(16); 181 } 182 function resolveToJSON(key, value) { 183 if (null === value) return null; 184 if ("object" === typeof value) { 185 switch(value.$$typeof){ 186 case REACT_ELEMENT_TYPE: 187 if (void 0 !== temporaryReferences && -1 === key.indexOf(":")) { 188 var parentReference = writtenObjects.get(this); 189 if (void 0 !== parentReference) return temporaryReferences.set(parentReference + ":" + key, value), "$T"; 190 } 191 if (void 0 !== temporaryReferences && modelRoot === value) return modelRoot = null, "$T"; 192 throw Error("React Element cannot be passed to Server Functions from the Client without a temporary reference set. Pass a TemporaryReferenceSet to the options."); 193 case REACT_LAZY_TYPE: 194 parentReference = value._payload; 195 var init = value._init; 196 null === formData && (formData = new FormData()); 197 pendingParts++; 198 try { 199 var resolvedModel = init(parentReference), lazyId = nextPartId++, partJSON = serializeModel(resolvedModel, lazyId); 200 formData.append(formFieldPrefix + lazyId, partJSON);
201 return "$" + lazyId.toString(16); 202 } catch (x) { 203 if ("object" === typeof x && null !== x && "function" === typeof x.then) { 204 pendingParts++; 205 var lazyId$23 = nextPartId++; 206 parentReference = function() { 207 try { 208 var partJSON$24 = serializeModel(value, lazyId$23), data$25 = formData; 209 data$25.append(formFieldPrefix + lazyId$23, partJSON$24); 210 pendingParts--; 211 0 === pendingParts && resolve(data$25); 212 } catch (reason) { 213 reject(reason); 214 } 215 }; 216 x.then(parentReference, parentReference); 217 return "$" + lazyId$23.toString(16); 218 } 219 reject(x); 220 return null; 221 } finally{ 222 pendingParts--; 223 } 224 } 225 parentReference = writtenObjects.get(value); 226 if ("function" === typeof value.then) { 227 if (void 0 !== parentReference) if (modelRoot === value) modelRoot = null; 228 else return parentReference; 229 null === formData && (formData = new FormData()); 230 pendingParts++; 231 var promiseId = nextPartId++; 232 key = "$@" + promiseId.toString(16); 233 writtenObjects.set(value, key); 234 value.then(function(partValue) { 235 try { 236 var previousReference = writtenObjects.get(partValue); 237 var partJSON$27 = void 0 !== previousReference ? JSON.stringify(previousReference) : serializeModel(partValue, promiseId); 238 partValue = formData; 239 partValue.append(formFieldPrefix + promiseId, partJSON$27); 240 pendingParts--; 241 0 === pendingParts && resolve(partValue); 242 } catch (reason) { 243 reject(reason); 244 } 245 }, reject); 246 return key; 247 } 248 if (void 0 !== parentReference) if (modelRoot === value) modelRoot = null; 249 else return parentReference; 250 else -1 === key.indexOf(":") && (parentReference = writtenObjects.get(this), void 0 !== parentReference && (key = parentReference + ":" + key, writtenObjects.set(value, key), void 0 !== temporaryReferences && temporaryReferences.set(key, value))); 251 if (isArrayImpl(value)) return value; 252 if (value instanceof FormData) { 253 null === formData && (formData = new FormData()); 254 var data$31 = formData; 255 key = nextPartId++; 256 var prefix = formFieldPrefix + "_" + key + "_"; 257 value.forEach(function(originalValue, originalKey) { 258 data$31.append(prefix + originalKey, originalValue); 259 }); 260 return "$K" + key.toString(16); 261 } 262 if (value instanceof Map) return key = nextPartId++, parentReference = serializeModel(Array.from(value), key), null === formData && (formData = new FormData()), formData.append(formFieldPrefix + key, parentReference), "$Q" + key.toString(16); 263 if (value instanceof Set) return key = nextPartId++, parentReference = serializeModel(Array.from(value), key), null === formData && (formData = new FormData()), formData.append(formFieldPrefix + key, parentReference), "$W" + key.toString(16); 264 if (value instanceof ArrayBuffer) return key = new Blob([ 265 value 266 ]), parentReference = nextPartId++, null === formData && (formData = new FormData()), formData.append(formFieldPrefix + parentReference, key), "$A" + parentReference.toString(16); 267 if (value instanceof Int8Array) return serializeTypedArray("O", value); 268 if (value instanceof Uint8Array) return serializeTypedArray("o", value); 269 if (value instanceof Uint8ClampedArray) return serializeTypedArray("U", value); 270 if (value instanceof Int16Array) return serializeTypedArray("S", value); 271 if (value instanceof Uint16Array) return serializeTypedArray("s", value); 272 if (value instanceof Int32Array) return serializeTypedArray("L", value); 273 if (value instanceof Uint32Array) return serializeTypedArray("l", value); 274 if (value instanceof Float32Array) return serializeTypedArray("G", value); 275 if (value instanceof Float64Array) return serializeTypedArray("g", value); 276 if (value instanceof BigInt64Array) return serializeTypedArray("M", value); 277 if (value instanceof BigUint64Array) return serializeTypedArray("m", value); 278 if (value instanceof DataView) return serializeTypedArray("V", value); 279 if ("function" === typeof Blob && value instanceof Blob) return null === formData && (formData = new FormData()), key = nextPartId++, formData.append(formFieldPrefix + key, value), "$B" + key.toString(16); 280 if (key = getIteratorFn(value)) return parentReference = key.call(value), parentReference === value ? (key = nextPartId++, parentReference = serializeModel(Array.from(parentReference), key), null === formData && (formData = new FormData()), formData.append(formFieldPrefix + key, parentReference), "$i" + key.toString(16)) : Array.from(parentReference); 281 if ("function" === typeof ReadableStream && value instanceof ReadableStream) return serializeReadableStream(value); 282 key = value[ASYNC_ITERATOR]; 283 if ("function" === typeof key) return serializeAsyncIterable(value, key.call(value)); 284 key = getPrototypeOf(value); 285 if (key !== ObjectPrototype && (null === key || null !== getPrototypeOf(key))) { 286 if (void 0 === temporaryReferences) throw Error("Only plain objects, and a few built-ins, can be passed to Server Functions. Classes or null prototypes are not supported."); 287 return "$T"; 288 } 289 return value; 290 } 291 if ("string" === typeof value) { 292 if ("Z" === value[value.length - 1] && this[key] instanceof Date) return "$D" + value; 293 key = "$" === value[0] ? "$" + value : value; 294 return key; 295 } 296 if ("boolean" === typeof value) return value; 297 if ("number" === typeof value) return serializeNumber(value); 298 if ("undefined" === typeof value) return "$undefined"; 299 if ("function" === typeof value) { 300 parentReference = knownServerReferences.get(value); 301 if (void 0 !== parentReference) { 302 key = writtenObjects.get(value); 303 if (void 0 !== key) return key; 304 key = JSON.stringify({ 305 id: parentReference.id, 306 bound: parentReference.bound 307 }, resolveToJSON); 308 null === formData && (formData = new FormData()); 309 parentReference = nextPartId++; 310 formData.set(formFieldPrefix + parentReference, key); 311 key = "$h" + parentReference.toString(16); 312 writtenObjects.set(value, key); 313 return key; 314 } 315 if (void 0 !== temporaryReferences && -1 === key.indexOf(":") && (parentReference = writtenObjects.get(this), void 0 !== parentReference)) return temporaryReferences.set(parentReference + ":" + key, value), "$T"; 316 throw Error("Client Functions cannot be passed directly to Server Functions. Only Functions passed from the Server can be passed back again."); 317 } 318 if ("symbol" === typeof value) { 319 if (void 0 !== temporaryReferences && -1 === key.indexOf(":") && (parentReference = writtenObjects.get(this), void 0 !== parentReference)) return temporaryReferences.set(parentReference + ":" + key, value), "$T"; 320 throw Error("Symbols cannot be passed to a Server Function without a temporary reference set. Pass a TemporaryReferenceSet to the options."); 321 } 322 if ("bigint" === typeof value) return "$n" + value.toString(10); 323 throw Error("Type " + typeof value + " is not supported as an argument to a Server Function."); 324 } 325 function serializeModel(model, id) { 326 "object" === typeof model && null !== model && (id = "$" + id.toString(16), writtenObjects.set(model, id), void 0 !== temporaryReferences && temporaryReferences.set(id, model)); 327 modelRoot = model; 328 return JSON.stringify(model, resolveToJSON); 329 } 330 var nextPartId = 1, pendingParts = 0, formData = null, writtenObjects = new WeakMap(), modelRoot = root, json = serializeModel(root, 0); 331 null === formData ? resolve(json) : (formData.set(formFieldPrefix + "0", json), 0 === pendingParts && resolve(formData)); 332 return function() { 333 0 < pendingParts && (pendingParts = 0, null === formData ? resolve(json) : resolve(formData)); 334 }; 335} 336function registerBoundServerReference(reference, id, bound) { 337 knownServerReferences.has(reference) || knownServerReferences.set(reference, { 338 id: id, 339 originalBind: reference.bind, 340 bound: bound 341 }); 342} 343function createBoundServerReference(metaData, callServer) { 344 function action() { 345 var args = Array.prototype.slice.call(arguments);
346 return bound ? "fulfilled" === bound.status ? callServer(id, bound.value.concat(args)) : Promise.resolve(bound).then(function(boundArgs) { 347 return callServer(id, boundArgs.concat(args)); 348 }) : callServer(id, args); 349 } 350 var id = metaData.id, bound = metaData.bound; 351 registerBoundServerReference(action, id, bound); 352 return action; 353} 354function ReactPromise(status, value, reason) { 355 this.status = status; 356 this.value = value; 357 this.reason = reason; 358} 359ReactPromise.prototype = Object.create(Promise.prototype); 360ReactPromise.prototype.then = function(resolve, reject) { 361 switch(this.status){ 362 case "resolved_model": 363 initializeModelChunk(this); 364 break; 365 case "resolved_module": 366 initializeModuleChunk(this); 367 } 368 switch(this.status){ 369 case "fulfilled": 370 "function" === typeof resolve && resolve(this.value); 371 break; 372 case "pending": 373 case "blocked": 374 "function" === typeof resolve && (null === this.value && (this.value = []), this.value.push(resolve)); 375 "function" === typeof reject && (null === this.reason && (this.reason = []), this.reason.push(reject)); 376 break; 377 case "halted": 378 break; 379 default: 380 "function" === typeof reject && reject(this.reason); 381 } 382}; 383function readChunk(chunk) { 384 switch(chunk.status){ 385 case "resolved_model": 386 initializeModelChunk(chunk); 387 break; 388 case "resolved_module": 389 initializeModuleChunk(chunk); 390 } 391 switch(chunk.status){ 392 case "fulfilled": 393 return chunk.value; 394 case "pending": 395 case "blocked": 396 case "halted": 397 throw chunk; 398 default: 399 throw chunk.reason; 400 } 401} 402function createPendingChunk() { 403 return new ReactPromise("pending", null, null); 404} 405function wakeChunk(response, listeners, value, chunk) { 406 for(var i = 0; i < listeners.length; i++){ 407 var listener = listeners[i]; 408 "function" === typeof listener ? listener(value) : fulfillReference(response, listener, value, chunk); 409 } 410} 411function rejectChunk(response, listeners, error) { 412 for(var i = 0; i < listeners.length; i++){ 413 var listener = listeners[i]; 414 "function" === typeof listener ? listener(error) : rejectReference(response, listener.handler, error); 415 } 416} 417function resolveBlockedCycle(resolvedChunk, reference) { 418 var referencedChunk = reference.handler.chunk; 419 if (null === referencedChunk) return null; 420 if (referencedChunk === resolvedChunk) return reference.handler; 421 reference = referencedChunk.value; 422 if (null !== reference) for(referencedChunk = 0; referencedChunk < reference.length; referencedChunk++){ 423 var listener = reference[referencedChunk]; 424 if ("function" !== typeof listener && (listener = resolveBlockedCycle(resolvedChunk, listener), null !== listener)) return listener; 425 } 426 return null; 427} 428function wakeChunkIfInitialized(response, chunk, resolveListeners, rejectListeners) { 429 switch(chunk.status){ 430 case "fulfilled": 431 wakeChunk(response, resolveListeners, chunk.value, chunk); 432 break; 433 case "blocked": 434 for(var i = 0; i < resolveListeners.length; i++){ 435 var listener = resolveListeners[i]; 436 if ("function" !== typeof listener) { 437 var cyclicHandler = resolveBlockedCycle(chunk, listener); 438 if (null !== cyclicHandler) switch(fulfillReference(response, listener, cyclicHandler.value, chunk), resolveListeners.splice(i, 1), i--, null !== rejectListeners && (listener = rejectListeners.indexOf(listener), -1 !== listener && rejectListeners.splice(listener, 1)), chunk.status){ 439 case "fulfilled": 440 wakeChunk(response, resolveListeners, chunk.value, chunk); 441 return; 442 case "rejected": 443 null !== rejectListeners && rejectChunk(response, rejectListeners, chunk.reason); 444 return; 445 } 446 } 447 } 448 case "pending": 449 if (chunk.value) for(response = 0; response < resolveListeners.length; response++)chunk.value.push(resolveListeners[response]); 450 else chunk.value = resolveListeners; 451 if (chunk.reason) { 452 if (rejectListeners) for(resolveListeners = 0; resolveListeners < rejectListeners.length; resolveListeners++)chunk.reason.push(rejectListeners[resolveListeners]); 453 } else chunk.reason = rejectListeners; 454 break; 455 case "rejected": 456 rejectListeners && rejectChunk(response, rejectListeners, chunk.reason); 457 } 458} 459function triggerErrorOnChunk(response, chunk, error) { 460 if ("pending" !== chunk.status && "blocked" !== chunk.status) chunk.reason.error(error); 461 else { 462 var listeners = chunk.reason; 463 chunk.status = "rejected"; 464 chunk.reason = error; 465 null !== listeners && rejectChunk(response, listeners, error); 466 } 467} 468function createResolvedIteratorResultChunk(response, value, done) { 469 return new ReactPromise("resolved_model", (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + "}", response); 470} 471function resolveIteratorResultChunk(response, chunk, value, done) { 472 resolveModelChunk(response, chunk, (done ? '{"done":true,"value":' : '{"done":false,"value":') + value + "}"); 473} 474function resolveModelChunk(response, chunk, value) { 475 if ("pending" !== chunk.status) chunk.reason.enqueueModel(value); 476 else { 477 var resolveListeners = chunk.value, rejectListeners = chunk.reason; 478 chunk.status = "resolved_model"; 479 chunk.value = value; 480 chunk.reason = response; 481 null !== resolveListeners && (initializeModelChunk(chunk), wakeChunkIfInitialized(response, chunk, resolveListeners, rejectListeners)); 482 } 483} 484function resolveModuleChunk(response, chunk, value) { 485 if ("pending" === chunk.status || "blocked" === chunk.status) { 486 var resolveListeners = chunk.value, rejectListeners = chunk.reason; 487 chunk.status = "resolved_module"; 488 chunk.value = value; 489 chunk.reason = null; 490 null !== resolveListeners && (initializeModuleChunk(chunk), wakeChunkIfInitialized(response, chunk, resolveListeners, rejectListeners)); 491 } 492} 493var initializingHandler = null; 494function initializeModelChunk(chunk) { 495 var prevHandler = initializingHandler; 496 initializingHandler = null; 497 var resolvedModel = chunk.value, response = chunk.reason; 498 chunk.status = "blocked"; 499 chunk.value = null; 500 chunk.reason = null; 501 try { 502 var value = parseModel(response, resolvedModel), resolveListeners = chunk.value; 503 if (null !== resolveListeners) for(chunk.value = null, chunk.reason = null, resolvedModel = 0; resolvedModel < resolveListeners.length; resolvedModel++){ 504 var listener = resolveListeners[resolvedModel]; 505 "function" === typeof listener ? listener(value) : fulfillReference(response, listener, value, chunk); 506 } 507 if (null !== initializingHandler) { 508 if (initializingHandler.errored) throw initializingHandler.reason; 509 if (0 < initializingHandler.deps) { 510 initializingHandler.value = value; 511 initializingHandler.chunk = chunk; 512 return; 513 } 514 } 515 chunk.status = "fulfilled"; 516 chunk.value = value; 517 chunk.reason = null; 518 } catch (error) { 519 chunk.status = "rejected", chunk.reason = error; 520 } finally{ 521 initializingHandler = prevHandler; 522 } 523} 524function initializeModuleChunk(chunk) { 525 try { 526 var value = requireModule(chunk.value); 527 chunk.status = "fulfilled"; 528 chunk.value = value; 529 chunk.reason = null; 530 } catch (error) { 531 chunk.status = "rejected", chunk.reason = error; 532 } 533} 534function reportGlobalError(weakResponse, error) { 535 weakResponse._closed = !0; 536 weakResponse._closedReason = error; 537 weakResponse._chunks.forEach(function(chunk) { 538 "pending" === chunk.status ? triggerErrorOnChunk(weakResponse, chunk, error) : "fulfilled" === chunk.status && null !== chunk.reason && chunk.reason.error(error); 539 }); 540} 541function createLazyChunkWrapper(chunk) { 542 return { 543 $$typeof: REACT_LAZY_TYPE, 544 _payload: chunk, 545 _init: readChunk 546 }; 547} 548function getChunk(response, id) { 549 var chunks = response._chunks, chunk = chunks.get(id); 550 chunk || (response._closed ? response._allowPartialStream ? (response = chunk = createPendingChunk(), response.status = "halted", response.value = null, response.reason = null) : chunk = new ReactPromise("rejected", null, response._closedReason) : chunk = createPendingChunk(), chunks.set(id, chunk)); 551 return chunk; 552} 553function fulfillReference(response, reference, value) { 554 var handler = reference.handler, parentObject = reference.parentObject, key = reference.key, map = reference.map, path = reference.path; 555 try { 556 for(var i = 1; i < path.length; i++){ 557 for(; "object" === typeof value && null !== value && value.$$typeof === REACT_LAZY_TYPE;){ 558 var referencedChunk = value._payload; 559 if (referencedChunk === handler.chunk) value = handler.value; 560 else { 561 switch(referencedChunk.status){ 562 case "resolved_model": 563 initializeModelChunk(referencedChunk); 564 break; 565 case "resolved_module": 566 initializeModuleChunk(referencedChunk); 567 } 568 switch(referencedChunk.status){ 569 case "fulfilled": 570 value = referencedChunk.value; 571 continue; 572 case "blocked": 573 var cyclicHandler = resolveBlockedCycle(referencedChunk, reference); 574 if (null !== cyclicHandler) { 575 value = cyclicHandler.value; 576 continue; 577 } 578 case "pending": 579 path.splice(0, i - 1); 580 null === referencedChunk.value ? referencedChunk.value = [ 581 reference 582 ] : referencedChunk.value.push(reference); 583 null === referencedChunk.reason ? referencedChunk.reason = [ 584 reference 585 ] : referencedChunk.reason.push(reference); 586 return; 587 case "halted": 588 return; 589 default: 590 rejectReference(response, reference.handler, referencedChunk.reason); 591 return; 592 } 593 } 594 } 595 var name = path[i]; 596 if ("object" === typeof value && null !== value && hasOwnProperty.call(value, name)) value = value[name]; 597 else throw Error("Invalid reference."); 598 } 599 for(; "object" === typeof value && null !== value && value.$$typeof === REACT_LAZY_TYPE;){ 600 var referencedChunk$44 = value._payload; 601 if (referencedChunk$44 === handler.chunk) value = handler.value; 602 else { 603 switch(referencedChunk$44.status){ 604 case "resolved_model": 605 initializeModelChunk(referencedChunk$44); 606 break; 607 case "resolved_module": 608 initializeModuleChunk(referencedChunk$44); 609 } 610 switch(referencedChunk$44.status){ 611 case "fulfilled": 612 value = referencedChunk$44.value; 613 continue; 614 } 615 break; 616 } 617 } 618 var mappedValue = map(response, value, parentObject, key);
619 "__proto__" !== key && (parentObject[key] = mappedValue); 620 "" === key && null === handler.value && (handler.value = mappedValue); 621 if (parentObject[0] === REACT_ELEMENT_TYPE && "object" === typeof handler.value && null !== handler.value && handler.value.$$typeof === REACT_ELEMENT_TYPE) { 622 var element = handler.value; 623 switch(key){ 624 case "3": 625 element.props = mappedValue; 626 } 627 } 628 } catch (error) { 629 rejectReference(response, reference.handler, error); 630 return; 631 } 632 handler.deps--; 633 0 === handler.deps && (reference = handler.chunk, null !== reference && "blocked" === reference.status && (value = reference.value, reference.status = "fulfilled", reference.value = handler.value, reference.reason = handler.reason, null !== value && wakeChunk(response, value, handler.value, reference))); 634} 635function rejectReference(response, handler, error) { 636 handler.errored || (handler.errored = !0, handler.value = null, handler.reason = error, handler = handler.chunk, null !== handler && "blocked" === handler.status && triggerErrorOnChunk(response, handler, error)); 637} 638function waitForReference(referencedChunk, parentObject, key, response, map, path) { 639 initializingHandler ? (response = initializingHandler, response.deps++) : response = initializingHandler = { 640 parent: null, 641 chunk: null, 642 value: null, 643 reason: null, 644 deps: 1, 645 errored: !1 646 }; 647 parentObject = { 648 handler: response, 649 parentObject: parentObject, 650 key: key, 651 map: map, 652 path: path 653 }; 654 null === referencedChunk.value ? referencedChunk.value = [ 655 parentObject 656 ] : referencedChunk.value.push(parentObject); 657 null === referencedChunk.reason ? referencedChunk.reason = [ 658 parentObject 659 ] : referencedChunk.reason.push(parentObject); 660 return null; 661} 662function loadServerReference(response, metaData, parentObject, key) { 663 if (!response._serverReferenceConfig) return createBoundServerReference(metaData, response._callServer); 664 var serverReference = resolveServerReference(response._serverReferenceConfig, metaData.id), promise = preloadModule(serverReference); 665 if (promise) metaData.bound && (promise = Promise.all([ 666 promise, 667 metaData.bound 668 ])); 669 else if (metaData.bound) promise = Promise.resolve(metaData.bound); 670 else return promise = requireModule(serverReference), registerBoundServerReference(promise, metaData.id, metaData.bound), promise; 671 if (initializingHandler) { 672 var handler = initializingHandler; 673 handler.deps++; 674 } else handler = initializingHandler = { 675 parent: null, 676 chunk: null, 677 value: null, 678 reason: null, 679 deps: 1, 680 errored: !1 681 }; 682 promise.then(function() { 683 var resolvedValue = requireModule(serverReference); 684 if (metaData.bound) { 685 var boundArgs = metaData.bound.value.slice(0); 686 boundArgs.unshift(null); 687 resolvedValue = resolvedValue.bind.apply(resolvedValue, boundArgs); 688 } 689 registerBoundServerReference(resolvedValue, metaData.id, metaData.bound); 690 "__proto__" !== key && (parentObject[key] = resolvedValue); 691 "" === key && null === handler.value && (handler.value = resolvedValue); 692 if (parentObject[0] === REACT_ELEMENT_TYPE && "object" === typeof handler.value && null !== handler.value && handler.value.$$typeof === REACT_ELEMENT_TYPE) switch(boundArgs = handler.value, key){ 693 case "3": 694 boundArgs.props = resolvedValue; 695 } 696 handler.deps--; 697 0 === handler.deps && (resolvedValue = handler.chunk, null !== resolvedValue && "blocked" === resolvedValue.status && (boundArgs = resolvedValue.value, resolvedValue.status = "fulfilled", resolvedValue.value = handler.value, resolvedValue.reason = null, null !== boundArgs && wakeChunk(response, boundArgs, handler.value, resolvedValue))); 698 }, function(error) { 699 if (!handler.errored) { 700 handler.errored = !0; 701 handler.value = null; 702 handler.reason = error; 703 var chunk = handler.chunk; 704 null !== chunk && "blocked" === chunk.status && triggerErrorOnChunk(response, chunk, error); 705 } 706 }); 707 return null; 708} 709function getOutlinedModel(response, reference, parentObject, key, map) { 710 reference = reference.split(":"); 711 var id = parseInt(reference[0], 16); 712 id = getChunk(response, id); 713 switch(id.status){ 714 case "resolved_model": 715 initializeModelChunk(id); 716 break; 717 case "resolved_module": 718 initializeModuleChunk(id); 719 } 720 switch(id.status){ 721 case "fulfilled": 722 id = id.value; 723 for(var i = 1; i < reference.length; i++){ 724 for(; "object" === typeof id && null !== id && id.$$typeof === REACT_LAZY_TYPE;){ 725 id = id._payload; 726 switch(id.status){ 727 case "resolved_model": 728 initializeModelChunk(id); 729 break; 730 case "resolved_module": 731 initializeModuleChunk(id); 732 } 733 switch(id.status){ 734 case "fulfilled": 735 id = id.value; 736 break; 737 case "blocked": 738 case "pending": 739 return waitForReference(id, parentObject, key, response, map, reference.slice(i - 1)); 740 case "halted": 741 return initializingHandler ? (response = initializingHandler, response.deps++) : initializingHandler = { 742 parent: null, 743 chunk: null, 744 value: null, 745 reason: null, 746 deps: 1, 747 errored: !1 748 }, null; 749 default: 750 return initializingHandler ? (initializingHandler.errored = !0, initializingHandler.value = null, initializingHandler.reason = id.reason) : initializingHandler = { 751 parent: null, 752 chunk: null, 753 value: null, 754 reason: id.reason, 755 deps: 0, 756 errored: !0 757 }, null; 758 } 759 } 760 id = id[reference[i]]; 761 } 762 for(; "object" === typeof id && null !== id && id.$$typeof === REACT_LAZY_TYPE;){ 763 reference = id._payload; 764 switch(reference.status){ 765 case "resolved_model": 766 initializeModelChunk(reference); 767 break; 768 case "resolved_module": 769 initializeModuleChunk(reference); 770 } 771 switch(reference.status){ 772 case "fulfilled": 773 id = reference.value; 774 continue; 775 } 776 break; 777 } 778 return map(response, id, parentObject, key); 779 case "pending": 780 case "blocked": 781 return waitForReference(id, parentObject, key, response, map, reference); 782 case "halted": 783 return initializingHandler ? (response = initializingHandler, response.deps++) : initializingHandler = { 784 parent: null, 785 chunk: null, 786 value: null, 787 reason: null, 788 deps: 1, 789 errored: !1 790 }, null; 791 default: 792 return initializingHandler ? (initializingHandler.errored = !0, initializingHandler.value = null, initializingHandler.reason = id.reason) : initializingHandler = { 793 parent: null, 794 chunk: null, 795 value: null, 796 reason: id.reason, 797 deps: 0, 798 errored: !0 799 }, null; 800 } 801} 802function createMap(response, model) { 803 return new Map(model); 804} 805function createSet(response, model) { 806 return new Set(model); 807} 808function createBlob(response, model) { 809 return new Blob(model.slice(1), { 810 type: model[0] 811 }); 812} 813function createFormData(response, model) { 814 response = new FormData(); 815 for(var i = 0; i < model.length; i++)response.append(model[i][0], model[i][1]); 816 return response; 817} 818function extractIterator(response, model) { 819 return model[Symbol.iterator](); 820} 821function createModel(response, model) { 822 return model; 823} 824function parseModelString(response, parentObject, key, value) { 825 if ("$" === value[0]) { 826 if ("$" === value) return null !== initializingHandler && "0" === key && (initializingHandler = { 827 parent: initializingHandler, 828 chunk: null, 829 value: null, 830 reason: null, 831 deps: 0, 832 errored: !1 833 }), REACT_ELEMENT_TYPE; 834 switch(value[1]){ 835 case "$": 836 return value.slice(1); 837 case "L": 838 return parentObject = parseInt(value.slice(2), 16), response = getChunk(response, parentObject), createLazyChunkWrapper(response); 839 case "@": 840 return parentObject = parseInt(value.slice(2), 16), getChunk(response, parentObject); 841 case "S": 842 return Symbol.for(value.slice(2)); 843 case "h": 844 return value = value.slice(2), getOutlinedModel(response, value, parentObject, key, loadServerReference); 845 case "T": 846 parentObject = "$" + value.slice(2); 847 response = response._tempRefs; 848 if (null == response) throw Error("Missing a temporary reference set but the RSC response returned a temporary reference. Pass a temporaryReference option with the set that was used with the reply."); 849 return response.get(parentObject); 850 case "Q": 851 return value = value.slice(2), getOutlinedModel(response, value, parentObject, key, createMap); 852 case "W": 853 return value = value.slice(2), getOutlinedModel(response, value, parentObject, key, createSet); 854 case "B": 855 return value = value.slice(2), getOutlinedModel(response, value, parentObject, key, createBlob); 856 case "K": 857 return value = value.slice(2), getOutlinedModel(response, value, parentObject, key, createFormData); 858 case "Z": 859 return resolveErrorProd(); 860 case "i": 861 return value = value.slice(2), getOutlinedModel(response, value, parentObject, key, extractIterator); 862 case "I": 863 return Infinity; 864 case "-": 865 return "$-0" === value ? -0 : -Infinity; 866 case "N": 867 return NaN; 868 case "u": 869 return; 870 case "D": 871 return new Date(Date.parse(value.slice(2))); 872 case "n": 873 return BigInt(value.slice(2)); 874 default: 875 return value = value.slice(1), getOutlinedModel(response, value, parentObject, key, createModel); 876 } 877 } 878 return value; 879} 880function missingCall() { 881 throw Error('Trying to call a function from "use server" but the callServer option was not implemented in your router runtime.'); 882} 883function ResponseInstance(bundlerConfig, serverReferenceConfig, moduleLoading, callServer, encodeFormAction, nonce, temporaryReferences, allowPartialStream) { 884 var chunks = new Map(); 885 this._bundlerConfig = bundlerConfig; 886 this._serverReferenceConfig = serverReferenceConfig; 887 this._moduleLoading = moduleLoading; 888 this._callServer = void 0 !== callServer ? callServer : missingCall; 889 this._encodeFormAction = encodeFormAction; 890 this._nonce = nonce; 891 this._chunks = chunks; 892 this._stringDecoder = new TextDecoder(); 893 this._closed = !1; 894 this._closedReason = null; 895 this._allowPartialStream = allowPartialStream; 896 this._tempRefs = temporaryReferences; 897} 898function resolveBuffer(response, id, buffer) { 899 response = response._chunks; 900 var chunk = response.get(id); 901 chunk && "pending" !== chunk.status ? chunk.reason.enqueueValue(buffer) : (buffer = new ReactPromise("fulfilled", buffer, null), response.set(id, buffer)); 902} 903function resolveModule(response, id, model) { 904 var chunks = response._chunks, chunk = chunks.get(id); 905 model = parseModel(response, model);
906 var clientReference = resolveClientReference(response._bundlerConfig, model); 907 if (model = preloadModule(clientReference)) { 908 if (chunk) { 909 var blockedChunk = chunk; 910 blockedChunk.status = "blocked"; 911 } else blockedChunk = new ReactPromise("blocked", null, null), chunks.set(id, blockedChunk); 912 model.then(function() { 913 return resolveModuleChunk(response, blockedChunk, clientReference); 914 }, function(error) { 915 return triggerErrorOnChunk(response, blockedChunk, error); 916 }); 917 } else chunk ? resolveModuleChunk(response, chunk, clientReference) : (chunk = new ReactPromise("resolved_module", clientReference, null), chunks.set(id, chunk)); 918} 919function resolveStream(response, id, stream, controller) { 920 var chunks = response._chunks, chunk = chunks.get(id); 921 chunk ? "pending" === chunk.status && (id = chunk.value, chunk.status = "fulfilled", chunk.value = stream, chunk.reason = controller, null !== id && wakeChunk(response, id, chunk.value, chunk)) : (response = new ReactPromise("fulfilled", stream, controller), chunks.set(id, response)); 922} 923function startReadableStream(response, id, type) { 924 var controller = null, closed = !1; 925 type = new ReadableStream({ 926 type: type, 927 start: function(c) { 928 controller = c; 929 } 930 }); 931 var previousBlockedChunk = null; 932 resolveStream(response, id, type, { 933 enqueueValue: function(value) { 934 null === previousBlockedChunk ? controller.enqueue(value) : previousBlockedChunk.then(function() { 935 controller.enqueue(value); 936 }); 937 }, 938 enqueueModel: function(json) { 939 if (null === previousBlockedChunk) { 940 var chunk = new ReactPromise("resolved_model", json, response); 941 initializeModelChunk(chunk); 942 "fulfilled" === chunk.status ? controller.enqueue(chunk.value) : (chunk.then(function(v) { 943 return controller.enqueue(v); 944 }, function(e) { 945 return controller.error(e); 946 }), previousBlockedChunk = chunk); 947 } else { 948 chunk = previousBlockedChunk; 949 var chunk$55 = createPendingChunk(); 950 chunk$55.then(function(v) { 951 return controller.enqueue(v); 952 }, function(e) { 953 return controller.error(e); 954 }); 955 previousBlockedChunk = chunk$55; 956 chunk.then(function() { 957 previousBlockedChunk === chunk$55 && (previousBlockedChunk = null); 958 resolveModelChunk(response, chunk$55, json); 959 }); 960 } 961 }, 962 close: function() { 963 if (!closed) if (closed = !0, null === previousBlockedChunk) controller.close(); 964 else { 965 var blockedChunk = previousBlockedChunk; 966 previousBlockedChunk = null; 967 blockedChunk.then(function() { 968 return controller.close(); 969 }); 970 } 971 }, 972 error: function(error) { 973 if (!closed) if (closed = !0, null === previousBlockedChunk) controller.error(error); 974 else { 975 var blockedChunk = previousBlockedChunk; 976 previousBlockedChunk = null; 977 blockedChunk.then(function() { 978 return controller.error(error); 979 }); 980 } 981 } 982 }); 983} 984function asyncIterator() { 985 return this; 986} 987function createIterator(next) { 988 next = { 989 next: next 990 }; 991 next[ASYNC_ITERATOR] = asyncIterator; 992 return next; 993} 994function startAsyncIterable(response, id, iterator) { 995 var buffer = [], closed = !1, nextWriteIndex = 0, iterable = {}; 996 iterable[ASYNC_ITERATOR] = function() { 997 var nextReadIndex = 0; 998 return createIterator(function(arg) { 999 if (void 0 !== arg) throw Error("Values cannot be passed to next() of AsyncIterables passed to Client Components."); 1000 if (nextReadIndex === buffer.length) { 1001 if (closed) return new ReactPromise("fulfilled", { 1002 done: !0, 1003 value: void 0 1004 }, null); 1005 buffer[nextReadIndex] = createPendingChunk(); 1006 } 1007 return buffer[nextReadIndex++]; 1008 }); 1009 }; 1010 resolveStream(response, id, iterator ? iterable[ASYNC_ITERATOR]() : iterable, { 1011 enqueueValue: function(value) { 1012 if (nextWriteIndex === buffer.length) buffer[nextWriteIndex] = new ReactPromise("fulfilled", { 1013 done: !1, 1014 value: value 1015 }, null); 1016 else { 1017 var chunk = buffer[nextWriteIndex], resolveListeners = chunk.value, rejectListeners = chunk.reason; 1018 chunk.status = "fulfilled"; 1019 chunk.value = { 1020 done: !1, 1021 value: value 1022 }; 1023 chunk.reason = null; 1024 null !== resolveListeners && wakeChunkIfInitialized(response, chunk, resolveListeners, rejectListeners); 1025 } 1026 nextWriteIndex++; 1027 }, 1028 enqueueModel: function(value) { 1029 nextWriteIndex === buffer.length ? buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, !1) : resolveIteratorResultChunk(response, buffer[nextWriteIndex], value, !1); 1030 nextWriteIndex++; 1031 }, 1032 close: function(value) { 1033 if (!closed) for(closed = !0, nextWriteIndex === buffer.length ? buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, !0) : resolveIteratorResultChunk(response, buffer[nextWriteIndex], value, !0), nextWriteIndex++; nextWriteIndex < buffer.length;)resolveIteratorResultChunk(response, buffer[nextWriteIndex++], '"$undefined"', !0); 1034 }, 1035 error: function(error) { 1036 if (!closed) for(closed = !0, nextWriteIndex === buffer.length && (buffer[nextWriteIndex] = createPendingChunk()); nextWriteIndex < buffer.length;)triggerErrorOnChunk(response, buffer[nextWriteIndex++], error); 1037 } 1038 }); 1039} 1040function resolveErrorProd() { 1041 var error = Error("An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error."); 1042 error.stack = "Error: " + error.message; 1043 return error; 1044} 1045function mergeBuffer(buffer, lastChunk) { 1046 for(var l = buffer.length, byteLength = lastChunk.length, i = 0; i < l; i++)byteLength += buffer[i].byteLength; 1047 byteLength = new Uint8Array(byteLength); 1048 for(var i$56 = i = 0; i$56 < l; i$56++){ 1049 var chunk = buffer[i$56]; 1050 byteLength.set(chunk, i); 1051 i += chunk.byteLength; 1052 } 1053 byteLength.set(lastChunk, i); 1054 return byteLength; 1055} 1056function resolveTypedArray(response, id, buffer, lastChunk, constructor, bytesPerElement) { 1057 buffer = 0 === buffer.length && 0 === lastChunk.byteOffset % bytesPerElement ? lastChunk : mergeBuffer(buffer, lastChunk); 1058 constructor = new constructor(buffer.buffer, buffer.byteOffset, buffer.byteLength / bytesPerElement); 1059 resolveBuffer(response, id, constructor); 1060}
1061function processFullBinaryRow(response, streamState, id, tag, buffer, chunk) { 1062 switch(tag){ 1063 case 65: 1064 resolveBuffer(response, id, mergeBuffer(buffer, chunk).buffer); 1065 return; 1066 case 79: 1067 resolveTypedArray(response, id, buffer, chunk, Int8Array, 1); 1068 return; 1069 case 111: 1070 resolveBuffer(response, id, 0 === buffer.length ? chunk : mergeBuffer(buffer, chunk)); 1071 return; 1072 case 85: 1073 resolveTypedArray(response, id, buffer, chunk, Uint8ClampedArray, 1); 1074 return; 1075 case 83: 1076 resolveTypedArray(response, id, buffer, chunk, Int16Array, 2); 1077 return; 1078 case 115: 1079 resolveTypedArray(response, id, buffer, chunk, Uint16Array, 2); 1080 return; 1081 case 76: 1082 resolveTypedArray(response, id, buffer, chunk, Int32Array, 4); 1083 return; 1084 case 108: 1085 resolveTypedArray(response, id, buffer, chunk, Uint32Array, 4); 1086 return; 1087 case 71: 1088 resolveTypedArray(response, id, buffer, chunk, Float32Array, 4); 1089 return; 1090 case 103: 1091 resolveTypedArray(response, id, buffer, chunk, Float64Array, 8); 1092 return; 1093 case 77: 1094 resolveTypedArray(response, id, buffer, chunk, BigInt64Array, 8); 1095 return; 1096 case 109: 1097 resolveTypedArray(response, id, buffer, chunk, BigUint64Array, 8); 1098 return; 1099 case 86: 1100 resolveTypedArray(response, id, buffer, chunk, DataView, 1); 1101 return; 1102 } 1103 streamState = response._stringDecoder; 1104 for(var row = "", i = 0; i < buffer.length; i++)row += streamState.decode(buffer[i], decoderOptions); 1105 buffer = row += streamState.decode(chunk); 1106 switch(tag){ 1107 case 73: 1108 resolveModule(response, id, buffer); 1109 break; 1110 case 72: 1111 id = buffer[0]; 1112 buffer = buffer.slice(1); 1113 response = parseModel(response, buffer); 1114 buffer = ReactDOMSharedInternals.d; 1115 switch(id){ 1116 case "D": 1117 buffer.D(response); 1118 break; 1119 case "C": 1120 "string" === typeof response ? buffer.C(response) : buffer.C(response[0], response[1]); 1121 break; 1122 case "L": 1123 id = response[0]; 1124 tag = response[1]; 1125 3 === response.length ? buffer.L(id, tag, response[2]) : buffer.L(id, tag); 1126 break; 1127 case "m": 1128 "string" === typeof response ? buffer.m(response) : buffer.m(response[0], response[1]); 1129 break; 1130 case "X": 1131 "string" === typeof response ? buffer.X(response) : buffer.X(response[0], response[1]); 1132 break; 1133 case "S": 1134 "string" === typeof response ? buffer.S(response) : buffer.S(response[0], 0 === response[1] ? void 0 : response[1], 3 === response.length ? response[2] : void 0); 1135 break; 1136 case "M": 1137 "string" === typeof response ? buffer.M(response) : buffer.M(response[0], response[1]); 1138 } 1139 break; 1140 case 69: 1141 tag = response._chunks; 1142 chunk = tag.get(id); 1143 buffer = JSON.parse(buffer); 1144 streamState = resolveErrorProd(); 1145 streamState.digest = buffer.digest; 1146 chunk ? triggerErrorOnChunk(response, chunk, streamState) : (response = new ReactPromise("rejected", null, streamState), tag.set(id, response)); 1147 break; 1148 case 84: 1149 response = response._chunks; 1150 (tag = response.get(id)) && "pending" !== tag.status ? tag.reason.enqueueValue(buffer) : (buffer = new ReactPromise("fulfilled", buffer, null), response.set(id, buffer)); 1151 break; 1152 case 78: 1153 case 68: 1154 case 74: 1155 case 87: 1156 throw Error("Failed to read a RSC payload created by a development version of React on the server while using a production version on the client. Always use matching versions on the server and the client."); 1157 case 82: 1158 startReadableStream(response, id, void 0); 1159 break; 1160 case 114: 1161 startReadableStream(response, id, "bytes"); 1162 break; 1163 case 88: 1164 startAsyncIterable(response, id, !1); 1165 break; 1166 case 120: 1167 startAsyncIterable(response, id, !0); 1168 break; 1169 case 67: 1170 (id = response._chunks.get(id)) && "fulfilled" === id.status && id.reason.close("" === buffer ? '"$undefined"' : buffer); 1171 break; 1172 default: 1173 tag = response._chunks, (chunk = tag.get(id)) ? resolveModelChunk(response, chunk, buffer) : (response = new ReactPromise("resolved_model", buffer, response), tag.set(id, response)); 1174 } 1175} 1176function parseModel(response, json) { 1177 json = JSON.parse(json); 1178 return reviveModel(response, json, { 1179 "": json 1180 }, ""); 1181} 1182function reviveModel(response, value, parentObject, key) { 1183 if ("string" === typeof value) return "$" === value[0] ? parseModelString(response, parentObject, key, value) : value; 1184 if ("object" !== typeof value || null === value) return value; 1185 if (isArrayImpl(value)) { 1186 for(var i = 0; i < value.length; i++)value[i] = reviveModel(response, value[i], value, "" + i); 1187 return value[0] === REACT_ELEMENT_TYPE ? (value[0] === REACT_ELEMENT_TYPE ? (response = { 1188 $$typeof: REACT_ELEMENT_TYPE, 1189 type: value[1], 1190 key: value[2], 1191 ref: null, 1192 props: value[3] 1193 }, null !== initializingHandler && (value = initializingHandler, initializingHandler = value.parent, value.errored ? (response = new ReactPromise("rejected", null, value.reason), response = createLazyChunkWrapper(response)) : 0 < value.deps && (i = new ReactPromise("blocked", null, null), value.value = response, value.chunk = i, response = createLazyChunkWrapper(i)))) : response = value, response)
1193: value; 1194 } 1195 for(i in value)"__proto__" === i ? delete value[i] : (parentObject = reviveModel(response, value[i], value, i), void 0 !== parentObject ? value[i] = parentObject : delete value[i]); 1196 return value; 1197} 1198function close(weakResponse) { 1199 weakResponse._allowPartialStream ? (weakResponse._closed = !0, weakResponse._chunks.forEach(function(chunk) { 1200 "pending" === chunk.status ? (chunk.status = "halted", chunk.value = null, chunk.reason = null) : "fulfilled" === chunk.status && null !== chunk.reason && chunk.reason.close('"$undefined"'); 1201 })) : reportGlobalError(weakResponse, Error("Connection closed.")); 1202} 1203function createResponseFromOptions(options) { 1204 return new ResponseInstance(null, null, null, options && options.callServer ? options.callServer : void 0, void 0, void 0, options && options.temporaryReferences ? options.temporaryReferences : void 0, options && options.unstable_allowPartialStream ? options.unstable_allowPartialStream : !1); 1205} 1206function startReadingFromStream(response, stream, onDone) { 1207 function progress(_ref2) { 1208 var value = _ref2.value; 1209 if (_ref2.done) return onDone(); 1210 var i = 0, rowState = streamState._rowState; 1211 _ref2 = streamState._rowID; 1212 for(var rowTag = streamState._rowTag, rowLength = streamState._rowLength, buffer = streamState._buffer, chunkLength = value.length; i < chunkLength;){ 1213 var lastIdx = -1; 1214 switch(rowState){ 1215 case 0: 1216 lastIdx = value[i++]; 1217 58 === lastIdx ? rowState = 1 : _ref2 = _ref2 << 4 | (96 < lastIdx ? lastIdx - 87 : lastIdx - 48); 1218 continue; 1219 case 1: 1220 rowState = value[i]; 1221 84 === rowState || 65 === rowState || 79 === rowState || 111 === rowState || 98 === rowState || 85 === rowState || 83 === rowState || 115 === rowState || 76 === rowState || 108 === rowState || 71 === rowState || 103 === rowState || 77 === rowState || 109 === rowState || 86 === rowState ? (rowTag = rowState, rowState = 2, i++) : 64 < rowState && 91 > rowState || 35 === rowState || 114 === rowState || 120 === rowState ? (rowTag = rowState, rowState = 3, i++) : (rowTag = 0, rowState = 3); 1222 continue; 1223 case 2: 1224 lastIdx = value[i++]; 1225 44 === lastIdx ? rowState = 4 : rowLength = rowLength << 4 | (96 < lastIdx ? lastIdx - 87 : lastIdx - 48); 1226 continue; 1227 case 3: 1228 lastIdx = value.indexOf(10, i); 1229 break; 1230 case 4: 1231 lastIdx = i + rowLength, lastIdx > value.length && (lastIdx = -1); 1232 } 1233 var offset = value.byteOffset + i; 1234 if (-1 < lastIdx) rowLength = new Uint8Array(value.buffer, offset, lastIdx - i), 98 === rowTag ? resolveBuffer(response, _ref2, lastIdx === chunkLength ? rowLength : rowLength.slice()) : processFullBinaryRow(response, streamState, _ref2, rowTag, buffer, rowLength), i = lastIdx, 3 === rowState && i++, rowLength = _ref2 = rowTag = rowState = 0, buffer.length = 0; 1235 else { 1236 value = new Uint8Array(value.buffer, offset, value.byteLength - i); 1237 98 === rowTag ? (rowLength -= value.byteLength, resolveBuffer(response, _ref2, value)) : (buffer.push(value), rowLength -= value.byteLength); 1238 break; 1239 } 1240 } 1241 streamState._rowState = rowState; 1242 streamState._rowID = _ref2; 1243 streamState._rowTag = rowTag; 1244 streamState._rowLength = rowLength; 1245 return reader.read().then(progress).catch(error); 1246 } 1247 function error(e) { 1248 reportGlobalError(response, e); 1249 } 1250 var streamState = { 1251 _rowState: 0, 1252 _rowID: 0, 1253 _rowTag: 0, 1254 _rowLength: 0, 1255 _buffer: [] 1256 }, reader = stream.getReader(); 1257 reader.read().then(progress).catch(error); 1258} 1259exports.createFromFetch = function(promiseForResponse, options) { 1260 var response = createResponseFromOptions(options); 1261 promiseForResponse.then(function(r) { 1262 startReadingFromStream(response, r.body, close.bind(null, response)); 1263 }, function(e) { 1264 reportGlobalError(response, e); 1265 }); 1266 return getChunk(response, 0); 1267}; 1268exports.createFromReadableStream = function(stream, options) { 1269 options = createResponseFromOptions(options); 1270 startReadingFromStream(options, stream, close.bind(null, options)); 1271 return getChunk(options, 0); 1272};
1273exports.createServerReference = function(id, callServer) { 1274 function action() { 1275 var args = Array.prototype.slice.call(arguments); 1276 return callServer(id, args); 1277 } 1278 registerBoundServerReference(action, id, null); 1279 return action; 1280}; 1281exports.createTemporaryReferenceSet = function() { 1282 return new Map(); 1283}; 1284exports.encodeReply = function(value, options) { 1285 return new Promise(function(resolve, reject) { 1286 var abort = processReply(value, "", options && options.temporaryReferences ? options.temporaryReferences : void 0, resolve, reject); 1287 if (options && options.signal) { 1288 var signal = options.signal; 1289 if (signal.aborted) abort(signal.reason); 1290 else { 1291 var listener = function() { 1292 abort(signal.reason); 1293 signal.removeEventListener("abort", listener); 1294 }; 1295 signal.addEventListener("abort", listener); 1296 } 1297 } 1298 }); 1299}; 1300exports.registerServerReference = function(reference, id) { 1301 registerBoundServerReference(reference, id, null); 1302 return reference; 1303}; 1304}), 1305121413, ((__turbopack_context__, module, exports) => { 1306"use strict"; 1307 1308var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 1309'use strict'; 1310if ("TURBOPACK compile-time truthy", 1) { 1311 module.exports = __turbopack_context__.r(964893); 1312} else //TURBOPACK unreachable 1313; 1314}), 1315235326, ((__turbopack_context__, module, exports) => { 1316"use strict"; 1317 1318module.exports = __turbopack_context__.r(121413); 1319}), 1320388540, ((__turbopack_context__, module, exports) => { 1321"use strict"; 1322 1323Object.defineProperty(exports, "__esModule", { 1324 value: true 1325}); 13260 && (module.exports = { 1327 ACTION_HMR_REFRESH: null, 1328 ACTION_NAVIGATE: null, 1329 ACTION_REFRESH: null, 1330 ACTION_RESTORE: null, 1331 ACTION_SERVER_ACTION: null, 1332 ACTION_SERVER_PATCH: null, 1333 PrefetchKind: null, 1334 ScrollBehavior: null 1335}); 1336function _export(target, all) { 1337 for(var name in all)Object.defineProperty(target, name, { 1338 enumerable: true, 1339 get: all[name] 1340 }); 1341} 1342_export(exports, { 1343 ACTION_HMR_REFRESH: function() { 1344 return ACTION_HMR_REFRESH; 1345 }, 1346 ACTION_NAVIGATE: function() { 1347 return ACTION_NAVIGATE; 1348 }, 1349 ACTION_REFRESH: function() { 1350 return ACTION_REFRESH; 1351 }, 1352 ACTION_RESTORE: function() { 1353 return ACTION_RESTORE; 1354 }, 1355 ACTION_SERVER_ACTION: function() { 1356 return ACTION_SERVER_ACTION; 1357 }, 1358 ACTION_SERVER_PATCH: function() { 1359 return ACTION_SERVER_PATCH; 1360 }, 1361 PrefetchKind: function() { 1362 return PrefetchKind; 1363 }, 1364 ScrollBehavior: function() { 1365 return ScrollBehavior; 1366 } 1367}); 1368const ACTION_REFRESH = 'refresh'; 1369const ACTION_NAVIGATE = 'navigate'; 1370const ACTION_RESTORE = 'restore'; 1371const ACTION_SERVER_PATCH = 'server-patch'; 1372const ACTION_HMR_REFRESH = 'hmr-refresh'; 1373const ACTION_SERVER_ACTION = 'server-action'; 1374var PrefetchKind = /*#__PURE__*/ function(PrefetchKind) { 1375 PrefetchKind["AUTO"] = "auto"; 1376 PrefetchKind["FULL"] = "full"; 1377 return PrefetchKind; 1378}({}); 1379var ScrollBehavior = /*#__PURE__*/ function(ScrollBehavior) { 1380 /** Use per-node ScrollRef to decide whether to scroll. */ ScrollBehavior[ScrollBehavior["Default"] = 0] = "Default"; 1381 /** Suppress scroll entirely (e.g. scroll={false} on Link or router.push). */ ScrollBehavior[ScrollBehavior["NoScroll"] = 1] = "NoScroll"; 1382 return ScrollBehavior; 1383}({}); 1384if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 1385 Object.defineProperty(exports.default, '__esModule', { 1386 value: true 1387 }); 1388 Object.assign(exports.default, exports); 1389 module.exports = exports.default; 1390} 1391}), 1392564245, ((__turbopack_context__, module, exports) => { 1393"use strict"; 1394 1395/** 1396 * Check to see if a value is Thenable. 1397 * 1398 * @param promise the maybe-thenable value 1399 * @returns true if the value is thenable 1400 */ Object.defineProperty(exports, "__esModule", { 1401 value: true 1402}); 1403Object.defineProperty(exports, "isThenable", { 1404 enumerable: true, 1405 get: function() { 1406 return isThenable; 1407 } 1408}); 1409function isThenable(promise) { 1410 return promise !== null && typeof promise === 'object' && 'then' in promise && typeof promise.then === 'function'; 1411} 1412}),
1413941538, ((__turbopack_context__, module, exports) => { 1414"use strict"; 1415 1416var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 1417"use strict"; 1418Object.defineProperty(exports, "__esModule", { 1419 value: true 1420}); 14210 && (module.exports = { 1422 dispatchAppRouterAction: null, 1423 dispatchGestureState: null, 1424 refreshOnInstantNavigationUnlock: null, 1425 useActionQueue: null 1426}); 1427function _export(target, all) { 1428 for(var name in all)Object.defineProperty(target, name, { 1429 enumerable: true, 1430 get: all[name] 1431 }); 1432} 1433_export(exports, { 1434 dispatchAppRouterAction: function() { 1435 return dispatchAppRouterAction; 1436 }, 1437 dispatchGestureState: function() { 1438 return dispatchGestureState; 1439 }, 1440 refreshOnInstantNavigationUnlock: function() { 1441 return refreshOnInstantNavigationUnlock; 1442 }, 1443 useActionQueue: function() { 1444 return useActionQueue; 1445 } 1446}); 1447const _interop_require_wildcard = __turbopack_context__.r(151836); 1448const _react = /*#__PURE__*/ _interop_require_wildcard._(__turbopack_context__.r(271645)); 1449const _isthenable = __turbopack_context__.r(564245); 1450const _routerreducertypes = __turbopack_context__.r(388540); 1451// The app router state lives outside of React, so we can import the dispatch 1452// method directly wherever we need it, rather than passing it around via props 1453// or context. 1454let dispatch = null; 1455function refreshOnInstantNavigationUnlock() { 1456 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 1457 ; 1458} 1459function dispatchAppRouterAction(action) { 1460 if (dispatch === null) { 1461 throw Object.defineProperty(new Error('Internal Next.js error: Router action dispatched before initialization.'), "__NEXT_ERROR_CODE", { 1462 value: "E668", 1463 enumerable: false, 1464 configurable: true 1465 }); 1466 } 1467 dispatch(action); 1468} 1469// Optimistic state setter for experimental_gesturePush. Only should be used 1470// during a gesture transition. 1471let setGestureRouterState = null; 1472function dispatchGestureState(state) { 1473 if (setGestureRouterState === null) { 1474 throw Object.defineProperty(new Error('Internal Next.js error: Router action dispatched before initialization.'), "__NEXT_ERROR_CODE", { 1475 value: "E668", 1476 enumerable: false, 1477 configurable: true 1478 }); 1479 } 1480 setGestureRouterState(state); 1481} 1482const __DEV__ = ("TURBOPACK compile-time value", "production") !== 'production'; 1483const promisesWithDebugInfo = ("TURBOPACK compile-time falsy", 0) ? "TURBOPACK unreachable" : null; 1484function useActionQueue(actionQueue) { 1485 const [canonicalState, setState] = _react.default.useState(actionQueue.state); 1486 // Wrap the canonical state in useOptimistic to support 1487 // experimental_gesturePush. During a gesture transition, this returns a fork 1488 // of the router state that represents the eventual target if/when the gesture 1489 // completes. Otherwise it returns the canonical state. 1490 const [state, setGesture] = (0, _react.useOptimistic)(canonicalState); 1491 if (typeof window !== 'undefined') { 1492 setGestureRouterState = setGesture; 1493 } 1494 // Because of a known issue that requires to decode Flight streams inside the 1495 // render phase, we have to be a bit clever and assign the dispatch method to 1496 // a module-level variable upon initialization. The useState hook in this 1497 // module only exists to synchronize state that lives outside of React. 1498 // Ideally, what we'd do instead is pass the state as a prop to root.render; 1499 // this is conceptually how we're modeling the app router state, despite the 1500 // weird implementation details. 1501 let nextDispatch; 1502 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 1503 ; 1504 else { 1505 nextDispatch = (action)=>actionQueue.dispatch(action, setState); 1506 } 1507 if (typeof window !== 'undefined') { 1508 dispatch = nextDispatch; 1509 } 1510 // When navigating to a non-prefetched route, then App Router state will be 1511 // blocked until the server responds. We need to transfer the `_debugInfo` 1512 // from the underlying Flight response onto the top-level promise that is 1513 // passed to React (via `use`) so that the latency is accurately represented 1514 // in the React DevTools. 1515 const stateWithDebugInfo = (0, _react.useMemo)(()=>{ 1516 if ("TURBOPACK compile-time truthy", 1) { 1517 return state; 1518 } 1519 //TURBOPACK unreachable 1520 ; 1521 }, [ 1522 state 1523 ]); 1524 return (0, _isthenable.isThenable)(stateWithDebugInfo) ? (0, _react.use)(stateWithDebugInfo) : stateWithDebugInfo; 1525} 1526if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 1527 Object.defineProperty(exports.default, '__esModule', { 1528 value: true 1529 });
1530 Object.assign(exports.default, exports); 1531 module.exports = exports.default; 1532} 1533}), 1534132120, ((__turbopack_context__, module, exports) => { 1535"use strict"; 1536 1537Object.defineProperty(exports, "__esModule", { 1538 value: true 1539}); 1540Object.defineProperty(exports, "callServer", { 1541 enumerable: true, 1542 get: function() { 1543 return callServer; 1544 } 1545}); 1546const _react = __turbopack_context__.r(271645); 1547const _routerreducertypes = __turbopack_context__.r(388540); 1548const _useactionqueue = __turbopack_context__.r(941538); 1549async function callServer(actionId, actionArgs) { 1550 return new Promise((resolve, reject)=>{ 1551 (0, _react.startTransition)(()=>{ 1552 (0, _useactionqueue.dispatchAppRouterAction)({ 1553 type: _routerreducertypes.ACTION_SERVER_ACTION, 1554 actionId, 1555 actionArgs, 1556 resolve, 1557 reject 1558 }); 1559 }); 1560 }); 1561} 1562if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 1563 Object.defineProperty(exports.default, '__esModule', { 1564 value: true 1565 }); 1566 Object.assign(exports.default, exports); 1567 module.exports = exports.default; 1568} 1569}), 157092245, ((__turbopack_context__, module, exports) => { 1571"use strict"; 1572 1573var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 1574"use strict"; 1575Object.defineProperty(exports, "__esModule", { 1576 value: true 1577}); 1578Object.defineProperty(exports, "findSourceMapURL", { 1579 enumerable: true, 1580 get: function() { 1581 return findSourceMapURL; 1582 } 1583}); 1584const basePath = ("TURBOPACK compile-time value", "") || ''; 1585const pathname = "".concat(basePath, "/__nextjs_source-map"); 1586const findSourceMapURL = ("TURBOPACK compile-time falsy", 0) ? "TURBOPACK unreachable" : undefined; 1587if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 1588 Object.defineProperty(exports.default, '__esModule', { 1589 value: true 1590 }); 1591 Object.assign(exports.default, exports); 1592 module.exports = exports.default; 1593} 1594}), 1595767764, ((__turbopack_context__, module, exports) => { 1596"use strict"; 1597 1598Object.defineProperty(exports, "__esModule", { 1599 value: true 1600}); 16010 && (module.exports = { 1602 HEAD_REQUEST_KEY: null, 1603 ROOT_SEGMENT_REQUEST_KEY: null,
1604 appendSegmentRequestKeyPart: null, 1605 convertSegmentPathToStaticExportFilename: null, 1606 createSegmentRequestKeyPart: null 1607}); 1608function _export(target, all) { 1609 for(var name in all)Object.defineProperty(target, name, { 1610 enumerable: true, 1611 get: all[name] 1612 }); 1613} 1614_export(exports, { 1615 HEAD_REQUEST_KEY: function() { 1616 return HEAD_REQUEST_KEY; 1617 }, 1618 ROOT_SEGMENT_REQUEST_KEY: function() { 1619 return ROOT_SEGMENT_REQUEST_KEY; 1620 }, 1621 appendSegmentRequestKeyPart: function() { 1622 return appendSegmentRequestKeyPart; 1623 }, 1624 convertSegmentPathToStaticExportFilename: function() { 1625 return convertSegmentPathToStaticExportFilename; 1626 }, 1627 createSegmentRequestKeyPart: function() { 1628 return createSegmentRequestKeyPart; 1629 } 1630}); 1631const _segment = __turbopack_context__.r(813258); 1632const ROOT_SEGMENT_REQUEST_KEY = ''; 1633const HEAD_REQUEST_KEY = '/_head'; 1634function createSegmentRequestKeyPart(segment) { 1635 if (typeof segment === 'string') { 1636 if (segment.startsWith(_segment.PAGE_SEGMENT_KEY)) { 1637 // The Flight Router State type sometimes includes the search params in 1638 // the page segment. However, the Segment Cache tracks this as a separate 1639 // key. So, we strip the search params here, and then add them back when 1640 // the cache entry is turned back into a FlightRouterState. This is an 1641 // unfortunate consequence of the FlightRouteState being used both as a 1642 // transport type and as a cache key; we'll address this once more of the 1643 // Segment Cache implementation has settled. 1644 // TODO: We should hoist the search params out of the FlightRouterState 1645 // type entirely, This is our plan for dynamic route params, too. 1646 return _segment.PAGE_SEGMENT_KEY; 1647 } 1648 const safeName = // But params typically don't include the leading slash. We should use 1649 // a different encoding to avoid this special case. 1650 segment === '/_not-found' ? '_not-found' : encodeToFilesystemAndURLSafeString(segment); 1651 // Since this is not a dynamic segment, it's fully encoded. It does not 1652 // need to be "hydrated" with a param value. 1653 return safeName; 1654 } 1655 const name = segment[0]; 1656 const paramType = segment[2]; 1657 const safeName = encodeToFilesystemAndURLSafeString(name); 1658 const encodedName = '$' + paramType + '$' + safeName; 1659 return encodedName; 1660}
1661function appendSegmentRequestKeyPart(parentRequestKey, parallelRouteKey, childRequestKeyPart) { 1662 // Aside from being filesystem safe, segment keys are also designed so that 1663 // each segment and parallel route creates its own subdirectory. Roughly in 1664 // the same shape as the source app directory. This is mostly just for easier 1665 // debugging (you can open up the build folder and navigate the output); if 1666 // we wanted to do we could just use a flat structure. 1667 // Omit the parallel route key for children, since this is the most 1668 // common case. Saves some bytes (and it's what the app directory does). 1669 const slotKey = parallelRouteKey === 'children' ? childRequestKeyPart : "@".concat(encodeToFilesystemAndURLSafeString(parallelRouteKey), "/").concat(childRequestKeyPart); 1670 return parentRequestKey + '/' + slotKey; 1671} 1672// Define a regex pattern to match the most common characters found in a route 1673// param. It excludes anything that might not be cross-platform filesystem 1674// compatible, like |. It does not need to be precise because the fallback is to 1675// just base64url-encode the whole parameter, which is fine; we just don't do it 1676// by default for compactness, and for easier debugging. 1677const simpleParamValueRegex = /^[a-zA-Z0-9\-_@]+$/; 1678function encodeToFilesystemAndURLSafeString(value) { 1679 if (simpleParamValueRegex.test(value)) { 1680 return value; 1681 } 1682 // If there are any unsafe characters, base64url-encode the entire value. 1683 // We also add a ! prefix so it doesn't collide with the simple case. 1684 const base64url = btoa(value).replace(/\+/g, '-') // Replace '+' with '-' 1685 .replace(/\//g, '_') // Replace '/' with '_' 1686 .replace(/=+$/, '') // Remove trailing '=' 1687 ; 1688 return '!' + base64url; 1689} 1690function convertSegmentPathToStaticExportFilename(segmentPath) { 1691 return "__next".concat(segmentPath.replace(/\//g, '.'), ".txt"); 1692} 1693}), 169433906, ((__turbopack_context__, module, exports) => { 1695"use strict"; 1696 1697var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 1698"use strict"; 1699Object.defineProperty(exports, "__esModule", { 1700 value: true 1701}); 17020 && (module.exports = { 1703 doesStaticSegmentAppearInURL: null, 1704 getCacheKeyForDynamicParam: null, 1705 getParamValueFromCacheKey: null, 1706 getRenderedPathname: null, 1707 getRenderedSearch: null, 1708 parseDynamicParamFromURLPart: null, 1709 urlSearchParamsToParsedUrlQuery: null, 1710 urlToUrlWithoutFlightMarker: null 1711}); 1712function _export(target, all) { 1713 for(var name in all)Object.defineProperty(target, name, { 1714 enumerable: true, 1715 get: all[name] 1716 }); 1717} 1718_export(exports, { 1719 doesStaticSegmentAppearInURL: function() { 1720 return doesStaticSegmentAppearInURL; 1721 }, 1722 getCacheKeyForDynamicParam: function() { 1723 return getCacheKeyForDynamicParam; 1724 }, 1725 getParamValueFromCacheKey: function() { 1726 return getParamValueFromCacheKey; 1727 }, 1728 getRenderedPathname: function() { 1729 return getRenderedPathname; 1730 }, 1731 getRenderedSearch: function() { 1732 return getRenderedSearch; 1733 }, 1734 parseDynamicParamFromURLPart: function() { 1735 return parseDynamicParamFromURLPart; 1736 }, 1737 urlSearchParamsToParsedUrlQuery: function() { 1738 return urlSearchParamsToParsedUrlQuery; 1739 }, 1740 urlToUrlWithoutFlightMarker: function() { 1741 return urlToUrlWithoutFlightMarker; 1742 } 1743}); 1744const _segment = __turbopack_context__.r(813258); 1745const _segmentvalueencoding = __turbopack_context__.r(767764); 1746const _approuterheaders = __turbopack_context__.r(621768); 1747function getRenderedSearch(response) { 1748 // If the server performed a rewrite, the search params used to render the 1749 // page will be different from the params in the request URL. In this case, 1750 // the response will include a header that gives the rewritten search query. 1751 const rewrittenQuery = response.headers.get(_approuterheaders.NEXT_REWRITTEN_QUERY_HEADER); 1752 if (rewrittenQuery !== null) { 1753 return rewrittenQuery === '' ? '' : '?' + rewrittenQuery; 1754 } 1755 // If the header is not present, there was no rewrite, so we use the search 1756 // query of the response URL. 1757 return urlToUrlWithoutFlightMarker(new URL(response.url)).search; 1758} 1759function getRenderedPathname(response) { 1760 // If the server performed a rewrite, the pathname used to render the 1761 // page will be different from the pathname in the request URL. In this case, 1762 // the response will include a header that gives the rewritten pathname. 1763 const rewrittenPath = response.headers.get(_approuterheaders.NEXT_REWRITTEN_PATH_HEADER); 1764 return rewrittenPath !== null && rewrittenPath !== void 0 ? rewrittenPath : urlToUrlWithoutFlightMarker(new URL(response.url)).pathname; 1765} 1766// Pathname parts come from `URL.pathname.split('/')`, so they are already 1767// in the encoded form the URL parser produces. The server-side equivalent 1768// (`get-dynamic-param.ts`) starts from a decoded param value and applies 1769// `encodeURIComponent` once. The two encodings are not the same — for 1770// example, the URL parser leaves `,` and `:` untouched while 1771// `encodeURIComponent` percent-encodes them. To produce the same canonical
1772// form on the client (and avoid double-encoding `%xx` sequences such as 1773// `%2F` → `%252F`), we decode the URL part first and re-encode it. 1774function canonicalizeURLPart(part) { 1775 try { 1776 return encodeURIComponent(decodeURIComponent(part)); 1777 } catch (unused) { 1778 // `decodeURIComponent` throws on malformed sequences. Fall back to the 1779 // already-encoded form rather than failing the navigation. 1780 return part; 1781 } 1782} 1783function parseDynamicParamFromURLPart(paramType, pathnameParts, partIndex) { 1784 // This needs to match the behavior in get-dynamic-param.ts. 1785 switch(paramType){ 1786 // Catchalls 1787 case 'c': 1788 { 1789 // Catchalls receive all the remaining URL parts. If there are no 1790 // remaining pathname parts, return an empty array. 1791 return partIndex < pathnameParts.length ? pathnameParts.slice(partIndex).map((s)=>canonicalizeURLPart(s)) : []; 1792 } 1793 // Catchall intercepted 1794 case 'ci(..)(..)': 1795 case 'ci(.)': 1796 case 'ci(..)': 1797 case 'ci(...)': 1798 { 1799 const prefix = paramType.length - 2; 1800 return partIndex < pathnameParts.length ? pathnameParts.slice(partIndex).map((s, i)=>{ 1801 if (i === 0) { 1802 return canonicalizeURLPart(s.slice(prefix)); 1803 } 1804 return canonicalizeURLPart(s); 1805 }) : []; 1806 } 1807 // Optional catchalls 1808 case 'oc': 1809 { 1810 // Optional catchalls receive all the remaining URL parts, unless this is 1811 // the end of the pathname, in which case they return null. 1812 return partIndex < pathnameParts.length ? pathnameParts.slice(partIndex).map((s)=>canonicalizeURLPart(s)) : null; 1813 } 1814 // Dynamic 1815 case 'd': 1816 { 1817 if (partIndex >= pathnameParts.length) { 1818 // The route tree expected there to be more parts in the URL than there 1819 // actually are. This could happen if the x-nextjs-rewritten-path header 1820 // is incorrectly set, or potentially due to bug in Next.js. TODO: 1821 // Should this be a hard error? During a prefetch, we can just abort. 1822 // During a client navigation, we could trigger a hard refresh. But if 1823 // it happens during initial render, we don't really have any 1824 // recovery options. 1825 return ''; 1826 } 1827 return canonicalizeURLPart(pathnameParts[partIndex]); 1828 } 1829 // Dynamic intercepted 1830 case 'di(..)(..)': 1831 case 'di(.)': 1832 case 'di(..)': 1833 case 'di(...)': 1834 { 1835 const prefix = paramType.length - 2; 1836 if (partIndex >= pathnameParts.length) { 1837 // The route tree expected there to be more parts in the URL than there 1838 // actually are. This could happen if the x-nextjs-rewritten-path header 1839 // is incorrectly set, or potentially due to bug in Next.js. TODO: 1840 // Should this be a hard error? During a prefetch, we can just abort. 1841 // During a client navigation, we could trigger a hard refresh. But if 1842 // it happens during initial render, we don't really have any 1843 // recovery options. 1844 return ''; 1845 } 1846 return canonicalizeURLPart(pathnameParts[partIndex].slice(prefix)); 1847 } 1848 default: 1849 paramType; 1850 return ''; 1851 } 1852} 1853function doesStaticSegmentAppearInURL(segment) { 1854 // This is not a parameterized segment; however, we need to determine 1855 // whether or not this segment appears in the URL. For example, this route 1856 // groups do not appear in the URL, so they should be skipped. Any other 1857 // special cases must be handled here. 1858 // TODO: Consider encoding this directly into the router tree instead of 1859 // inferring it on the client based on the segment type. Something like 1860 // a `doesAppearInURL` flag in FlightRouterState. 1861 if (segment === _segmentvalueencoding.ROOT_SEGMENT_REQUEST_KEY || // For some reason, the loader tree sometimes includes extra __PAGE__ 1862 // "layouts" when part of a parallel route. But it's not a leaf node. 1863 // Otherwise, we wouldn't need this special case because pages are 1864 // always leaf nodes. 1865 // TODO: Investigate why the loader produces these fake page segments. 1866 segment.startsWith(_segment.PAGE_SEGMENT_KEY) || // Route groups. 1867 segment[0] === '(' && segment.endsWith(')') || segment === _segment.DEFAULT_SEGMENT_KEY || segment === '/_not-found') { 1868 return false;
1869 } else { 1870 // All other segment types appear in the URL 1871 return true; 1872 } 1873} 1874function getCacheKeyForDynamicParam(paramValue, renderedSearch) { 1875 // This needs to match the logic in get-dynamic-param.ts, until we're able to 1876 // unify the various implementations so that these are always computed on 1877 // the client. 1878 if (typeof paramValue === 'string') { 1879 // TODO: Refactor or remove this helper function to accept a string rather 1880 // than the whole segment type. Also we can probably just append the 1881 // search string instead of turning it into JSON. 1882 const pageSegmentWithSearchParams = (0, _segment.addSearchParamsIfPageSegment)(paramValue, Object.fromEntries(new URLSearchParams(renderedSearch))); 1883 return pageSegmentWithSearchParams; 1884 } else if (paramValue === null) { 1885 return ''; 1886 } else { 1887 return paramValue.join('/'); 1888 } 1889} 1890function urlToUrlWithoutFlightMarker(url) { 1891 const urlWithoutFlightParameters = new URL(url); 1892 urlWithoutFlightParameters.searchParams.delete(_approuterheaders.NEXT_RSC_UNION_QUERY); 1893 if ("TURBOPACK compile-time truthy", 1) { 1894 if (("TURBOPACK compile-time value", "standalone") === 'export' && urlWithoutFlightParameters.pathname.endsWith('.txt')) //TURBOPACK unreachable 1895 ; 1896 } 1897 return urlWithoutFlightParameters; 1898} 1899function getParamValueFromCacheKey(paramCacheKey, paramType) { 1900 // Turn the cache key string sent by the server (as part of FlightRouterState) 1901 // into a value that can be passed to `useParams` and client components. 1902 const isCatchAll = paramType === 'c' || paramType === 'oc'; 1903 if (isCatchAll) { 1904 // Catch-all param keys are a concatenation of the path segments. 1905 // See equivalent logic in `getSelectedParams`. 1906 // TODO: We should just pass the array directly, rather than concatenate 1907 // it to a string and then split it back to an array. It needs to be an 1908 // array in some places, like when passing a key React, but we can convert 1909 // it at runtime in those places. 1910 return paramCacheKey.split('/'); 1911 } 1912 return paramCacheKey; 1913} 1914function urlSearchParamsToParsedUrlQuery(searchParams) { 1915 // Converts a URLSearchParams object to the same type used by the server when 1916 // creating search params props, i.e. the type returned by Node's 1917 // "querystring" module. 1918 const result = {}; 1919 for (const [key, value] of searchParams.entries()){ 1920 if (result[key] === undefined) { 1921 result[key] = value; 1922 } else if (Array.isArray(result[key])) { 1923 result[key].push(value); 1924 } else { 1925 result[key] = [ 1926 result[key], 1927 value 1928 ]; 1929 } 1930 } 1931 return result; 1932} 1933if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 1934 Object.defineProperty(exports.default, '__esModule', { 1935 value: true 1936 }); 1937 Object.assign(exports.default, exports); 1938 module.exports = exports.default; 1939} 1940}), 1941450590, ((__turbopack_context__, module, exports) => { 1942"use strict"; 1943 1944Object.defineProperty(exports, "__esModule", { 1945 value: true 1946}); 19470 && (module.exports = { 1948 createInitialRSCPayloadFromFallbackPrerender: null,
1949 getFlightDataPartsFromPath: null, 1950 getNextFlightSegmentPath: null, 1951 normalizeFlightData: null, 1952 prepareFlightRouterStateForRequest: null 1953}); 1954function _export(target, all) { 1955 for(var name in all)Object.defineProperty(target, name, { 1956 enumerable: true, 1957 get: all[name] 1958 }); 1959} 1960_export(exports, { 1961 createInitialRSCPayloadFromFallbackPrerender: function() { 1962 return createInitialRSCPayloadFromFallbackPrerender; 1963 }, 1964 getFlightDataPartsFromPath: function() { 1965 return getFlightDataPartsFromPath; 1966 }, 1967 getNextFlightSegmentPath: function() { 1968 return getNextFlightSegmentPath; 1969 }, 1970 normalizeFlightData: function() { 1971 return normalizeFlightData; 1972 }, 1973 prepareFlightRouterStateForRequest: function() { 1974 return prepareFlightRouterStateForRequest; 1975 } 1976}); 1977const _segment = __turbopack_context__.r(813258); 1978const _routeparams = __turbopack_context__.r(33906); 1979const _createhreffromurl = __turbopack_context__.r(451191); 1980function getFlightDataPartsFromPath(flightDataPath) { 1981 var _segmentPath_; 1982 // Pick the last 4 items from the `FlightDataPath` to get the [tree, seedData, viewport, isHeadPartial]. 1983 const flightDataPathLength = 4; 1984 // tree, seedData, and head are *always* the last three items in the `FlightDataPath`. 1985 const [tree, seedData, head, isHeadPartial] = flightDataPath.slice(-flightDataPathLength); 1986 // The `FlightSegmentPath` is everything except the last three items. For a root render, it won't be present. 1987 const segmentPath = flightDataPath.slice(0, -flightDataPathLength); 1988 return { 1989 // TODO: Unify these two segment path helpers. We are inconsistently pushing an empty segment ("") 1990 // to the start of the segment path in some places which makes it hard to use solely the segment path. 1991 // Look for "// TODO-APP: remove ''" in the codebase. 1992 pathToSegment: segmentPath.slice(0, -1), 1993 segmentPath, 1994 // if the `FlightDataPath` corresponds with the root, there'll be no segment path, 1995 // in which case we default to ''. 1996 segment: (_segmentPath_ = segmentPath[segmentPath.length - 1]) !== null && _segmentPath_ !== void 0 ? _segmentPath_ : '', 1997 tree, 1998 seedData, 1999 head, 2000 isHeadPartial, 2001 isRootRender: flightDataPath.length === flightDataPathLength 2002 }; 2003} 2004function createInitialRSCPayloadFromFallbackPrerender(response, fallbackInitialRSCPayload) { 2005 // This is a static fallback page. In order to hydrate the page, we need to 2006 // parse the client params from the URL, but to account for the possibility 2007 // that the page was rewritten, we need to check the response headers 2008 // for x-nextjs-rewritten-path or x-nextjs-rewritten-query headers. Since 2009 // we can't access the headers of the initial document response, the client 2010 // performs a fetch request to the current location. Since it's possible that 2011 // the fetch request will be dynamically rewritten to a different path than 2012 // the initial document, this fetch request delivers _all_ the hydration data 2013 // for the page; it was not inlined into the document, like it normally 2014 // would be. 2015 // 2016 // TODO: Consider treating the case where fetch is rewritten to a different 2017 // path from the document as a special deopt case. We should optimistically 2018 // assume this won't happen, inline the data into the document, and perform 2019 // a minimal request (like a HEAD or range request) to verify that the 2020 // response matches. Tricky to get right because we need to account for 2021 // all the different deployment environments we support, like output: 2022 // "export" mode, where we currently don't assume that custom response 2023 // headers are present. 2024 // Patch the Flight data sent by the server with the correct params parsed 2025 // from the URL + response object. 2026 const renderedPathname = (0, _routeparams.getRenderedPathname)(response); 2027 const renderedSearch = (0, _routeparams.getRenderedSearch)(response); 2028 const canonicalUrl = (0, _createhreffromurl.createHrefFromUrl)(new URL(location.href)); 2029 const originalFlightDataPath = fallbackInitialRSCPayload.f[0]; 2030 const originalFlightRouterState = originalFlightDataPath[0]; 2031 const payload = { 2032 c: canonicalUrl.split('/'), 2033 q: renderedSearch, 2034 i: fallbackInitialRSCPayload.i, 2035 f: [ 2036 [
2037 fillInFallbackFlightRouterState(originalFlightRouterState, renderedPathname, renderedSearch), 2038 originalFlightDataPath[1], 2039 originalFlightDataPath[2], 2040 originalFlightDataPath[2] 2041 ] 2042 ], 2043 m: fallbackInitialRSCPayload.m, 2044 G: fallbackInitialRSCPayload.G, 2045 S: fallbackInitialRSCPayload.S, 2046 h: fallbackInitialRSCPayload.h 2047 }; 2048 if (fallbackInitialRSCPayload.b) { 2049 payload.b = fallbackInitialRSCPayload.b; 2050 } 2051 return payload; 2052} 2053function fillInFallbackFlightRouterState(flightRouterState, renderedPathname, renderedSearch) { 2054 const pathnameParts = renderedPathname.split('/').filter((p)=>p !== ''); 2055 const index = 0; 2056 return fillInFallbackFlightRouterStateImpl(flightRouterState, renderedSearch, pathnameParts, index); 2057} 2058function fillInFallbackFlightRouterStateImpl(flightRouterState, renderedSearch, pathnameParts, pathnamePartsIndex) { 2059 const originalSegment = flightRouterState[0]; 2060 let newSegment; 2061 let doesAppearInURL; 2062 if (typeof originalSegment === 'string') { 2063 newSegment = originalSegment; 2064 doesAppearInURL = (0, _routeparams.doesStaticSegmentAppearInURL)(originalSegment); 2065 } else { 2066 const paramName = originalSegment[0]; 2067 const paramType = originalSegment[2]; 2068 const staticSiblings = originalSegment[3]; 2069 const paramValue = (0, _routeparams.parseDynamicParamFromURLPart)(paramType, pathnameParts, pathnamePartsIndex); 2070 const cacheKey = (0, _routeparams.getCacheKeyForDynamicParam)(paramValue, renderedSearch); 2071 newSegment = [ 2072 paramName, 2073 cacheKey, 2074 paramType, 2075 staticSiblings 2076 ]; 2077 doesAppearInURL = true; 2078 } 2079 // Only increment the index if the segment appears in the URL. If it's a 2080 // "virtual" segment, like a route group, it remains the same. 2081 const childPathnamePartsIndex = doesAppearInURL ? pathnamePartsIndex + 1 : pathnamePartsIndex; 2082 const children = flightRouterState[1]; 2083 const newChildren = {}; 2084 for(let key in children){ 2085 const childFlightRouterState = children[key]; 2086 newChildren[key] = fillInFallbackFlightRouterStateImpl(childFlightRouterState, renderedSearch, pathnameParts, childPathnamePartsIndex); 2087 } 2088 const newState = [ 2089 newSegment, 2090 newChildren, 2091 null, 2092 flightRouterState[3], 2093 flightRouterState[4] 2094 ]; 2095 return newState; 2096} 2097function getNextFlightSegmentPath(flightSegmentPath) { 2098 // Since `FlightSegmentPath` is a repeated tuple of `Segment` and `ParallelRouteKey`, we slice off two items 2099 // to get the next segment path. 2100 return flightSegmentPath.slice(2); 2101} 2102function normalizeFlightData(flightData) { 2103 // FlightData can be a string when the server didn't respond with a proper flight response, 2104 // or when a redirect happens, to signal to the client that it needs to perform an MPA navigation. 2105 if (typeof flightData === 'string') { 2106 return flightData; 2107 } 2108 return flightData.map((flightDataPath)=>getFlightDataPartsFromPath(flightDataPath)); 2109} 2110function prepareFlightRouterStateForRequest(flightRouterState, isHmrRefresh) { 2111 // HMR requests need the complete, unmodified state for proper functionality 2112 if (isHmrRefresh) { 2113 return encodeURIComponent(JSON.stringify(flightRouterState)); 2114 } 2115 return encodeURIComponent(JSON.stringify(stripClientOnlyDataFromFlightRouterState(flightRouterState))); 2116} 2117/** 2118 * Recursively strips client-only data from FlightRouterState while preserving 2119 * server-needed information for proper rendering decisions. 2120 */ function stripClientOnlyDataFromFlightRouterState(flightRouterState) { 2121 const [segment, parallelRoutes, _refreshState, refreshMarker, prefetchHints] = flightRouterState; 2122 // Strip client-only data from the segment 2123 const cleanedSegment = stripClientOnlyDataFromSegment(segment); 2124 // Recursively process parallel routes 2125 const cleanedParallelRoutes = {}; 2126 for (const [key, childState] of Object.entries(parallelRoutes)){ 2127 cleanedParallelRoutes[key] = stripClientOnlyDataFromFlightRouterState(childState); 2128 } 2129 const result = [ 2130 cleanedSegment, 2131 cleanedParallelRoutes 2132 ]; 2133 if (refreshMarker) { 2134 result[2] = null // null slightly more compact than undefined 2135 ; 2136 result[3] = refreshMarker; 2137 } 2138 // Append optional fields if present 2139 if (prefetchHints !== undefined) { 2140 result[4] = prefetchHints; 2141 } 2142 // Everything else is used only by the client and is not needed for requests. 2143 return result; 2144} 2145/** 2146 * Strips client-only data from segments: 2147 * - Search parameters from __PAGE__ segments 2148 * - staticSiblings from dynamic segment tuples (only needed for client-side 2149 * prefetch reuse decisions) 2150 */ function stripClientOnlyDataFromSegment(segment) { 2151 if (typeof segment === 'string') { 2152 // Strip search params from __PAGE__ segments 2153 if (segment.startsWith(_segment.PAGE_SEGMENT_KEY + '?')) { 2154 return _segment.PAGE_SEGMENT_KEY; 2155 } 2156 return segment; 2157 } 2158 // Dynamic segment tuple: [paramName, paramCacheKey, paramType, staticSiblings] 2159 // Strip staticSiblings (4th element) since server doesn't need it 2160 const [paramName, paramCacheKey, paramType] = segment; 2161 return [ 2162 paramName, 2163 paramCacheKey, 2164 paramType, 2165 null 2166 ]; 2167} 2168if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 2169 Object.defineProperty(exports.default, '__esModule', { 2170 value: true 2171 });
2172 Object.assign(exports.default, exports); 2173 module.exports = exports.default; 2174} 2175}), 2176419921, ((__turbopack_context__, module, exports) => { 2177"use strict"; 2178 2179// http://www.cse.yorku.ca/~oz/hash.html 2180// More specifically, 32-bit hash via djbxor 2181// (ref: https://gist.github.com/eplawless/52813b1d8ad9af510d85?permalink_comment_id=3367765#gistcomment-3367765) 2182// This is due to number type differences between rust for turbopack to js number types, 2183// where rust does not have easy way to repreesnt js's 53-bit float number type for the matching 2184// overflow behavior. This is more `correct` in terms of having canonical hash across different runtime / implementation 2185// as can gaurantee determinstic output from 32bit hash. 2186Object.defineProperty(exports, "__esModule", { 2187 value: true 2188}); 21890 && (module.exports = { 2190 djb2Hash: null, 2191 hexHash: null 2192}); 2193function _export(target, all) { 2194 for(var name in all)Object.defineProperty(target, name, { 2195 enumerable: true, 2196 get: all[name] 2197 }); 2198} 2199_export(exports, { 2200 djb2Hash: function() { 2201 return djb2Hash; 2202 }, 2203 hexHash: function() { 2204 return hexHash; 2205 } 2206}); 2207function djb2Hash(str) { 2208 let hash = 5381; 2209 for(let i = 0; i < str.length; i++){ 2210 const char = str.charCodeAt(i); 2211 hash = (hash << 5) + hash + char & 0xffffffff; 2212 } 2213 return hash >>> 0; 2214} 2215function hexHash(str) { 2216 return djb2Hash(str).toString(36).slice(0, 5); 2217} 2218}), 2219686051, ((__turbopack_context__, module, exports) => { 2220"use strict"; 2221 2222Object.defineProperty(exports, "__esModule", { 2223 value: true 2224}); 22250 && (module.exports = { 2226 computeCacheBustingSearchParam: null, 2227 computeLegacyCacheBustingSearchParam: null 2228}); 2229function _export(target, all) { 2230 for(var name in all)Object.defineProperty(target, name, { 2231 enumerable: true, 2232 get: all[name] 2233 }); 2234} 2235_export(exports, { 2236 computeCacheBustingSearchParam: function() { 2237 return computeCacheBustingSearchParam; 2238 }, 2239 computeLegacyCacheBustingSearchParam: function() { 2240 return computeLegacyCacheBustingSearchParam; 2241 } 2242}); 2243const _hash = __turbopack_context__.r(419921); 2244const CACHE_BUSTING_SEARCH_PARAM_DIGEST_BYTES = 12; 2245const textEncoder = new TextEncoder(); 2246function encodeCacheBustingSearchParam(bytes) { 2247 let binary = ''; 2248 for(let i = 0; i < bytes.length; i++){ 2249 binary += String.fromCharCode(bytes[i]); 2250 } 2251 return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); 2252} 2253function normalizeCacheBustingInput(value) { 2254 if (value === undefined) { 2255 return '0'; 2256 } 2257 return Array.isArray(value) ? value.join(',') : value; 2258} 2259function createCacheBustingSearchParamInput(prefetchHeader, segmentPrefetchHeader, stateTreeHeader, nextUrlHeader) { 2260 if ((prefetchHeader === undefined || prefetchHeader === '0') && segmentPrefetchHeader === undefined && stateTreeHeader === undefined && nextUrlHeader === undefined) { 2261 return null; 2262 } 2263 return [ 2264 prefetchHeader !== null && prefetchHeader !== void 0 ? prefetchHeader : '0', 2265 normalizeCacheBustingInput(segmentPrefetchHeader), 2266 normalizeCacheBustingInput(stateTreeHeader), 2267 normalizeCacheBustingInput(nextUrlHeader) 2268 ].join(','); 2269} 2270async function computeCacheBustingSearchParamFromInput(input) { 2271 // Truncate SHA-256 to 96 bits to keep `_rsc` compact 2272 const digest = await globalThis.crypto.subtle.digest('SHA-256', textEncoder.encode(input)); 2273 return encodeCacheBustingSearchParam(new Uint8Array(digest).subarray(0, CACHE_BUSTING_SEARCH_PARAM_DIGEST_BYTES)); 2274} 2275async function computeCacheBustingSearchParam(prefetchHeader, segmentPrefetchHeader, stateTreeHeader, nextUrlHeader) { 2276 const input = createCacheBustingSearchParamInput(prefetchHeader, segmentPrefetchHeader, stateTreeHeader, nextUrlHeader); 2277 if (input === null) { 2278 return ''; 2279 } 2280 return computeCacheBustingSearchParamFromInput(input); 2281} 2282function computeLegacyCacheBustingSearchParam(prefetchHeader, segmentPrefetchHeader, stateTreeHeader, nextUrlHeader) { 2283 const input = createCacheBustingSearchParamInput(prefetchHeader, segmentPrefetchHeader, stateTreeHeader, nextUrlHeader); 2284 if (input === null) { 2285 return ''; 2286 } 2287 return (0, _hash.hexHash)(input); 2288} 2289}),
2290288093, ((__turbopack_context__, module, exports) => { 2291"use strict"; 2292 2293Object.defineProperty(exports, "__esModule", { 2294 value: true 2295}); 22960 && (module.exports = { 2297 setCacheBustingSearchParam: null, 2298 setCacheBustingSearchParamWithHash: null 2299}); 2300function _export(target, all) { 2301 for(var name in all)Object.defineProperty(target, name, { 2302 enumerable: true, 2303 get: all[name] 2304 }); 2305} 2306_export(exports, { 2307 setCacheBustingSearchParam: function() { 2308 return setCacheBustingSearchParam; 2309 }, 2310 setCacheBustingSearchParamWithHash: function() { 2311 return setCacheBustingSearchParamWithHash; 2312 } 2313}); 2314const _cachebustingsearchparam = __turbopack_context__.r(686051); 2315const _approuterheaders = __turbopack_context__.r(621768); 2316async function computeClientCacheBustingSearchParam(headers) { 2317 var _globalThis_crypto_subtle, _globalThis_crypto; 2318 if (typeof ((_globalThis_crypto = globalThis.crypto) === null || _globalThis_crypto === void 0 ? void 0 : (_globalThis_crypto_subtle = _globalThis_crypto.subtle) === null || _globalThis_crypto_subtle === void 0 ? void 0 : _globalThis_crypto_subtle.digest) === 'function') { 2319 return (0, _cachebustingsearchparam.computeCacheBustingSearchParam)(headers[_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER], headers[_approuterheaders.NEXT_ROUTER_SEGMENT_PREFETCH_HEADER], headers[_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER], headers[_approuterheaders.NEXT_URL]); 2320 } 2321 return (0, _cachebustingsearchparam.computeLegacyCacheBustingSearchParam)(headers[_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER], headers[_approuterheaders.NEXT_ROUTER_SEGMENT_PREFETCH_HEADER], headers[_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER], headers[_approuterheaders.NEXT_URL]); 2322} 2323const setCacheBustingSearchParam = async (url, headers)=>{ 2324 const uniqueCacheKey = await computeClientCacheBustingSearchParam(headers); 2325 setCacheBustingSearchParamWithHash(url, uniqueCacheKey); 2326}; 2327const setCacheBustingSearchParamWithHash = (url, hash)=>{ 2328 /** 2329 * Note that we intentionally do not use `url.searchParams.set` here: 2330 * 2331 * const url = new URL('https://example.com/search?q=custom%20spacing'); 2332 * url.searchParams.set('_rsc', 'abc123'); 2333 * console.log(url.toString()); // Outputs: https://example.com/search?q=custom+spacing&_rsc=abc123 2334 * ^ <--- this is causing confusion 2335 * This is in fact intended based on https://url.spec.whatwg.org/#interface-urlsearchparams, but 2336 * we want to preserve the %20 as %20 if that's what the user passed in, hence the custom 2337 * logic below. 2338 */ const existingSearch = url.search; 2339 const rawQuery = existingSearch.startsWith('?') ? existingSearch.slice(1) : existingSearch; 2340 // Always remove any existing cache busting param and add a fresh one to ensure 2341 // we have the correct value based on current request headers 2342 const pairs = rawQuery.split('&').filter((pair)=>pair && !pair.startsWith("".concat(_approuterheaders.NEXT_RSC_UNION_QUERY, "="))); 2343 if (hash.length > 0) { 2344 pairs.push("".concat(_approuterheaders.NEXT_RSC_UNION_QUERY, "=").concat(hash)); 2345 } else { 2346 pairs.push("".concat(_approuterheaders.NEXT_RSC_UNION_QUERY)); 2347 } 2348 url.search = pairs.length ? "?".concat(pairs.join('&')) : ''; 2349}; 2350if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 2351 Object.defineProperty(exports.default, '__esModule', { 2352 value: true 2353 }); 2354 Object.assign(exports.default, exports); 2355 module.exports = exports.default; 2356} 2357}), 2358732992, ((__turbopack_context__, module, exports) => { 2359"use strict"; 2360 2361// This gets assigned as a side-effect during app initialization. Because it 2362// represents the build used to create the JS bundle, it should never change 2363// after being set, so we store it in a global variable. 2364// 2365// When performing RSC requests, if the incoming data has a different build ID, 2366// we perform an MPA navigation/refresh to load the updated build and ensure 2367// that the client and server in sync. 2368// 2369// Starts as an empty string. In practice, because setNavigationBuildId is called during initialization 2370// before hydration starts, this will always get reassigned to the actual ID before it's ever needed 2371// by a navigation. If for some reasons it didn't, due to a bug or race condition, then on
2372// navigation the build comparision would fail and trigger an MPA navigation. 2373// 2374// Note that this can also be initialized with the deployment id instead (if available). So it's not 2375// the same as "the build id", but we are running out of alternative names for "build id or 2376// deployment id". 2377Object.defineProperty(exports, "__esModule", { 2378 value: true 2379}); 23800 && (module.exports = { 2381 getNavigationBuildId: null, 2382 setNavigationBuildId: null 2383}); 2384function _export(target, all) { 2385 for(var name in all)Object.defineProperty(target, name, { 2386 enumerable: true, 2387 get: all[name] 2388 }); 2389} 2390_export(exports, { 2391 getNavigationBuildId: function() { 2392 return getNavigationBuildId; 2393 }, 2394 setNavigationBuildId: function() { 2395 return setNavigationBuildId; 2396 } 2397}); 2398let globalBuildId = ''; 2399function setNavigationBuildId(buildId) { 2400 globalBuildId = buildId; 2401} 2402function getNavigationBuildId() { 2403 return globalBuildId; 2404} 2405if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 2406 Object.defineProperty(exports.default, '__esModule', { 2407 value: true 2408 }); 2409 Object.assign(exports.default, exports); 2410 module.exports = exports.default; 2411} 2412}), 2413663416, ((__turbopack_context__, module, exports) => { 2414"use strict"; 2415 2416Object.defineProperty(exports, "__esModule", { 2417 value: true 2418}); 24190 && (module.exports = { 2420 ACTION_SUFFIX: null, 2421 APP_DIR_ALIAS: null, 2422 CACHE_ONE_YEAR_SECONDS: null, 2423 DOT_NEXT_ALIAS: null, 2424 ESLINT_DEFAULT_DIRS: null, 2425 GSP_NO_RETURNED_VALUE: null, 2426 GSSP_COMPONENT_MEMBER_ERROR: null, 2427 GSSP_NO_RETURNED_VALUE: null, 2428 HTML_CONTENT_TYPE_HEADER: null, 2429 INFINITE_CACHE: null, 2430 INSTRUMENTATION_HOOK_FILENAME: null, 2431 JSON_CONTENT_TYPE_HEADER: null, 2432 MATCHED_PATH_HEADER: null, 2433 MIDDLEWARE_FILENAME: null, 2434 MIDDLEWARE_LOCATION_REGEXP: null, 2435 NEXT_BODY_SUFFIX: null, 2436 NEXT_CACHE_IMPLICIT_TAG_ID: null, 2437 NEXT_CACHE_REVALIDATED_TAGS_HEADER: null, 2438 NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER: null, 2439 NEXT_CACHE_ROOT_PARAM_TAG_ID: null, 2440 NEXT_CACHE_SOFT_TAG_MAX_LENGTH: null, 2441 NEXT_CACHE_TAGS_HEADER: null, 2442 NEXT_CACHE_TAG_MAX_ITEMS: null, 2443 NEXT_CACHE_TAG_MAX_LENGTH: null, 2444 NEXT_DATA_SUFFIX: null, 2445 NEXT_INTERCEPTION_MARKER_PREFIX: null, 2446 NEXT_META_SUFFIX: null, 2447 NEXT_NAV_DEPLOYMENT_ID_HEADER: null, 2448 NEXT_QUERY_PARAM_PREFIX: null, 2449 NEXT_RESUME_HEADER: null, 2450 NEXT_RESUME_STATE_LENGTH_HEADER: null, 2451 NON_STANDARD_NODE_ENV: null, 2452 PAGES_DIR_ALIAS: null, 2453 PRERENDER_REVALIDATE_HEADER: null, 2454 PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER: null, 2455 PROXY_FILENAME: null, 2456 PROXY_LOCATION_REGEXP: null, 2457 PUBLIC_DIR_MIDDLEWARE_CONFLICT: null, 2458 ROOT_DIR_ALIAS: null, 2459 RSC_ACTION_CLIENT_WRAPPER_ALIAS: null, 2460 RSC_ACTION_ENCRYPTION_ALIAS: null, 2461 RSC_ACTION_PROXY_ALIAS: null, 2462 RSC_ACTION_VALIDATE_ALIAS: null, 2463 RSC_CACHE_WRAPPER_ALIAS: null, 2464 RSC_DYNAMIC_IMPORT_WRAPPER_ALIAS: null, 2465 RSC_MOD_REF_PROXY_ALIAS: null, 2466 RSC_SEGMENTS_DIR_SUFFIX: null, 2467 RSC_SEGMENT_SUFFIX: null, 2468 RSC_SUFFIX: null, 2469 SERVER_PROPS_EXPORT_ERROR: null, 2470 SERVER_PROPS_GET_INIT_PROPS_CONFLICT: null, 2471 SERVER_PROPS_SSG_CONFLICT: null, 2472 SERVER_RUNTIME: null, 2473 SSG_FALLBACK_EXPORT_ERROR: null, 2474 SSG_GET_INITIAL_PROPS_CONFLICT: null, 2475 STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR: null, 2476 TEXT_PLAIN_CONTENT_TYPE_HEADER: null, 2477 UNSTABLE_REVALIDATE_RENAME_ERROR: null, 2478 WEBPACK_LAYERS: null, 2479 WEBPACK_RESOURCE_QUERIES: null, 2480 WEB_SOCKET_MAX_RECONNECTIONS: null 2481}); 2482function _export(target, all) { 2483 for(var name in all)Object.defineProperty(target, name, { 2484 enumerable: true, 2485 get: all[name] 2486 }); 2487} 2488_export(exports, { 2489 ACTION_SUFFIX: function() { 2490 return ACTION_SUFFIX; 2491 }, 2492 APP_DIR_ALIAS: function() { 2493 return APP_DIR_ALIAS; 2494 }, 2495 CACHE_ONE_YEAR_SECONDS: function() { 2496 return CACHE_ONE_YEAR_SECONDS; 2497 }, 2498 DOT_NEXT_ALIAS: function() { 2499 return DOT_NEXT_ALIAS; 2500 }, 2501 ESLINT_DEFAULT_DIRS: function() { 2502 return ESLINT_DEFAULT_DIRS; 2503 }, 2504 GSP_NO_RETURNED_VALUE: function() { 2505 return GSP_NO_RETURNED_VALUE; 2506 }, 2507 GSSP_COMPONENT_MEMBER_ERROR: function() { 2508 return GSSP_COMPONENT_MEMBER_ERROR; 2509 }, 2510 GSSP_NO_RETURNED_VALUE: function() { 2511 return GSSP_NO_RETURNED_VALUE; 2512 }, 2513 HTML_CONTENT_TYPE_HEADER: function() { 2514 return HTML_CONTENT_TYPE_HEADER; 2515 }, 2516 INFINITE_CACHE: function() { 2517 return INFINITE_CACHE; 2518 }, 2519 INSTRUMENTATION_HOOK_FILENAME: function() { 2520 return INSTRUMENTATION_HOOK_FILENAME; 2521 }, 2522 JSON_CONTENT_TYPE_HEADER: function() { 2523 return JSON_CONTENT_TYPE_HEADER; 2524 }, 2525 MATCHED_PATH_HEADER: function() { 2526 return MATCHED_PATH_HEADER; 2527 }, 2528 MIDDLEWARE_FILENAME: function() { 2529 return MIDDLEWARE_FILENAME; 2530 }, 2531 MIDDLEWARE_LOCATION_REGEXP: function() { 2532 return MIDDLEWARE_LOCATION_REGEXP; 2533 }, 2534 NEXT_BODY_SUFFIX: function() { 2535 return NEXT_BODY_SUFFIX; 2536 }, 2537 NEXT_CACHE_IMPLICIT_TAG_ID: function() { 2538 return NEXT_CACHE_IMPLICIT_TAG_ID; 2539 }, 2540 NEXT_CACHE_REVALIDATED_TAGS_HEADER: function() { 2541 return NEXT_CACHE_REVALIDATED_TAGS_HEADER; 2542 }, 2543 NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER: function() { 2544 return NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER; 2545 }, 2546 NEXT_CACHE_ROOT_PARAM_TAG_ID: function() { 2547 return NEXT_CACHE_ROOT_PARAM_TAG_ID; 2548 }, 2549 NEXT_CACHE_SOFT_TAG_MAX_LENGTH: function() { 2550 return NEXT_CACHE_SOFT_TAG_MAX_LENGTH; 2551 }, 2552 NEXT_CACHE_TAGS_HEADER: function() { 2553 return NEXT_CACHE_TAGS_HEADER; 2554 }, 2555 NEXT_CACHE_TAG_MAX_ITEMS: function() { 2556 return NEXT_CACHE_TAG_MAX_ITEMS; 2557 }, 2558 NEXT_CACHE_TAG_MAX_LENGTH: function() { 2559 return NEXT_CACHE_TAG_MAX_LENGTH; 2560 }, 2561 NEXT_DATA_SUFFIX: function() { 2562 return NEXT_DATA_SUFFIX; 2563 }, 2564 NEXT_INTERCEPTION_MARKER_PREFIX: function() { 2565 return NEXT_INTERCEPTION_MARKER_PREFIX; 2566 },
2567 NEXT_META_SUFFIX: function() { 2568 return NEXT_META_SUFFIX; 2569 }, 2570 NEXT_NAV_DEPLOYMENT_ID_HEADER: function() { 2571 return NEXT_NAV_DEPLOYMENT_ID_HEADER; 2572 }, 2573 NEXT_QUERY_PARAM_PREFIX: function() { 2574 return NEXT_QUERY_PARAM_PREFIX; 2575 }, 2576 NEXT_RESUME_HEADER: function() { 2577 return NEXT_RESUME_HEADER; 2578 }, 2579 NEXT_RESUME_STATE_LENGTH_HEADER: function() { 2580 return NEXT_RESUME_STATE_LENGTH_HEADER; 2581 }, 2582 NON_STANDARD_NODE_ENV: function() { 2583 return NON_STANDARD_NODE_ENV; 2584 }, 2585 PAGES_DIR_ALIAS: function() { 2586 return PAGES_DIR_ALIAS; 2587 }, 2588 PRERENDER_REVALIDATE_HEADER: function() { 2589 return PRERENDER_REVALIDATE_HEADER; 2590 }, 2591 PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER: function() { 2592 return PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER; 2593 }, 2594 PROXY_FILENAME: function() { 2595 return PROXY_FILENAME; 2596 }, 2597 PROXY_LOCATION_REGEXP: function() { 2598 return PROXY_LOCATION_REGEXP; 2599 }, 2600 PUBLIC_DIR_MIDDLEWARE_CONFLICT: function() { 2601 return PUBLIC_DIR_MIDDLEWARE_CONFLICT; 2602 }, 2603 ROOT_DIR_ALIAS: function() { 2604 return ROOT_DIR_ALIAS; 2605 }, 2606 RSC_ACTION_CLIENT_WRAPPER_ALIAS: function() { 2607 return RSC_ACTION_CLIENT_WRAPPER_ALIAS; 2608 }, 2609 RSC_ACTION_ENCRYPTION_ALIAS: function() { 2610 return RSC_ACTION_ENCRYPTION_ALIAS; 2611 }, 2612 RSC_ACTION_PROXY_ALIAS: function() { 2613 return RSC_ACTION_PROXY_ALIAS; 2614 }, 2615 RSC_ACTION_VALIDATE_ALIAS: function() { 2616 return RSC_ACTION_VALIDATE_ALIAS; 2617 }, 2618 RSC_CACHE_WRAPPER_ALIAS: function() { 2619 return RSC_CACHE_WRAPPER_ALIAS; 2620 }, 2621 RSC_DYNAMIC_IMPORT_WRAPPER_ALIAS: function() { 2622 return RSC_DYNAMIC_IMPORT_WRAPPER_ALIAS; 2623 }, 2624 RSC_MOD_REF_PROXY_ALIAS: function() { 2625 return RSC_MOD_REF_PROXY_ALIAS; 2626 }, 2627 RSC_SEGMENTS_DIR_SUFFIX: function() { 2628 return RSC_SEGMENTS_DIR_SUFFIX; 2629 }, 2630 RSC_SEGMENT_SUFFIX: function() { 2631 return RSC_SEGMENT_SUFFIX; 2632 }, 2633 RSC_SUFFIX: function() { 2634 return RSC_SUFFIX; 2635 }, 2636 SERVER_PROPS_EXPORT_ERROR: function() { 2637 return SERVER_PROPS_EXPORT_ERROR; 2638 }, 2639 SERVER_PROPS_GET_INIT_PROPS_CONFLICT: function() { 2640 return SERVER_PROPS_GET_INIT_PROPS_CONFLICT; 2641 }, 2642 SERVER_PROPS_SSG_CONFLICT: function() { 2643 return SERVER_PROPS_SSG_CONFLICT; 2644 }, 2645 SERVER_RUNTIME: function() { 2646 return SERVER_RUNTIME; 2647 }, 2648 SSG_FALLBACK_EXPORT_ERROR: function() { 2649 return SSG_FALLBACK_EXPORT_ERROR; 2650 }, 2651 SSG_GET_INITIAL_PROPS_CONFLICT: function() { 2652 return SSG_GET_INITIAL_PROPS_CONFLICT; 2653 }, 2654 STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR: function() { 2655 return STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR; 2656 }, 2657 TEXT_PLAIN_CONTENT_TYPE_HEADER: function() { 2658 return TEXT_PLAIN_CONTENT_TYPE_HEADER; 2659 }, 2660 UNSTABLE_REVALIDATE_RENAME_ERROR: function() { 2661 return UNSTABLE_REVALIDATE_RENAME_ERROR; 2662 }, 2663 WEBPACK_LAYERS: function() { 2664 return WEBPACK_LAYERS; 2665 }, 2666 WEBPACK_RESOURCE_QUERIES: function() { 2667 return WEBPACK_RESOURCE_QUERIES; 2668 }, 2669 WEB_SOCKET_MAX_RECONNECTIONS: function() { 2670 return WEB_SOCKET_MAX_RECONNECTIONS; 2671 } 2672}); 2673const TEXT_PLAIN_CONTENT_TYPE_HEADER = 'text/plain'; 2674const HTML_CONTENT_TYPE_HEADER = 'text/html; charset=utf-8'; 2675const JSON_CONTENT_TYPE_HEADER = 'application/json; charset=utf-8'; 2676const NEXT_QUERY_PARAM_PREFIX = 'nxtP'; 2677const NEXT_INTERCEPTION_MARKER_PREFIX = 'nxtI'; 2678const MATCHED_PATH_HEADER = 'x-matched-path'; 2679const PRERENDER_REVALIDATE_HEADER = 'x-prerender-revalidate'; 2680const PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER = 'x-prerender-revalidate-if-generated'; 2681const RSC_SEGMENTS_DIR_SUFFIX = '.segments'; 2682const RSC_SEGMENT_SUFFIX = '.segment.rsc'; 2683const RSC_SUFFIX = '.rsc'; 2684const ACTION_SUFFIX = '.action'; 2685const NEXT_DATA_SUFFIX = '.json'; 2686const NEXT_META_SUFFIX = '.meta'; 2687const NEXT_BODY_SUFFIX = '.body'; 2688const NEXT_NAV_DEPLOYMENT_ID_HEADER = 'x-nextjs-deployment-id'; 2689const NEXT_CACHE_TAGS_HEADER = 'x-next-cache-tags'; 2690const NEXT_CACHE_REVALIDATED_TAGS_HEADER = 'x-next-revalidated-tags'; 2691const NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER = 'x-next-revalidate-tag-token'; 2692const NEXT_RESUME_HEADER = 'next-resume'; 2693const NEXT_RESUME_STATE_LENGTH_HEADER = 'x-next-resume-state-length'; 2694const NEXT_CACHE_TAG_MAX_ITEMS = 128; 2695const NEXT_CACHE_TAG_MAX_LENGTH = 256; 2696const NEXT_CACHE_SOFT_TAG_MAX_LENGTH = 1024; 2697const NEXT_CACHE_IMPLICIT_TAG_ID = '_N_T_'; 2698const NEXT_CACHE_ROOT_PARAM_TAG_ID = '_N_RP_'; 2699const CACHE_ONE_YEAR_SECONDS = 31536000; 2700const INFINITE_CACHE = 0xfffffffe; 2701const MIDDLEWARE_FILENAME = 'middleware'; 2702const MIDDLEWARE_LOCATION_REGEXP = "(?:src/)?".concat(MIDDLEWARE_FILENAME); 2703const PROXY_FILENAME = 'proxy'; 2704const PROXY_LOCATION_REGEXP = "(?:src/)?".concat(PROXY_FILENAME); 2705const INSTRUMENTATION_HOOK_FILENAME = 'instrumentation'; 2706const PAGES_DIR_ALIAS = 'private-next-pages'; 2707const DOT_NEXT_ALIAS = 'private-dot-next'; 2708const ROOT_DIR_ALIAS = 'private-next-root-dir'; 2709const APP_DIR_ALIAS = 'private-next-app-dir'; 2710const RSC_MOD_REF_PROXY_ALIAS = 'private-next-rsc-mod-ref-proxy'; 2711const RSC_ACTION_VALIDATE_ALIAS = 'private-next-rsc-action-validate'; 2712const RSC_ACTION_PROXY_ALIAS = 'private-next-rsc-server-reference'; 2713const RSC_CACHE_WRAPPER_ALIAS = 'private-next-rsc-cache-wrapper'; 2714const RSC_DYNAMIC_IMPORT_WRAPPER_ALIAS = 'private-next-rsc-track-dynamic-import'; 2715const RSC_ACTION_ENCRYPTION_ALIAS = 'private-next-rsc-action-encryption'; 2716const RSC_ACTION_CLIENT_WRAPPER_ALIAS = 'private-next-rsc-action-client-wrapper'; 2717const PUBLIC_DIR_MIDDLEWARE_CONFLICT = "You can not have a '_next' folder inside of your public folder. This conflicts with the internal '/_next' route. https://nextjs.org/docs/messages/public-next-folder-conflict"; 2718const SSG_GET_INITIAL_PROPS_CONFLICT = "You can not use getInitialProps with getStaticProps. To use SSG, please remove your getInitialProps"; 2719const SERVER_PROPS_GET_INIT_PROPS_CONFLICT = "You can not use getInitialProps with getServerSideProps. Please remove getInitialProps."; 2720const SERVER_PROPS_SSG_CONFLICT = "You can not use getStaticProps or getStaticPaths with getServerSideProps. To use SSG, please remove getServerSideProps"; 2721const STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR = "can not have getInitialProps/getServerSideProps, https://nextjs.org/docs/messages/404-get-initial-props"; 2722const SERVER_PROPS_EXPORT_ERROR = "pages with `getServerSideProps` can not be exported. See more info here: https://nextjs.org/docs/messages/gssp-export"; 2723const GSP_NO_RETURNED_VALUE = 'Your `getStaticProps` function did not return an object. Did you forget to add a `return`?'; 2724const GSSP_NO_RETURNED_VALUE = 'Your `getServerSideProps` function did not return an object. Did you forget to add a `return`?'; 2725const UNSTABLE_REVALIDATE_RENAME_ERROR = 'The `unstable_revalidate` property is available for general use.\n' + 'Please use `revalidate` instead.'; 2726const GSSP_COMPONENT_MEMBER_ERROR = "can not be attached to a page's component and must be exported from the page. See more info here: https://nextjs.org/docs/messages/gssp-component-member"; 2727const NON_STANDARD_NODE_ENV = 'You are using a non-standard "NODE_ENV" value in y
2727our environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env'; 2728const SSG_FALLBACK_EXPORT_ERROR = "Pages with `fallback` enabled in `getStaticPaths` can not be exported. See more info here: https://nextjs.org/docs/messages/ssg-fallback-true-export"; 2729const ESLINT_DEFAULT_DIRS = [ 2730 'app', 2731 'pages', 2732 'components', 2733 'lib', 2734 'src' 2735]; 2736const SERVER_RUNTIME = { 2737 edge: 'edge', 2738 experimentalEdge: 'experimental-edge', 2739 nodejs: 'nodejs' 2740}; 2741const WEB_SOCKET_MAX_RECONNECTIONS = 12; 2742/** 2743 * The names of the webpack layers. These layers are the primitives for the 2744 * webpack chunks. 2745 */ const WEBPACK_LAYERS_NAMES = { 2746 /** 2747 * The layer for the shared code between the client and server bundles. 2748 */ shared: 'shared', 2749 /** 2750 * The layer for server-only runtime and picking up `react-server` export conditions. 2751 * Including app router RSC pages and app router custom routes and metadata routes. 2752 */ reactServerComponents: 'rsc', 2753 /** 2754 * Server Side Rendering layer for app (ssr). 2755 */ serverSideRendering: 'ssr', 2756 /** 2757 * The browser client bundle layer for actions. 2758 */ actionBrowser: 'action-browser', 2759 /** 2760 * The Node.js bundle layer for the API routes. 2761 */ apiNode: 'api-node', 2762 /** 2763 * The Edge Lite bundle layer for the API routes. 2764 */ apiEdge: 'api-edge', 2765 /** 2766 * The layer for the middleware code. 2767 */ middleware: 'middleware', 2768 /** 2769 * The layer for the instrumentation hooks. 2770 */ instrument: 'instrument', 2771 /** 2772 * The layer for assets on the edge. 2773 */ edgeAsset: 'edge-asset', 2774 /** 2775 * The browser client bundle layer for App directory. 2776 */ appPagesBrowser: 'app-pages-browser', 2777 /** 2778 * The browser client bundle layer for Pages directory. 2779 */ pagesDirBrowser: 'pages-dir-browser', 2780 /** 2781 * The Edge Lite bundle layer for Pages directory. 2782 */ pagesDirEdge: 'pages-dir-edge', 2783 /** 2784 * The Node.js bundle layer for Pages directory. 2785 */ pagesDirNode: 'pages-dir-node' 2786}; 2787const WEBPACK_LAYERS = {
2788 ...WEBPACK_LAYERS_NAMES, 2789 GROUP: { 2790 builtinReact: [ 2791 WEBPACK_LAYERS_NAMES.reactServerComponents, 2792 WEBPACK_LAYERS_NAMES.actionBrowser 2793 ], 2794 serverOnly: [ 2795 WEBPACK_LAYERS_NAMES.reactServerComponents, 2796 WEBPACK_LAYERS_NAMES.actionBrowser, 2797 WEBPACK_LAYERS_NAMES.instrument, 2798 WEBPACK_LAYERS_NAMES.middleware 2799 ], 2800 neutralTarget: [ 2801 // pages api 2802 WEBPACK_LAYERS_NAMES.apiNode, 2803 WEBPACK_LAYERS_NAMES.apiEdge 2804 ], 2805 clientOnly: [ 2806 WEBPACK_LAYERS_NAMES.serverSideRendering, 2807 WEBPACK_LAYERS_NAMES.appPagesBrowser 2808 ], 2809 bundled: [ 2810 WEBPACK_LAYERS_NAMES.reactServerComponents, 2811 WEBPACK_LAYERS_NAMES.actionBrowser, 2812 WEBPACK_LAYERS_NAMES.serverSideRendering, 2813 WEBPACK_LAYERS_NAMES.appPagesBrowser, 2814 WEBPACK_LAYERS_NAMES.shared, 2815 WEBPACK_LAYERS_NAMES.instrument, 2816 WEBPACK_LAYERS_NAMES.middleware 2817 ], 2818 appPages: [ 2819 // app router pages and layouts 2820 WEBPACK_LAYERS_NAMES.reactServerComponents, 2821 WEBPACK_LAYERS_NAMES.serverSideRendering, 2822 WEBPACK_LAYERS_NAMES.appPagesBrowser, 2823 WEBPACK_LAYERS_NAMES.actionBrowser 2824 ] 2825 } 2826}; 2827const WEBPACK_RESOURCE_QUERIES = { 2828 edgeSSREntry: '__next_edge_ssr_entry__', 2829 metadata: '__next_metadata__', 2830 metadataRoute: '__next_metadata_route__', 2831 metadataImageMeta: '__next_metadata_image_meta__' 2832}; 2833}), 2834606372, ((__turbopack_context__, module, exports) => { 2835"use strict"; 2836 2837/** 2838 * Vary Params Decoding 2839 * 2840 * This module is shared between server and client. 2841 */ Object.defineProperty(exports, "__esModule", { 2842 value: true 2843}); 2844Object.defineProperty(exports, "readVaryParams", { 2845 enumerable: true, 2846 get: function() { 2847 return readVaryParams; 2848 } 2849}); 2850function readVaryParams(thenable) { 2851 // Attach a no-op listener to force Flight to synchronously resolve the 2852 // thenable. When a thenable arrives from the Flight stream, it may be in an 2853 // intermediate 'resolved_model' state (data received but not unwrapped). 2854 // Calling .then() triggers Flight to transition it to 'fulfilled', making 2855 // the value available synchronously. React uses this same optimization 2856 // internally to avoid unnecessary microtasks. 2857 thenable.then(noop); 2858 // If the thenable is still not 'fulfilled' after calling .then(), the server 2859 // failed to resolve it before the stream ended. Treat as unknown. 2860 if (thenable.status !== 'fulfilled') { 2861 return null; 2862 } 2863 return thenable.value; 2864} 2865const noop = ()=>{}; 2866}), 2867522744, ((__turbopack_context__, module, exports) => { 2868"use strict"; 2869 2870/** 2871 * App Router types - Client-safe types for the Next.js App Router 2872 * 2873 * This file contains type definitions that can be safely imported 2874 * by both client-side and server-side code without circular dependencies. 2875 */ Object.defineProperty(exports, "__esModule", { 2876 value: true 2877}); 2878Object.defineProperty(exports, "PrefetchHint", { 2879 enumerable: true, 2880 get: function() { 2881 return PrefetchHint; 2882 } 2883}); 2884var PrefetchHint = /*#__PURE__*/ function(PrefetchHint) { 2885 // This segment has a runtime prefetch enabled (via unstable_instant with 2886 // prefetch: 'runtime'). Per-segment only, does not propagate to ancestors. 2887 PrefetchHint[PrefetchHint["HasRuntimePrefetch"] = 1] = "HasRuntimePrefetch"; 2888 // This segment or one of its descendants has an instant config defined 2889 // (any truthy unstable_instant, regardless of prefetch mode). Propagates 2890 // upward so the root segment reflects the entire subtree. 2891 PrefetchHint[PrefetchHint["SubtreeHasInstant"] = 2] = "SubtreeHasInstant"; 2892 // This segment itself has a loading.tsx boundary. 2893 PrefetchHint[PrefetchHint["SegmentHasLoadingBoundary"] = 4] = "SegmentHasLoadingBoundary"; 2894 // A descendant segment (but not this one) has a loading.tsx boundary. 2895 // Propagates upward so the root reflects the entire subtree. 2896 PrefetchHint[PrefetchHint["SubtreeHasLoadingBoundary"] = 8] = "SubtreeHasLoadingBoundary"; 2897 // This segment is the root layout of the application. 2898 PrefetchHint[PrefetchHint["IsRootLayout"] = 16] = "IsRootLayout"; 2899 // This segment's response includes its parent's data inlined into it. 2900 // Set at build time by the segment size measurement pass. 2901 PrefetchHint[PrefetchHint["ParentInlinedIntoSelf"] = 32] = "ParentInlinedIntoSelf"; 2902 // This segment's data is inlined into one of its children — don't fetch 2903 // it separately. Set at build time by the segment size measurement pass. 2904 PrefetchHint[PrefetchHint["InlinedIntoChild"] = 64] = "InlinedIntoChild"; 2905 // On a __PAGE__: this page's response includes the head (metadata/viewport) 2906 // at the end of its SegmentPrefetch[] array.
2907 PrefetchHint[PrefetchHint["HeadInlinedIntoSelf"] = 128] = "HeadInlinedIntoSelf"; 2908 // On the root hint node: the head was NOT inlined into any page — fetch 2909 // it separately. Absence of this bit means the head is bundled into a page. 2910 PrefetchHint[PrefetchHint["HeadOutlined"] = 256] = "HeadOutlined"; 2911 return PrefetchHint; 2912}({}); 2913}), 2914756019, ((__turbopack_context__, module, exports) => { 2915"use strict"; 2916 2917Object.defineProperty(exports, "__esModule", { 2918 value: true 2919}); 2920Object.defineProperty(exports, "matchSegment", { 2921 enumerable: true, 2922 get: function() { 2923 return matchSegment; 2924 } 2925}); 2926const matchSegment = (existingSegment, segment)=>{ 2927 // segment is either Array or string 2928 if (typeof existingSegment === 'string') { 2929 if (typeof segment === 'string') { 2930 // Common case: segment is just a string 2931 return existingSegment === segment; 2932 } 2933 return false; 2934 } 2935 if (typeof segment === 'string') { 2936 return false; 2937 } 2938 return existingSegment[0] === segment[0] && existingSegment[1] === segment[1]; 2939}; 2940if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 2941 Object.defineProperty(exports.default, '__esModule', { 2942 value: true 2943 }); 2944 Object.assign(exports.default, exports); 2945 module.exports = exports.default; 2946} 2947}), 2948477048, ((__turbopack_context__, module, exports) => { 2949"use strict"; 2950 2951// TypeScript trick to simulate opaque types, like in Flow. 2952Object.defineProperty(exports, "__esModule", { 2953 value: true 2954}); 2955Object.defineProperty(exports, "createCacheKey", { 2956 enumerable: true, 2957 get: function() { 2958 return createCacheKey; 2959 } 2960}); 2961function createCacheKey(originalHref, nextUrl) { 2962 const originalUrl = new URL(originalHref); 2963 const cacheKey = { 2964 pathname: originalUrl.pathname, 2965 search: originalUrl.search, 2966 nextUrl: nextUrl 2967 }; 2968 return cacheKey; 2969} 2970if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 2971 Object.defineProperty(exports.default, '__esModule', { 2972 value: true 2973 }); 2974 Object.assign(exports.default, exports); 2975 module.exports = exports.default; 2976} 2977}), 2978509396, ((__turbopack_context__, module, exports) => { 2979"use strict"; 2980 2981/** 2982 * Shared types and constants for the Segment Cache. 2983 */ Object.defineProperty(exports, "__esModule", { 2984 value: true 2985}); 29860 && (module.exports = { 2987 FetchStrategy: null, 2988 NavigationResultTag: null, 2989 PrefetchPriority: null 2990}); 2991function _export(target, all) { 2992 for(var name in all)Object.defineProperty(target, name, { 2993 enumerable: true, 2994 get: all[name] 2995 }); 2996} 2997_export(exports, { 2998 FetchStrategy: function() { 2999 return FetchStrategy; 3000 }, 3001 NavigationResultTag: function() { 3002 return NavigationResultTag; 3003 }, 3004 PrefetchPriority: function() { 3005 return PrefetchPriority; 3006 } 3007}); 3008var NavigationResultTag = /*#__PURE__*/ function(NavigationResultTag) { 3009 NavigationResultTag[NavigationResultTag["MPA"] = 0] = "MPA"; 3010 NavigationResultTag[NavigationResultTag["Success"] = 1] = "Success"; 3011 NavigationResultTag[NavigationResultTag["NoOp"] = 2] = "NoOp"; 3012 NavigationResultTag[NavigationResultTag["Async"] = 3] = "Async"; 3013 return NavigationResultTag; 3014}({}); 3015var PrefetchPriority = /*#__PURE__*/ function(PrefetchPriority) { 3016 /** 3017 * Assigned to the most recently hovered/touched link. Special network 3018 * bandwidth is reserved for this task only. There's only ever one Intent- 3019 * priority task at a time; when a new Intent task is scheduled, the previous 3020 * one is bumped down to Default. 3021 */ PrefetchPriority[PrefetchPriority["Intent"] = 2] = "Intent"; 3022 /** 3023 * The default priority for prefetch tasks. 3024 */ PrefetchPriority[PrefetchPriority["Default"] = 1] = "Default"; 3025 /** 3026 * Assigned to tasks when they spawn non-blocking background work, like 3027 * revalidating a partially cached entry to see if more data is available.
3028 */ PrefetchPriority[PrefetchPriority["Background"] = 0] = "Background"; 3029 return PrefetchPriority; 3030}({}); 3031var FetchStrategy = /*#__PURE__*/ function(FetchStrategy) { 3032 // Deliberately ordered so we can easily compare two segments 3033 // and determine if one segment is "more specific" than another 3034 // (i.e. if it's likely that it contains more data) 3035 FetchStrategy[FetchStrategy["LoadingBoundary"] = 0] = "LoadingBoundary"; 3036 FetchStrategy[FetchStrategy["PPR"] = 1] = "PPR"; 3037 FetchStrategy[FetchStrategy["PPRRuntime"] = 2] = "PPRRuntime"; 3038 FetchStrategy[FetchStrategy["Full"] = 3] = "Full"; 3039 return FetchStrategy; 3040}({}); 3041if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 3042 Object.defineProperty(exports.default, '__esModule', { 3043 value: true 3044 }); 3045 Object.assign(exports.default, exports); 3046 module.exports = exports.default; 3047} 3048}), 3049511, ((__turbopack_context__, module, exports) => { 3050"use strict"; 3051 3052Object.defineProperty(exports, "__esModule", { 3053 value: true 3054}); 30550 && (module.exports = { 3056 Fallback: null, 3057 createCacheMap: null, 3058 deleteFromCacheMap: null, 3059 deleteMapEntry: null, 3060 getFromCacheMap: null, 3061 isValueExpired: null, 3062 setInCacheMap: null, 3063 setSizeInCacheMap: null 3064}); 3065function _export(target, all) { 3066 for(var name in all)Object.defineProperty(target, name, { 3067 enumerable: true, 3068 get: all[name] 3069 }); 3070} 3071_export(exports, { 3072 Fallback: function() { 3073 return Fallback; 3074 }, 3075 createCacheMap: function() { 3076 return createCacheMap; 3077 }, 3078 deleteFromCacheMap: function() { 3079 return deleteFromCacheMap; 3080 }, 3081 deleteMapEntry: function() { 3082 return deleteMapEntry; 3083 }, 3084 getFromCacheMap: function() { 3085 return getFromCacheMap; 3086 }, 3087 isValueExpired: function() { 3088 return isValueExpired; 3089 }, 3090 setInCacheMap: function() { 3091 return setInCacheMap; 3092 }, 3093 setSizeInCacheMap: function() { 3094 return setSizeInCacheMap; 3095 } 3096}); 3097const _lru = __turbopack_context__.r(373861); 3098const Fallback = {}; 3099// This is a special internal key that is used for "revalidation" entries. It's 3100// an implementation detail that shouldn't leak outside of this module. 3101const Revalidation = {}; 3102function createCacheMap() { 3103 const cacheMap = { 3104 parent: null, 3105 key: null, 3106 value: null, 3107 map: null, 3108 // LRU-related fields 3109 prev: null, 3110 next: null, 3111 size: 0 3112 }; 3113 return cacheMap; 3114} 3115function getOrInitialize(cacheMap, keys, isRevalidation) { 3116 // Go through each level of keys until we find the entry that matches, or 3117 // create a new entry if one doesn't exist. 3118 // 3119 // This function will only return entries that match the keypath _exactly_. 3120 // Unlike getWithFallback, it will not access fallback entries unless it's 3121 // explicitly part of the keypath. 3122 let entry = cacheMap; 3123 let remainingKeys = keys; 3124 let key = null; 3125 while(true){ 3126 const previousKey = key; 3127 if (remainingKeys !== null) { 3128 key = remainingKeys.value; 3129 remainingKeys = remainingKeys.parent; 3130 } else if (isRevalidation && previousKey !== Revalidation) { 3131 // During a revalidation, we append an internal "Revalidation" key to 3132 // the end of the keypath. The "normal" entry is its parent. 3133 // However, if the parent entry is currently empty, we don't need to store 3134 // this as a revalidation entry. Just insert the revalidation into the 3135 // normal slot. 3136 if (entry.value === null) { 3137 return entry; 3138 } 3139 // Otheriwse, create a child entry. 3140 key = Revalidation; 3141 } else { 3142 break; 3143 } 3144 let map = entry.map; 3145 if (map !== null) { 3146 const existingEntry = map.get(key); 3147 if (existingEntry !== undefined) { 3148 // Found a match. Keep going. 3149 entry = existingEntry; 3150 continue; 3151 } 3152 } else { 3153 map = new Map(); 3154 entry.map = map; 3155 }
3156 // No entry exists yet at this level. Create a new one. 3157 const newEntry = { 3158 parent: entry, 3159 key, 3160 value: null, 3161 map: null, 3162 // LRU-related fields 3163 prev: null, 3164 next: null, 3165 size: 0 3166 }; 3167 map.set(key, newEntry); 3168 entry = newEntry; 3169 } 3170 return entry; 3171} 3172function getFromCacheMap(now, currentCacheVersion, rootEntry, keys, isRevalidation) { 3173 const entry = getEntryWithFallbackImpl(now, currentCacheVersion, rootEntry, keys, isRevalidation, 0); 3174 if (entry === null || entry.value === null) { 3175 return null; 3176 } 3177 // This is an LRU access. Move the entry to the front of the list. 3178 (0, _lru.lruPut)(entry); 3179 return entry.value; 3180} 3181function isValueExpired(now, currentCacheVersion, value) { 3182 return value.staleAt <= now || value.version < currentCacheVersion; 3183} 3184function lazilyEvictIfNeeded(now, currentCacheVersion, entry) { 3185 // We have a matching entry, but before we can return it, we need to check if 3186 // it's still fresh. Otherwise it should be treated the same as a cache miss. 3187 if (entry.value === null) { 3188 // This entry has no value, so there's nothing to evict. 3189 return entry; 3190 } 3191 const value = entry.value; 3192 if (isValueExpired(now, currentCacheVersion, value)) { 3193 // The value expired. Lazily evict it from the cache, and return null. This 3194 // is conceptually the same as a cache miss. 3195 deleteMapEntry(entry); 3196 return null; 3197 } 3198 // The matched entry has not expired. Return it. 3199 return entry; 3200} 3201function getEntryWithFallbackImpl(now, currentCacheVersion, entry, keys, isRevalidation, previousKey) { 3202 // This is similar to getExactEntry, but if an exact match is not found for 3203 // a key, it will return the fallback entry instead. This is recursive at 3204 // every level, e.g. an entry with keypath [a, Fallback, c, Fallback] is 3205 // valid match for [a, b, c, d]. 3206 // 3207 // It will return the most specific match available. 3208 let key; 3209 let remainingKeys; 3210 if (keys !== null) { 3211 key = keys.value; 3212 remainingKeys = keys.parent; 3213 } else if (isRevalidation && previousKey !== Revalidation) { 3214 // During a revalidation, we append an internal "Revalidation" key to 3215 // the end of the keypath. 3216 key = Revalidation; 3217 remainingKeys = null; 3218 } else { 3219 // There are no more keys. This is the terminal entry. 3220 // TODO: When performing a lookup during a navigation, as opposed to a 3221 // prefetch, we may want to skip entries that are Pending if there's also 3222 // a Fulfilled fallback entry. Tricky to say, though, since if it's 3223 // already pending, it's likely to stream in soon. Maybe we could do this 3224 // just on slow connections and offline mode. 3225 return lazilyEvictIfNeeded(now, currentCacheVersion, entry); 3226 } 3227 const map = entry.map; 3228 if (map !== null) { 3229 const existingEntry = map.get(key); 3230 if (existingEntry !== undefined) { 3231 // Found an exact match for this key. Keep searching. 3232 const result = getEntryWithFallbackImpl(now, currentCacheVersion, existingEntry, remainingKeys, isRevalidation, key); 3233 if (result !== null) { 3234 return result; 3235 } 3236 } 3237 // No match found for this key. Check if there's a fallback. 3238 const fallbackEntry = map.get(Fallback); 3239 if (fallbackEntry !== undefined) { 3240 // Found a fallback for this key. Keep searching. 3241 return getEntryWithFallbackImpl(now, currentCacheVersion, fallbackEntry, remainingKeys, isRevalidation, key); 3242 } 3243 } 3244 return null; 3245} 3246function setInCacheMap(cacheMap, keys, value, isRevalidation) { 3247 // Add a value to the map at the given keypath. If the value is already 3248 // part of the map, it's removed from its previous keypath. (NOTE: This is 3249 // unlike a regular JS map, but the behavior is intentional.) 3250 const entry = getOrInitialize(cacheMap, keys, isRevalidation); 3251 setMapEntryValue(entry, value); 3252 // This is an LRU access. Move the entry to the front of the list. 3253 (0, _lru.lruPut)(entry); 3254 (0, _lru.updateLruSize)(entry, value.size); 3255} 3256function setMapEntryValue(entry, value) { 3257 if (entry.value !== null) { 3258 // There's already a value at the given keypath. Disconnect the old value 3259 // from the map. We're not calling `deleteMapEntry` here because the 3260 // entry itself is still in the map. We just want to overwrite its value. 3261 dropRef(entry.value); 3262 entry.value = null; 3263 } 3264 // This value may already be in the map at a different keypath. 3265 // Grab a reference before we overwrite it. 3266 const oldEntry = value.ref; 3267 entry.value = value; 3268 value.ref = entry; 3269 (0, _lru.updateLruSize)(entry, value.size); 3270 if (oldEntry !== null && oldEntry !== entry && oldEntry.value === value) { 3271 // This value is already in the map at a different keypath in the map. 3272 // Values only exist at a single keypath at a time. Remove it from the 3273 // previous keypath. 3274 // 3275 // Note that only the internal map entry is garbage collected; we don't 3276 // call `dropRef` here because it's still in the map, just 3277 // at a new keypath (the one we just set, above). 3278 deleteMapEntry(oldEntry); 3279 } 3280} 3281function deleteFromCacheMap(value) { 3282 const entry = value.ref; 3283 if (entry === null) { 3284 // This value is not a member of any map. 3285 return; 3286 } 3287 dropRef(value); 3288 deleteMapEntry(entry); 3289} 3290function dropRef(value) { 3291 // Drop the value from the map by setting its `ref` backpointer to 3292 // null. This is a separate operation from `deleteMapEntry` because when 3293 // re-keying a value we need to be able to delete the old, internal map 3294 // entry without garbage collecting the value itself. 3295 value.ref = null; 3296} 3297function deleteMapEntry(entry) { 3298 // Delete the entry from the cache. 3299 entry.value = null; 3300 (0, _lru.deleteFromLru)(entry); 3301 // Check if we can garbage collect the entry. 3302 const map = entry.map; 3303 if (map === null) { 3304 // Since this entry has no value, and also no child entries, we can 3305 // garbage collect it. Remove it from its parent, and keep garbage 3306 // collecting the parents until we reach a non-empty entry. 3307 let parent = entry.parent; 3308 let key = entry.key; 3309 while(parent !== null){ 3310 const parentMap = parent.map; 3311 if (parentMap !== null) { 3312 parentMap.delete(key); 3313 if (parentMap.size === 0) { 3314 // We just removed the last entry in the parent map. 3315 parent.map = null; 3316 if (parent.value === null) { 3317 // The parent node has no child entries, nor does it have a value 3318 // on itself. It can be garbage collected. Keep going. 3319 key = parent.key; 3320 parent = parent.parent; 3321 continue; 3322 } 3323 } 3324 } 3325 break; 3326 } 3327 } else { 3328 // Check if there's a revalidating entry. If so, promote it to a 3329 // "normal" entry, since the normal one was just deleted. 3330 const revalidatingEntry = map.get(Revalidation); 3331 if (revalidatingEntry !== undefined && revalidatingEntry.value !== null) { 3332 setMapEntryValue(entry, revalidatingEntry.value); 3333 } 3334 } 3335} 3336function setSizeInCacheMap(value, size) { 3337 const entry = value.ref; 3338 if (entry === null) { 3339 // This value is not a member of any map. 3340 return; 3341 } 3342 // Except during initialization (when the size is set to 0), this is the only 3343 // place the `size` field should be updated, to ensure it's in sync with the 3344 // the LRU. 3345 value.size = size; 3346 (0, _lru.updateLruSize)(entry, size); 3347} 3348if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 3349 Object.defineProperty(exports.default, '__esModule', { 3350 value: true 3351 });
3352 Object.assign(exports.default, exports); 3353 module.exports = exports.default; 3354} 3355}), 3356373861, ((__turbopack_context__, module, exports) => { 3357"use strict"; 3358 3359Object.defineProperty(exports, "__esModule", { 3360 value: true 3361}); 33620 && (module.exports = { 3363 cleanup: null, 3364 deleteFromLru: null, 3365 lruPut: null, 3366 updateLruSize: null 3367}); 3368function _export(target, all) { 3369 for(var name in all)Object.defineProperty(target, name, { 3370 enumerable: true, 3371 get: all[name] 3372 }); 3373} 3374_export(exports, { 3375 cleanup: function() { 3376 return cleanup; 3377 }, 3378 deleteFromLru: function() { 3379 return deleteFromLru; 3380 }, 3381 lruPut: function() { 3382 return lruPut; 3383 }, 3384 updateLruSize: function() { 3385 return updateLruSize; 3386 } 3387}); 3388const _cachemap = __turbopack_context__.r(511); 3389const _scheduler = __turbopack_context__.r(777709); 3390// We use an LRU for memory management. We must update this whenever we add or 3391// remove a new cache entry, or when an entry changes size. 3392let head = null; 3393let lruSize = 0; 3394// TODO: I chose the max size somewhat arbitrarily. Consider setting this based 3395// on navigator.deviceMemory, or some other heuristic. We should make this 3396// customizable via the Next.js config, too. 3397const maxLruSize = 50 * 1024 * 1024 // 50 MB 3398; 3399function lruPut(node) { 3400 if (head === node) { 3401 // Already at the head 3402 return; 3403 } 3404 const prev = node.prev; 3405 const next = node.next; 3406 if (next === null || prev === null) { 3407 // This is an insertion 3408 lruSize += node.size; 3409 // Whenever we add an entry, we need to check if we've exceeded the 3410 // max size. We don't evict entries immediately; they're evicted later in 3411 // an asynchronous task. 3412 ensureCleanupIsScheduled(); 3413 } else { 3414 // This is a move. Remove from its current position. 3415 prev.next = next; 3416 next.prev = prev; 3417 } 3418 // Move to the front of the list 3419 if (head === null) { 3420 // This is the first entry 3421 node.prev = node; 3422 node.next = node; 3423 } else { 3424 // Add to the front of the list 3425 const tail = head.prev; 3426 node.prev = tail; 3427 // In practice, this is never null, but that isn't encoded in the type 3428 if (tail !== null) { 3429 tail.next = node; 3430 } 3431 node.next = head; 3432 head.prev = node; 3433 } 3434 head = node; 3435} 3436function updateLruSize(node, newNodeSize) { 3437 // This is a separate function from `put` so that we can resize the entry 3438 // regardless of whether it's currently being tracked by the LRU. 3439 const prevNodeSize = node.size; 3440 node.size = newNodeSize; 3441 if (node.next === null) { 3442 // This entry is not currently being tracked by the LRU. 3443 return; 3444 } 3445 // Update the total LRU size 3446 lruSize = lruSize - prevNodeSize + newNodeSize; 3447 ensureCleanupIsScheduled(); 3448} 3449function deleteFromLru(deleted) { 3450 const next = deleted.next; 3451 const prev = deleted.prev; 3452 if (next !== null && prev !== null) { 3453 lruSize -= deleted.size; 3454 deleted.next = null; 3455 deleted.prev = null; 3456 // Remove from the list 3457 if (head === deleted) { 3458 // Update the head 3459 if (next === head) { 3460 // This was the last entry 3461 head = null; 3462 } else { 3463 head = next; 3464 prev.next = next; 3465 next.prev = prev; 3466 } 3467 } else { 3468 prev.next = next; 3469 next.prev = prev; 3470 } 3471 } else { 3472 // Already deleted 3473 } 3474} 3475function ensureCleanupIsScheduled() { 3476 if (lruSize <= maxLruSize) { 3477 return; 3478 } 3479 // To schedule cleanup, ping the prefetch scheduler. At the end of its work 3480 // loop, once there are no queued tasks and no in-progress requests, it will 3481 // call cleanup(). 3482 (0, _scheduler.pingPrefetchScheduler)(); 3483} 3484function cleanup() { 3485 if (lruSize <= maxLruSize) { 3486 return; 3487 } 3488 // Evict entries until we're at 90% capacity. We can assume this won't 3489 // infinite loop because even if `maxLruSize` were 0, eventually 3490 // `deleteFromLru` sets `head` to `null` when we run out entries. 3491 const ninetyPercentMax = maxLruSize * 0.9; 3492 while(lruSize > ninetyPercentMax && head !== null){ 3493 const tail = head.prev; 3494 // In practice, this is never null, but that isn't encoded in the type 3495 if (tail !== null) { 3496 // Delete the entry from the map. In turn, this will remove it from 3497 // the LRU. 3498 (0, _cachemap.deleteMapEntry)(tail); 3499 } 3500 } 3501} 3502if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 3503 Object.defineProperty(exports.default, '__esModule', { 3504 value: true 3505 });
3506 Object.assign(exports.default, exports); 3507 module.exports = exports.default; 3508} 3509}), 3510777709, ((__turbopack_context__, module, exports) => { 3511"use strict"; 3512 3513var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 3514"use strict"; 3515Object.defineProperty(exports, "__esModule", { 3516 value: true 3517}); 35180 && (module.exports = { 3519 cancelPrefetchTask: null, 3520 isPrefetchTaskDirty: null, 3521 pingPrefetchScheduler: null, 3522 pingPrefetchTask: null, 3523 reschedulePrefetchTask: null, 3524 schedulePrefetchTask: null, 3525 startRevalidationCooldown: null 3526}); 3527function _export(target, all) { 3528 for(var name in all)Object.defineProperty(target, name, { 3529 enumerable: true, 3530 get: all[name] 3531 }); 3532} 3533_export(exports, { 3534 cancelPrefetchTask: function() { 3535 return cancelPrefetchTask; 3536 }, 3537 isPrefetchTaskDirty: function() { 3538 return isPrefetchTaskDirty; 3539 }, 3540 pingPrefetchScheduler: function() { 3541 return pingPrefetchScheduler; 3542 }, 3543 pingPrefetchTask: function() { 3544 return pingPrefetchTask; 3545 }, 3546 reschedulePrefetchTask: function() { 3547 return reschedulePrefetchTask; 3548 }, 3549 schedulePrefetchTask: function() { 3550 return schedulePrefetchTask; 3551 }, 3552 startRevalidationCooldown: function() { 3553 return startRevalidationCooldown; 3554 } 3555}); 3556const _approutertypes = __turbopack_context__.r(522744); 3557const _matchsegments = __turbopack_context__.r(756019); 3558const _cache = __turbopack_context__.r(620896); 3559const _cachekey = __turbopack_context__.r(477048); 3560const _types = __turbopack_context__.r(509396); 3561const _segment = __turbopack_context__.r(813258); 3562const _lru = __turbopack_context__.r(373861); 3563const scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : (fn)=>Promise.resolve().then(fn).catch((error)=>setTimeout(()=>{ 3564 throw error; 3565 })); 3566const taskHeap = []; 3567let inProgressRequests = 0; 3568let sortIdCounter = 0; 3569let didScheduleMicrotask = false; 3570// The most recently hovered (or touched, etc) link, i.e. the most recent task 3571// scheduled at Intent priority. There's only ever a single task at Intent 3572// priority at a time. We reserve special network bandwidth for this task only. 3573let mostRecentlyHoveredLink = null; 3574// CDN cache propagation delay after revalidation (in milliseconds) 3575const REVALIDATION_COOLDOWN_MS = 300; 3576// Timeout handle for the revalidation cooldown. When non-null, prefetch 3577// requests are blocked to allow CDN cache propagation. 3578let revalidationCooldownTimeoutHandle = null; 3579function startRevalidationCooldown() { 3580 // Clear any existing timeout in case multiple revalidations happen 3581 // in quick succession. 3582 if (revalidationCooldownTimeoutHandle !== null) { 3583 clearTimeout(revalidationCooldownTimeoutHandle); 3584 } 3585 // Schedule the cooldown to expire after the delay. 3586 revalidationCooldownTimeoutHandle = setTimeout(()=>{ 3587 revalidationCooldownTimeoutHandle = null; 3588 // Retry the prefetch queue now that the cooldown has expired. 3589 pingPrefetchScheduler(); 3590 }, REVALIDATION_COOLDOWN_MS); 3591} 3592function schedulePrefetchTask(key, treeAtTimeOfPrefetch, fetchStrategy, priority, onInvalidate, _onComplete) { 3593 // Spawn a new prefetch task 3594 const task = { 3595 key, 3596 treeAtTimeOfPrefetch, 3597 routeCacheVersion: (0, _cache.getCurrentRouteCacheVersion)(), 3598 segmentCacheVersion: (0, _cache.getCurrentSegmentCacheVersion)(), 3599 priority, 3600 phase: 1, 3601 hasBackgroundWork: false, 3602 spawnedRuntimePrefetches: null, 3603 fetchStrategy, 3604 sortId: sortIdCounter++, 3605 isCanceled: false, 3606 onInvalidate, 3607 _heapIndex: -1 3608 }; 3609 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 3610 ; 3611 trackMostRecentlyHoveredLink(task); 3612 heapPush(taskHeap, task); 3613 // Schedule an async task to process the queue. 3614 // 3615 // The main reason we process the queue in an async task is for batching. 3616 // It's common for a single JS task/event to trigger multiple prefetches. 3617 // By deferring to a microtask, we only process the queue once per JS task. 3618 // If they have different priorities, it also ensures they are processed in 3619 // the optimal order. 3620 pingPrefetchScheduler(); 3621 return task; 3622} 3623function cancelPrefetchTask(task) { 3624 // Remove the prefetch task from the queue. If the task already completed, 3625 // then this is a no-op. 3626 // 3627 // We must also explicitly mark the task as canceled so that a blocked task 3628 // does not get added back to the queue when it's pinged by the network. 3629 task.isCanceled = true; 3630 heapDelete(taskHeap, task); 3631 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 3632 ; 3633} 3634function reschedulePrefetchTask(task, treeAtTimeOfPrefetch, fetchStrategy, priority) { 3635 // Bump the prefetch task to the top of the queue, as if it were a fresh 3636 // task. This is essentially the same as canceling the task and scheduling 3637 // a new one, except it reuses the original object. 3638 // 3639 // The primary use case is to increase the priority of a Link-initated 3640 // prefetch on hover. 3641 // 3642 // Note: _onComplete is not reset here because it's preserved on the same 3643 // task object. When the rescheduled task completes, the original callback 3644 // will still be invoked. 3645 // Un-cancel the task, in case it was previously canceled. 3646 task.isCanceled = false;
3647 task.phase = 1; 3648 // Assign a new sort ID to move it ahead of all other tasks at the same 3649 // priority level. (Higher sort IDs are processed first.) 3650 task.sortId = sortIdCounter++; 3651 task.priority = // Intent priority, even if the rescheduled priority is lower. 3652 task === mostRecentlyHoveredLink ? _types.PrefetchPriority.Intent : priority; 3653 task.treeAtTimeOfPrefetch = treeAtTimeOfPrefetch; 3654 task.fetchStrategy = fetchStrategy; 3655 trackMostRecentlyHoveredLink(task); 3656 if (task._heapIndex !== -1) { 3657 // The task is already in the queue. 3658 heapResift(taskHeap, task); 3659 } else { 3660 heapPush(taskHeap, task); 3661 } 3662 pingPrefetchScheduler(); 3663} 3664function isPrefetchTaskDirty(task, nextUrl, tree) { 3665 // This is used to quickly bail out of a prefetch task if the result is 3666 // guaranteed to not have changed since the task was initiated. This is 3667 // strictly an optimization — theoretically, if it always returned true, no 3668 // behavior should change because a full prefetch task will effectively 3669 // perform the same checks. 3670 return task.routeCacheVersion !== (0, _cache.getCurrentRouteCacheVersion)() || task.segmentCacheVersion !== (0, _cache.getCurrentSegmentCacheVersion)() || task.treeAtTimeOfPrefetch !== tree || task.key.nextUrl !== nextUrl; 3671} 3672function trackMostRecentlyHoveredLink(task) { 3673 // Track the mostly recently hovered link, i.e. the most recently scheduled 3674 // task at Intent priority. There must only be one such task at a time. 3675 if (task.priority === _types.PrefetchPriority.Intent && task !== mostRecentlyHoveredLink) { 3676 if (mostRecentlyHoveredLink !== null) { 3677 // Bump the previously hovered link's priority down to Default. 3678 if (mostRecentlyHoveredLink.priority !== _types.PrefetchPriority.Backgroun
3678d) { 3679 mostRecentlyHoveredLink.priority = _types.PrefetchPriority.Default; 3680 heapResift(taskHeap, mostRecentlyHoveredLink); 3681 } 3682 } 3683 mostRecentlyHoveredLink = task; 3684 } 3685} 3686function pingPrefetchScheduler() { 3687 if (didScheduleMicrotask) { 3688 // Already scheduled a task to process the queue 3689 return; 3690 } 3691 didScheduleMicrotask = true; 3692 scheduleMicrotask(processQueueInMicrotask); 3693} 3694/** 3695 * Checks if we've exceeded the maximum number of concurrent prefetch requests, 3696 * to avoid saturating the browser's internal network queue. This is a 3697 * cooperative limit — prefetch tasks should check this before issuing 3698 * new requests. 3699 * 3700 * Also checks if we're within the revalidation cooldown window, during which 3701 * prefetch requests are delayed to allow CDN cache propagation. 3702 */ function hasNetworkBandwidth(task) { 3703 // Check if we're within the revalidation cooldown window 3704 if (revalidationCooldownTimeoutHandle !== null) { 3705 // We're within the cooldown window. Return false to prevent prefetching. 3706 // When the cooldown expires, the timeout will call ensureWorkIsScheduled() 3707 // to retry the queue. 3708 return false; 3709 } 3710 // TODO: Also check if there's an in-progress navigation. We should never 3711 // add prefetch requests to the network queue if an actual navigation is 3712 // taking place, to ensure there's sufficient bandwidth for render-blocking 3713 // data and resources. 3714 // TODO: Consider reserving some amount of bandwidth for static prefetches. 3715 if (task.priority === _types.PrefetchPriority.Intent) { 3716 // The most recently hovered link is allowed to exceed the default limit. 3717 // 3718 // The goal is to always have enough bandwidth to start a new prefetch 3719 // request when hovering over a link. 3720 // 3721 // However, because we don't abort in-progress requests, it's still possible 3722 // we'll run out of bandwidth. When links are hovered in quick succession, 3723 // there could be multiple hover requests running simultaneously. 3724 return inProgressRequests < 12; 3725 } 3726 // The default limit is lower than the limit for a hovered link. 3727 return inProgressRequests < 4; 3728} 3729function spawnPrefetchSubtask(prefetchSubtask) { 3730 // When the scheduler spawns an async task, we don't await its result. 3731 // Instead, the async task writes its result directly into the cache, then 3732 // pings the scheduler to continue. 3733 // 3734 // We process server responses streamingly, so the prefetch subtask will 3735 // likely resolve before we're finished receiving all the data. The subtask 3736 // result includes a promise that resolves once the network connection is 3737 // closed. The scheduler uses this to control network bandwidth by tracking 3738 // and limiting the number of concurrent requests. 3739 inProgressRequests++; 3740 return prefetchSubtask.then((result)=>{ 3741 if (result === null) { 3742 // The prefetch task errored before it could start processing the 3743 // network stream. Assume the connection is closed. 3744 onPrefetchConnectionClosed(); 3745 return null; 3746 } 3747 // Wait for the connection to close before freeing up more bandwidth. 3748 result.closed.then(onPrefetchConnectionClosed); 3749 return result.value; 3750 }); 3751} 3752function onPrefetchConnectionClosed() { 3753 inProgressRequests--; 3754 // Notify the scheduler that we have more bandwidth, and can continue 3755 // processing tasks. 3756 pingPrefetchScheduler(); 3757} 3758function pingPrefetchTask(task) { 3759 // "Ping" a prefetch that's already in progress to notify it of new data. 3760 if (task.isCanceled || // Check if prefetch is already queued. 3761 task._heapIndex !== -1) { 3762 return; 3763 } 3764 // Add the task back to the queue. 3765 heapPush(taskHeap, task); 3766 pingPrefetchScheduler(); 3767} 3768function processQueueInMicrotask() { 3769 didScheduleMicrotask = false; 3770 // We aim to minimize how often we read the current time. Since nearly all 3771 // functions in the prefetch scheduler are synchronous, we can read the time 3772 // once and pass it as an argument wherever it's needed. 3773 const now = Date.now(); 3774 // Process the task queue until we run out of network bandwidth. 3775 let task = heapPeek(taskHeap); 3776 while(task !== null && hasNetworkBandwidth(task)){ 3777 task.routeCacheVersion = (0, _cache.getCurrentRouteCacheVersion)(); 3778 task.segmentCacheVersion = (0, _cache.getCurrentSegmentCacheVersion)(); 3779 const exitStatus = pingRoute(now, task); 3780 // These fields are only valid for a single attempt. Reset them after each 3781 // iteration of the task queue.
3782 const hasBackgroundWork = task.hasBackgroundWork; 3783 task.hasBackgroundWork = false; 3784 task.spawnedRuntimePrefetches = null; 3785 switch(exitStatus){ 3786 case 0: 3787 // The task yielded because there are too many requests in progress. 3788 // Stop processing tasks until we have more bandwidth. 3789 return; 3790 case 1: 3791 // The task is blocked. It needs more data before it can proceed. 3792 // Keep the task out of the queue until the server responds. 3793 heapPop(taskHeap); 3794 // Continue to the next task 3795 task = heapPeek(taskHeap); 3796 continue; 3797 case 2: 3798 if (task.phase === 1) { 3799 // Finished prefetching the route tree. Proceed to prefetching 3800 // the segments. 3801 task.phase = 0; 3802 heapResift(taskHeap, task); 3803 } else if (hasBackgroundWork) { 3804 // The task spawned additional background work. Reschedule the task 3805 // at background priority. 3806 task.priority = _types.PrefetchPriority.Backgroun
3806d; 3807 heapResift(taskHeap, task); 3808 } else { 3809 // The prefetch is complete. Continue to the next task. 3810 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 3811 ; 3812 heapPop(taskHeap); 3813 } 3814 task = heapPeek(taskHeap); 3815 continue; 3816 default: 3817 exitStatus; 3818 } 3819 } 3820 // Run LRU cleanup only when the scheduler is fully idle: no queued tasks and 3821 // no in-progress requests. At that point, all active prefetch tasks have 3822 // finished reading from the cache (moving recently used entries to the front 3823 // of the list), so only genuinely stale data gets evicted. 3824 if (task === null && inProgressRequests === 0) { 3825 (0, _lru.cleanup)(); 3826 } 3827} 3828/** 3829 * Check this during a prefetch task to determine if background work can be 3830 * performed. If so, it evaluates to `true`. Otherwise, it returns `false`, 3831 * while also scheduling a background task to run later. Usage: 3832 * 3833 * @example 3834 * if (background(task)) { 3835 * // Perform background-pri work 3836 * } 3837 */ function background(task) {
3838 if (task.priority === _types.PrefetchPriority.Background) { 3839 return true; 3840 } 3841 task.hasBackgroundWork = true; 3842 return false; 3843} 3844function pingRoute(now, task) { 3845 const key = task.key; 3846 const route = (0, _cache.readOrCreateRouteCacheEntry)(now, task, key); 3847 const exitStatus = pingRootRouteTree(now, task, route); 3848 if (exitStatus !== 0 && key.search !== '') { 3849 // If the URL has a non-empty search string, also prefetch the pathname 3850 // without the search string. We use the searchless route tree as a base for 3851 // optimistic routing; see requestOptimisticRouteCacheEntry for details. 3852 // 3853 // Note that we don't need to prefetch any of the segment data. Just the 3854 // route tree. 3855 // 3856 // TODO: This is a temporary solution; the plan is to replace this by adding 3857 // a wildcard lookup method to the TupleMap implementation. This is 3858 // non-trivial to implement because it needs to account for things like 3859 // fallback route entries, hence this temporary workaround. 3860 const url = new URL(key.pathname, location.origin); 3861 const keyWithoutSearch = (0, _cachekey.createCacheKey)(url.href, key.nextUrl); 3862 const routeWithoutSearch = (0, _cache.readOrCreateRouteCacheEntry)(now, task, keyWithoutSearch); 3863 switch(routeWithoutSearch.status){ 3864 case _cache.EntryStatus.Empty: 3865 { 3866 if (background(task)) { 3867 routeWithoutSearch.status = _cache.EntryStatus.Pending; 3868 spawnPrefetchSubtask((0, _cache.fetchRouteOnCacheMiss)(routeWithoutSearch, keyWithoutSearch)); 3869 } 3870 break; 3871 } 3872 case _cache.EntryStatus.Pending: 3873 case _cache.EntryStatus.Fulfilled: 3874 case _cache.EntryStatus.Rejected: 3875 { 3876 break; 3877 } 3878 default: 3879 routeWithoutSearch; 3880 } 3881 } 3882 return exitStatus; 3883} 3884function pingRootRouteTree(now, task, route) { 3885 switch(route.status){ 3886 case _cache.EntryStatus.Empty: 3887 { 3888 // Route is not yet cached, and there's no request already in progress. 3889 // Spawn a task to request the route, load it into the cache, and ping 3890 // the task to continue. 3891 // TODO: There are multiple strategies in the <Link> API for prefetching 3892 // a route. Currently we've only implemented the main one: per-segment, 3893 // static-data only. 3894 // 3895 // There's also `<Link prefetch={true}>` 3896 // which prefetch both static *and* dynamic data. 3897 // Similarly, we need to fallback to the old, per-page 3898 // behavior if PPR is disabled for a route (via the incremental opt-in). 3899 // 3900 // Those cases will be handled here. 3901 spawnPrefetchSubtask((0, _cache.fetchRouteOnCacheMiss)(route, task.key)); 3902 // If the request takes longer than a minute, a subsequent request should 3903 // retry instead of waiting for this one. When the response is received, 3904 // this value will be replaced by a new value based on the stale time sent 3905 // from the server. 3906 // TODO: We should probably also manually abort the fetch task, to reclaim 3907 // server bandwidth. 3908 route.staleAt = now + 60 * 1000; 3909 // Upgrade to Pending so we know there's already a request in progress 3910 route.status = _cache.EntryStatus.Pending; 3911 // Intentional fallthrough to the Pending branch 3912 } 3913 case _cache.EntryStatus.Pending: 3914 { 3915 // Still pending. We can't start prefetching the segments until the route 3916 // tree has loaded. Add the task to the set of blocked tasks so that it 3917 // is notified when the route tree is ready. 3918 const blockedTasks = route.blockedTasks; 3919 if (blockedTasks === null) { 3920 route.blockedTasks = new Set([ 3921 task 3922 ]); 3923 } else { 3924 blockedTasks.add(task); 3925 } 3926 return 1; 3927 } 3928 case _cache.EntryStatus.Rejected: 3929 { 3930 // Route tree failed to load. Treat as a 404. 3931 return 2; 3932 } 3933 case _cache.EntryStatus.Fulfilled: 3934 { 3935 if (task.phase !== 0) {
3936 // Do not prefetch segment data until we've entered the segment phase. 3937 return 2; 3938 } 3939 // Recursively fill in the segment tree. 3940 if (!hasNetworkBandwidth(task)) { 3941 // Stop prefetching segments until there's more bandwidth. 3942 return 0; 3943 } 3944 const tree = route.tree; 3945 // A task's fetch strategy gets set to `PPR` for any "auto" prefetch. 3946 // If it turned out that the route isn't PPR-enabled, we need to use `LoadingBoundary` instead. 3947 // We don't need to do this for runtime prefetches, because those are only available in 3948 // `cacheComponents`, where every route is PPR. 3949 let fetchStrategy; 3950 if (tree.prefetchHints & _approutertypes.PrefetchHint.SubtreeHasInstant) { 3951 // If `instant` is defined anywhere on the target route, ignore the 3952 // fetch strategy and switch to unified strategy used by Cache 3953 // Components (called `PPR` for now, will likely be renamed). 3954 // 3955 // In practice, this just means that a "full" prefetch (<Link 3956 // prefetch={true}>) has no effect. You're meant to use Runtime 3957 // Prefetching instead — that's the new pattern that replaces 3958 // prefetch={true}. 3959 // 3960 // The reason we check for `instant` rather than the `cacheComponents` 3961 // flag is to support incremental adoption. `prefetch={true}` will 3962 // continue to work until you opt into `instant`. 3963 fetchStrategy = _types.FetchStrategy.PPR; 3964 } else if (task.fetchStrategy === _types.FetchStrategy.PPR) { 3965 fetchStrategy = route.supportsPerSegmentPrefetching ? _types.FetchStrategy.PPR : _types.FetchStrategy.LoadingBoundary; 3966 } else { 3967 fetchStrategy = task.fetchStrategy; 3968 } 3969 switch(fetchStrategy){ 3970 case _types.FetchStrategy.PPR: 3971 { 3972 // For Cache Components pages, each segment may be prefetched 3973 // statically or using a runtime request, based on various 3974 // configurations and heuristics. We'll do this in two passes: first 3975 // traverse the tree and perform all the static prefetches. 3976 // 3977 // Then, if there are any segments that need a runtime request, 3978 // do another pass to perform a runtime prefetch. 3979 pingStaticHead(now, task, route); 3980 const exitStatus = pingSharedPartOfCacheComponentsTree(now, task, route, task.treeAtTimeOfPrefetch, tree); 3981 if (exitStatus === 0) { 3982 // Child yielded without finishing. 3983 return 0; 3984 } 3985 const spawnedRuntimePrefetches = task.spawnedRuntimePrefetches; 3986 if (spawnedRuntimePrefetches !== null) { 3987 // During the first pass, we discovered segments that require a 3988 // runtime prefetch. Do a second pass to construct a request tree. 3989 const spawnedEntries = new Map(); 3990 pingRuntimeHead(now, task, route, spawnedEntries, _types.FetchStrategy.PPRRuntime); 3991 const requestTree = pingRuntimePrefetches(now, task, route, tree, spawnedRuntimePrefetches, spawnedEntries); 3992 let needsDynamicRequest = spawnedEntries.size > 0; 3993 if (needsDynamicRequest) { 3994 // Perform a dynamic prefetch request and populate the cache with 3995 // the result. 3996 spawnPrefetchSubtask((0, _cache.fetchSegmentPrefetchesUsingDynamicRequest)(task, route, _types.FetchStrategy.PPRRuntime, requestTree, spawnedEntries)); 3997 } 3998 } 3999 return 2; 4000 } 4001 case _types.FetchStrategy.Full: 4002 case _types.FetchStrategy.PPRRuntime: 4003 case _types.FetchStrategy.LoadingBoundary: 4004 { 4005 // Prefetch multiple segments using a single dynamic request. 4006 // TODO: We can consolidate this branch with previous one by modeling 4007 // it as if the first segment in the new tree has runtime prefetching 4008 // enabled. Will do this as a follow-up refactor. Might want to remove 4009 // the special metatdata case below first. In the meantime, it's not 4010 // really that much duplication, just would be nice to remove one of 4011 // these codepaths. 4012 const spawnedEntries = new Map(); 4013 pingRuntimeHead(now, task, route, spawnedEntries, fetchStrategy); 4014 const dynamicRequestTree = diffRouteTreeAgainstCurrent(now, task, route, task.treeAtTimeOfPrefetch, tree, spawnedEntries, fetchStrategy); 4015 let needsDynamicRequest = spawnedEntries.size > 0; 4016 if (needsDynamicRequest) { 4017 spawnPrefetchSubtask((0, _cache.fetchSegmentPrefetchesUsingDynamicRequest)(task, route, fetchStrategy, dynamicRequestTree, spawnedEntries)); 4018 } 4019 return 2; 4020 } 4021 default: 4022 fetchStrategy; 4023 } 4024 break; 4025 } 4026 default: 4027 { 4028 route; 4029 } 4030 } 4031 return 2; 4032} 4033function pingStaticHead(now, task, route) { 4034 // The Head data for a page (metadata, viewport) is not really a route 4035 // segment, in the sense that it doesn't appear in the route tree. But we 4036 // store it in the cache as if it were, using a special key. 4037 pingStaticSegmentData(now, task, route, (0, _cache.readOrCreateSegmentCacheEntry)(now, _types.FetchStrategy.PPR, route.metadata), task.key, route.metadata); 4038} 4039function pingRuntimeHead(now, task, route, spawnedEntries, fetchStrategy) { 4040 pingRouteTreeAndIncludeDynamicData(now, task, route, route.metadata, false, spawnedEntries, // and LoadingBoundary 4041 fetchStrategy === _types.FetchStrategy.LoadingBoundary ? _types.FetchStrategy.Full : fetchStrategy); 4042} 4043// TODO: Rename dynamic -> runtime throughout this module 4044function pingSharedPartOfCacheComponentsTree(now, task, route, oldTree, newTree) { 4045 // When Cache Components is enabled (or PPR, or a fully static route when PPR 4046 // is disabled; those cases are treated equivalently to Cache Components), we 4047 // start by prefetching each segment individually. Once we reach the "new" 4048 // part of the tree — the part that doesn't exist on the current page — we 4049 // may choose to switch to a runtime prefetch instead, based on the 4050 // information sent by the server in the route tree. 4051 // 4052 // The traversal starts in the "shared" part of the tree. Once we reach the 4053 // "new" part of the tree, we switch to a different traversal, 4054 // pingNewPartOfCacheComponentsTree. 4055 // Prefetch this segment's static data. 4056 const segment = (0, _cache.readOrCreateSegmentCacheEntry)(now, task.fetchStrategy, newTree); 4057 pingStaticSegmentData(now, task, route, segment, task.key, newTree); 4058 // Recursively ping the children. 4059 const oldTreeChildren = oldTree[1]; 4060 const newTreeChildren = newTree.slots; 4061 if (newTreeChildren !== null) { 4062 for(const parallelRouteKey in newTreeChildren){ 4063 if (!hasNetworkBandwidth(task)) { 4064 // Stop prefetching segments until there's more bandwidth. 4065 return 0; 4066 } 4067 const newTreeChild = newTreeChildren[parallelRouteKey]; 4068 const newTreeChildSegment = newTreeChild.segment; 4069 const oldTreeChild = oldTreeChildren[parallelRouteKey]; 4070 const oldTreeChildSegment = oldTreeChild === null || oldTreeChild === void 0 ? void 0 : oldTreeChild[0]; 4071 let childExitStatus; 4072 if (oldTreeChildSegment !== undefined && doesCurrentSegmentMatchCachedSegment(route, newTreeChildSegment, oldTreeChildSegment)) { 4073 // We're still in the "shared" part of the tree. 4074 childExitStatus = pingSharedPartOfCacheComponentsTree(now, task, route, oldTreeChild, newTreeChild); 4075 } else { 4076 // We've entered the "new" part of the tree. Switch 4077 // traversal functions. 4078 childExitStatus = pingNewPartOfCacheComponentsTree(now, task, route, newTreeChild); 4079 } 4080 if (childExitStatus === 0) { 4081 // Child yielded without finishing. 4082 return 0; 4083 } 4084 } 4085 } 4086 return 2; 4087} 4088function pingNewPartOfCacheComponentsTree(now, task, route, tree) { 4089 // We're now prefetching in the "new" part of the tree, the part that doesn't 4090 // exist on the current page. (In other words, we're deeper than the 4091 // shared layouts.) Segments in here default to being prefetched statically. 4092 // However, if the server instructs us to, we may switch to a runtime 4093 // prefetch instead. Traverse the tree and check at each segment. 4094 if (tree.prefetchHints & _approutertypes.PrefetchHint.HasRuntimePrefetch) { 4095 // This route has a runtime prefetch response. Since we're below the shared 4096 // layout, everything from this point should be prefetched using a single,
4097 // combined runtime request, rather than using per-segment static requests. 4098 // This is true even if some of the child segments are known to be fully 4099 // static — once we've decided to perform a runtime prefetch, we might as 4100 // well respond with the static segments in the same roundtrip. (That's how 4101 // regular navigations work, too.) We'll still skip over segments that are 4102 // already cached, though. 4103 // 4104 // It's the server's responsibility to set a reasonable value of 4105 // `hasRuntimePrefetch`. Currently it's user-defined, but eventually, the 4106 // server may send a value of `false` even if the user opts in, if it 4107 // determines during build that the route is always fully static. There are 4108 // more optimizations we can do once we implement fallback param 4109 // tracking, too. 4110 // 4111 // Use the task object to collect the segments that need a runtime prefetch. 4112 // This will signal to the outer task queue that a second traversal is 4113 // required to construct a request tree. 4114 if (task.spawnedRuntimePrefetches === null) { 4115 task.spawnedRuntimePrefetches = new Set([ 4116 tree.requestKey 4117 ]); 4118 } else { 4119 task.spawnedRuntimePrefetches.add(tree.requestKey); 4120 } 4121 // Then exit the traversal without prefetching anything further. 4122 return 2; 4123 } 4124 // This segment should not be runtime prefetched. Prefetch its static data. 4125 const segment = (0, _cache.readOrCreateSegmentCacheEntry)(now, task.fetchStrategy, tree); 4126 pingStaticSegmentData(now, task, route, segment, task.key, tree); 4127 if (tree.slots !== null) { 4128 if (!hasNetworkBandwidth(task)) { 4129 // Stop prefetching segments until there's more bandwidth. 4130 return 0; 4131 } 4132 // Recursively ping the children. 4133 for(const parallelRouteKey in tree.slots){ 4134 const childTree = tree.slots[parallelRouteKey]; 4135 const childExitStatus = pingNewPartOfCacheComponentsTree(now, task, route, childTree); 4136 if (childExitStatus === 0) { 4137 // Child yielded without finishing. 4138 return 0; 4139 } 4140 } 4141 } 4142 // This segment and all its children have finished prefetching. 4143 return 2; 4144} 4145function diffRouteTreeAgainstCurrent(now, task, route, oldTree, newTree, spawnedEntries, fetchStrategy) { 4146 // This is a single recursive traversal that does multiple things: 4147 // - Finds the parts of the target route (newTree) that are not part of 4148 // of the current page (oldTree) by diffing them, using the same algorithm 4149 // as a real navigation. 4150 // - Constructs a request tree (FlightRouterState) that describes which 4151 // segments need to be prefetched and which ones are already cached. 4152 // - Creates a set of pending cache entries for the segments that need to 4153 // be prefetched, so that a subsequent prefetch task does not request the 4154 // same segments again. 4155 const oldTreeChildren = oldTree[1]; 4156 const newTreeChildren = newTree.slots; 4157 let requestTreeChildren = {}; 4158 if (newTreeChildren !== null) { 4159 for(const parallelRouteKey in newTreeChildren){ 4160 const newTreeChild = newTreeChildren[parallelRouteKey]; 4161 const newTreeChildSegment = newTreeChild.segment; 4162 const oldTreeChild = oldTreeChildren[parallelRouteKey]; 4163 const oldTreeChildSegment = oldTreeChild === null || oldTreeChild === void 0 ? void 0 : oldTreeChild[0]; 4164 if (oldTreeChildSegment !== undefined && doesCurrentSegmentMatchCachedSegment(route, newTreeChildSegment, oldTreeChildSegment)) { 4165 // This segment is already part of the current route. Keep traversing. 4166 const requestTreeChild = diffRouteTreeAgainstCurrent(now, task, route, oldTreeChild, newTreeChild, spawnedEntries, fetchStrategy); 4167 requestTreeChildren[parallelRouteKey] = requestTreeChild; 4168 } else { 4169 // This segment is not part of the current route. We're entering a 4170 // part of the tree that we need to prefetch (unless everything is 4171 // already cached). 4172 switch(fetchStrategy){ 4173 case _types.FetchStrategy.LoadingBoundary: 4174 { 4175 // When PPR is disabled, we can't prefetch per segment. We must 4176 // fallback to the old prefetch behavior and send a dynamic request. 4177 // Only routes that include a loading boundary can be prefetched in 4178 // this way. 4179 // 4180 // This is simlar to a "full" prefetch, but we're much more 4181 // conservative about which segments to include in the request. 4182 // 4183 // The server will only render up to the first loading boundary 4184 // inside new part of the tree. If there's no loading boundary 4185 // anywhere in the tree, the server will never return any data, so 4186 // we can skip the request. 4187 const subtreeHasLoadingBoundary = (newTreeChild.prefetchHints & (_approutertypes.PrefetchHint.SegmentHasLoadingBoundary | _approutertypes.PrefetchHint.SubtreeHasLoadingBoundary)) !== 0; 4188 const requestTreeChild = subtreeHasLoadingBoundary ? pingPPRDisabledRouteTreeUpToLoadingBoundary(now, task, route, newTreeChild, null, spawnedEntries) : (0, _cache.convertRouteTreeToFlightRouterState)(newTreeChild); 4189 requestTreeChildren[parallelRouteKey] = requestTreeChild; 4190 break; 4191 } 4192 case _types.FetchStrategy.PPRRuntime: 4193 { 4194 // This is a runtime prefetch. Fetch all cacheable data in the tree, 4195 // not just the static PPR shell. 4196 const requestTreeChild = pingRouteTreeAndIncludeDynamicData(now, task, route, newTreeChild, false, spawnedEntries, fetchStrategy); 4197 requestTreeChildren[parallelRouteKey] = requestTreeChild; 4198 break; 4199 } 4200 case _types.FetchStrategy.Full: 4201 { 4202 // This is a "full" prefetch. Fetch all the data in the tree, both 4203 // static and dynamic. We issue roughly the same request that we 4204 // would during a real navigation. The goal is that once the 4205 // navigation occurs, the router should not have to fetch any 4206 // additional data. 4207 // 4208 // Although the response will include dynamic data, opting into a 4209 // Full prefetch — via <Link prefetch={true}> — implicitly 4210 // instructs the cache to treat the response as "static", or non- 4211 // dynamic, since the whole point is to cache it for 4212 // future navigations. 4213 // 4214 // Construct a tree (currently a FlightRouterState) that represents 4215 // which segments need to be prefetched and which ones are already 4216 // cached. If the tree is empty, then we can exit. Otherwise, we'll 4217 // send the request tree to the server and use the response to 4218 // populate the segment cache. 4219 const requestTreeChild = pingRouteTreeAndIncludeDynamicData(now, task, route, newTreeChild, false, spawnedEntries, fetchStrategy); 4220 requestTreeChildren[parallelRouteKey] = requestTreeChild; 4221 break; 4222 } 4223 default: 4224 fetchStrategy; 4225 } 4226 } 4227 } 4228 } 4229 const requestTree = [ 4230 newTree.segment, 4231 requestTreeChildren, 4232 null, 4233 null 4234 ]; 4235 return requestTree; 4236} 4237function pingPPRDisabledRouteTreeUpToLoadingBoundary(now, task, route, tree, refetchMarkerContext, spawnedEntries) { 4238 // This function is similar to pingRouteTreeAndIncludeDynamicData, except the 4239 // server is only going to return a minimal loading state — it will stop 4240 // rendering at the first loading boundary. Whereas a Full prefetch is 4241 // intentionally aggressive and tries to pretfetch all the data that will be 4242 // needed for a navigation, a LoadingBoundary prefetch is much more 4243 // conservative. For example, it will omit from the request tree any segment 4244 // that is already cached, regardles of whether it's partial or full. By 4245 // contrast, a Full prefetch will refetch partial segments. 4246 // "inside-shared-layout" tells the server where to start looking for a 4247 // loading boundary. 4248 let refetchMarker = refetchMarkerContext === null ? 'inside-shared-layout' : null; 4249 const segment = (0, _cache.readOrCreateSegmentCacheEntry)(now, task.fetchStrategy, tree); 4250 switch(segment.status){ 4251 case _cache.EntryStatus.Empty: 4252 { 4253 // This segment is not cached. Add a refetch marker so the server knows 4254 // to start rendering here. 4255 // TODO: Instead of a "refetch" marker, we could just omit this subtree's 4256 // FlightRouterState from the request tree. I think this would probably 4257 // already work even without any updates to the server. For consistency, 4258 // though, I'll send the full tree and we'll look into this later as part 4259 // of a larger redesign of the request protocol.
4260 // Add the pending cache entry to the result map. 4261 spawnedEntries.set(tree.requestKey, (0, _cache.upgradeToPendingSegment)(segment, // might not include it in the pending response. If another route is able 4262 // to issue a per-segment request, we'll do that in the background. 4263 _types.FetchStrategy.LoadingBoundary)); 4264 if (refetchMarkerContext !== 'refetch') { 4265 refetchMarker = refetchMarkerContext = 'refetch'; 4266 } else { 4267 // There's already a parent with a refetch marker, so we don't need 4268 // to add another one. 4269 } 4270 break; 4271 } 4272 case _cache.EntryStatus.Fulfilled: 4273 { 4274 // The segment is already cached. 4275 const segmentHasLoadingBoundary = (tree.prefetchHints & _approutertypes.PrefetchHint.SegmentHasLoadingBoundary) !== 0; 4276 if (segmentHasLoadingBoundary) { 4277 // This segment has a loading boundary, which means the server won't 4278 // render its children. So there's nothing left to prefetch along this 4279 // path. We can bail out. 4280 return (0, _cache.convertRouteTreeToFlightRouterState)(tree); 4281 } 4282 break; 4283 } 4284 case _cache.EntryStatus.Pending: 4285 { 4286 break; 4287 } 4288 case _cache.EntryStatus.Rejected: 4289 { 4290 break; 4291 } 4292 default: 4293 segment; 4294 } 4295 const requestTreeChildren = {}; 4296 if (tree.slots !== null) { 4297 for(const parallelRouteKey in tree.slots){ 4298 const childTree = tree.slots[parallelRouteKey]; 4299 requestTreeChildren[parallelRouteKey] = pingPPRDisabledRouteTreeUpToLoadingBoundary(now, task, route, childTree, refetchMarkerContext, spawnedEntries); 4300 } 4301 } 4302 const requestTree = [ 4303 tree.segment, 4304 requestTreeChildren, 4305 null, 4306 refetchMarker 4307 ]; 4308 return requestTree; 4309} 4310function pingRouteTreeAndIncludeDynamicData(now, task, route, tree, isInsideRefetchingParent, spawnedEntries, fetchStrategy) { 4311 // The tree we're constructing is the same shape as the tree we're navigating 4312 // to. But even though this is a "new" tree, some of the individual segments 4313 // may be cached as a result of other route prefetches. 4314 // 4315 // So we need to find the first uncached segment along each path add an 4316 // explicit "refetch" marker so the server knows where to start rendering. 4317 // Once the server starts rendering along a path, it keeps rendering the 4318 // entire subtree. 4319 const segment = (0, _cache.readOrCreateSegmentCacheEntry)(now, // and we have to use the former here. 4320 // We can have a task with `FetchStrategy.PPR` where some of its segments are configured to 4321 // always use runtime prefetching (via `export const prefetch`), and those should check for 4322 // entries that include search params. 4323 fetchStrategy, tree); 4324 let spawnedSegment = null; 4325 switch(segment.status){ 4326 case _cache.EntryStatus.Empty: 4327 { 4328 // This segment is not cached. 4329 if (fetchStrategy === _types.FetchStrategy.Full) { 4330 // Check if there's a matching entry in the bfcache. If so, fulfill the 4331 // segment using the bfcache entry instead of issuing a new request. 4332 const fulfilled = (0, _cache.attemptToFulfillDynamicSegmentFromBFCache)(now, segment, tree); 4333 if (fulfilled !== null) { 4334 break; 4335 } 4336 } 4337 // Include it in the request. 4338 spawnedSegment = (0, _cache.upgradeToPendingSegment)(segment, fetchStrategy); 4339 break; 4340 } 4341 case _cache.EntryStatus.Fulfilled: 4342 { 4343 // The segment is already cached. 4344 if (segment.isPartial && (0, _cache.canNewFetchStrategyProvideMoreContent)(segment.fetchStrategy, fetchStrategy)) { 4345 // The cached segment contains dynamic holes, and was prefetched using a 4346 // less specific strategy than the current one. This means we're in one 4347 // of these cases: 4348 // - we have a static prefetch, and we're doing a runtime prefetch 4349 // - we have a static or runtime prefetch, and we're doing a Full 4350 // prefetch (or a navigation). 4351 // In either case, we need to include it in the request to get a more 4352 // specific (or full) version. However, if there's a non-stale bfcache 4353 // entry from a previous navigation, prefer that over making a new 4354 // request. 4355 if (fetchStrategy === _types.FetchStrategy.Full) { 4356 const fulfilled = (0, _cache.attemptToUpgradeSegmentFromBFCache)(now, tree); 4357 if (fulfilled !== null) { 4358 break; 4359 } 4360 } 4361 spawnedSegment = pingFullSegmentRevalidation(now, tree, fetchStrategy); 4362 } 4363 break; 4364 } 4365 case _cache.EntryStatus.Pending: 4366 case _cache.EntryStatus.Rejected: 4367 { 4368 // There's either another prefetch currently in progress, or the previous 4369 // attempt failed. If the new strategy can provide more content, fetch it again. 4370 if ((0, _cache.canNewFetchStrategyProvideMoreContent)(segment.fetchStrategy, fetchStrategy)) { 4371 spawnedSegment = pingFullSegmentRevalidation(now, tree, fetchStrategy); 4372 } 4373 break; 4374 } 4375 default: 4376 segment; 4377 } 4378 const requestTreeChildren = {}; 4379 if (tree.slots !== null) { 4380 for(const parallelRouteKey in tree.slots){ 4381 const childTree = tree.slots[parallelRouteKey]; 4382 requestTreeChildren[parallelRouteKey] = pingRouteTreeAndIncludeDynamicData(now, task, route, childTree, isInsideRefetchingParent || spawnedSegment !== null, spawnedEntries, fetchStrategy); 4383 } 4384 } 4385 if (spawnedSegment !== null) { 4386 // Add the pending entry to the result map. 4387 spawnedEntries.set(tree.requestKey, spawnedSegment); 4388 } 4389 // Don't bother to add a refetch marker if one is already present in a parent. 4390 const refetchMarker = !isInsideRefetchingParent && spawnedSegment !== null ? 'refetch' : null; 4391 const requestTree = [ 4392 tree.segment, 4393 requestTreeChildren, 4394 null, 4395 refetchMarker 4396 ]; 4397 return requestTree; 4398} 4399function pingRuntimePrefetches(now, task, route, tree, spawnedRuntimePrefetches, spawnedEntries) { 4400 // Construct a request tree (FlightRouterState) for a runtime prefetch. If 4401 // a segment is part of the runtime prefetch, the tree is constructed by 4402 // diffing against what's already in the prefetch cache. Otherwise, we send 4403 // a regular FlightRouterState with no special markers. 4404 // 4405 // See pingRouteTreeAndIncludeDynamicData for details. 4406 if (spawnedRuntimePrefetches.has(tree.requestKey)) { 4407 // This segment needs a runtime prefetch. 4408 return pingRouteTreeAndIncludeDynamicData(now, task, route, tree, false, spawnedEntries, _types.FetchStrategy.PPRRuntime); 4409 } 4410 let requestTreeChildren = {}; 4411 const slots = tree.slots; 4412 if (slots !== null) { 4413 for(const parallelRouteKey in slots){ 4414 const childTree = slots[parallelRouteKey]; 4415 requestTreeChildren[parallelRouteKey] = pingRuntimePrefetches(now, task, route, childTree, spawnedRuntimePrefetches, spawnedEntries); 4416 } 4417 } 4418 // This segment is not part of the runtime prefetch. Clone the base tree. 4419 const requestTree = [ 4420 tree.segment, 4421 requestTreeChildren, 4422 null, 4423 null 4424 ]; 4425 return requestTree; 4426} 4427function pingStaticSegmentData(now, task, route, segment, routeKey, tree) { 4428 switch(segment.status){ 4429 case _cache.EntryStatus.Empty: 4430 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 4431 ; 4432 // Upgrade to Pending so we know there's already a request in progress 4433 spawnPrefetchSubtask((0, _cache.fetchSegmentOnCacheMiss)(route, (0, _cache.upgradeToPendingSegment)(segment, _types.FetchStrategy.PPR), routeKey, tree)); 4434 break; 4435 case _cache.EntryStatus.Pending: 4436 { 4437 // There's already a request in progress. Depending on what kind of 4438 // request it is, we may want to revalidate it. 4439 switch(segment.fetchStrategy){ 4440 case _types.FetchStrategy.PPR: 4441 case _types.FetchStrategy.PPRRuntime: 4442 case _types.FetchStrategy.Full: 4443 break; 4444 case _types.FetchStrategy.LoadingBoundary:
4445 // There's a pending request, but because it's using the old 4446 // prefetching strategy, we can't be sure if it will be fulfilled by 4447 // the response — it might be inside the loading boundary. Perform 4448 // a revalidation, but because it's speculative, wait to do it at 4449 // background priority. 4450 if (background(task)) { 4451 // TODO: Instead of speculatively revalidating, consider including 4452 // `hasLoading` in the route tree prefetch response. 4453 pingPPRSegmentRevalidation(now, route, routeKey, tree); 4454 } 4455 break; 4456 default: 4457 segment.fetchStrategy; 4458 } 4459 break; 4460 } 4461 case _cache.EntryStatus.Rejected: 4462 { 4463 // The existing entry in the cache was rejected. Depending on how it 4464 // was originally fetched, we may or may not want to revalidate it. 4465 switch(segment.fetchStrategy){ 4466 case _types.FetchStrategy.PPR: 4467 case _types.FetchStrategy.PPRRuntime: 4468 case _types.FetchStrategy.Full: 4469 break; 4470 case _types.FetchStrategy.LoadingBoundary: 4471 // There's a rejected entry, but it was fetched using the loading 4472 // boundary strategy. So the reason it wasn't returned by the server 4473 // might just be because it was inside a loading boundary. Or because 4474 // there was a dynamic rewrite. Revalidate it using the per- 4475 // segment strategy. 4476 // 4477 // Because a rejected segment will definitely prevent the segment (and 4478 // all of its children) from rendering, we perform this revalidation 4479 // immediately instead of deferring it to a background task. 4480 pingPPRSegmentRevalidation(now, route, routeKey, tree); 4481 break; 4482 default: 4483 segment.fetchStrategy; 4484 } 4485 break; 4486 } 4487 case _cache.EntryStatus.Fulfilled: 4488 break; 4489 default: 4490 segment; 4491 } 4492// Segments do not have dependent tasks, so once the prefetch is initiated, 4493// there's nothing else for us to do (except write the server data into the 4494// entry, which is handled by `fetchSegmentOnCacheMiss`). 4495} 4496/** 4497 * Walks the RouteTree (including the head metadata) and collects any segments 4498 * that are still Empty into a Map, upgrading them to Pending. These entries 4499 * will be fulfilled by the inlined prefetch response. 4500 */ function collectInlinedEntries(now, route) { 4501 const entries = new Map(); 4502 collectInlinedEntriesImpl(now, route.tree, entries); 4503 // Also collect the head/metadata entry. 4504 const headEntry = (0, _cache.readOrCreateSegmentCacheEntry)(now, _types.FetchStrategy.PPR, route.metadata); 4505 if (headEntry.status === _cache.EntryStatus.Empty) { 4506 entries.set(route.metadata.requestKey, (0, _cache.upgradeToPendingSegment)(headEntry, _types.FetchStrategy.PPR)); 4507 } 4508 return entries; 4509} 4510function collectInlinedEntriesImpl(now, tree, entries) { 4511 const entry = (0, _cache.readOrCreateSegmentCacheEntry)(now, _types.FetchStrategy.PPR, tree); 4512 if (entry.status === _cache.EntryStatus.Empty) { 4513 entries.set(tree.requestKey, (0, _cache.upgradeToPendingSegment)(entry, _types.FetchStrategy.PPR)); 4514 } 4515 if (tree.slots !== null) { 4516 for(const parallelRouteKey in tree.slots){ 4517 collectInlinedEntriesImpl(now, tree.slots[parallelRouteKey], entries); 4518 } 4519 } 4520} 4521function pingPPRSegmentRevalidation(now, route, routeKey, tree) { 4522 const revalidatingSegment = (0, _cache.readOrCreateRevalidatingSegmentEntry)(now, _types.FetchStrategy.PPR, tree); 4523 switch(revalidatingSegment.status){ 4524 case _cache.EntryStatus.Empty: 4525 // Spawn a prefetch request. The fetch function handles upserting 4526 // the entry at the correct fulfilled vary path upon completion. 4527 spawnPrefetchSubtask((0, _cache.fetchSegmentOnCacheMiss)(route, (0, _cache.upgradeToPendingSegment)(reval
4527idatingSegment, _types.FetchStrategy.PPR), routeKey, tree)); 4528 break; 4529 case _cache.EntryStatus.Pending: 4530 break; 4531 case _cache.EntryStatus.Fulfilled: 4532 case _cache.EntryStatus.Rejected: 4533 break; 4534 default: 4535 revalidatingSegment; 4536 } 4537} 4538function pingFullSegmentRevalidation(now, tree, fetchStrategy) { 4539 const revalidatingSegment = (0, _cache.readOrCreateRevalidatingSegmentEntry)(now, fetchStrategy, tree); 4540 if (revalidatingSegment.status === _cache.EntryStatus.Empty) { 4541 // During a Full/PPRRuntime prefetch, a single dynamic request is made for all the 4542 // segments that we need. So we don't initiate a request here directly. By 4543 // returning a pending entry from this function, it signals to the caller 4544 // that this segment should be included in the request that's sent to 4545 // the server. 4546 const pendingSegment = (0, _cache.upgradeToPendingSegment)(revalidatingSegment, fetchStrategy); 4547 // The upsert is handled by fulfillEntrySpawnedByRuntimePrefetch 4548 // when the dynamic prefetch response is written into the cache. 4549 return pendingSegment; 4550 } else { 4551 // There's already a revalidation in progress. 4552 const nonEmptyRevalidatingSegment = revalidatingSegment; 4553 if ((0, _cache.canNewFetchStrategyProvideMoreContent)(nonEmptyRevalidatingSegment.fetchStrategy, fetchStrategy)) { 4554 // The existing revalidation was fetched using a less specific strategy. 4555 // Reset it and start a new revalidation. 4556 const emptySegment = (0, _cache.overwriteRevalidatingSegmentCacheEntry)(now, fetchStrategy, tree); 4557 const pendingSegment = (0, _cache.upgradeToPendingSegment)(emptySegment, fetchStrategy); 4558 // The upsert is handled by fulfillEntrySpawnedByRuntimePrefetch 4559 // when the dynamic prefetch response is written into the cache. 4560 return pendingSegment; 4561 } 4562 switch(nonEmptyRevalidatingSegment.status){ 4563 case _cache.EntryStatus.Pending: 4564 // There's already an in-progress prefetch that includes this
4564segment. 4565 return null; 4566 case _cache.EntryStatus.Fulfilled: 4567 case _cache.EntryStatus.Rejected: 4568 // A previous revalidation attempt finished, but we chose not to replace 4569 // the existing entry in the cache. Don't try again until or unless the 4570 // revalidation entry expires. 4571 return null; 4572 default: 4573 nonEmptyRevalidatingSegment; 4574 return null; 4575 } 4576 } 4577} 4578function doesCurrentSegmentMatchCachedSegment(route, currentSegment, cachedSegment) { 4579 if (cachedSegment === _segment.PAGE_SEGMENT_KEY) { 4580 // In the FlightRouterState stored by the router, the page segment has the 4581 // rendered search params appended to the name of the segment. In the 4582 // prefetch cache, however, this is stored separately. So, when comparing 4583 // the router's current FlightRouterState to the cached FlightRouterState, 4584 // we need to make sure we compare both parts of the segment. 4585 // TODO: This is not modeled clearly. We use the same type, 4586 // FlightRouterState, for both the CacheNode tree _and_ the prefetch cache 4587 // _and_ the server response format, when conceptually those are three 4588 // different things and treated in different ways. We should encode more of 4589 // this information into the type design so mistakes are less likely. 4590 return currentSegment === (0, _segment.addSearchParamsIfPageSegment)(_segment.PAGE_SEGMENT_KEY, Object.fromEntries(new URLSearchParams(route.renderedSearch))); 4591 } 4592 // Non-page segments are compared using the same function as the server 4593 return (0, _matchsegments.matchSegment)(cachedSegment, currentSegment); 4594} 4595// ----------------------------------------------------------------------------- 4596// The remainder of the module is a MinHeap implementation. Try not to put any 4597// logic below here unless it's related to the heap algorithm. We can extract 4598// this to a separate module if/when we need multiple kinds of heaps. 4599// ----------------------------------------------------------------------------- 4600function compareQueuePriority(a, b) { 4601 // Since the queue is a MinHeap, this should return a positive number if b is 4602 // higher priority than a, and a negative number if a is higher priority 4603 // than b. 4604 // `priority` is an integer, where higher numbers are higher priority. 4605 const priorityDiff = b.priority - a.priority; 4606 if (priorityDiff !== 0) { 4607 return priorityDiff; 4608 } 4609 // If the priority is the same, check which phase the prefetch is in — is it 4610 // prefetching the route tree, or the segments? Route trees are prioritized. 4611 const phaseDiff = b.phase - a.phase; 4612 if (phaseDiff !== 0) { 4613 return phaseDiff; 4614 } 4615 // Finally, check the insertion order. `sortId` is an incrementing counter 4616 // assigned to prefetches. We want to process the newest prefetches first. 4617 return b.sortId - a.sortId; 4618} 4619function heapPush(heap, node) { 4620 const index = heap.length; 4621 heap.push(node); 4622 node._heapIndex = index; 4623 heapSiftUp(heap, node, index); 4624} 4625function heapPeek(heap) { 4626 return heap.length === 0 ? null : heap[0]; 4627} 4628function heapPop(heap) { 4629 if (heap.length === 0) { 4630 return null; 4631 } 4632 const first = heap[0]; 4633 first._heapIndex = -1; 4634 const last = heap.pop(); 4635 if (last !== first) { 4636 heap[0] = last; 4637 last._heapIndex = 0; 4638 heapSiftDown(heap, last, 0); 4639 } 4640 return first; 4641} 4642function heapDelete(heap, node) { 4643 const index = node._heapIndex; 4644 if (index !== -1) { 4645 node._heapIndex = -1; 4646 if (heap.length !== 0) { 4647 const last = heap.pop(); 4648 if (last !== node) { 4649 heap[index] = last; 4650 last._heapIndex = index; 4651 heapSiftDown(heap, last, index); 4652 } 4653 } 4654 } 4655} 4656function heapResift(heap, node) { 4657 const index = node._heapIndex; 4658 if (index !== -1) { 4659 if (index === 0) { 4660 heapSiftDown(heap, node, 0); 4661 } else { 4662 const parentIndex = index - 1 >>> 1; 4663 const parent = heap[parentIndex]; 4664 if (compareQueuePriority(parent, node) > 0) { 4665 // The parent is larger. Sift up.
4666 heapSiftUp(heap, node, index); 4667 } else { 4668 // The parent is smaller (or equal). Sift down. 4669 heapSiftDown(heap, node, index); 4670 } 4671 } 4672 } 4673} 4674function heapSiftUp(heap, node, i) { 4675 let index = i; 4676 while(index > 0){ 4677 const parentIndex = index - 1 >>> 1; 4678 const parent = heap[parentIndex]; 4679 if (compareQueuePriority(parent, node) > 0) { 4680 // The parent is larger. Swap positions. 4681 heap[parentIndex] = node; 4682 node._heapIndex = parentIndex; 4683 heap[index] = parent; 4684 parent._heapIndex = index; 4685 index = parentIndex; 4686 } else { 4687 // The parent is smaller. Exit. 4688 return; 4689 } 4690 } 4691} 4692function heapSiftDown(heap, node, i) { 4693 let index = i; 4694 const length = heap.length; 4695 const halfLength = length >>> 1; 4696 while(index < halfLength){ 4697 const leftIndex = (index + 1) * 2 - 1; 4698 const left = heap[leftIndex]; 4699 const rightIndex = leftIndex + 1; 4700 const right = heap[rightIndex]; 4701 // If the left or right node is smaller, swap with the smaller of those. 4702 if (compareQueuePriority(left, node) < 0) { 4703 if (rightIndex < length && compareQueuePriority(right, left) < 0) { 4704 heap[index] = right; 4705 right._heapIndex = index; 4706 heap[rightIndex] = node; 4707 node._heapIndex = rightIndex; 4708 index = rightIndex; 4709 } else { 4710 heap[index] = left; 4711 left._heapIndex = index; 4712 heap[leftIndex] = node; 4713 node._heapIndex = leftIndex; 4714 index = leftIndex; 4715 } 4716 } else if (rightIndex < length && compareQueuePriority(right, node) < 0) { 4717 heap[index] = right; 4718 right._heapIndex = index; 4719 heap[rightIndex] = node; 4720 node._heapIndex = rightIndex; 4721 index = rightIndex; 4722 } else { 4723 // Neither child is smaller. Exit. 4724 return; 4725 } 4726 } 4727} 4728if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 4729 Object.defineProperty(exports.default, '__esModule', { 4730 value: true 4731 }); 4732 Object.assign(exports.default, exports); 4733 module.exports = exports.default; 4734} 4735}), 4736856655, ((__turbopack_context__, module, exports) => { 4737"use strict"; 4738 4739Object.defineProperty(exports, "__esModule", { 4740 value: true 4741}); 47420 && (module.exports = { 4743 appendLayoutVaryPath: null, 4744 clonePageVaryPathWithNewSearchParams: null, 4745 finalizeLayoutVaryPath: null, 4746 finalizeMetadataVaryPath: null, 4747 finalizePageVaryPath: null, 4748 getFulfilledRouteVaryPath: null, 4749 getFulfilledSegmentVaryPath: null, 4750 getPartialLayoutVaryPath: null, 4751 getPartialPageVaryPath: null, 4752 getRenderedSearchFromVaryPath: null, 4753 getRouteVaryPath: null, 4754 getSegmentVaryPathForRequest: null 4755}); 4756function _export(target, all) { 4757 for(var name in all)Object.defineProperty(target, name, { 4758 enumerable: true, 4759 get: all[name] 4760 }); 4761} 4762_export(exports, { 4763 appendLayoutVaryPath: function() { 4764 return appendLayoutVaryPath; 4765 }, 4766 clonePageVaryPathWithNewSearchParams: function() { 4767 return clonePageVaryPathWithNewSearchParams; 4768 }, 4769 finalizeLayoutVaryPath: function() { 4770 return finalizeLayoutVaryPath; 4771 }, 4772 finalizeMetadataVaryPath: function() { 4773 return finalizeMetadataVaryPath; 4774 }, 4775 finalizePageVaryPath: function() { 4776 return finalizePageVaryPath; 4777 }, 4778 getFulfilledRouteVaryPath: function() { 4779 return getFulfilledRouteVaryPath; 4780 }, 4781 getFulfilledSegmentVaryPath: function() { 4782 return getFulfilledSegmentVaryPath; 4783 }, 4784 getPartialLayoutVaryPath: function() { 4785 return getPartialLayoutVaryPath; 4786 }, 4787 getPartialPageVaryPath: function() { 4788 return getPartialPageVaryPath; 4789 }, 4790 getRenderedSearchFromVaryPath: function() { 4791 return getRenderedSearchFromVaryPath; 4792 },
4793 getRouteVaryPath: function() { 4794 return getRouteVaryPath; 4795 }, 4796 getSegmentVaryPathForRequest: function() { 4797 return getSegmentVaryPathForRequest; 4798 } 4799}); 4800const _types = __turbopack_context__.r(509396); 4801const _cachemap = __turbopack_context__.r(511); 4802const _segmentvalueencoding = __turbopack_context__.r(767764); 4803function getRouteVaryPath(pathname, search, nextUrl) { 4804 // requestKey -> searchParams -> nextUrl 4805 const varyPath = { 4806 id: null, 4807 value: pathname, 4808 parent: { 4809 id: '?', 4810 value: search, 4811 parent: { 4812 id: null, 4813 value: nextUrl, 4814 parent: null 4815 } 4816 } 4817 }; 4818 return varyPath; 4819} 4820function getFulfilledRouteVaryPath(pathname, search, nextUrl, couldBeIntercepted) { 4821 // This is called when a route's data is fulfilled. The cache entry will be 4822 // re-keyed based on which inputs the response varies by. 4823 // requestKey -> searchParams -> nextUrl 4824 const varyPath = { 4825 id: null, 4826 value: pathname, 4827 parent: { 4828 id: '?', 4829 value: search, 4830 parent: { 4831 id: null, 4832 value: couldBeIntercepted ? nextUrl : _cachemap.Fallback, 4833 parent: null 4834 } 4835 } 4836 }; 4837 return varyPath; 4838} 4839function appendLayoutVaryPath(parentPath, cacheKey, paramName) { 4840 const varyPathPart = { 4841 id: paramName, 4842 value: cacheKey, 4843 parent: parentPath 4844 }; 4845 return varyPathPart; 4846} 4847function finalizeLayoutVaryPath(requestKey, varyPath) { 4848 const layoutVaryPath = { 4849 id: null, 4850 value: requestKey, 4851 parent: varyPath 4852 }; 4853 return layoutVaryPath; 4854} 4855function getPartialLayoutVaryPath(finalizedVaryPath) { 4856 // This is the inverse of finalizeLayoutVaryPath. 4857 return finalizedVaryPath.parent; 4858} 4859function finalizePageVaryPath(requestKey, renderedSearch, varyPath) { 4860 // Unlike layouts, a page segment's vary path also includes the search string. 4861 // requestKey -> searchParams -> pathParams 4862 const pageVaryPath = { 4863 id: null, 4864 value: requestKey, 4865 parent: { 4866 id: '?', 4867 value: renderedSearch, 4868 parent: varyPath 4869 } 4870 }; 4871 return pageVaryPath; 4872} 4873function getPartialPageVaryPath(finalizedVaryPath) { 4874 // This is the inverse of finalizePageVaryPath. 4875 return finalizedVaryPath.parent.parent; 4876} 4877function finalizeMetadataVaryPath(pageRequestKey, renderedSearch, varyPath) { 4878 // The metadata "segment" is not a real segment because it doesn't exist in 4879 // the normal structure of the route tree, but in terms of caching, it 4880 // behaves like a page segment because it varies by all the same params as 4881 // a page. 4882 // 4883 // To keep the protocol for querying the server simple, the request key for 4884 // the metadata does not include any path information. It's unnecessary from 4885 // the server's perspective, because unlike page segments, there's only one 4886 // metadata response per URL, i.e. there's no need to distinguish multiple 4887 // parallel pages. 4888 // 4889 // However, this means the metadata request key is insufficient for 4890 // caching the the metadata in the client cache, because on the client we 4891 // use the request key to distinguish the metadata entry from all other 4892 // page's metadata entries. 4893 // 4894 // So instead we create a simulated request key based on the page segment. 4895 // Conceptually this is equivalent to the request key the server would have 4896 // assigned the metadata segment if it treated it as part of the actual 4897 // route structure. 4898 // If there are multiple parallel pages, we use whichever is the first one. 4899 // This is fine because the only difference between request keys for 4900 // different parallel pages are things like route groups and parallel 4901 // route slots. As long as it's always the same one, it doesn't matter. 4902 const pageVaryPath = { 4903 id: null, 4904 // Append the actual metadata request key to the page request key. Note 4905 // that we're not using a separate vary path part; it's unnecessary because 4906 // these are not conceptually separate inputs.
4907 value: pageRequestKey + _segmentvalueencoding.HEAD_REQUEST_KEY, 4908 parent: { 4909 id: '?', 4910 value: renderedSearch, 4911 parent: varyPath 4912 } 4913 }; 4914 return pageVaryPath; 4915} 4916function getSegmentVaryPathForRequest(fetchStrategy, tree) { 4917 // This is used for storing pending requests in the cache. We want to choose 4918 // the most generic vary path based on the strategy used to fetch it, i.e. 4919 // static/PPR versus runtime prefetching, so that it can be reused as much 4920 // as possible. 4921 // 4922 // We may be able to re-key the response to something even more generic once 4923 // we receive it — for example, if the server tells us that the response 4924 // doesn't vary on a particular param — but even before we send the request, 4925 // we know some params are reusable based on the fetch strategy alone. For 4926 // example, a static prefetch will never vary on search params. 4927 // 4928 // The original vary path with all the params filled in is stored on the 4929 // route tree object. We will clone this one to create a new vary path 4930 // where certain params are replaced with Fallback. 4931 // 4932 // This result of this function is not stored anywhere. It's only used to 4933 // access the cache a single time. 4934 // 4935 // TODO: Rather than create a new list object just to access the cache, the 4936 // plan is to add the concept of a "vary mask". This will represent all the 4937 // params that can be treated as Fallback. (Or perhaps the inverse.) 4938 const originalVaryPath = tree.varyPath; 4939 // Only page segments (and the special "metadata" segment, which is treated
4940 // like a page segment for the purposes of caching) may contain search 4941 // params. There's no reason to include them in the vary path otherwise. 4942 if (tree.isPage) { 4943 // Only a runtime prefetch will include search params in the vary path. 4944 // Static prefetches never include search params, so they can be reused 4945 // across all possible search param values. 4946 const doesVaryOnSearchParams = fetchStrategy === _types.FetchStrategy.Full || fetchStrategy === _types.FetchStrategy.PPRRuntime; 4947 if (!doesVaryOnSearchParams) { 4948 // The response from the the server will not vary on search params. Clone 4949 // the end of the original vary path to replace the search params 4950 // with Fallback. 4951 // 4952 // requestKey -> searchParams -> pathParams 4953 // ^ This part gets replaced with Fallback 4954 const searchParamsVaryPath = originalVaryPath.parent; 4955 const pathParamsVaryPath = searchParamsVaryPath.parent; 4956 const patchedVaryPath = { 4957 id: null, 4958 value: originalVaryPath.value, 4959 parent: { 4960 id: '?', 4961 value: _cachemap.Fallback, 4962 parent: pathParamsVaryPath 4963 } 4964 }; 4965 return patchedVaryPath; 4966 } 4967 } 4968 // The request does vary on search params. We don't need to modify anything. 4969 return originalVaryPath; 4970} 4971function clonePageVaryPathWithNewSearchParams(originalVaryPath, newSearch) { 4972 // requestKey -> searchParams -> pathParams 4973 // ^ This part gets replaced with newSearch 4974 const searchParamsVaryPath = originalVaryPath.parent; 4975 const clonedVaryPath = { 4976 id: null, 4977 value: originalVaryPath.value, 4978 parent: { 4979 id: '?', 4980 value: newSearch, 4981 parent: searchParamsVaryPath.parent 4982 } 4983 }; 4984 return clonedVaryPath; 4985} 4986function getRenderedSearchFromVaryPath(varyPath) { 4987 const searchParams = varyPath.parent.value; 4988 return typeof searchParams === 'string' ? searchParams : null; 4989} 4990function getFulfilledSegmentVaryPath(original, varyParams) { 4991 // Re-keys a segment's vary path based on which params the segment actually 4992 // depends on. Params that are NOT in the varyParams set are replaced with 4993 // Fallback, allowing the cache entry to be reused across different values of 4994 // those params. 4995 // This is called when a segment is fulfilled with data from the server. The 4996 // varyParams set comes from the server and indicates which params were 4997 // accessed during rendering. 4998 const clone = { 4999 id: original.id, 5000 // If the id is null, this node is not a param (e.g., it's a request key). 5001 // If the id is in the varyParams set, keep the original value. 5002 // Otherwise, replace with Fallback to make it reusable. 5003 value: original.id === null || varyParams.has(original.id) ? original.value : _cachemap.Fallback, 5004 parent: original.parent === null ? null : getFulfilledSegmentVaryPath(original.parent, varyParams) 5005 }; 5006 return clone; 5007} 5008if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 5009 Object.defineProperty(exports.default, '__esModule', { 5010 value: true 5011 }); 5012 Object.assign(exports.default, exports); 5013 module.exports = exports.default; 5014} 5015}), 5016572463, ((__turbopack_context__, module, exports) => { 5017"use strict"; 5018 5019/** 5020 * Given a path this function will find the pathname, query and hash and return 5021 * them. This is useful to parse full paths on the client side. 5022 * @param path A path to parse e.g. /foo/bar?id=1#hash 5023 */ Object.defineProperty(exports, "__esModule", { 5024 value: true 5025}); 5026Object.defineProperty(exports, "parsePath", { 5027 enumerable: true, 5028 get: function() { 5029 return parsePath; 5030 } 5031}); 5032function parsePath(path) { 5033 const hashIndex = path.indexOf('#'); 5034 const queryIndex = path.indexOf('?'); 5035 const hasQuery = queryIndex > -1 && (hashIndex < 0 || queryIndex < hashIndex); 5036 if (hasQuery || hashIndex > -1) { 5037 return { 5038 pathname: path.substring(0, hasQuery ? queryIndex : hashIndex), 5039 query: hasQuery ? path.substring(queryIndex, hashIndex > -1 ? hashIndex : undefined) : '', 5040 hash: hashIndex > -1 ? path.slice(hashIndex) : '' 5041 }; 5042 } 5043 return { 5044 pathname: path, 5045 query: '', 5046 hash: '' 5047 }; 5048} 5049}),
5050541858, ((__turbopack_context__, module, exports) => { 5051"use strict"; 5052 5053Object.defineProperty(exports, "__esModule", { 5054 value: true 5055}); 5056Object.defineProperty(exports, "addPathPrefix", { 5057 enumerable: true, 5058 get: function() { 5059 return addPathPrefix; 5060 } 5061}); 5062const _parsepath = __turbopack_context__.r(572463); 5063function addPathPrefix(path, prefix) { 5064 if (!path.startsWith('/') || !prefix) { 5065 return path; 5066 } 5067 const { pathname, query, hash } = (0, _parsepath.parsePath)(path); 5068 return "".concat(prefix).concat(pathname).concat(query).concat(hash); 5069} 5070}), 5071938281, ((__turbopack_context__, module, exports) => { 5072"use strict"; 5073 5074/** 5075 * Removes the trailing slash for a given route or page path. Preserves the 5076 * root page. Examples: 5077 * - `/foo/bar/` -> `/foo/bar` 5078 * - `/foo/bar` -> `/foo/bar` 5079 * - `/` -> `/` 5080 */ Object.defineProperty(exports, "__esModule", { 5081 value: true 5082}); 5083Object.defineProperty(exports, "removeTrailingSlash", { 5084 enumerable: true, 5085 get: function() { 5086 return removeTrailingSlash; 5087 } 5088}); 5089function removeTrailingSlash(route) { 5090 return route.replace(/\/$/, '') || '/'; 5091} 5092}), 509382823, ((__turbopack_context__, module, exports) => { 5094"use strict"; 5095 5096var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 5097"use strict"; 5098Object.defineProperty(exports, "__esModule", { 5099 value: true 5100}); 5101Object.defineProperty(exports, "normalizePathTrailingSlash", { 5102 enumerable: true, 5103 get: function() { 5104 return normalizePathTrailingSlash; 5105 } 5106}); 5107const _removetrailingslash = __turbopack_context__.r(938281); 5108const _parsepath = __turbopack_context__.r(572463); 5109const normalizePathTrailingSlash = (path)=>{ 5110 if (!path.startsWith('/') || ("TURBOPACK compile-time value", void 0)) { 5111 return path; 5112 } 5113 const { pathname, query, hash } = (0, _parsepath.parsePath)(path); 5114 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 5115 ; 5116 return "".concat((0, _removetrailingslash.removeTrailingSlash)(pathname)).concat(query).concat(hash); 5117}; 5118if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 5119 Object.defineProperty(exports.default, '__esModule', { 5120 value: true 5121 }); 5122 Object.assign(exports.default, exports); 5123 module.exports = exports.default; 5124} 5125}), 5126405550, ((__turbopack_context__, module, exports) => { 5127"use strict"; 5128 5129var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 5130"use strict"; 5131Object.defineProperty(exports, "__esModule", { 5132 value: true 5133}); 5134Object.defineProperty(exports, "addBasePath", { 5135 enumerable: true, 5136 get: function() { 5137 return addBasePath; 5138 } 5139}); 5140const _addpathprefix = __turbopack_context__.r(541858); 5141const _normalizetrailingslash = __turbopack_context__.r(82823); 5142const basePath = ("TURBOPACK compile-time value", "") || ''; 5143function addBasePath(path, required) { 5144 return (0, _normalizetrailingslash.normalizePathTrailingSlash)(("TURBOPACK compile-time falsy", 0) ? "TURBOPACK unreachable" : (0, _addpathprefix.addPathPrefix)(path, basePath)); 5145} 5146if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 5147 Object.defineProperty(exports.default, '__esModule', { 5148 value: true 5149 }); 5150 Object.assign(exports.default, exports); 5151 module.exports = exports.default; 5152} 5153}), 5154657630, ((__turbopack_context__, module, exports) => { 5155"use strict"; 5156 5157var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 5158"use strict"; 5159Object.defineProperty(exports, "__esModule", { 5160 value: true 5161}); 51620 && (module.exports = { 5163 createPrefetchURL: null, 5164 isExternalURL: null 5165}); 5166function _export(target, all) { 5167 for(var name in all)Object.defineProperty(target, name, { 5168 enumerable: true, 5169 get: all[name] 5170 }); 5171} 5172_export(exports, { 5173 createPrefetchURL: function() { 5174 return createPrefetchURL; 5175 }, 5176 isExternalURL: function() { 5177 return isExternalURL; 5178 } 5179}); 5180const _isbot = __turbopack_context__.r(82604); 5181const _addbasepath = __turbopack_context__.r(405550); 5182function isExternalURL(url) { 5183 return url.origin !== window.location.origin; 5184} 5185function createPrefetchURL(href) { 5186 // Don't prefetch for bots as they don't navigate. 5187 if ((0, _isbot.isBot)(window.navigator.userAgent)) { 5188 return null; 5189 } 5190 let url; 5191 try { 5192 url = new URL((0, _addbasepath.addBasePath)(href), window.location.href); 5193 } catch (_) { 5194 // TODO: Does this need to throw or can we just console.error instead? Does 5195 // anyone rely on this throwing? (Seems unlikely.) 5196 throw Object.defineProperty(new Error("Cannot prefetch '".concat(href, "' because it cannot be converted to a URL.")), "__NEXT_ERROR_CODE", { 5197 value: "E234", 5198 enumerable: false, 5199 configurable: true 5200 }); 5201 } 5202 // Don't prefetch during development (improves compilation performance) 5203 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 5204 ; 5205 // External urls can't be prefetched in the same way. 5206 if (isExternalURL(url)) { 5207 return null; 5208 } 5209 return url; 5210} 5211if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 5212 Object.defineProperty(exports.default, '__esModule', { 5213 value: true 5214 });
5215 Object.assign(exports.default, exports); 5216 module.exports = exports.default; 5217} 5218}), 5219769688, ((__turbopack_context__, module, exports) => { 5220"use strict"; 5221 5222var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 5223"use strict"; 5224Object.defineProperty(exports, "__esModule", { 5225 value: true 5226}); 52270 && (module.exports = { 5228 IDLE_LINK_STATUS: null, 5229 PENDING_LINK_STATUS: null, 5230 getLinkForCurrentNavigation: null, 5231 mountFormInstance: null, 5232 mountLinkInstance: null, 5233 onLinkVisibilityChanged: null, 5234 onNavigationIntent: null, 5235 pingVisibleLinks: null, 5236 setLinkForCurrentNavigation: null, 5237 unmountLinkForCurrentNavigation: null, 5238 unmountPrefetchableInstance: null 5239}); 5240function _export(target, all) { 5241 for(var name in all)Object.defineProperty(target, name, { 5242 enumerable: true, 5243 get: all[name] 5244 }); 5245} 5246_export(exports, { 5247 IDLE_LINK_STATUS: function() { 5248 return IDLE_LINK_STATUS; 5249 }, 5250 PENDING_LINK_STATUS: function() { 5251 return PENDING_LINK_STATUS; 5252 }, 5253 getLinkForCurrentNavigation: function() { 5254 return getLinkForCurrentNavigation; 5255 }, 5256 mountFormInstance: function() { 5257 return mountFormInstance; 5258 }, 5259 mountLinkInstance: function() { 5260 return mountLinkInstance; 5261 }, 5262 onLinkVisibilityChanged: function() { 5263 return onLinkVisibilityChanged; 5264 }, 5265 onNavigationIntent: function() { 5266 return onNavigationIntent; 5267 }, 5268 pingVisibleLinks: function() { 5269 return pingVisibleLinks; 5270 }, 5271 setLinkForCurrentNavigation: function() { 5272 return setLinkForCurrentNavigation; 5273 }, 5274 unmountLinkForCurrentNavigation: function() { 5275 return unmountLinkForCurrentNavigation; 5276 }, 5277 unmountPrefetchableInstance: function() { 5278 return unmountPrefetchableInstance; 5279 } 5280}); 5281const _types = __turbopack_context__.r(509396); 5282const _cachekey = __turbopack_context__.r(477048); 5283const _scheduler = __turbopack_context__.r(777709); 5284const _react = __turbopack_context__.r(271645); 5285// Tracks the most recently navigated link instance. When null, indicates 5286// the current navigation was not initiated by a link click. 5287let linkForMostRecentNavigation = null; 5288const PENDING_LINK_STATUS = { 5289 pending: true 5290}; 5291const IDLE_LINK_STATUS = { 5292 pending: false 5293}; 5294function setLinkForCurrentNavigation(link) { 5295 (0, _react.startTransition)(()=>{ 5296 linkForMostRecentNavigation === null || linkForMostRecentNavigation === void 0 ? void 0 : linkForMostRecentNavigation.setOptimisticLinkStatus(IDLE_LINK_STATUS); 5297 link === null || link === void 0 ? void 0 : link.setOptimisticLinkStatus(PENDING_LINK_STATUS); 5298 linkForMostRecentNavigation = link; 5299 }); 5300} 5301function unmountLinkForCurrentNavigation(link) { 5302 if (linkForMostRecentNavigation === link) { 5303 linkForMostRecentNavigation = null; 5304 } 5305} 5306function getLinkForCurrentNavigation() { 5307 return linkForMostRecentNavigation; 5308} 5309// Use a WeakMap to associate a Link instance with its DOM element. This is 5310// used by the IntersectionObserver to track the link's visibility. 5311const prefetchable = typeof WeakMap === 'function' ? new WeakMap() : new Map(); 5312// A Set of the currently visible links. We re-prefetch visible links after a 5313// cache invalidation, or when the current URL changes. It's a separate data 5314// structure from the WeakMap above because only the visible links need to 5315// be enumerated. 5316const prefetchableAndVisible = new Set(); 5317// A single IntersectionObserver instance shared by all <Link> components. 5318const observer = typeof IntersectionObserver === 'function' ? new IntersectionObserver(handleIntersect, { 5319 rootMargin: '200px' 5320}) : null; 5321function observeVisibility(element, instance) { 5322 const existingInstance = prefetchable.get(element); 5323 if (existingInstance !== undefined) { 5324 // This shouldn't happen because each <Link> component should have its own 5325 // anchor tag instance, but it's defensive coding to avoid a memory leak in 5326 // case there's a logical error somewhere else. 5327 unmountPrefetchableInstance(element); 5328 } 5329 // Only track prefetchable links that have a valid prefetch URL 5330 prefetchable.set(element, instance); 5331 if (observer !== null) { 5332 observer.observe(element); 5333 } 5334} 5335function coercePrefetchableUrl(href) { 5336 if (typeof window !== 'undefined') { 5337 const { createPrefetchURL } = __turbopack_context__.r(657630); 5338 try { 5339 return createPrefetchURL(href); 5340 } catch (unused) { 5341 // createPrefetchURL sometimes throws an error if an invali
5341d URL is 5342 // provided, though I'm not sure if it's actually necessary. 5343 // TODO: Consider removing the throw from the inner function, or change it 5344 // to reportError. Or maybe the error isn't even necessary for automatic 5345 // prefetches, just navigations. 5346 const reportErrorFn = typeof reportError === 'function' ? reportError : console.error; 5347 reportErrorFn("Cannot prefetch '".concat(href, "' because it cannot be converted to a URL.")); 5348 return null; 5349 } 5350 } else { 5351 return null; 5352 } 5353} 5354function mountLinkInstance(element, href, router, fetchStrategy, prefetchEnabled, setOptimisticLinkStatus) { 5355 if (prefetchEnabled) { 5356 const prefetchURL = coercePrefetchableUrl(href); 5357 if (prefetchURL !== null) { 5358 const instance = { 5359 router, 5360 fetchStrategy, 5361 isVisible: false, 5362 prefetchTask: null, 5363 prefetchHref: prefetchURL.href, 5364 setOptimisticLinkStatus 5365 }; 5366 // We only observe the link's visibility if it's prefetchable. For 5367 // example, this excludes links to external URLs. 5368 observeVisibility(element, instance); 5369 return instance; 5370 } 5371 } 5372 // If the link is not prefetchable, we still create an instance so we can 5373 // track its optimistic state (i.e. useLinkStatus). 5374 const instance = { 5375 router, 5376 fetchStrategy, 5377 isVisible: false, 5378 prefetchTask: null, 5379 prefetchHref: null, 5380 setOptimisticLinkStatus 5381 }; 5382 return instance; 5383} 5384function mountFormInstance(element, href, router, fetchStrategy) { 5385 const prefetchURL = coercePrefetchableUrl(href); 5386 if (prefetchURL === null) { 5387 // This href is not prefetchable, so we don't track it. 5388 // TODO: We currently observe/unobserve a form every time its href changes. 5389 // For Links, this isn't a big deal because the href doesn't usually change, 5390 // but for forms it's extremely common. We should optimize this. 5391 return; 5392 } 5393 const instance = { 5394 router, 5395 fetchStrategy, 5396 isVisible: false, 5397 prefetchTask: null, 5398 prefetchHref: prefetchURL.href, 5399 setOptimisticLinkStatus: null 5400 }; 5401 observeVisibility(element, instance); 5402} 5403function unmountPrefetchableInstance(element) { 5404 const instance = prefetchable.get(element); 5405 if (instance !== undefined) { 5406 prefetchable.delete(element); 5407 prefetchableAndVisible.delete(instance); 5408 const prefetchTask = instance.prefetchTask; 5409 if (prefetchTask !== null) { 5410 (0, _scheduler.cancelPrefetchTask)(prefetchTask); 5411 } 5412 } 5413 if (observer !== null) { 5414 observer.unobserve(element); 5415 } 5416} 5417function handleIntersect(entries) { 5418 for (const entry of entries){ 5419 // Some extremely old browsers or polyfills don't reliably support 5420 // isIntersecting so we check intersectionRatio instead. (Do we care? Not 5421 // really. But whatever this is fine.) 5422 const isVisible = entry.intersectionRatio > 0; 5423 onLinkVisibilityChanged(entry.target, isVisible); 5424 } 5425} 5426function onLinkVisibilityChanged(element, isVisible) { 5427 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 5428 ; 5429 const instance = prefetchable.get(element); 5430 if (instance === undefined) { 5431 return; 5432 } 5433 instance.isVisible = isVisible; 5434 if (isVisible) { 5435 prefetchableAndVisible.add(instance); 5436 } else { 5437 prefetchableAndVisible.delete(instance); 5438 } 5439 rescheduleLinkPrefetch(instance, _types.PrefetchPriority.Default); 5440} 5441function onNavigationIntent(element, unstable_upgradeToDynamicPrefetch) { 5442 const instance = prefetchable.get(element); 5443 if (instance === undefined) { 5444 return; 5445 } 5446 // Prefetch the link on hover/touchstart. 5447 if (instance !== undefined) { 5448 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 5449 ; 5450 rescheduleLinkPrefetch(instance, _types.PrefetchPriority.Intent); 5451 } 5452} 5453function rescheduleLinkPrefetch(instance, priority) { 5454 // Ensures that app-router-instance is not compiled in the server bundle 5455 if (typeof window !== 'undefined') { 5456 const existingPrefetchTask = instance.prefetchTask; 5457 if (!instance.isVisible) { 5458 // Cancel any in-progress prefetch task. (If it already finished then this 5459 // is a no-op.) 5460 if (existingPrefetchTask !== null) { 5461 (0, _scheduler.cancelPrefetchTask)(existingPrefetchTask); 5462 } 5463 // We don't need to reset the prefetchTask to null upon cancellation; an 5464 // old task object can be rescheduled with reschedulePrefetchTask. This is a 5465 // micro-optimization but also makes the code simpler (don't need to 5466 // worry about whether an old task object is stale). 5467 return; 5468 } 5469 const { getCurrentAppRouterState } = __turbopack_context__.r(699781); 5470 const appRouterState = getCurrentAppRouterState(); 5471 if (appRouterState !== null) { 5472 const treeAtTimeOfPrefetch = appRouterState.tree; 5473 if (existingPrefetchTask === null) { 5474 // Initiate a prefetch task. 5475 const nextUrl = appRouterState.nextUrl; 5476 const cacheKey = (0, _cachekey.createCacheKey)(instance.prefetchHref, nextUrl); 5477 instance.prefetchTask = (0, _scheduler.schedulePrefetchTask)(cacheKey, treeAtTimeOfPrefetch, instance.fetchStrategy, priority, null); 5478 } else { 5479 // We already have an old task object that we can reschedule. This is 5480 // effectively the same as canceling the old task and creating a new one. 5481 (0, _scheduler.reschedulePrefetchTask)(existingPrefetchTask, treeAtTimeOfPrefetch, instance.fetchStrategy, priority); 5482 } 5483 } 5484 } 5485} 5486function pingVisibleLinks(nextUrl, tree) { 5487 // For each currently visible link, cancel the existing prefetch task (if it 5488 // exists) and schedule a new one. This is effectively the same as if all the 5489 // visible links left and then re-entered the viewport. 5490 // 5491 // This is called when the Next-Url or the base tree changes, since those 5492 // may affect the result of a prefetch task. It's also called after a 5493 // cache invalidation. 5494 for (const instance of prefetchableAndVisible){ 5495 const task = instance.prefetchTask; 5496 if (task !== null && !(0, _scheduler.isPrefetchTaskDirty)(task, nextUrl, tree)) { 5497 continue; 5498 } 5499 // Something changed. Cancel the existing prefetch task and schedule a 5500 // new one. 5501 if (task !== null) { 5502 (0, _scheduler.cancelPrefetchTask)(task); 5503 } 5504 const cacheKey = (0, _cachekey.createCacheKey)(instance.prefetchHref, nextUrl); 5505 instance.prefetchTask = (0, _scheduler.schedulePrefetchTask)(cacheKey, tree, instance.fetchStrategy, _types.PrefetchPriority.Default, null); 5506 } 5507} 5508if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 5509 Object.defineProperty(exports.default, '__esModule', { 5510 value: true 5511 });
5512 Object.assign(exports.default, exports); 5513 module.exports = exports.default; 5514} 5515}), 5516179027, ((__turbopack_context__, module, exports) => { 5517"use strict"; 5518 5519Object.defineProperty(exports, "__esModule", { 5520 value: true 5521}); 55220 && (module.exports = { 5523 UnknownDynamicStaleTime: null, 5524 computeDynamicStaleAt: null, 5525 invalidateBfCache: null, 5526 readFromBFCache: null, 5527 readFromBFCacheDuringRegularNavigation: null, 5528 updateBFCacheEntryStaleAt: null, 5529 writeHeadToBFCache: null, 5530 writeToBFCache: null 5531}); 5532function _export(target, all) { 5533 for(var name in all)Object.defineProperty(target, name, { 5534 enumerable: true, 5535 get: all[name] 5536 }); 5537} 5538_export(exports, { 5539 UnknownDynamicStaleTime: function() { 5540 return UnknownDynamicStaleTime; 5541 }, 5542 computeDynamicStaleAt: function() { 5543 return computeDynamicStaleAt; 5544 }, 5545 invalidateBfCache: function() { 5546 return invalidateBfCache; 5547 }, 5548 readFromBFCache: function() { 5549 return readFromBFCache; 5550 }, 5551 readFromBFCacheDuringRegularNavigation: function() { 5552 return readFromBFCacheDuringRegularNavigation; 5553 }, 5554 updateBFCacheEntryStaleAt: function() { 5555 return updateBFCacheEntryStaleAt; 5556 }, 5557 writeHeadToBFCache: function() { 5558 return writeHeadToBFCache; 5559 }, 5560 writeToBFCache: function() { 5561 return writeToBFCache; 5562 } 5563}); 5564const _navigatereducer = __turbopack_context__.r(754069); 5565const _cachemap = __turbopack_context__.r(511); 5566const UnknownDynamicStaleTime = -1; 5567function computeDynamicStaleAt(now, dynamicStaleTimeSeconds) { 5568 return dynamicStaleTimeSeconds !== UnknownDynamicStaleTime ? now + dynamicStaleTimeSeconds * 1000 : now + _navigatereducer.DYNAMIC_STALETIME_MS; 5569} 5570const bfcacheMap = (0, _cachemap.createCacheMap)(); 5571let currentBfCacheVersion = 0;
5572function invalidateBfCache() { 5573 if (typeof window === 'undefined') { 5574 return; 5575 } 5576 currentBfCacheVersion++; 5577} 5578function writeToBFCache(now, varyPath, rsc, prefetchRsc, head, prefetchHead, dynamicStaleAt) { 5579 if (typeof window === 'undefined') { 5580 return; 5581 } 5582 const entry = { 5583 rsc, 5584 prefetchRsc, 5585 // TODO: These fields will be removed from both BFCacheEntry and 5586 // SegmentCacheEntry. The head has its own separate cache entry. 5587 head, 5588 prefetchHead, 5589 ref: null, 5590 // TODO: This is just a heuristic. Getting the actual size of the segment 5591 // isn't feasible because it's part of a larger streaming response. The 5592 // LRU will still evict it, we just won't have a fully accurate total 5593 // LRU size. However, we'll probably remove the size tracking from the LRU 5594 // entirely and use memory pressure events instead. 5595 size: 100, 5596 navigatedAt: now, 5597 // A back/forward navigation will disregard the stale time. This field is 5598 // only relevant when staleTimes.dynamic is enabled or unstable_dynamicStaleTime 5599 // is exported by a page. 5600 staleAt: dynamicStaleAt, 5601 version: currentBfCacheVersion 5602 }; 5603 const isRevalidation = false; 5604 (0, _cachemap.setInCacheMap)(bfcacheMap, varyPath, entry, isRevalidation); 5605} 5606function writeHeadToBFCache(now, varyPath, head, prefetchHead, dynamicStaleAt) { 5607 // Read the special "segment" that represents the head data. 5608 writeToBFCache(now, varyPath, head, prefetchHead, null, null, dynamicStaleAt); 5609} 5610function updateBFCacheEntryStaleAt(varyPath, newStaleAt) { 5611 if (typeof window === 'undefined') { 5612 return; 5613 } 5614 const isRevalidation = false; 5615 // Read with staleness bypass (-1) so we can update even stale entries 5616 const entry = (0, _cachemap.getFromCacheMap)(-1, currentBfCacheVersion, bfcacheMap, varyPath, isRevalidation); 5617 if (entry !== null) { 5618 entry.staleAt = newStaleAt; 5619 } 5620} 5621function readFromBFCache(varyPath) { 5622 if (typeof window === 'undefined') { 5623 return null; 5624 } 5625 const isRevalidation = false; 5626 return (0, _cachemap.getFromCacheMap)(// might be. Pass -1 instead of the actual current time to bypass 5627 // staleness checks. 5628 -1, currentBfCacheVersion, bfcacheMap, varyPath, isRevalidation); 5629} 5630function readFromBFCacheDuringRegularNavigation(now, varyPath) { 5631 if (typeof window === 'undefined') { 5632 return null; 5633 } 5634 const isRevalidation = false; 5635 return (0, _cachemap.getFromCacheMap)(now, currentBfCacheVersion, bfcacheMap, varyPath, isRevalidation); 5636} 5637if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 5638 Object.defineProperty(exports.default, '__esModule', { 5639 value: true 5640 }); 5641 Object.assign(exports.default, exports); 5642 module.exports = exports.default; 5643} 5644}), 5645496167, ((__turbopack_context__, module, exports) => { 5646"use strict"; 5647 5648/** 5649 * Optimistic Routing (Known Routes) 5650 * 5651 * This module enables the client to predict route structure for URLs that 5652 * haven't been prefetched yet, based on previously learned route patterns. 5653 * When successful, this allows skipping the route tree prefetch request 5654 * entirely. 5655 * 5656 * The core idea is that many URLs map to the same route structure. For example, 5657 * /blog/post-1 and /blog/post-2 both resolve to /blog/[slug]. Once we've 5658 * prefetched one, we can predict the structure of the other. 5659 * 5660 * However, we can't always make this prediction. Static siblings (like 5661 * /blog/featured alongside /blog/[slug]) have different route structures. 5662 * When we learn a dynamic route, we also learn its static siblings so we 5663 * know when NOT to apply the prediction. 5664 * 5665 * Main entry points: 5666 * 5667 * 1. discoverKnownRoute: Called after receiving a route tree from the server. 5668 * Traverses the route tree, compares URL parts to segments, and populates 5669 * the known route tree if they match. Routes are always inserted into the 5670 * cache. 5671 * 5672 * 2. matchKnownRoute: Called when looking up a route with no cache entry. 5673 * Matches the candidate URL against learned patterns. Returns a synthetic 5674 * cache entry if successful, or null to fall back to server resolution. 5675 * 5676 * Rewrite detection happens during traversal: if a URL path part doesn't match 5677 * the corresponding route segment, we stop populating the known route tree 5678 * (since the mapping is incorrect) but still insert the route into the cache. 5679 * 5680 * The known route tree is append-only with no eviction. Route patterns are 5681 * derived from the filesystem, so they don't become stale within a session. 5682 * Cache invalidation on deploy clears everything anyway. 5683 * 5684 * Current limitations (deopt to server resolution): 5685 * - Rewrites: Detected during traversal (tree not populated, but route cached) 5686 * - Intercepted routes: The route tree varies by referrer (Next-Url header), 5687 * so we can't predict the correct structure from the URL alone. Patterns are 5688 * still stored during discovery (so the trie stays populated for non- 5689 * intercepted siblings), but matching bails out when the pattern is marked 5690 * as interceptable. 5691 */ Object.defineProperty(exports, "__esModule", { 5692 value: true 5693}); 56940 && (module.exports = { 5695 discoverKnownRoute: null, 5696 matchKnownRoute: null, 5697 resetKnownRoutes: null 5698}); 5699function _export(target, all) { 5700 for(var name in all)Object.defineProperty(target, name, { 5701 enumerable: true, 5702 get: all[name] 5703 }); 5704} 5705_export(exports, { 5706 discoverKnownRoute: function() { 5707 return discoverKnownRoute; 5708 }, 5709 matchKnownRoute: function() { 5710 return matchKnownRoute; 5711 }, 5712 resetKnownRoutes: function() { 5713 return resetKnownRoutes; 5714 } 5715}); 5716const _cache = __turbopack_context__.r(620896); 5717const _routeparams = __turbopack_context__.r(33906); 5718const _varypath = __turbopack_context__.r(856655); 5719function createEmptyPart() { 5720 return { 5721 staticChildren: null, 5722 dynamicChild: null, 5723 dynamicChildParamName: null, 5724 dynamicChildParamType: null, 5725 pattern: null 5726 }; 5727} 5728// The root of the known route tree. 5729let knownRouteTreeRoot = createEmptyPart(); 5730function discoverKnownRoute(now, pathname, nextUrl, pendingEntry, routeTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite) { 5731 const tree = routeTree; 5732 const pathnameParts = pathname.split('/').filter((p)=>p !== ''); 5733 const firstPart = pathnameParts.length > 0 ? pathnameParts[0] : null; 5734 const remainingParts = pathnameParts.length > 0 ? pathnameParts.slice(1) : []; 5735 if (pendingEntry !== null) { 5736 // Fulfill the pending entry first 5737 const fulfilledEntry = (0, _cache.fulfillRouteCacheEntry)(now, pendingEntry, tree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching); 5738 if (hasDynamicRewrite) { 5739 fulfilledEntry.hasDynamicRewrite = true; 5740 } 5741 // Populate the known route tree (handles rewrite detection internally). 5742 // The entry is already in the cache; this just stores it as a pattern 5743 // if the URL matches the route structure. 5744 discoverKnownRoutePart(knownRouteTreeRoot, tree, firstPart, remainingParts, fulfilledEntry, now, pathname, nextUrl, tree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite); 5745 return fulfilledEntry; 5746 } 5747 // No pending entry - discoverKnownRoutePart will create one and insert it 5748 // into the cache, or return an existing pattern if one exists. 5749 return discoverKnownRoutePart(knownRouteTreeRoot, tree, firstPart, remainingParts, null, now, pathname, nextUrl, tree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite); 5750} 5751/** 5752 * Gets or creates the dynamic child node for a KnownRoutePart. 5753 * A node can have at most one dynamic child (you can't have both [slug] and 5754 * [id] at the same route level), so we either return existing or create new. 5755 */ function discoverDynamicChild(part, paramName, paramType) { 5756 if (part.dynamicChild !== null) { 5757 return part.dynamicChild; 5758 } 5759 const newChild = createEmptyPart(); 5760 // Type assertion needed because we're converting from "without" to "with" 5761 // dynamic child variant. 5762 const mutablePart = part;
5763 mutablePart.dynamicChild = newChild; 5764 mutablePart.dynamicChildParamName = paramName; 5765 mutablePart.dynamicChildParamType = paramType; 5766 return newChild; 5767} 5768/** 5769 * Recursive workhorse for discoverKnownRoute. 5770 * 5771 * Walks the route tree and URL parts in parallel, building out the known 5772 * route tree as it goes. At each step: 5773 * 1. Determines if the current segment appears in the URL (dynamic/static) 5774 * 2. Validates URL matches route structure (detects rewrites) 5775 * 3. Creates/updates the corresponding KnownRoutePart node 5776 * 4. Records static siblings for future matching 5777 * 5. Recurses into child slots (parallel routes) 5778 * 5779 * If a URL/route mismatch is detected (rewrite), we stop building the known 5780 * route tree but still cache the route entry for direct lookup. 5781 */ function discoverKnownRoutePart(parentKnownRoutePart, routeTree, urlPart, remainingParts, existingEntry, now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite) { 5782 const segment = routeTree.segment; 5783 let segmentAppearsInURL; 5784 let paramName = null; 5785 let paramType = null; 5786 let staticSiblings = null; 5787 if (typeof segment === 'string') { 5788 segmentAppearsInURL = (0, _routeparams.doesStaticSegmentAppearInURL)(segment); 5789 } else { 5790 // Dynamic segment tuple: [paramName, paramCacheKey, paramType, staticSiblings] 5791 paramName = segment[0]; 5792 paramType = segment[2]; 5793 staticSiblings = segment[3]; 5794 segmentAppearsInURL = true; 5795 } 5796 let knownRoutePart = parentKnownRoutePart; 5797 let nextUrlPart = urlPart; 5798 let nextRemainingParts = remainingParts; 5799 if (segmentAppearsInURL) { 5800 // Check for mismatch: if this is a static segment, the URL part must match 5801 if (paramName === null && urlPart !== segment) { 5802 // URL doesn't match route structure (likely a rewrite). 5803 // Don't populate the known route tree, just write the route into the 5804 // cache and return immediately. 5805 if (existingEntry !== null) { 5806 return existingEntry; 5807 } 5808 return (0, _cache.writeRouteIntoCache)(now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching); 5809 } 5810 // URL matches route structure. Build the known route tree. 5811 if (paramName !== null && paramType !== null) { 5812 // Dynamic segment 5813 knownRoutePart = discoverDynamicChild(parentKnownRoutePart, paramName, paramType); 5814 // Record static siblings as placeholder parts. 5815 // IMPORTANT: We use the null vs Map distinction to track whether 5816 // siblings are known at this level: 5817 // - staticChildren: null = siblings unknown (can't safely match dynamic) 5818 // - staticChildren: Map = siblings known (even if empty) 5819 // This matters in dev mode where webpack may not know all siblings yet. 5820 if (staticSiblings !== null) { 5821 // Siblings are known - ensure we have a Map (even if empty) 5822 if (parentKnownRoutePart.staticChildren === null) { 5823 parentKnownRoutePart.staticChildren = new Map(); 5824 } 5825 for (const sibling of staticSiblings){ 5826 if (!parentKnownRoutePart.staticChildren.has(sibling)) { 5827 parentKnownRoutePart.staticChildren.set(sibling, createEmptyPart()); 5828 } 5829 } 5830 } 5831 } else { 5832 // Static segment 5833 if (parentKnownRoutePart.staticChildren === null) { 5834 parentKnownRoutePart.staticChildren = new Map(); 5835 } 5836 let existingChild = parentKnownRoutePart.staticChildren.get(urlPart); 5837 if (existingChild === undefined) { 5838 existingChild = createEmptyPart(); 5839 parentKnownRoutePart.staticChildren.set(urlPart, existingChild); 5840 } 5841 knownRoutePart = existingChild; 5842 } 5843 // Advance to next URL part 5844 nextUrlPart = remainingParts.length > 0 ? remainingParts[0] : null; 5845 nextRemainingParts = remainingParts.length > 0 ? remainingParts.slice(1) : []; 5846 } 5847 // else: Transparent segment (route group, __PAGE__, etc.) 5848 // Stay at the same known route part, don't advance URL parts 5849 // Recurse into child routes. A route tree can have multiple parallel routes 5850 // (e.g., @modal alongside children). Each parallel route is a separate 5851 // branch, but they all share the same URL - we just need to traverse all 5852 // branches to build out the known route tree. 5853 const slots = routeTree.slots; 5854 let resultFromChildren = null; 5855 if (slots !== null) { 5856 for(const parallelRouteKey in slots){ 5857 const childRouteTree = slots[parallelRouteKey]; 5858 // Skip branches with refreshState set - these were reused from a 5859 // different route (e.g., a "default" parallel slot) and don't represent 5860 // the actual route structure for this URL. 5861 if (childRouteTree.refreshState !== null) { 5862 continue; 5863 } 5864 const result = discoverKnownRoutePart(knownRoutePart, childRouteTree, nextUrlPart, nextRemainingParts, existingEntry, now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite); 5865 // All parallel route branches share the same URL, so they should all 5866 // reach compatible leaf nodes. We capture any result. 5867 resultFromChildren = result; 5868 } 5869 if (resultFromChildren !== null) { 5870 return resultFromChildren; 5871 } 5872 // Defensive fallback: no children returned a result. This shouldn't happen 5873 // for valid route trees, but handle it gracefully. 5874 if (existingEntry !== null) { 5875 return existingEntry; 5876 } 5877 return (0, _cache.writeRouteIntoCache)(now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching); 5878 } 5879 // Reached a page node. Create/get the route cache entry and store as a 5880 // pattern. First, check if there's already a pattern for this route. 5881 if (knownRoutePart.pattern !== null) { 5882 // If this route has a dynamic rewrite, mark the existing pattern. 5883 if (hasDynamicRewrite) { 5884 knownRoutePart.pattern.hasDynamicRewrite = true; 5885 } 5886 return knownRoutePart.pattern; 5887 } 5888 // Get or create the entry 5889 let entry; 5890 if (existingEntry !== null) { 5891 // Already have a fulfilled entry, use it directly. It's already in the 5892 // route cache map. 5893 entry = existingEntry; 5894 } else { 5895 // Create the entry and insert it into the route cache map. 5896 entry = (0, _cache.writeRouteIntoCache)(now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching); 5897 } 5898 if (hasDynamicRewrite) { 5899 entry.hasDynamicRewrite = true; 5900 } 5901 // Store as pattern 5902 knownRoutePart.pattern = entry; 5903 return entry; 5904} 5905function matchKnownRoute(pathname, search) { 5906 const pathnameParts = pathname.split('/').filter((p)=>p !== ''); 5907 const resolvedParams = new Map(); 5908 const match = matchKnownRoutePart(knownRouteTreeRoot, pathnameParts, 0, resolvedParams); 5909 if (match === null) { 5910 return null; 5911 } 5912 const matchedPart = match.part; 5913 const pattern = match.pattern; 5914 // If the pattern could be intercepted, we can't safely use it for prediction. 5915 // Interception routes resolve to different route trees depending on the 5916 // referrer (the Next-Url header), which means the same URL can map to 5917 // different page components depending on where the navigation originated. 5918 // Since the known route tree only stores a single pattern per URL shape, we 5919 // can't distinguish between the intercepted and non-intercepted cases, so we 5920 // bail out to server resolution. 5921 // 5922 // TODO: We could store interception behavior in the known route tree itself 5923 // (e.g., which segments use interception markers and what they resolve to). 5924 // With enough information embedded in the trie, we could match interception 5925 // routes entirely on the client without a server round-trip. 5926 if (pattern.couldBeIntercepted) { 5927 return null; 5928 } 5929 // "Reify" the pattern: clone the template tree with concrete param values. 5930 // This substitutes resolved params (e.g., slug: "hello") into dynamic
5931 // segments and recomputes vary paths for correct segment cache keying. 5932 const acc = { 5933 metadataVaryPath: null 5934 }; 5935 const reifiedTree = reifyRouteTree(pattern.tree, resolvedParams, search, null, acc); 5936 // The metadata tree is a flat page node without the intermediate layout 5937 // structure. Clone it with the updated metadata vary path collected during 5938 // the main tree traversal. 5939 const metadataVaryPath = acc.metadataVaryPath; 5940 if (metadataVaryPath === null) { 5941 // This shouldn't be reachable for a valid route tree. 5942 return null; 5943 } 5944 const reifiedMetadata = (0, _cache.createMetadataRouteTree)(metadataVaryPath); 5945 // Create a synthetic (predicted) entry and store it as the new pattern. 5946 // 5947 // Why replace the pattern? We intentionally update the pattern with this 5948 // synthetic entry so that if our prediction was wrong (server returns a 5949 // different pathname due to dynamic rewrite), the entry gets marked with 5950 // hasDynamicRewrite. Future predictions for this route will see the flag 5951 // and bail out to server resolution instead of making the same mistake. 5952 const syntheticEntry = { 5953 canonicalUrl: pathname + search, 5954 status: _cache.EntryStatus.Fulfilled, 5955 blockedTasks: null, 5956 tree: reifiedTree, 5957 metadata: reifiedMetadata, 5958 couldBeIntercepted: pattern.couldBeIntercepted, 5959 supportsPerSegmentPrefetching: pattern.supportsPerSegmentPrefetching, 5960 hasDynamicRewrite: false, 5961 renderedSearch: search, 5962 ref: null, 5963 size: pattern.size, 5964 staleAt: pattern.staleAt, 5965 version: pattern.version 5966 }; 5967 matchedPart.pattern = syntheticEntry; 5968 return syntheticEntry; 5969} 5970/** 5971 * Recursively matches a URL against the known route tree. 5972 * 5973 * Matching priority (most specific first): 5974 * 1. Static children - exact path segment match 5975 * 2. Dynamic child - [param], [...param], [[...param]] 5976 * 3. Direct pattern - when no more URL parts remain 5977 * 5978 * Collects resolved param values in resolvedParams as it traverses. 5979 * Returns null if no match found (caller should fall back to server). 5980 */ function matchKnownRoutePart(part, pathnameParts, partIndex, resolvedParams) { 5981 const urlPart = partIndex < pathnameParts.length ? pathnameParts[partIndex] : null; 5982 // If staticChildren is null, we don't know what static routes exist at this 5983 // level. This happens in webpack dev mode where routes are compiled 5984 // on-demand. We can't safely match a dynamicChild because the URL part might 5985 // be a static sibling we haven't discovered yet. Example: We know 5986 // /blog/[slug] exists, but haven't compiled /blog/featured. A request for 5987 // /blog/featured would incorrectly match /blog/[slug]. 5988 if (part.staticChildren === null) { 5989 // The only safe match is a direct pattern when no URL parts remain. 5990 if (urlPart === null) { 5991 const pattern = part.pattern; 5992 if (pattern !== null && !pattern.hasDynamicRewrite) { 5993 return { 5994 part, 5995 pattern 5996 }; 5997 } 5998 } 5999 return null; 6000 } 6001 // Static children take priority over dynamic. This ensures /blog/featured 6002 // matches its own route rather than /blog/[slug]. 6003 if (urlPart !== null) { 6004 const staticChild = part.staticChildren.get(urlPart); 6005 if (staticChild !== undefined) { 6006 // Check if this is an "unknown" placeholder part. These are created when 6007 // we learn about static siblings (from the route tree's staticSiblings 6008 // field) but haven't prefetched them yet. We know the path exists but 6009 // don't know its structure, so we can't predict it. 6010 if (staticChild.pattern === null && staticChild.dynamicChild === null && staticChild.staticChildren === null) { 6011 // Bail out - server must resolve this route. 6012 return null; 6013 } 6014 const match = matchKnownRoutePart(staticChild, pathnameParts, partIndex + 1, resolvedParams); 6015 if (match !== null) { 6016 return match; 6017 } 6018 // Static child is a real node (not a placeholder) but its subtree 6019 // didn't match the remaining URL parts. This means the route exists 6020 // in the static subtree but hasn't been fully discovered yet. Do not 6021 // fall through to try the dynamic child — the static match is 6022 // authoritative. Bail out to server resolution. 6023 return null; 6024 } 6025 } 6026 // Try dynamic child 6027 if (part.dynamicChild !== null) { 6028 const dynamicPart = part.dynamicChild; 6029 const paramName = part.dynamicChildParamName; 6030 const paramType = part.dynamicChildParamType; 6031 const dynamicPattern = dynamicPart.pattern; 6032 switch(paramType){ 6033 case 'c': 6034 // Required catch-all [...param]: consumes 1+ URL parts 6035 if (dynamicPattern !== null && !dynamicPattern.hasDynamicRewrite && urlPart !== null) { 6036 resolvedParams.set(paramName, pathnameParts.slice(partIndex)); 6037 return { 6038 part: dynamicPart, 6039 pattern: dynamicPattern 6040 }; 6041 } 6042 break; 6043 case 'oc': 6044 // Optional catch-all [[...param]]: consumes 0+ URL parts 6045 if (dynamicPattern !== null && !dynamicPattern.hasDynamicRewrite) { 6046 if (urlPart !== null) { 6047 resolvedParams.set(paramName, pathnameParts.slice(partIndex)); 6048 return { 6049 part: dynamicPart, 6050 pattern: dynamicPattern 6051 }; 6052 } 6053 // urlPart is null - can match with zero parts, but a direct pattern 6054 // (e.g., page.tsx alongside [[...param]]) takes precedence. 6055 if (part.pattern === null || part.pattern.hasDynamicRewrite) { 6056 resolvedParams.set(paramName, []); 6057 return { 6058 part: dynamicPart, 6059 pattern: dynamicPattern 6060 }; 6061 } 6062 } 6063 break; 6064 case 'd': 6065 // Regular dynamic [param]: consumes exactly 1 URL part. 6066 // Unlike catch-all which terminates here, regular dynamic must 6067 // continue recursing to find the leaf pattern. 6068 if (urlPart !== null) { 6069 resolvedParams.set(paramName, urlPart); 6070 return matchKnownRoutePart(dynamicPart, pathnameParts, partIndex + 1, resolvedParams); 6071 } 6072 break; 6073 // Intercepted routes use relative path markers like (.), (..), (...) 6074 // Their behavior depends on navigation context (soft vs hard nav), 6075 // so we can't predict them client-side. Defer to server. 6076 case 'ci(..)(..)': 6077 case 'ci(.)': 6078 case 'ci(..)': 6079 case 'ci(...)': 6080 case 'di(..)(..)': 6081 case 'di(.)': 6082 case 'di(..)': 6083 case 'di(...)': 6084 return null; 6085 default: 6086 paramType; 6087 } 6088 } 6089 // No children matched. If we've consumed all URL parts, check for a direct 6090 // pattern at this node (the route terminates here). 6091 if (urlPart === null) { 6092 const pattern = part.pattern; 6093 if (pattern !== null && !pattern.hasDynamicRewrite) { 6094 return { 6095 part, 6096 pattern 6097 }; 6098 } 6099 } 6100 return null; 6101} 6102/** 6103 * "Reify" means to make concrete - we take an abstract pattern (the template 6104 * route tree) and produce a concrete instance with actual param values. 6105 * 6106 * This function clones a RouteTree, substituting dynamic segment values from 6107 * resolvedParams and computing new vary paths. The vary path encodes param 6108 * values so segment cache entries can be correctly keyed. 6109 * 6110 * Example: Pattern for /blog/[slug] with resolvedParams { slug: "hello" } 6111 * produces a tree where segment [slug] has cacheKey "hello". 6112 */ function reifyRouteTree(pattern, resolvedParams, search, parentPartialVaryPath, acc) { 6113 const originalSegment = pattern.segment; 6114 let newSegment = originalSegment; 6115 let partialVaryPath; 6116 if (typeof originalSegment !== 'string') { 6117 // Dynamic segment: compute new cache key and append to partial vary path 6118 const paramName = originalSegment[0]; 6119 const paramType = originalSegment[2]; 6120 const staticSiblings = originalSegment[3]; 6121 const newValue = resolvedParams.get(paramName); 6122 if (newValue !== undefined) { 6123 const newCacheKey = Array.isArray(newValue) ? newValue.join('/') : newValue; 6124 newSegment = [ 6125 paramName, 6126 newCacheKey, 6127 paramType, 6128 staticSiblings 6129 ]; 6130 partialVaryPath = (0, _varypath.appendLayoutVaryPath)(parentPartialVaryPath, newCacheKey, paramName); 6131 } else { 6132 // Param not found in resolvedParams - keep original and inherit partial 6133 // TODO: This should never happen. Bail out with null. 6134 partialVaryPath = parentPartialVaryPath; 6135 } 6136 } else { 6137 // Static segment: inherit partial vary path from parent 6138 partialVaryPath = parentPartialVaryPath; 6139 } 6140 // Recurse into children with the (possibly updated) partial vary path 6141 let newSlots = null; 6142 if (pattern.slots !== null) { 6143 newSlots = {}; 6144 for(const key in pattern.slots){ 6145 newSlots[key] = reifyRouteTree(pattern.slots[key], resolvedParams, search, partialVaryPath, acc); 6146 } 6147 } 6148 if (pattern.isPage) { 6149 // Page segment: finalize with search params 6150 const newVaryPath = (0, _varypath.finalizePageVaryPath)(pattern.requestKey, search, partialVaryPath); 6151 // Collect metadata vary path (first page wins, same as original algorithm) 6152 if (acc.metadataVaryPath === null) { 6153 acc.metadataVaryPath = (0, _varypath.finalizeMetadataVaryPath)(pattern.requestKey, search, partialVaryPath); 6154 } 6155 return { 6156 requestKey: pattern.requestKey, 6157 segment: newSegment, 6158 refreshState: pattern.refreshState, 6159 slots: newSlots, 6160 prefetchHints: pattern.prefetchHints, 6161 isPage: true, 6162 varyPath: newVaryPath 6163 }; 6164 } else { 6165 // Layout segment: finalize without search params 6166 const newVaryPath = (0, _varypath.finalizeLayoutVaryPath)(pattern.requestKey, partialVaryPath); 6167 return { 6168 requestKey: pattern.requestKey, 6169 segment: newSegment, 6170 refreshState: pattern.refreshState, 6171 slots: newSlots, 6172 prefetchHints: pattern.prefetchHints, 6173 isPage: false, 6174 varyPath: newVaryPath 6175 }; 6176 } 6177} 6178function resetKnownRoutes() { 6179 knownRouteTreeRoot = createEmptyPart(); 6180} 6181if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 6182 Object.defineProperty(exports.default, '__esModule', { 6183 value: true 6184 });
6185 Object.assign(exports.default, exports); 6186 module.exports = exports.default; 6187} 6188}), 6189620896, ((__turbopack_context__, module, exports) => { 6190"use strict"; 6191 6192var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 6193"use strict"; 6194Object.defineProperty(exports, "__esModule", { 6195 value: true 6196}); 61970 && (module.exports = { 6198 EntryStatus: null, 6199 attemptToFulfillDynamicSegmentFromBFCache: null, 6200 attemptToUpgradeSegmentFromBFCache: null, 6201 canNewFetchStrategyProvideMoreContent: null, 6202 convertReusedFlightRouterStateToRouteTree: null, 6203 convertRootFlightRouterStateToRouteTree: null, 6204 convertRouteTreeToFlightRouterState: null, 6205 createDetachedSegmentCacheEntry: null, 6206 createMetadataRouteTree: null, 6207 deprecated_requestOptimisticRouteCacheEntry: null, 6208 fetchInlinedSegmentsOnCacheMiss: null, 6209 fetchRouteOnCacheMiss: null, 6210 fetchSegmentOnCacheMiss: null, 6211 fetchSegmentPrefetchesUsingDynamicRequest: null, 6212 fulfillRouteCacheEntry: null, 6213 getCurrentRouteCacheVersion: null, 6214 getCurrentSegmentCacheVersion: null, 6215 getStaleAt: null, 6216 getStaleTimeMs: null, 6217 invalidateEntirePrefetchCache: null, 6218 invalidateRouteCacheEntries: null, 6219 invalidateSegmentCacheEntries: null, 6220 markRouteEntryAsDynamicRewrite: null, 6221 overwriteRevalidatingSegmentCacheEntry: null, 6222 pingInvalidationListeners: null, 6223 processRuntimePrefetchStream: null, 6224 readOrCreateRevalidatingSegmentEntry: null, 6225 readOrCreateRouteCacheEntry: null, 6226 readOrCreateSegmentCacheEntry: null, 6227 readRouteCacheEntry: null, 6228 readSegmentCacheEntry: null, 6229 stripIsPartialByte: null, 6230 upgradeToPendingSegment: null, 6231 upsertSegmentEntry: null, 6232 waitForSegmentCacheEntry: null, 6233 writeDynamicRenderResponseIntoCache: null, 6234 writeRouteIntoCache: null, 6235 writeStaticStageResponseIntoCache: null 6236}); 6237function _export(target, all) { 6238 for(var name in all)Object.defineProperty(target, name, { 6239 enumerable: true, 6240 get: all[name] 6241 }); 6242} 6243_export(exports, { 6244 EntryStatus: function() { 6245 return EntryStatus; 6246 }, 6247 attemptToFulfillDynamicSegmentFromBFCache: function() { 6248 return attemptToFulfillDynamicSegmentFromBFCache; 6249 }, 6250 attemptToUpgradeSegmentFromBFCache: function() { 6251 return attemptToUpgradeSegmentFromBFCache; 6252 }, 6253 canNewFetchStrategyProvideMoreContent: function() { 6254 return canNewFetchStrategyProvideMoreContent; 6255 }, 6256 convertReusedFlightRouterStateToRouteTree: function() { 6257 return convertReusedFlightRouterStateToRouteTree; 6258 }, 6259 convertRootFlightRouterStateToRouteTree: function() { 6260 return convertRootFlightRouterStateToRouteTree; 6261 }, 6262 convertRouteTreeToFlightRouterState: function() { 6263 return convertRouteTreeToFlightRouterState; 6264 }, 6265 createDetachedSegmentCacheEntry: function() { 6266 return createDetachedSegmentCacheEntry; 6267 }, 6268 createMetadataRouteTree: function() { 6269 return createMetadataRouteTree; 6270 }, 6271 deprecated_requestOptimisticRouteCacheEntry: function() { 6272 return deprecated_requestOptimisticRouteCacheEntry; 6273 }, 6274 fetchInlinedSegmentsOnCacheMiss: function() { 6275 return fetchInlinedSegmentsOnCacheMiss; 6276 }, 6277 fetchRouteOnCacheMiss: function() { 6278 return fetchRouteOnCacheMiss; 6279 }, 6280 fetchSegmentOnCacheMiss: function() { 6281 return fetchSegmentOnCacheMiss; 6282 }, 6283 fetchSegmentPrefetchesUsingDynamicRequest: function() { 6284 return fetchSegmentPrefetchesUsingDynamicRequest; 6285 }, 6286 fulfillRouteCacheEntry: function() { 6287 return fulfillRouteCacheEntry; 6288 }, 6289 getCurrentRouteCacheVersion: function() { 6290 return getCurrentRouteCacheVersion; 6291 }, 6292 getCurrentSegmentCacheVersion: function() { 6293 return getCurrentSegmentCacheVersion; 6294 }, 6295 getStaleAt: function() { 6296 return getStaleAt; 6297 }, 6298 getStaleTimeMs: function() { 6299 return getStaleTimeMs; 6300 }, 6301 invalidateEntirePrefetchCache: function() { 6302 return invalidateEntirePrefetchCache; 6303 }, 6304 invalidateRouteCacheEntries: function() { 6305 return invalidateRouteCacheEntries; 6306 }, 6307 invalidateSegmentCacheEntries: function() { 6308 return invalidateSegmentCacheEntries; 6309 }, 6310 markRouteEntryAsDynamicRewrite: function() { 6311 return markRouteEntryAsDynamicRewrite; 6312 }, 6313 overwriteRevalidatingSegmentCacheEntry: function() { 6314 return overwriteRevalidatingSegmentCacheEntry; 6315 }, 6316 pingInvalidationListeners: function() { 6317 return pingInvalidationListeners; 6318 }, 6319 processRuntimePrefetchStream: function() { 6320 return processRuntimePrefetchStream; 6321 }, 6322 readOrCreateRevalidatingSegmentEntry: function() { 6323 return readOrCreateRevalidatingSegmentEntry; 6324 }, 6325 readOrCreateRouteCacheEntry: function() { 6326 return readOrCreateRouteCacheEntry; 6327 }, 6328 readOrCreateSegmentCacheEntry: function() { 6329 return readOrCreateSegmentCacheEntry; 6330 }, 6331 readRouteCacheEntry: function() { 6332 return readRouteCacheEntry; 6333 }, 6334 readSegmentCacheEntry: function() { 6335 return readSegmentCacheEntry; 6336 }, 6337 stripIsPartialByte: function() { 6338 return stripIsPartialByte; 6339 }, 6340 upgradeToPendingSegment: function() { 6341 return upgradeToPendingSegment; 6342 }, 6343 upsertSegmentEntry: function() { 6344 return upsertSegmentEntry; 6345 }, 6346 waitForSegmentCacheEntry: function() { 6347 return waitForSegmentCacheEntry; 6348 }, 6349 writeDynamicRenderResponseIntoCache: function() { 6350 return writeDynamicRenderResponseIntoCache; 6351 }, 6352 writeRouteIntoCache: function() { 6353 return writeRouteIntoCache; 6354 }, 6355 writeStaticStageResponseIntoCache: function() { 6356 return writeStaticStageResponseIntoCache; 6357 } 6358}); 6359const _varyparamsdecoding = __turbopack_context__.r(606372); 6360const _approuterheaders = __turbopack_context__.r(621768); 6361const _fetchserverresponse = __turbopack_context__.r(787288); 6362const _scheduler = __turbopack_context__.r(777709); 6363const _varypath = __turbopack_context__.r(856655); 6364const _createhreffromurl = __turbopack_context__.r(451191); 6365const _cachekey = __turbopack_context__.r(477048); 6366const _routeparams = __turbopack_context__.r(33906); 6367const _cachemap = __turbopack_context__.r(511); 6368const _segmentvalueencoding = __turbopack_context__.r(767764); 6369const _flightdatahelpers = __turbopack_context__.r(450590); 6370const _navigatereducer = __turbopack_context__.r(754069); 6371const _links = __turbopack_context__.r(769688); 6372const _segment = __turbopack_context__.r(813258); 6373const _types = __turbopack_context__.r(509396); 6374const _promisewithresolvers = __turbopack_context__.r(839470); 6375const _bfcache = __turbopack_context__.r(179027); 6376const _optimisticroutes = __turbopack_context__.r(496167);
6377const _navigation = __turbopack_context__.r(760355); 6378const _navigationbuildid = __turbopack_context__.r(732992); 6379const _constants = __turbopack_context__.r(663416); 6380function getStaleTimeMs(staleTimeSeconds) { 6381 return Math.max(staleTimeSeconds, 30) * 1000; 6382} 6383var EntryStatus = /*#__PURE__*/ function(EntryStatus) { 6384 EntryStatus[EntryStatus["Empty"] = 0] = "Empty"; 6385 EntryStatus[EntryStatus["Pending"] = 1] = "Pending"; 6386 EntryStatus[EntryStatus["Fulfilled"] = 2] = "Fulfilled"; 6387 EntryStatus[EntryStatus["Rejected"] = 3] = "Rejected"; 6388 return EntryStatus; 6389}({}); 6390const isOutputExportMode = ("TURBOPACK compile-time value", "production") === 'production' && ("TURBOPACK compile-time value", "standalone") === 'export'; 6391const MetadataOnlyRequestTree = [ 6392 '', 6393 {}, 6394 null, 6395 'metadata-only' 6396]; 6397let routeCacheMap = (0, _cachemap.createCacheMap)(); 6398let segmentCacheMap = (0, _cachemap.createCacheMap)(); 6399// All invalidation listeners for the whole cache are tracked in single set. 6400// Since we don't yet support tag or path-based invalidation, there's no point 6401// tracking them any more granularly than this. Once we add granular 6402// invalidation, that may change, though generally the model is to just notify 6403// the listeners and allow the caller to poll the prefetch cache with a new 6404// prefetch task if desired. 6405let invalidationListeners = null; 6406// Incrementing counters used to track cache invalidations. Route and segment 6407// caches have separate versions so they can be invalidated independently. 6408// Invalidation does not eagerly evict anything from the cache; entries are 6409// lazily evicted when read. 6410let currentRouteCacheVersion = 0; 6411let currentSegmentCacheVersion = 0; 6412function getCurrentRouteCacheVersion() { 6413 return currentRouteCacheVersion; 6414} 6415function getCurrentSegmentCacheVersion() { 6416 return currentSegmentCacheVersion; 6417}
6418function invalidateEntirePrefetchCache(nextUrl, tree) { 6419 currentRouteCacheVersion++; 6420 currentSegmentCacheVersion++; 6421 (0, _links.pingVisibleLinks)(nextUrl, tree); 6422 pingInvalidationListeners(nextUrl, tree); 6423} 6424function invalidateRouteCacheEntries(nextUrl, tree) { 6425 currentRouteCacheVersion++; 6426 (0, _links.pingVisibleLinks)(nextUrl, tree); 6427 pingInvalidationListeners(nextUrl, tree); 6428} 6429function invalidateSegmentCacheEntries(nextUrl, tree) { 6430 currentSegmentCacheVersion++; 6431 (0, _links.pingVisibleLinks)(nextUrl, tree); 6432 pingInvalidationListeners(nextUrl, tree); 6433} 6434function attachInvalidationListener(task) { 6435 // This function is called whenever a prefetch task reads a cache entry. If 6436 // the task has an onInvalidate function associated with it — i.e. the one 6437 // optionally passed to router.prefetch(onInvalidate) — then we attach that 6438 // listener to the every cache entry that the task reads. Then, if an entry 6439 // is invalidated, we call the function. 6440 if (task.onInvalidate !== null) { 6441 if (invalidationListeners === null) { 6442 invalidationListeners = new Set([ 6443 task 6444 ]); 6445 } else { 6446 invalidationListeners.add(task); 6447 } 6448 } 6449} 6450function notifyInvalidationListener(task) { 6451 const onInvalidate = task.onInvalidate; 6452 if (onInvalidate !== null) { 6453 // Clear the callback from the task object to guarantee it's not called more 6454 // than once. 6455 task.onInvalidate = null; 6456 // This is a user-space function, so we must wrap in try/catch. 6457 try { 6458 onInvalidate(); 6459 } catch (error) { 6460 if (typeof reportError === 'function') { 6461 reportError(error); 6462 } else { 6463 console.error(error); 6464 } 6465 } 6466 } 6467} 6468function pingInvalidationListeners(nextUrl, tree) { 6469 // The rough equivalent of pingVisibleLinks, but for onInvalidate callbacks. 6470 // This is called when the Next-Url or the base tree changes, since those 6471 // may affect the result of a prefetch task. It's also called after a 6472 // cache invalidation. 6473 if (invalidationListeners !== null) { 6474 const tasks = invalidationListeners; 6475 invalidationListeners = null; 6476 for (const task of tasks){ 6477 if ((0, _scheduler.isPrefetchTaskDirty)(task, nextUrl, tree)) { 6478 notifyInvalidationListener(task); 6479 } 6480 } 6481 } 6482} 6483function readRouteCacheEntry(now, key) {
6484 const varyPath = (0, _varypath.getRouteVaryPath)(key.pathname, key.search, key.nextUrl); 6485 const isRevalidation = false; 6486 const existingEntry = (0, _cachemap.getFromCacheMap)(now, getCurrentRouteCacheVersion(), routeCacheMap, varyPath, isRevalidation); 6487 if (existingEntry !== null) { 6488 return existingEntry; 6489 } 6490 // No cache hit. Attempt to construct from template using the new 6491 // optimistic routing mechanism (pattern-based matching). 6492 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 6493 ; 6494 return null; 6495} 6496function readSegmentCacheEntry(now, varyPath) { 6497 const isRevalidation = false; 6498 return (0, _cachemap.getFromCacheMap)(now, getCurrentSegmentCacheVersion(), segmentCacheMap, varyPath, isRevalidation); 6499} 6500function readRevalidatingSegmentCacheEntry(now, varyPath) { 6501 const isRevalidation = true; 6502 return (0, _cachemap.getFromCacheMap)(now, getCurrentSegmentCacheVersion(), segmentCacheMap, varyPath, isRevalidation); 6503} 6504function waitForSegmentCacheEntry(pendingEntry) { 6505 // Because the entry is pending, there's already a in-progress request. 6506 // Attach a promise to the entry that will resolve when the server responds. 6507 let promiseWithResolvers = pendingEntry.promise; 6508 if (promiseWithResolvers === null) { 6509 promiseWithResolvers = pendingEntry.promise = (0, _promisewithresolvers.createPromiseWithResolvers)(); 6510 } else { 6511 // There's already a promise we can use 6512 } 6513 return promiseWithResolvers.promise; 6514} 6515function createDetachedRouteCacheEntry() { 6516 return { 6517 canonicalUrl: null, 6518 status: 0, 6519 blockedTasks: null, 6520 tree: null, 6521 metadata: null, 6522 // This is initialized to true because we don't know yet whether the route 6523 // could be intercepted. It's only set to false once we receive a response 6524 // from the server. 6525 couldBeIntercepted: true, 6526 // Similarly, we don't yet know if the route supports PPR. 6527 supportsPerSegmentPrefetching: false, 6528 renderedSearch: null, 6529 // Map-related fields 6530 ref: null, 6531 size: 0, 6532 // Since this is an empty entry, there's no reason to ever evict it. It will 6533 // be updated when the data is populated. 6534 staleAt: Infinity, 6535 version: getCurrentRouteCacheVersion() 6536 }; 6537} 6538function readOrCreateRouteCacheEntry(now, task, key) { 6539 attachInvalidationListener(task); 6540 const existingEntry = readRouteCacheEntry(now, key); 6541 if (existingEntry !== null) { 6542 return existingEntry; 6543 } 6544 // Create a pending entry and add it to the cache. 6545 const pendingEntry = createDetachedRouteCacheEntry();
6546 const varyPath = (0, _varypath.getRouteVaryPath)(key.pathname, key.search, key.nextUrl); 6547 const isRevalidation = false; 6548 (0, _cachemap.setInCacheMap)(routeCacheMap, varyPath, pendingEntry, isRevalidation); 6549 return pendingEntry; 6550} 6551function deprecated_requestOptimisticRouteCacheEntry(now, requestedUrl, nextUrl) { 6552 // This function is called during a navigation when there was no matching 6553 // route tree in the prefetch cache. Before de-opting to a blocking, 6554 // unprefetched navigation, we will first attempt to construct an "optimistic" 6555 // route tree by checking the cache for similar routes. 6556 // 6557 // Check if there's a route with the same pathname, but with different 6558 // search params. We can then base our optimistic route tree on this entry. 6559 // 6560 // Conceptually, we are simulating what would happen if we did perform a 6561 // prefetch the requested URL, under the assumption that the server will 6562 // not redirect or rewrite the request in a different manner than the 6563 // base route tree. This assumption might not hold, in which case we'll have 6564 // to recover when we perform the dynamic navigation request. However, this 6565 // is what would happen if a route were dynamically rewritten/redirected 6566 // in between the prefetch and the navigation. So the logic needs to exist 6567 // to handle this case regardless. 6568 // Look for a route with the same pathname, but with an empty search string. 6569 // TODO: There's nothing inherently special about the empty search string; 6570 // it's chosen somewhat arbitrarily, with the rationale that it's the most 6571 // likely one to exist. But we should update this to match _any_ search 6572 // string. The plan is to generalize this logic alongside other improvements 6573 // related to "fallback" cache entries. 6574 const requestedSearch = requestedUrl.search; 6575 if (requestedSearch === '') { 6576 // The caller would have already checked if a route with an empty search 6577 // string is in the cache. So we can bail out here. 6578 return null; 6579 } 6580 const urlWithoutSearchParams = new URL(requestedUrl); 6581 urlWithoutSearchParams.search = ''; 6582 const routeWithNoSearchParams = readRouteCacheEntry(now, (0, _cachekey.createCacheKey)(urlWithoutSearchParams.href, nextUrl)); 6583 if (routeWithNoSearchParams === null || routeWithNoSearchParams.status !== 2) { 6584 // Bail out of constructing an optimistic route tree. This will result in 6585 // a blocking, unprefetched navigation. 6586 return null; 6587 } 6588 // Now we have a base route tree we can "patch" with our optimistic values. 6589 // Optimistically assume that redirects for the requested pathname do 6590 // not vary on the search string. Therefore, if the base route was 6591 // redirected to a different search string, then the optimistic route 6592 // should be redirected to the same search string. Otherwise, we use 6593 // the requested search string. 6594 const canonicalUrlForRouteWithNoSearchParams = new URL(routeWithNoSearchParams.canonicalUrl, requestedUrl.origin); 6595 const optimisticCanonicalSearch = canonicalUrlForRouteWithNoSearchParams.search !== '' ? canonicalUrlForRouteWithNoSearchParams.search : requestedSearch; 6596 // Similarly, optimistically assume that rewrites for the requested 6597 // pathname do not vary on the search string. Therefore, if the base 6598 // route was rewritten to a different search string, then the optimistic 6599 // route should be rewritten to the same search string. Otherwise, we use 6600 // the requested search string. 6601 const optimisticRenderedSearch = routeWithNoSearchParams.renderedSearch !== '' ? routeWithNoSearchParams.renderedSearch : requestedSearch; 6602 const optimisticUrl = new URL(routeWithNoSearchParams.canonicalUrl, location.origin); 6603 optimisticUrl.search = optimisticCanonicalSearch; 6604 const optimisticCanonicalUrl = (0, _createhreffromurl.createHrefFromUrl)(optimisticUrl); 6605 const optimisticRouteTree = deprecated_createOptimisticRouteTree(routeWithNoSearchParams.tree, optimisticRenderedSearch); 6606 const optimisticMetadataTree = deprecated_createOptimisticRouteTree(routeWithNoSearchParams.metadata, optimisticRenderedSearch); 6607 // Clone the base route tree, and override the relevant fields with our 6608 // optimistic values. 6609 const optimisticEntry = { 6610 canonicalUrl: optimisticCanonicalUrl, 6611 status: 2, 6612 // This isn't cloned because it's instance-specific 6613 blockedTasks: null, 6614 tree: optimisticRouteTree, 6615 metadata: optimisticMetadataTree, 6616 couldBeIntercepted: routeWithNoSearchParams.couldBeIntercepted, 6617 supportsPerSegmentPrefetching: routeWithNoSearchParams.supportsPerSegmentPrefetching, 6618 hasDynamicRewrite: routeWithNoSearchParams.hasDynamicRewrite, 6619 // Override the rendered search with the optimistic value. 6620 renderedSearch: optimisticRenderedSearch, 6621 // Map-related fields 6622 ref: null, 6623 size: 0, 6624 staleAt: routeWithNoSearchParams.staleAt, 6625 version: routeWithNoSearchParams.version 6626 };
6627 // Do not insert this entry into the cache. It only exists so we can 6628 // perform the current navigation. Just return it to the caller. 6629 return optimisticEntry; 6630} 6631function deprecated_createOptimisticRouteTree(tree, newRenderedSearch) { 6632 // Create a new route tree that identical to the original one except for 6633 // the rendered search string, which is contained in the vary path. 6634 let clonedSlots = null; 6635 const originalSlots = tree.slots; 6636 if (originalSlots !== null) { 6637 clonedSlots = {}; 6638 for(const parallelRouteKey in originalSlots){ 6639 const childTree = originalSlots[parallelRouteKey]; 6640 clonedSlots[parallelRouteKey] = deprecated_createOptimisticRouteTree(childTree, newRenderedSearch); 6641 } 6642 } 6643 // We only need to clone the vary path if the route is a page. 6644 if (tree.isPage) { 6645 return { 6646 requestKey: tree.requestKey, 6647 segment: tree.segment, 6648 refreshState: tree.refreshState, 6649 varyPath: (0, _varypath.clonePageVaryPathWithNewSearchParams)(tree.varyPath, newRenderedSearch), 6650 isPage: true, 6651 slots: clonedSlots, 6652 prefetchHints: tree.prefetchHints 6653 }; 6654 } 6655 return { 6656 requestKey: tree.requestKey, 6657 segment: tree.segment, 6658 refreshState: tree.refreshState, 6659 varyPath: tree.varyPath, 6660 isPage: false, 6661 slots: clonedSlots, 6662 prefetchHints: tree.prefetchHints 6663 }; 6664} 6665function readOrCreateSegmentCacheEntry(now, fetchStrategy, tree) { 6666 const existingEntry = readSegmentCacheEntry(now, tree.varyPath); 6667 if (existingEntry !== null) { 6668 return existingEntry; 6669 } 6670 // Create a pending entry and add it to the cache. The stale time is set to a 6671 // default value; the actual stale time will be set when the entry is 6672 // fulfilled with data from the server response. 6673 const varyPathForRequest = (0, _varypath.getSegmentVaryPathForRequest)(fetchStrategy, tree); 6674 const pendingEntry = createDetachedSegmentCacheEntry(now); 6675 const isRevalidation = false; 6676 (0, _cachemap.setInCacheMap)(segmentCacheMap, varyPathForRequest, pendingEntry, isRevalidation); 6677 return pendingEntry; 6678} 6679function readOrCreateRevalidatingSegmentEntry(now, fetchStrategy, tree) { 6680 // This function is called when we've already confirmed that a particular 6681 // segment is cached, but we want to perform another request anyway in case it 6682 // returns more complete and/or fresher data than we already have. The logic 6683 // for deciding whether to replace the existing entry is handled elsewhere; 6684 // this function just handles retrieving a cache entry that we can use to 6685 // track the revalidation. 6686 // 6687 // The reason revalidations are stored in the cache is because we need to be 6688 // able to dedupe multiple revalidation requests. The reason they have to be 6689 // handled specially is because we shouldn't overwrite a "normal" entry if 6690 // one exists at the same keypath. So, for each internal cache location, there 6691 // is a special "revalidation" slot that is used solely for this purpose. 6692 // 6693 // You can think of it as if all the revalidation entries were stored in a 6694 // separate cache map from the canonical entries, and then transfered to the 6695 // canonical cache map once the request is complete — this isn't how it's 6696 // actually implemented, since it's more efficient to store them in the same 6697 // data structure as the normal entries, but that's how it's modeled 6698 // conceptually. 6699 // TODO: Once we implement Fallback behavior for params, where an entry is 6700 // re-keyed based on response information, we'll need to account for the 6701 // possibility that the keypath of the previous entry is more generic than 6702 // the keypath of the revalidating entry. In other words, the server could 6703 // return a less generic entry upon revalidation. For now, though, this isn't 6704 // a concern because the keypath is based solely on the prefetch strategy, 6705 // not on data contained in the response. 6706 const existingEntry = readRevalidatingSegmentCacheEntry(now, tree.varyPath); 6707 if (existingEntry !== null) { 6708 return existingEntry; 6709 } 6710 // Create a pending entry and add it to the cache. The stale time is set to a 6711 // default value; the actual stale time will be set when the entry is 6712 // fulfilled with data from the server response. 6713 const varyPathForRequest = (0, _varypath.getSegmentVaryPathForRequest)(fetchStrategy, tree); 6714 const pendingEntry = createDetachedSegmentCacheEntry(now); 6715 const isRevalidation = true; 6716 (0, _cachemap.setInCacheMap)(segmentCacheMap, varyPathForRequest, pendingEntry, isRevalidation); 6717 return pendingEntry; 6718} 6719function overwriteRevalidatingSegmentCacheEntry(now, fetchStrategy, tree) { 6720 // This function is called when we've already decided to replace an existing 6721 // revalidation entry. Create a new entry and write it into the cache, 6722 // overwriting the previous value. The stale time is set to a default value; 6723 // the actual stale time will be set when the entry is fulfilled with data 6724 // from the server response. 6725 const varyPathForRequest = (0, _varypath.getSegmentVaryPathForRequest)(fetchStrategy, tree); 6726 const pendingEntry = createDetachedSegmentCacheEntry(now); 6727 const isRevalidation = true; 6728 (0, _cachemap.setInCacheMap)(segmentCacheMap, varyPathForRequest, pendingEntry, isRevalidation); 6729 return pendingEntry; 6730} 6731function upsertSegmentEntry(now, varyPath, candidateEntry) { 6732 // We have a new entry that has not yet been inserted into the cache. Before 6733 // we do so, we need to confirm whether it takes precedence over the existing 6734 // entry (if one exists). 6735 // TODO: We should not upsert an entry if its key was invali
6735dated in the time 6736 // since the request was made. We can do that by passing the "owner" entry to 6737 // this function and confirming it's the same as `existingEntry`. 6738 if ((0, _cachemap.isValueExpired)(now, getCurrentSegmentCacheVersion(), candidateEntry)) { 6739 // The entry is expired. We cannot upsert it. 6740 return null; 6741 } 6742 const existingEntry = readSegmentCacheEntry(now, varyPath); 6743 if (existingEntry !== null) { 6744 // Don't replace a more specific segment with a less-specific one. A case where this 6745 // might happen is if the existing segment was fetched via 6746 // `<Link prefetch={true}>`. 6747 if (// than the segment we already have in the cache, so it can't have more content. 6748 candidateEntry.fetchStrategy !== existingEntry.fetchStrategy && !canNewFetchStrategyProvideMoreContent(existingEntry.fetchStrategy, candidateEntry.fetchStrategy) || // The existing entry isn't partial, but the new one is. 6749 // (TODO: can this be true if `candidateEntry.fetchStrategy >= existingEntry.fetchStrategy`?) 6750 !existingEntry.isPartial && candidateEntry.isPartial) { 6751 // We're going to leave revalidating entry in the cache so that it doesn't 6752 // get revalidated again unnecessarily. Downgrade the Fulfilled entry to 6753 // Rejected and null out the data so it can be garbage collected. We leave 6754 // `staleAt` intact to prevent subsequent revalidation attempts only until 6755 // the entry expires. 6756 const rejectedEntry = candidateEntry; 6757 rejectedEntry.status = 3; 6758 rejectedEntry.rsc = null; 6759 return null; 6760 } 6761 // Evict the existing entry from the cache. 6762 (0, _cachemap.deleteFromCacheMap)(existingEntry); 6763 } 6764 const isRevalidation = false; 6765 (0, _cachemap.setInCacheMap)(segmentCacheMap, varyPath, candidateEntry, isRevalidation); 6766 return candidateEntry; 6767} 6768function createDetachedSegmentCacheEntry(now) { 6769 // Default stale time for pending segment cache entries. The actual stale time 6770 // is set when the entry is fulfilled with data from the server response. 6771 const staleAt = now + 30 * 1000; 6772 const emptyEntry = { 6773 status: 0, 6774 // Default to assuming the fetch strategy will be PPR. This will be updated 6775 // when a fetch is actually initiated. 6776 fetchStrategy: _types.FetchStrategy.PPR, 6777 rsc: null, 6778 isPartial: true, 6779 promise: null, 6780 // Map-related fields 6781 ref: null, 6782 size: 0, 6783 staleAt, 6784 version: 0 6785 }; 6786 return emptyEntry; 6787} 6788function upgradeToPendingSegment(emptyEntry, fetchStrategy) { 6789 const pendingEntry = emptyEntry; 6790 pendingEntry.status = 1; 6791 pendingEntry.fetchStrategy = fetchStrategy; 6792 if (fetchStrategy === _types.FetchStrategy.Full) { 6793 // We can assume the response will contain the full segment data. Set this 6794 // to false so we know it's OK to omit this segment from any navigation 6795 // requests that may happen while the data is still pending. 6796 pendingEntry.isPartial = false; 6797 } 6798 // Set the version here, since this is right before the request is initiated. 6799 // The next time the segment cache version is incremented, the entry will 6800 // effectively be evicted. This happens before initiating the request, rather 6801 // than when receiving the response, because it's guaranteed to happen 6802 // before the data is read on the server. 6803 pendingEntry.version = getCurrentSegmentCacheVersion(); 6804 return pendingEntry; 6805} 6806function attemptToFulfillDynamicSegmentFromBFCache(now, segment, tree) { 6807 // Attempts to fulfill an empty segment cache entry using data from the 6808 // bfcache. This is only valid during a Full prefetch (i.e. one that includes 6809 // dynamic data), because the bfcache stores data from navigations which 6810 // always include dynamic data. 6811 // We always use the canonical vary path when checking the bfcache. This is 6812 // the same operation we'd use to access the cache during a 6813 // regular navigation. 6814 const varyPath = tree.varyPath; 6815 // Read from the BFCache without expiring it (pass -1). We check freshness 6816 // ourselves using navigatedAt, because the BFCache's staleAt may have been 6817 // overridden by a per-page unstable_dynamicStaleTime and can't be used to 6818 // derive the original request time. 6819 const bfcacheEntry = (0, _bfcache.readFromBFCache)(varyPath); 6820 if (bfcacheEntry !== null) { 6821 // The stale time for dynamic prefetches (default: 5 mins) is different 6822 // from the stale time for regular navigations (default: 0 secs). Use 6823 // navigatedAt to compute the correct expiry for prefetch purposes. 6824 const dynamicPrefetchStaleAt = bfcacheEntry.navigatedAt + _navigatereducer.STATIC_STALETIME_MS; 6825 if (now > dynamicPrefetchStaleAt) { 6826 return null; 6827 } 6828 const pendingSegment = upgradeToPendingSegment(segment, _types.FetchStrategy.Full); 6829 const isPartial = false;
6830 return fulfillSegmentCacheEntry(pendingSegment, bfcacheEntry.rsc, dynamicPrefetchStaleAt, isPartial); 6831 } 6832 return null; 6833} 6834function attemptToUpgradeSegmentFromBFCache(now, tree) { 6835 const varyPath = tree.varyPath; 6836 const bfcacheEntry = (0, _bfcache.readFromBFCache)(varyPath); 6837 if (bfcacheEntry !== null) { 6838 const dynamicPrefetchStaleAt = bfcacheEntry.navigatedAt + _navigatereducer.STATIC_STALETIME_MS; 6839 if (now > dynamicPrefetchStaleAt) { 6840 return null; 6841 } 6842 const pendingSegment = upgradeToPendingSegment(createDetachedSegmentCacheEntry(now), _types.FetchStrategy.Full); 6843 const isPartial = false; 6844 const newEntry = fulfillSegmentCacheEntry(pendingSegment, bfcacheEntry.rsc, dynamicPrefetchStaleAt, isPartial); 6845 const segmentVaryPath = (0, _varypath.getSegmentVaryPathForRequest)(_types.FetchStrategy.Full, tree); 6846 const upserted = upsertSegmentEntry(now, segmentVaryPath, newEntry); 6847 if (upserted !== null && upserted.status === 2) { 6848 return upserted; 6849 } 6850 } 6851 return null; 6852} 6853function pingBlockedTasks(entry) { 6854 const blockedTasks = entry.blockedTasks; 6855 if (blockedTasks !== null) { 6856 for (const task of blockedTasks){ 6857 (0, _scheduler.pingPrefetchTask)(task); 6858 } 6859 entry.blockedTasks = null; 6860 } 6861} 6862function createMetadataRouteTree(metadataVaryPath) { 6863 // The Head is not actually part of the route tree, but other than that, it's 6864 // fetched and cached like a segment. Some functions expect a RouteTree 6865 // object, so rather than fork the logic in all those places, we use this 6866 // "fake" one. 6867 const metadata = { 6868 requestKey: _segmentvalueencoding.HEAD_REQUEST_KEY, 6869 segment: _segmentvalueencoding.HEAD_REQUEST_KEY, 6870 refreshState: null, 6871 varyPath: metadataVaryPath, 6872 // The metadata isn't really a "page" (though it isn't really a "segment" 6873 // either) but for the purposes of how this field is used, it behaves like 6874 // one. If this logic ever gets more complex we can change this to an enum. 6875 isPage: true, 6876 slots: null, 6877 prefetchHints: 0 6878 }; 6879 return metadata; 6880} 6881function fulfillRouteCacheEntry(now, entry, tree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching) { 6882 var _ref; 6883 // Get the rendered search from the vary path 6884 const renderedSearch = (_ref = (0, _varypath.getRenderedSearchFromVaryPath)(metadataVaryPath)) !== null && _ref !== void 0 ? _ref : ''; 6885 const fulfilledEntry = entry; 6886 fulfilledEntry.status = 2; 6887 fulfilledEntry.tree = tree; 6888 fulfilledEntry.metadata = createMetadataRouteTree(metadataVaryPath); 6889 // Route structure is essentially static — it only changes on deploy. 6890 // Always use the static stale time. 6891 // NOTE: An exception is rewrites/redirects in middleware or proxy, which can 6892 // change routes dynamically. We have other strategies for handling those. 6893 fulfilledEntry.staleAt = now + _navigatereducer.STATIC_STALETIME_MS; 6894 fulfilledEntry.couldBeIntercepted = couldBeIntercepted; 6895 fulfilledEntry.canonicalUrl = canonicalUrl; 6896 fulfilledEntry.renderedSearch = renderedSearch; 6897 fulfilledEntry.supportsPerSegmentPrefetching = supportsPerSegmentPrefetching; 6898 fulfilledEntry.hasDynamicRewrite = false; 6899 pingBlockedTasks(entry); 6900 return fulfilledEntry; 6901} 6902function writeRouteIntoCache(now, pathname, nextUrl, tree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching) { 6903 const pendingEntry = createDetachedRouteCacheEntry(); 6904 const fulfilledEntry = fulfillRouteCacheEntry(now, pendingEntry, tree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching); 6905 const renderedSearch = fulfilledEntry.renderedSearch; 6906 const varyPath = (0, _varypath.getFulfilledRouteVaryPath)(pathname, renderedSearch, nextUrl, couldBeIntercepted); 6907 const isRevalidation = false; 6908 (0, _cachemap.setInCacheMap)(routeCacheMap, varyPath, fulfilledEntry, isRevalidation); 6909 return fulfilledEntry; 6910} 6911function markRouteEntryAsDynamicRewrite(entry) { 6912 entry.hasDynamicRewrite = true; 6913// Note: The caller is responsible for also calling invalidateRouteCacheEntries
6914// to invalidate other entries that may have been derived from this template 6915// before we knew it had a dynamic rewrite. 6916} 6917function fulfillSegmentCacheEntry(segmentCacheEntry, rsc, staleAt, isPartial) { 6918 const fulfilledEntry = segmentCacheEntry; 6919 fulfilledEntry.status = 2; 6920 fulfilledEntry.rsc = rsc; 6921 fulfilledEntry.staleAt = staleAt; 6922 fulfilledEntry.isPartial = isPartial; 6923 // Resolve any listeners that were waiting for this data. 6924 if (segmentCacheEntry.promise !== null) { 6925 segmentCacheEntry.promise.resolve(fulfilledEntry); 6926 // Free the promise for garbage collection. 6927 fulfilledEntry.promise = null; 6928 } 6929 return fulfilledEntry; 6930} 6931function rejectRouteCacheEntry(entry, staleAt) { 6932 const rejectedEntry = entry; 6933 rejectedEntry.status = 3; 6934 rejectedEntry.staleAt = staleAt; 6935 pingBlockedTasks(entry); 6936} 6937function rejectSegmentCacheEntry(entry, staleAt) { 6938 const rejectedEntry = entry; 6939 rejectedEntry.status = 3; 6940 rejectedEntry.staleAt = staleAt; 6941 if (entry.promise !== null) { 6942 // NOTE: We don't currently propagate the reason the prefetch was canceled 6943 // but we could by accepting a `reason` argument. 6944 entry.promise.resolve(null); 6945 entry.promise = null; 6946 } 6947} 6948function convertRootTreePrefetchToRouteTree(rootTree, renderedPathname, renderedSearch, acc) { 6949 // Remove trailing and leading slashes 6950 const pathnameParts = renderedPathname.split('/').filter((p)=>p !== ''); 6951 const index = 0; 6952 const rootSegment = _segmentvalueencoding.ROOT_SEGMENT_REQUEST_KEY; 6953 return convertTreePrefetchToRouteTree(rootTree.tree, rootSegment, null, _segmentvalueencoding.ROOT_SEGMENT_REQUEST_KEY, pathnameParts, index, renderedSearch, acc); 6954} 6955function convertTreePrefetchToRouteTree(prefetch, segment, partialVaryPath, requestKey, pathnameParts, pathnamePartsIndex, renderedSearch, acc) { 6956 // Converts the route tree sent by the server into the format used by the 6957 // cache. The cached version of the tree includes additional fields, such as a 6958 // cache key for each segment. Since this is frequently accessed, we compute 6959 // it once instead of on every access. This same cache key is also used to 6960 // request the segment from the server. 6961 let slots = null; 6962 let isPage; 6963 let varyPath; 6964 const prefetchSlots = prefetch.slots; 6965 if (prefetchSlots !== null) { 6966 isPage = false; 6967 varyPath = (0, _varypath.finalizeLayoutVaryPath)(requestKey, partialVaryPath); 6968 slots = {}; 6969 for(let parallelRouteKey in prefetchSlots){ 6970 const childPrefetch = prefetchSlots[parallelRouteKey]; 6971 const childSegmentName = childPrefetch.name; 6972 const childParam = childPrefetch.param; 6973 let childDoesAppearInURL; 6974 let childSegment; 6975 let childPartialVaryPath; 6976 if (childParam !== null) { 6977 // This segment is parameterized. Get the param from the pathname. 6978 const childParamValue = (0, _routeparams.parseDynamicParamFromURLPart)(childParam.type, pathnameParts, pathnamePartsIndex); 6979 // Assign a cache key to the segment, based on the param value. In the 6980 // pre-Segment Cache implementation, the server computes this and sends 6981 // it in the body of the response. In the Segment Cache implementation, 6982 // the server sends an empty string and we fill it in here. 6983 // TODO: We're intentionally not adding the search param to page 6984 // segments here; it's tracked separately and added back during a read. 6985 // This would clearer if we waited to construct the segment until it's 6986 // read from the cache, since that's effectively what we're 6987 // doing anyway. 6988 const childParamKey = // cacheComponents is enabled. 6989 childParam.key !== null ? childParam.key : (0, _routeparams.getCacheKeyForDynamicParam)(childParamValue, ''); 6990 childPartialVaryPath = (0, _varypath.appendLayoutVaryPath)(partialVaryPath, childParamKey, childSegmentName); 6991 childSegment = [ 6992 childSegmentName, 6993 childParamKey, 6994 childParam.type, 6995 childParam.siblings 6996 ]; 6997 childDoesAppearInURL = true; 6998 } else { 6999 // This segment does not have a param. Inherit the partial vary path of 7000 // the parent. 7001 childPartialVaryPath = partialVaryPath; 7002 childSegment = childSegmentName; 7003 childDoesAppearInURL = (0, _routeparams.doesStaticSegmentAppearInURL)(childSegmentName); 7004 } 7005 // Only increment the index if the segment appears in the URL. If it's a 7006 // "virtual" segment, like a route group, it remains the same. 7007 const childPathnamePartsIndex = childDoesAppearInURL ? pathnamePartsIndex + 1 : pathnamePartsIndex;
7008 const childRequestKeyPart = (0, _segmentvalueencoding.createSegmentRequestKeyPart)(childSegment); 7009 const childRequestKey = (0, _segmentvalueencoding.appendSegmentRequestKeyPart)(requestKey, parallelRouteKey, childRequestKeyPart); 7010 slots[parallelRouteKey] = convertTreePrefetchToRouteTree(childPrefetch, childSegment, childPartialVaryPath, childRequestKey, pathnameParts, childPathnamePartsIndex, renderedSearch, acc); 7011 } 7012 } else { 7013 if (requestKey.endsWith(_segment.PAGE_SEGMENT_KEY)) { 7014 // This is a page segment. 7015 isPage = true; 7016 varyPath = (0, _varypath.finalizePageVaryPath)(requestKey, renderedSearch, partialVaryPath); 7017 // The metadata "segment" is not part the route tree, but it has the same 7018 // conceptual params as a page segment. Write the vary path into the 7019 // accumulator object. If there are multiple parallel pages, we use the 7020 // first one. Which page we choose is arbitrary as long as it's 7021 // consistently the same one every time every time. See 7022 // finalizeMetadataVaryPath for more details. 7023 if (acc.metadataVaryPath === null) { 7024 acc.metadataVaryPath = (0, _varypath.finalizeMetadataVaryPath)(requestKey, renderedSearch, partialVaryPath); 7025 } 7026 } else { 7027 // This is a layout segment. 7028 isPage = false; 7029 varyPath = (0, _varypath.finalizeLayoutVaryPath)(requestKey, partialVaryPath); 7030 } 7031 } 7032 return { 7033 requestKey, 7034 segment, 7035 refreshState: null, 7036 // TODO: Cheating the type system here a bit because TypeScript can't tell 7037 // that the type of isPage and varyPath are consistent. The fix would be to 7038 // create separate constructors and call the appropriate one from each of 7039 // the branches above. Just seems a bit overkill only for one field so I'll 7040 // leave it as-is for now. If isPage were wrong it would break the behavior 7041 // and we'd catch it quickly, anyway. 7042 varyPath: varyPath, 7043 isPage: isPage, 7044 slots, 7045 prefetchHints: prefetch.prefetchHints 7046 }; 7047} 7048function convertRootFlightRouterStateToRouteTree(flightRouterState, renderedSearch, acc) { 7049 return convertFlightRouterStateToRouteTree(flightRouterState, _segmentvalueencoding.ROOT_SEGMENT_REQUEST_KEY, null, renderedSearch, acc); 7050} 7051function convertReusedFlightRouterStateToRouteTree(parentRouteTree, parallelRouteKey, flightRouterState, renderedSearch, acc) { 7052 // Create a RouteTree for a FlightRouterState that was reused from an older 7053 // route. This happens during a navigation when a parallel route slot does not 7054 // match the target route; we reuse whatever slot was already active. 7055 // Unlike a FlightRouterState, the RouteTree type contains backreferences to 7056 // the parent segments. Append the vary path to the parent's vary path. 7057 const parentPartialVaryPath = parentRouteTree.isPage ? (0, _varypath.getPartialPageVaryPath)(parentRouteTree.varyPath) : (0, _varypath.getPartialLayoutVaryPath)(parentRouteTree.varyPath); 7058 const segment = flightRouterState[0]; 7059 // And the request key.
7060 const parentRequestKey = parentRouteTree.requestKey; 7061 const requestKeyPart = (0, _segmentvalueencoding.createSegmentRequestKeyPart)(segment); 7062 const requestKey = (0, _segmentvalueencoding.appendSegmentRequestKeyPart)(parentRequestKey, parallelRouteKey, requestKeyPart); 7063 return convertFlightRouterStateToRouteTree(flightRouterState, requestKey, parentPartialVaryPath, renderedSearch, acc); 7064} 7065function convertFlightRouterStateToRouteTree(flightRouterState, requestKey, parentPartialVaryPath, parentRenderedSearch, acc) { 7066 var _flightRouterState_, _flightRouterState_1; 7067 const originalSegment = flightRouterState[0]; 7068 // If the FlightRouterState has a refresh state, then this segment is part of 7069 // an inactive parallel route. It has a different rendered search query than 7070 // the outer parent route. In order to construct the inactive route correctly, 7071 // we must restore the query that was originally used to render it. 7072 const compressedRefreshState = (_flightRouterState_ = flightRouterState[2]) !== null && _flightRouterState_ !== void 0 ? _flightRouterState_ : null; 7073 const refreshState = compressedRefreshState !== null ? { 7074 canonicalUrl: compressedRefreshState[0], 7075 renderedSearch: compressedRefreshState[1] 7076 } : null; 7077 const renderedSearch = refreshState !== null ? refreshState.renderedSearch : parentRenderedSearch; 7078 let segment; 7079 let partialVaryPath; 7080 let isPage; 7081 let varyPath; 7082 if (Array.isArray(originalSegment)) { 7083 isPage = false; 7084 const paramCacheKey = originalSegment[1]; 7085 const paramName = originalSegment[0]; 7086 partialVaryPath = (0, _varypath.appendLayoutVaryPath)(parentPartialVaryPath, paramCacheKey, paramName); 7087 varyPath = (0, _varypath.finalizeLayoutVaryPath)(requestKey, partialVaryPath); 7088 segment = originalSegment; 7089 } else { 7090 // This segment does not have a param. Inherit the partial vary path of 7091 // the parent. 7092 partialVaryPath = parentPartialVaryPath; 7093 if (requestKey.endsWith(_segment.PAGE_SEGMENT_KEY)) { 7094 // This is a page segment. 7095 isPage = true; 7096 // The navigation implementation expects the search params to be included 7097 // in the segment. However, in the case of a static response, the search 7098 // params are omitted. So the client needs to add them back in when reading 7099 // from the Segment Cache. 7100 // 7101 // For consistency, we'll do this for dynamic responses, too. 7102 // 7103 // TODO: We should move search params out of FlightRouterState and handle 7104 // them entirely on the client, similar to our plan for dynamic params. 7105 segment = _segment.PAGE_SEGMENT_KEY; 7106 varyPath = (0, _varypath.finalizePageVaryPath)(requestKey, renderedSearch, partialVaryPath); 7107 // The metadata "segment" is not part the route tree, but it has the same 7108 // conceptual params as a page segment. Write the vary path into the 7109 // accumulator object. If there are multiple parallel pages, we use the 7110 // first one. Which page we choose is arbitrary as long as it's 7111 // consistently the same one every time every time. See 7112 // finalizeMetadataVaryPath for more details. 7113 if (acc.metadataVaryPath === null) { 7114 acc.metadataVaryPath = (0, _varypath.finalizeMetadataVaryPath)(requestKey, renderedSearch, partialVaryPath); 7115 } 7116 } else { 7117 // This is a layout segment. 7118 isPage = false; 7119 segment = originalSegment; 7120 varyPath = (0, _varypath.finalizeLayoutVaryPath)(requestKey, partialVaryPath); 7121 } 7122 } 7123 let slots = null; 7124 const parallelRoutes = flightRouterState[1]; 7125 for(let parallelRouteKey in parallelRoutes){ 7126 const childRouterState = parallelRoutes[parallelRouteKey]; 7127 const childSegment = childRouterState[0]; 7128 // TODO: Eventually, the param values will not be included in the response 7129 // from the server. We'll instead fill them in on the client by parsing 7130 // the URL. This is where we'll do that.
7131 const childRequestKeyPart = (0, _segmentvalueencoding.createSegmentRequestKeyPart)(childSegment); 7132 const childRequestKey = (0, _segmentvalueencoding.appendSegmentRequestKeyPart)(requestKey, parallelRouteKey, childRequestKeyPart); 7133 const childTree = convertFlightRouterStateToRouteTree(childRouterState, childRequestKey, partialVaryPath, renderedSearch, acc); 7134 if (slots === null) { 7135 slots = { 7136 [parallelRouteKey]: childTree 7137 }; 7138 } else { 7139 slots[parallelRouteKey] = childTree; 7140 } 7141 } 7142 return { 7143 requestKey, 7144 segment, 7145 refreshState, 7146 // TODO: Cheating the type system here a bit because TypeScript can't tell 7147 // that the type of isPage and varyPath are consistent. The fix would be to 7148 // create separate constructors and call the appropriate one from each of 7149 // the branches above. Just seems a bit overkill only for one field so I'll 7150 // leave it as-is for now. If isPage were wrong it would break the behavior 7151 // and we'd catch it quickly, anyway. 7152 varyPath: varyPath, 7153 isPage: isPage, 7154 slots, 7155 prefetchHints: (_flightRouterState_1 = flightRouterState[4]) !== null && _flightRouterState_1 !== void 0 ? _flightRouterState_1 : 0 7156 }; 7157} 7158function convertRouteTreeToFlightRouterState(routeTree) { 7159 const parallelRoutes = {}; 7160 if (routeTree.slots !== null) { 7161 for(const parallelRouteKey in routeTree.slots){ 7162 parallelRoutes[parallelRouteKey] = convertRouteTreeToFlightRouterState(routeTree.slots[parallelRouteKey]); 7163 } 7164 } 7165 const flightRouterState = [ 7166 routeTree.segment, 7167 parallelRoutes, 7168 null, 7169 null 7170 ]; 7171 return flightRouterState; 7172} 7173async function fetchRouteOnCacheMiss(entry, key) { 7174 // This function is allowed to use async/await because it contains the actual 7175 // fetch that gets issued on a cache miss. Notice it writes the result to the 7176 // cache entry directly, rather than return data that is then written by 7177 // the caller. 7178 const pathname = key.pathname; 7179 const search = key.search; 7180 const nextUrl = key.nextUrl; 7181 const segmentPath = '/_tree'; 7182 const headers = { 7183 [_approuterheaders.RSC_HEADER]: '1', 7184 [_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER]: '1', 7185 [_approuterheaders.NEXT_ROUTER_SEGMENT_PREFETCH_HEADER]: segmentPath 7186 }; 7187 if (nextUrl !== null) { 7188 headers[_approuterheaders.NEXT_URL] = nextUrl; 7189 } 7190 // Tell the server to perform a static pre-render for the Instant Navigation 7191 // Testing API. Static pre-renders don't normally happen during development. 7192 addInstantPrefetchHeaderIfLocked(headers); 7193 try { 7194 const url = new URL(pathname + search, location.origin); 7195 let response; 7196 let urlAfterRedirects; 7197 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 7198 ; 7199 else { 7200 // "Server" mode. We can use request headers instead of the pathname. 7201 // TODO: The eventual plan is to get rid of our custom request headers and 7202 // encode everything into the URL, using a similar strategy to the 7203 // "output: export" block above. 7204 response = await fetchPrefetchResponse(url, headers); 7205 urlAfterRedirects = response !== null && response.redirected ? new URL(response.url) : url; 7206 } 7207 if (!response || !response.ok || // 204 is a Cache miss. Though theoretically this shouldn't happen when 7208 // PPR is enabled, because we always respond to route tree requests, even 7209 // if it needs to be blockingly generated on demand. 7210 response.status === 204 || !response.body) { 7211 // Server responded with an error, or with a miss. We should still cache 7212 // the response, but we can try again after 10 seconds. 7213 rejectRouteCacheEntry(entry, Date.now() + 10 * 1000); 7214 return null; 7215 } 7216 // TODO: The canonical URL is the href without the origin. I think 7217 // historically the reason for this is because the initial canonical URL 7218 // gets passed as a prop to the top-level React component, which means it
7219 // needs to be computed during SSR. If it were to include the origin, it 7220 // would need to always be same as location.origin on the client, to prevent 7221 // a hydration mismatch. To sidestep this complexity, we omit the origin. 7222 // 7223 // However, since this is neither a native URL object nor a fully qualified 7224 // URL string, we need to be careful about how we use it. To prevent subtle 7225 // mistakes, we should create a special type for it, instead of just string. 7226 // Or, we should just use a (readonly) URL object instead. The type of the 7227 // prop that we pass to seed the initial state does not need to be the same 7228 // type as the state itself. 7229 const canonicalUrl = (0, _createhreffromurl.createHrefFromUrl)(urlAfterRedirects); 7230 // Check whether the response varies based on the Next-Url header. 7231 const varyHeader = response.headers.get('vary'); 7232 const couldBeIntercepted = varyHeader !== null && varyHeader.includes(_approuterheaders.NEXT_URL); 7233 // TODO: The `closed` promise was originally used to track when a streaming 7234 // network connection closes, so the scheduler could limit concurrent 7235 // connections. Now that prefetch responses are buffered, `closed` is 7236 // resolved immediately after buffering — before the outer function even 7237 // returns. This mechanism is only still meaningful for dynamic (Full) 7238 // prefetches, which use incremental streaming. Consider removing the 7239 // `closed` plumbing for buffered prefetch paths. 7240 const closed = (0, _promisewithresolvers.createPromiseWithResolvers)(); 7241 // This checks whether the response was served from the per-segment cache, 7242 // rather than the old prefetching flow. If it fails, it implies that PPR 7243 // is disabled on this route. 7244 const routeIsPPREnabled = response.headers.get(_approuterheaders.NEXT_DID_POSTPONE_HEADER) === '2' || // In output: "export" mode, we can't rely on response headers. But if we 7245 // receive a well-formed response, we can assume it's a static response, 7246 // because all data is static in this mode. 7247 isOutputExportMode; 7248 if (routeIsPPREnabled) { 7249 var _response_headers_get; 7250 const { stream: prefetchStream, size: responseSize } = await createNonTaskyPrefetchResponseStream(response.body); 7251 closed.resolve(); 7252 (0, _cachemap.setSizeInCacheMap)(entry, responseSize); 7253 const serverData = await (0, _fetchserverresponse.createFromNextReadableStream)(prefetchStream, headers, { 7254 allowPartialStream: true 7255 }); 7256 if (((_response_headers_get = response.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _response_headers_get !== void 0 ? _response_headers_get : serverData.buildId) !== (0, _navigationbuildid.getNavigationBuildId)()) { 7257 // The server build does not match the client. Treat as a 404. During 7258 // an actual navigation, the router will trigger an MPA navigation. 7259 // TODO: We should cache the fact that this is an MPA navigation. 7260 rejectRouteCacheEntry(entry, Date.now() + 10 * 1000); 7261 return null; 7262 } 7263 // Get the params that were used to render the target page. These may 7264 // be different from the params in the request URL, if the page 7265 // was rewritten. 7266 const renderedPathname = (0, _routeparams.getRenderedPathname)(response); 7267 const renderedSearch = (0, _routeparams.getRenderedSearch)(response); 7268 // Convert the server-sent data into the RouteTree format used by the 7269 // client cache. 7270 // 7271 // During this traversal, we accumulate additional data into this 7272 // "accumulator" object. 7273 const acc = { 7274 metadataVaryPath: null 7275 }; 7276 const routeTree = convertRootTreePrefetchToRouteTree(serverData, renderedPathname, renderedSearch, acc); 7277 const metadataVaryPath = acc.metadataVaryPath; 7278 if (metadataVaryPath === null) { 7279 rejectRouteCacheEntry(entry, Date.now() + 10 * 1000); 7280 return null; 7281 } 7282 (0, _optimisticroutes.discoverKnownRoute)(Date.now(), pathname, nextUrl, entry, routeTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, routeIsPPREnabled, false // hasDynamicRewrite 7283 ); 7284 } else { 7285 var _response_headers_get1; 7286 // PPR is not enabled for this route. The server responds with a 7287 // different format (FlightRouterState) that we need to convert. 7288 // TODO: We will unify the responses eventually. I'm keeping the types 7289 // separate for now because FlightRouterState has so many 7290 // overloaded concerns. 7291 const { stream: prefetchStream, size: responseSize } = await createNonTaskyPrefetchResponseStream(response.body); 7292 closed.resolve(); 7293 (0, _cachemap.setSizeInCacheMap)(entry, responseSize); 7294 const serverData = await (0, _fetchserverresponse.createFromNextReadableStream)(prefetchStream, headers, {
7295 allowPartialStream: true 7296 }); 7297 if (((_response_headers_get1 = response.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _response_headers_get1 !== void 0 ? _response_headers_get1 : serverData.b) !== (0, _navigationbuildid.getNavigationBuildId)()) { 7298 // The server build does not match the client. Treat as a 404. During 7299 // an actual navigation, the router will trigger an MPA navigation. 7300 // TODO: We should cache the fact that this is an MPA navigation. 7301 rejectRouteCacheEntry(entry, Date.now() + 10 * 1000); 7302 return null; 7303 } 7304 // Read head vary params synchronously. Individual segments carry their 7305 // own thenables in CacheNodeSeedData. 7306 const headVaryParamsThenable = serverData.h; 7307 const headVaryParams = headVaryParamsThenable !== null ? (0, _varyparamsdecoding.readVaryParams)(headVaryParamsThenable) : null; 7308 writeDynamicTreeResponseIntoCache(Date.now(), // using the LoadingBoundary fetch strategy, so mark their cache entries accordingly. 7309 _types.FetchStrategy.LoadingBoundary, response, serverData, entry, couldBeIntercepted, canonicalUrl, routeIsPPREnabled, headVaryParams, pathname, nextUrl); 7310 } 7311 if (!couldBeIntercepted) { 7312 // This route will never be intercepted. So we can use this entry for all 7313 // requests to this route, regardless of the Next-Url header. This works 7314 // because when reading the cache we always check for a valid 7315 // non-intercepted entry first. 7316 // Re-key the entry. The `set` implementation handles removing it from 7317 // its previous position in the cache. We don't need to do anything to 7318 // update the LRU, because the entry is already in it. 7319 // TODO: Treat this as an upsert — should check if an entry already 7320 // exists at the new keypath, and if so, whether we should keep that 7321 // one instead. 7322 const fulfilledVaryPath = (0, _varypath.getFulfilledRouteVaryPath)(pathname, search, nextUrl, couldBeIntercepted); 7323 const isRevalidation = false; 7324 (0, _cachemap.setInCacheMap)(routeCacheMap, fulfilledVaryPath, entry, isRevalidation); 7325 } 7326 // Return a promise that resolves when the network connection closes, so 7327 // the scheduler can track the number of concurrent network connections. 7328 return { 7329 value: null, 7330 closed: closed.promise 7331 }; 7332 } catch (error) { 7333 // Either the connection itself failed, or something bad happened while 7334 // decoding the response. 7335 rejectRouteCacheEntry(entry, Date.now() + 10 * 1000); 7336 return null; 7337 } 7338} 7339async function fetchSegmentOnCacheMiss(route, segmentCacheEntry, routeKey, tree) { 7340 // This function is allowed to use async/await because it contains the actual 7341 // fetch that gets issued on a cache miss. Notice it writes the result to the 7342 // cache entry directly, rather than return data that is then written by 7343 // the caller. 7344 // 7345 // Segment fetches are non-blocking so we don't need to ping the scheduler 7346 // on completion. 7347 // Use the canonical URL to request the segment, not the original URL. These 7348 // are usually the same, but the canonical URL will be different if the route 7349 // tree response was redirected. To avoid an extra waterfall on every segment 7350 // request, we pass the redirected URL instead of the original one. 7351 const url = new URL(route.canonicalUrl, location.origin); 7352 const nextUrl = routeKey.nextUrl; 7353 const requestKey = tree.requestKey; 7354 const normalizedRequestKey = requestKey === _segmentvalueencoding.ROOT_SEGMENT_REQUEST_KEY ? // `_index` instead of as an empty string. This should be treated as 7355 // an implementation detail and not as a stable part of the protocol. 7356 // It just needs to match the equivalent logic that happens when 7357 // prerendering the responses. It should not leak outside of Next.js. 7358 '/_index' : requestKey; 7359 const headers = { 7360 [_approuterheaders.RSC_HEADER]: '1', 7361 [_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER]: '1', 7362 [_approuterheaders.NEXT_ROUTER_SEGMENT_PREFETCH_HEADER]: normalizedRequestKe
7362y 7363 }; 7364 if (nextUrl !== null) { 7365 headers[_approuterheaders.NEXT_URL] = nextUrl; 7366 } 7367 // Tell the server to perform a static pre-render for the Instant Navigation 7368 // Testing API. Static pre-renders don't normally happen during development. 7369 addInstantPrefetchHeaderIfLocked(headers); 7370 const requestUrl = ("TURBOPACK compile-time falsy", 0) ? "TURBOPACK unreachable" : url; 7371 try { 7372 var _response_headers_get; 7373 const response = await fetchPrefetchResponse(requestUrl, headers); 7374 if (!response || !response.ok || response.status === 204 || // Cache miss 7375 // This checks whether the response was served from the per-segment cache, 7376 // rather than the old prefetching flow. If it fails, it implies that PPR 7377 // is disabled on this route. Theoretically this should never happen 7378 // because we only issue requests for segments once we've verified that 7379 // the route supports PPR. 7380 response.headers.get(_approuterheaders.NEXT_DID_POSTPONE_HEADER) !== '2' && // In output: "export" mode, we can't rely on response headers. But if 7381 // we receive a well-formed response, we can assume it's a static 7382 // response, because all data is static in this mode. 7383 !isOutputExportMode || !response.body) { 7384 // Server responded with an error, or with a miss. We should still cache 7385 // the response, but we can try again after 10 seconds. 7386 rejectSegmentCacheEntry(segmentCacheEntry, Date.now() + 10 * 1000); 7387 return null; 7388 } 7389 // See TODO in fetchRouteOnCacheMiss about removing `closed` for 7390 // buffered prefetch paths. 7391 const closed = (0, _promisewithresolvers.createPromiseWithResolvers)(); 7392 const { stream: prefetchStream, size: responseSize } = await createNonTaskyPrefetchResponseStream(response.body); 7393 closed.resolve(); 7394 (0, _cachemap.setSizeInCacheMap)(segmentCacheEntry, responseSize); 7395 const serverData = await (0, _fetchserverresponse.createFromNextReadableStream)(prefetchStream, headers, { 7396 allowPartialStream: true 7397 }); 7398 if (((_response_headers_get = response.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _response_headers_get !== void 0 ? _response_headers_get : serverData.buildId) !== (0, _navigationbuildid.getNavigationBuildId)()) { 7399 // The server build does not match the client. Treat as a 404. During 7400 // an actual navigation, the router will trigger an MPA navigation. 7401 rejectSegmentCacheEntry(segmentCacheEntry, Date.now() + 10 * 1000); 7402 return null; 7403 } 7404 const now = Date.now(); 7405 const staleAt = now + getStaleTimeMs(serverData.staleTime); 7406 const fulfilledEntry = fulfillSegmentCacheEntry(segmentCacheEntry, serverData.rsc, staleAt, serverData.isPartial); 7407 // If the server tells us which params the segment varies by, we can re-key 7408 // the entry to a more generic vary path. This allows the entry to be reused 7409 // across different param values for params that the segment doesn't 7410 // actually depend on. 7411 const varyParams = serverData.varyParams; 7412 const fulfilledVaryPath = ("TURBOPACK compile-time falsy", 0) ? "TURBOPACK unreachable" : (0, _varypath.getSegmentVaryPathForRequest)(segmentCacheEntry.fetchStrategy, tree); 7413 // Re-key and upsert the entry at the fulfilled vary path. This ensures 7414 // the entry is stored at the most generic path possible based on which 7415 // params the segment actually depends on. 7416 upsertSegmentEntry(now, fulfilledVaryPath, fulfilledEntry); 7417 return { 7418 value: fulfilledEntry, 7419 // Return a promise that resolves when the network connection closes, so 7420 // the scheduler can track the number of concurrent network connections. 7421 closed: closed.promise 7422 }; 7423 } catch (error) { 7424 // Either the connection itself failed, or something bad happened while 7425 // decoding the response. 7426 rejectSegmentCacheEntry(segmentCacheEntry, Date.now() + 10 * 1000); 7427 return null; 7428 } 7429} 7430async function fetchInlinedSegmentsOnCacheMiss(route, routeKey, tree, spawnedEntries) { 7431 // When prefetch inlining is enabled, all segment data for a route is bundled 7432 // into a single /_inlined response instead of individual per-segment 7433 // requests. This function fetches that response and walks the tree to fill 7434 // all segment cache entries at once. 7435 const url = new URL(route.canonicalUrl, location.origin); 7436 const nextUrl = routeKey.nextUrl; 7437 const headers = { 7438 [_approuterheaders.RSC_HEADER]: '1', 7439 [_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER]: '1', 7440 [_approuterheaders.NEXT_ROUTER_SEGMENT_PREFETCH_HEADER]: '/' + _segment.PAGE_SEGMENT_KEY 7441 }; 7442 if (nextUrl !== null) { 7443 headers[_approuterheaders.NEXT_URL] = nextUrl; 7444 } 7445 addInstantPrefetchHeaderIfLocked(headers); 7446 try { 7447 var _response_headers_get; 7448 const response = await fetchPrefetchResponse(url, headers); 7449 if (!response || !response.ok || response.status === 204 || response.headers.get(_approuterheaders.NEXT_DID_POSTPONE_HEADER) !== '2' && !isOutputExportMode || !response.body) { 7450 rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000); 7451 return null; 7452 }
7453 // See TODO in fetchRouteOnCacheMiss about removing `closed` for 7454 // buffered prefetch paths. 7455 const closed = (0, _promisewithresolvers.createPromiseWithResolvers)(); 7456 const { stream: prefetchStream } = await createNonTaskyPrefetchResponseStream(response.body); 7457 closed.resolve(); 7458 const serverData = await (0, _fetchserverresponse.createFromNextReadableStream)(prefetchStream, headers, { 7459 allowPartialStream: true 7460 }); 7461 if (((_response_headers_get = response.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _response_headers_get !== void 0 ? _response_headers_get : serverData.tree.segment.buildId) !== (0, _navigationbuildid.getNavigationBuildId)()) { 7462 rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000); 7463 return null; 7464 } 7465 const now = Date.now(); 7466 // Walk the inlined tree in parallel with the RouteTree and fill 7467 // segment cache entries. 7468 fillInlinedSegmentEntries(now, route, tree, serverData.tree, spawnedEntries); 7469 // Fill the head entry. 7470 const headStaleAt = now + getStaleTimeMs(serverData.head.staleTime); 7471 const headKey = route.metadata.requestKey; 7472 const ownedHeadEntry = spawnedEntries.get(headKey); 7473 if (ownedHeadEntry !== undefined) { 7474 fulfillSegmentCacheEntry(ownedHeadEntry, serverData.head.rsc, headStaleAt, serverData.head.isPartial); 7475 } else { 7476 // The head was already cached. Try to upsert if the entry is empty. 7477 const existingEntry = readOrCreateSegmentCacheEntry(now, _types.FetchStrategy.PPR, route.metadata); 7478 if (existingEntry.status === 0) { 7479 fulfillSegmentCacheEntry(upgradeToPendingSegment(existingEntry, _types.FetchStrategy.PPR), serverData.head.rsc, headStaleAt, serverData.head.isPartial); 7480 } 7481 } 7482 // Reject any remaining entries that were not fulfilled by the response. 7483 rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000); 7484 return { 7485 value: null, 7486 closed: closed.promise 7487 }; 7488 } catch (error) { 7489 rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000); 7490 return null; 7491 } 7492} 7493function fillInlinedSegmentEntries(now, route, tree, inlinedNode, spawnedEntries) { 7494 // Check if the spawned entries map has an entry for this segment's key. 7495 const segment = inlinedNode.segment; 7496 const staleAt = now + getStaleTimeMs(segment.staleTime); 7497 const ownedEntry = spawnedEntries.get(tree.requestKey); 7498 if (ownedEntry !== undefined) { 7499 // We own this entry. Fulfill it directly. 7500 fulfillSegmentCacheEntry(ownedEntry, segment.rsc, staleAt, segment.isPartial); 7501 } else { 7502 // Not owned by us — this is extra data from the inlined response for a 7503 // segment that was already cached. Try to upsert if the entry is empty. 7504 const existingEntry = readOrCreateSegmentCacheEntry(now, _types.FetchStrategy.PPR, tree); 7505 if (existingEntry.status === 0) { 7506 fulfillSegmentCacheEntry(upgradeToPendingSegment(existingEntry, _types.FetchStrategy.PPR), segment.rsc, staleAt, segment.isPartial); 7507 } 7508 } 7509 // Recurse into children. 7510 if (tree.slots !== null && inlinedNode.slots !== null) { 7511 for(const parallelRouteKey in tree.slots){ 7512 const childTree = tree.slots[parallelRouteKey]; 7513 const childInlinedNode = inlinedNode.slots[parallelRouteKey]; 7514 if (childInlinedNode !== undefined) { 7515 fillInlinedSegmentEntries(now, route, childTree, childInlinedNode, spawnedEntries); 7516 } 7517 } 7518 } 7519} 7520async function fetchSegmentPrefetchesUsingDynamicRequest(task, route, fetchStrategy, dynamicRequestTree, spawnedEntries) { 7521 const key = task.key; 7522 const url = new URL(route.canonicalUrl, location.origin); 7523 const nextUrl = key.nextUrl; 7524 if (spawnedEntries.size === 1 && spawnedEntries.has(route.metadata.requestKey)) { 7525 // The only thing pending is the head. Instruct the server to 7526 // skip over everything else. 7527 dynamicRequestTree = MetadataOnlyRequestTree; 7528 } 7529 const headers = { 7530 [_approuterheaders.RSC_HEADER]: '1', 7531 [_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER]: (0, _flightdatahelpers.prepareFlightRouterStateForRequest)(dynamicRequestTree) 7532 }; 7533 if (nextUrl !== null) { 7534 headers[_approuterheaders.NEXT_URL] = nextUrl; 7535 } 7536 switch(fetchStrategy){ 7537 case _types.FetchStrategy.Full: 7538 { 7539 break; 7540 } 7541 case _types.FetchStrategy.PPRRuntime: 7542 { 7543 headers[_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER] = '2'; 7544 break; 7545 } 7546 case _types.FetchStrategy.LoadingBoundary: 7547 { 7548 headers[_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER] = '1'; 7549 break; 7550 } 7551 default: 7552 { 7553 fetchStrategy; 7554 } 7555 } 7556 try { 7557 var _ref, _response_headers_get; 7558 const response = await fetchPrefetchResponse(url, headers); 7559 if (!response || !response.ok || !response.body) { 7560 // Server responded with an error, or with a miss. We should still cache 7561 // the response, but we can try again after 10 seconds. 7562 rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000); 7563 return null; 7564 } 7565 const renderedSearch = (0, _routeparams.getRenderedSearch)(response); 7566 if (renderedSearch !== route.renderedSearch) { 7567 // The search params that were used to render the target page are 7568 // different from the search params in the request URL. This only happens 7569 // when there's a dynamic rewrite in between the tree prefetch and the 7570 // data prefetch.
7571 // TODO: For now, since this is an edge case, we reject the prefetch, but 7572 // the proper way to handle this is to evict the stale route tree entry 7573 // then fill the cache with the new response. 7574 rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000); 7575 return null; 7576 } 7577 // Track when the network connection closes. Only meaningful for Full 7578 // (dynamic) prefetches which use incremental streaming. For buffered 7579 // paths, this is resolved immediately — see TODO in fetchRouteOnCacheMiss. 7580 const closed = (0, _promisewithresolvers.createPromiseWithResolvers)(); 7581 let fulfilledEntries = null; 7582 let prefetchStream; 7583 let bufferedResponseSize = null; 7584 if (fetchStrategy === _types.FetchStrategy.Full) { 7585 // Full prefetches are dynamic responses stored in the prefetch cache. 7586 // They don't carry vary params or other cache metadata, so there's no 7587 // need to buffer them. Use the incremental version to allow data to be 7588 // processed as it arrives. 7589 prefetchStream = createIncrementalPrefetchResponseStream(response.body, closed.resolve, function onResponseSizeUpdate(totalBytesReceivedSoFar) { 7590 // When processing a dynamic response, we don't know how large each 7591 // individual segment is, so approximate by assigning each segment 7592 // the average of the total response size. 7593 if (fulfilledEntries === null) { 7594 // Haven't received enough data yet to know which segments 7595 // were included. 7596 return; 7597 } 7598 const averageSize = totalBytesReceivedSoFar / fulfilledEntries.length; 7599 for (const entry of fulfilledEntries){ 7600 (0, _cachemap.setSizeInCacheMap)(entry, averageSize); 7601 } 7602 }); 7603 } else { 7604 const { stream, size } = await createNonTaskyPrefetchResponseStream(response.body); 7605 closed.resolve(); 7606 prefetchStream = stream; 7607 bufferedResponseSize = size; 7608 } 7609 const [serverData, cacheData] = await Promise.all([ 7610 (0, _fetchserverresponse.createFromNextReadableStream)(prefetchStream, headers, { 7611 allowPartialStream: true 7612 }), 7613 response.cacheData 7614 ]); 7615 // Read head vary params synchronously. Individual segments carry their 7616 // own thenables in CacheNodeSeedData. 7617 const headVaryParamsThenable = serverData.h; 7618 const headVaryParams = headVaryParamsThenable !== null ? (0, _varyparamsdecoding.readVaryParams)(headVaryParamsThenable) : null; 7619 const now = Date.now(); 7620 const staleAt = await getStaleAt(now, serverData.s, response); 7621 // PPRRuntime prefetches are partial when the server marks the response 7622 // as '~' (Partial). Full/LoadingBoundary prefetches are always complete. 7623 const isResponsePartial = fetchStrategy === _types.FetchStrategy.PPRRuntime && ((_ref = cacheData === null || cacheData === void 0 ? void 0 : cacheData.isResponsePartial) !== null && _ref !== void 0 ? _ref : false); 7624 // Aside from writing the data into the cache, this function also returns 7625 // the entries that were fulfilled, so we can streamingly update their sizes 7626 // in the LRU as more data comes in. 7627 const buildId = (_response_headers_get = response.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _response_headers_get !== void 0 ? _response_headers_get : serverData.b; 7628 const flightDatas = (0, _flightdatahelpers.normalizeFlightData)(serverData.f); 7629 if (typeof flightDatas === 'string') { 7630 rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000); 7631 return null; 7632 } 7633 const navigationSeed = (0, _navigation.convertServerPatchToFullTree)(now, dynamicRequestTree, flightDatas, renderedSearch, _bfcache.UnknownDynamicStaleTime); 7634 fulfilledEntries = writeDynamicRenderResponseIntoCache(now, fetchStrategy, flightDatas, buildId, isResponsePartial, headVaryParams, staleAt, navigationSeed, spawnedEntries); 7635 // For buffered responses, update LRU sizes now that we know
7635which 7636 // entries were fulfilled. 7637 if (bufferedResponseSize !== null && fulfilledEntries !== null && fulfilledEntries.length > 0) { 7638 const averageSize = bufferedResponseSize / fulfilledEntries.length; 7639 for (const entry of fulfilledEntries){ 7640 (0, _cachemap.setSizeInCacheMap)(entry, averageSize); 7641 } 7642 } 7643 // Return a promise that resolves when the network connection closes, so 7644 // the scheduler can track the number of concurrent network connections. 7645 return { 7646 value: null, 7647 closed: closed.promise 7648 }; 7649 } catch (error) { 7650 rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000); 7651 return null; 7652 } 7653} 7654function writeDynamicTreeResponseIntoCache(now, fetchStrategy, response, serverData, entry, couldBeIntercepted, canonicalUrl, routeIsPPREnabled, headVaryParams, originalPathname, nextUrl) { 7655 var _response_headers_get; 7656 const renderedSearch = (0, _routeparams.getRenderedSearch)(response); 7657 const normalizedFlightDataResult = (0, _flightdatahelpers.normalizeFlightData)(serverData.f); 7658 if (// MPA navigation. 7659 typeof normalizedFlightDataResult === 'string' || normalizedFlightDataResult.length !== 1) { 7660 rejectRouteCacheEntry(entry, now + 10 * 1000); 7661 return; 7662 } 7663 const flightData = normalizedFlightDataResult[0]; 7664 if (!flightData.isRootRender) { 7665 // Unexpected response format. 7666 rejectRouteCacheEntry(entry, now + 10 * 1000); 7667 return; 7668 } 7669 const flightRouterState = flightData.tree; 7670 // If the response was postponed, segments may contain dynamic holes. 7671 // The head has its own partiality flag (flightDataEntry.isHeadPartial) 7672 // which is handled separately in writeDynamicRenderResponseIntoCache. 7673 const isResponsePartial = response.headers.get(_approuterheaders.NEXT_DID_POSTPONE_HEADER) === '1'; 7674 // Convert the server-sent data into the RouteTree format used by the 7675 // client cache. 7676 // 7677 // During this traversal, we accumulate additional data into this 7678 // "accumulator" object. 7679 const acc = { 7680 metadataVaryPath: null 7681 }; 7682 const routeTree = convertRootFlightRouterStateToRouteTree(flightRouterState, renderedSearch, acc); 7683 const metadataVaryPath = acc.metadataVaryPath; 7684 if (metadataVaryPath === null) { 7685 rejectRouteCacheEntry(entry, now + 10 * 1000); 7686 return; 7687 } 7688 (0, _optimisticroutes.discoverKnownRoute)(now, originalPathname, nextUrl, entry, routeTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, routeIsPPREnabled, false // hasDynamicRewrite 7689 ); 7690 // If the server sent segment data as part of the response, we should write 7691 // it into the cache to prevent a second, redundant prefetch request. 7692 // TODO: This is a leftover branch from before Client Segment Cache was 7693 // enabled everywhere. Tree prefetches should never include segment data. We 7694 // can delete it. Leaving for a subsequent PR. 7695 const navigationSeed = (0, _navigation.convertServerPatchToFullTree)(now, flightRouterState, normalizedFlightDataResult, renderedSearch, _bfcache.UnknownDynamicStaleTime); 7696 const buildId = (_response_headers_get = response.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _response_headers_get !== void 0 ? _response_headers_get : serverData.b; 7697 writeDynamicRenderResponseIntoCache(now, fetchStrategy, normalizedFlightDataResult, buildId, isResponsePartial, headVaryParams, getStaleAtFromHeader(now, response), navigationSeed, null); 7698} 7699function rejectSegmentEntriesIfStillPending(entries, staleAt) { 7700 const fulfilledEntries = []; 7701 for (const entry of entries.values()){ 7702 if (entry.status === 1) { 7703 rejectSegmentCacheEntry(entry, staleAt); 7704 } else if (entry.status === 2) { 7705 fulfilledEntries.push(entry); 7706 } 7707 } 7708 return fulfilledEntries; 7709} 7710function writeDynamicRenderResponseIntoCache(now, fetchStrategy, flightDatas, buildId, isResponsePartial, headVaryParams, staleAt, navigationSeed, spawnedEntries) { 7711 if (buildId && buildId !== (0, _navigationbuildid.getNavigationBuildId)()) { 7712 // The server build does not match the client. Treat as a 404. During 7713 // an actual navigation, the router will trigger an MPA navigation. 7714 if (spawnedEntries !== null) { 7715 rejectSegmentEntriesIfStillPending(spawnedEntries, now + 10 * 1000); 7716 } 7717 return null; 7718 } 7719 const routeTree = navigationSeed.routeTree; 7720 const metadataTree = navigationSeed.metadataVaryPath !== null ? createMetadataRouteTree(navigationSeed.metadataVaryPath) : null; 7721 for (const flightDataEntry of flightDatas){ 7722 const seedData = flightDataEntry.seedData; 7723 if (seedData !== null) { 7724 // The data sent by the server represents only a subtree of the app. We 7725 // need to find the part of the task tree that matches the response. 7726 // 7727 // segmentPath represents the parent path of subtree. It's a repeating 7728 // pattern of parallel route key and segment: 7729 // 7730 // [string, Segment, string, Segment, string, Segment, ...] 7731 const segmentPath = flightDataEntry.segmentPath; 7732 let tree = routeTree; 7733 for(let i = 0; i < segmentPath.length; i += 2){ 7734 var _tree_slots; 7735 const parallelRouteKey = segmentPath[i]; 7736 if ((tree === null || tree === void 0 ? void 0 : (_tree_slots = tree.slots) === null || _tree_slots === void 0 ? void 0 : _tree_slots[parallelRouteKey]) !== undefined) { 7737 tree = tree.slots[parallelRouteKey]; 7738 } else { 7739 if (spawnedEntries !== null) { 7740 rejectSegmentEntriesIfStillPending(spawnedEntries, now + 10 * 1000); 7741 } 7742 return null; 7743 } 7744 } 7745 writeSeedDataIntoCache(now, fetchStrategy, tree, staleAt, seedData, isResponsePartial, spawnedEntries); 7746 } 7747 const head = flightDataEntry.head; 7748 if (head !== null && metadataTree !== null) { 7749 // When Cache Components is enabled, the server conservatively marks 7750 // the head as partial during static generation (isPossiblyPartialHead 7751 // in app-render.tsx), even for fully static pages where the head is 7752 // actually complete. When the response is non-partial, we override 7753 // this since the server confirmed no dynamic content exists. 7754 //
7755 // Without Cache Components, the server always sends the correct 7756 // isHeadPartial value, so no override is needed. 7757 const isHeadPartial = ("TURBOPACK compile-time falsy", 0) ? "TURBOPACK unreachable" : flightDataEntry.isHeadPartial; 7758 fulfillEntrySpawnedByRuntimePrefetch(now, fetchStrategy, head, isHeadPartial, staleAt, // parameter. 7759 headVaryParams, metadataTree, spawnedEntries); 7760 } 7761 } 7762 // Any entry that's still pending was intentionally not rendered by the 7763 // server, because it was inside the loading boundary. Mark them as rejected 7764 // so we know not to fetch them again. 7765 // TODO: If PPR is enabled on some routes but not others, then it's possible 7766 // that a different page is able to do a per-segment prefetch of one of the 7767 // segments we're marking as rejected here. We should mark on the segment 7768 // somehow that the reason for the rejection is because of a non-PPR prefetch. 7769 // That way a per-segment prefetch knows to disregard the rejection. 7770 if (spawnedEntries !== null) { 7771 const fulfilledEntries = rejectSegmentEntriesIfStillPending(spawnedEntries, now + 10 * 1000); 7772 return fulfilledEntries; 7773 } 7774 return null; 7775} 7776function writeSeedDataIntoCache(now, fetchStrategy, tree, staleAt, seedData, isResponsePartial, entriesOwnedByCurrentTask) { 7777 // This function is used to write the result of a runtime server request 7778 // (CacheNodeSeedData) into the prefetch cache. 7779 const rsc = seedData[0]; 7780 const isPartial = rsc === null || isResponsePartial; 7781 const varyParamsThenable = seedData[4]; 7782 // Each segment carries its own vary params thenable in the seed data. The 7783 // thenable resolves to the set of params the segment accessed during render. 7784 // A null thenable means tracking was not enabled (not a prerender). 7785 const varyParams = varyParamsThenable !== null ? (0, _varyparamsdecoding.readVaryParams)(varyParamsThenable) : null; 7786 fulfillEntrySpawnedByRuntimePrefetch(now, fetchStrategy, rsc, isPartial, staleAt, varyParams, tree, entriesOwnedByCurrentTask); 7787 // Recursively write the child data into the cache. 7788 const slots = tree.slots; 7789 if (slots !== null) { 7790 const seedDataChildren = seedData[1]; 7791 for(const parallelRouteKey in slots){ 7792 const childTree = slots[parallelRouteKey]; 7793 const childSeedData = seedDataChildren[parallelRouteKey]; 7794 if (childSeedData !== null && childSeedData !== undefined) { 7795 writeSeedDataIntoCache(now, fetchStrategy, childTree, staleAt, childSeedData, isResponsePartial, entriesOwnedByCurrentTask); 7796 } 7797 } 7798 } 7799} 7800function fulfillEntrySpawnedByRuntimePrefetch(now, fetchStrategy, rsc, isPartial, staleAt, segmentVaryParams, tree, entriesOwnedByCurrentTask) { 7801 // We should only write into cache entries that are owned by us. Or create 7802 // a new one and write into that. We must never write over an entry that was 7803 // created by a different task, because that causes data races. 7804 const ownedEntry = entriesOwnedByCurrentTask !== null ? entriesOwnedByCurrentTask.get(tree.requestKey) : undefined; 7805 if (ownedEntry !== undefined) { 7806 const fulfilledEntry = fulfillSegmentCacheEntry(ownedEntry, rsc, staleAt, isPartial); 7807 // Re-key the entry based on which params the segment actually depends on. 7808 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 7809 ; 7810 } else { 7811 // There's no matching entry. Attempt to create a new one. 7812 const possiblyNewEntry = readOrCreateSegmentCacheEntry(now, fetchStrategy, tree); 7813 if (possiblyNewEntry.status === 0) { 7814 // Confirmed this is a new entry. We can fulfill it. 7815 const newEntry = possiblyNewEntry; 7816 const fulfilledEntry = fulfillSegmentCacheEntry(upgradeToPendingSegment(newEntry, fetchStrategy), rsc, staleAt, isPartial); 7817 // Re-key the entry based on which params the segment actually depends on. 7818 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 7819 ; 7820 } else { 7821 // There was already an entry in the cache. But we may be able to 7822 // replace it with the new one from the server. 7823 const newEntry = fulfillSegmentCacheEntry(upgradeToPendingSegment(createDetachedSegmentCacheEntry(now), fetchStrategy), rsc, staleAt, isPartial); 7824 // Use the fulfilled vary path if available, otherwise fall back to 7825 // the request vary path. 7826 const varyPath = ("TURBOPACK compile-time falsy", 0) ? "TURBOPACK unreachable" : (0, _varypath.getSegmentVaryPathForRequest)(fetchStrategy, tree); 7827 upsertSegmentEntry(now, varyPath, newEntry); 7828 } 7829 } 7830} 7831async function fetchPrefetchResponse(url, headers) { 7832 const fetchPriority = 'low'; 7833 // When issuing a prefetch request, don't immediately decode the response; we 7834 // use the lower level `createFromResponse` API instead because we need to do 7835 // some extra processing of the response stream. See 7836 // `createNonTaskyPrefetchResponseStream` for more details. 7837 const shouldImmediatelyDecode = false;
7838 const response = await (0, _fetchserverresponse.createFetch)(url, headers, fetchPriority, shouldImmediatelyDecode); 7839 if (!response.ok) { 7840 return null; 7841 } 7842 // Check the content type 7843 if ("TURBOPACK compile-time falsy", 0) { 7844 // In output: "export" mode, we relaxed about the content type, since it's 7845 // not Next.js that's serving the response. If the status is OK, assume the 7846 // response is valid. If it's not a valid response, the Flight client won't 7847 // be able to decode it, and we'll treat it as a miss. 7848 } else { 7849 const contentType = response.headers.get('content-type'); 7850 const isFlightResponse = contentType && contentType.startsWith(_approuterheaders.RSC_CONTENT_TYPE_HEADER); 7851 if (!isFlightResponse) { 7852 return null; 7853 } 7854 } 7855 return response; 7856} 7857async function createNonTaskyPrefetchResponseStream(body) { 7858 // Buffer the entire response before passing it to the Flight client. This 7859 // ensures that when Flight processes the stream, all model data is available 7860 // synchronously. This is important for readVaryParams, which synchronously 7861 // checks the thenable status — if data arrived in multiple network chunks, 7862 // the thenables might not yet be fulfilled. 7863 // 7864 // TODO: There are too many intermediate stream transformations in the 7865 // prefetch response pipeline (e.g. stripIsPartialByte, this function). 7866 // These could all be consolidated into a single transformation. Refactor 7867 // once the cached navigations experiment lands. 7868 // 7869 // Read the entire response from the network. 7870 const reader = body.getReader(); 7871 const chunks = []; 7872 let size = 0; 7873 while(true){ 7874 const { done, value } = await reader.read(); 7875 if (done) break; 7876 chunks.push(value); 7877 size += value.byteLength; 7878 } 7879 // Concatenate into a single chunk so that Flight's processBinaryChunk 7880 // processes all rows synchronously in one call. Multiple chunks would not 7881 // be sufficient: even though reader.read() resolves as a microtask for 7882 // already-enqueued data, the `await` continuation from 7883 // createFromReadableStream can interleave between chunks. If the root 7884 // model row isn't the first row (e.g. outlined values come first), the 7885 // PromiseResolveThenableJob from `await` can cause the root to initialize 7886 // eagerly, scheduling the continuation before remaining chunks (including 7887 // promise value rows) are processed. A single chunk avoids this. 7888 let buffer; 7889 if (chunks.length === 1) { 7890 buffer = chunks[0]; 7891 } else if (chunks.length > 1) { 7892 buffer = new Uint8Array(size); 7893 let offset = 0; 7894 for (const chunk of chunks){ 7895 buffer.set(chunk, offset); 7896 offset += chunk.byteLength; 7897 } 7898 } else { 7899 buffer = new Uint8Array(0); 7900 } 7901 const stream = new ReadableStream({ 7902 start (controller) { 7903 controller.enqueue(buffer); 7904 controller.close(); 7905 } 7906 }); 7907 return { 7908 stream, 7909 size 7910 }; 7911} 7912/** 7913 * Creates a streaming (non-buffered) prefetch response stream for dynamic/Full 7914 * prefetches. These are essentially dynamic responses that get stored in the 7915 * prefetch cache — they don't carry vary params or other cache metadata that 7916 * requires synchronous thenable resolution, so there's no need to buffer them. 7917 * They should continue to stream so consumers can process data as it arrives. 7918 */ function createIncrementalPrefetchResponseStream(originalFlightStream, onStreamClose, onResponseSizeUpdate) { 7919 // While processing the original stream, we incrementally update the size 7920 // of the cache entry in the LRU. 7921 let totalByteLength = 0; 7922 const reader = originalFlightStream.getReader(); 7923 return new ReadableStream({ 7924 async pull (controller) { 7925 while(true){ 7926 const { done, value } = await reader.read(); 7927 if (!done) { 7928 // Pass to the target stream and keep consuming the Flight response 7929 // from the server. 7930 controller.enqueue(value); 7931 // Incrementally update the size of the cache entry in the LRU. 7932 totalByteLength += value.byteLength; 7933 onResponseSizeUpdate(totalByteLength); 7934 continue; 7935 } 7936 controller.close(); 7937 onStreamClose(); 7938 return; 7939 } 7940 } 7941 }); 7942} 7943function addSegmentPathToUrlInOutputExportMode(url, segmentPath) { 7944 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 7945 ; 7946 return url; 7947} 7948function canNewFetchStrategyProvideMoreContent(currentStrategy, newStrategy) { 7949 return currentStrategy < newStrategy; 7950} 7951/**
7952 * Adds the instant prefetch header if the navigation lock is active. 7953 * Uses a lazy require to ensure dead code elimination. 7954 */ function addInstantPrefetchHeaderIfLocked(headers) { 7955 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 7956 ; 7957} 7958function getStaleAtFromHeader(now, response) { 7959 var _response_headers_get; 7960 const staleTimeSeconds = parseInt((_response_headers_get = response.headers.get(_approuterheaders.NEXT_ROUTER_STALE_TIME_HEADER)) !== null && _response_headers_get !== void 0 ? _response_headers_get : '', 10); 7961 const staleTimeMs = !isNaN(staleTimeSeconds) ? getStaleTimeMs(staleTimeSeconds) : _navigatereducer.STATIC_STALETIME_MS; 7962 return now + staleTimeMs; 7963} 7964async function getStaleAt(now, staleTimeIterable, response) { 7965 if (staleTimeIterable !== undefined) { 7966 // Iterate the async iterable and take the last yielded value. The server 7967 // yields updated staleTime values during the render; the last one is the 7968 // final staleTime. 7969 let staleTimeSeconds; 7970 for await (const value of staleTimeIterable){ 7971 staleTimeSeconds = value; 7972 } 7973 if (staleTimeSeconds !== undefined) { 7974 const staleTimeMs = isNaN(staleTimeSeconds) ? _navigatereducer.STATIC_STALETIME_MS : getStaleTimeMs(staleTimeSeconds); 7975 return now + staleTimeMs; 7976 } 7977 } 7978 if (response !== undefined) { 7979 return getStaleAtFromHeader(now, response); 7980 } 7981 return now + _navigatereducer.STATIC_STALETIME_MS; 7982} 7983function writeStaticStageResponseIntoCache(now, flightData, buildId, headVaryParamsThenable, staleAt, baseTree, renderedSearch, isResponsePartial) { 7984 const fetchStrategy = isResponsePartial ? _types.FetchStrategy.PPR : _types.FetchStrategy.Full; 7985 const headVaryParams = headVaryParamsThenable !== null ? (0, _varyparamsdecoding.readVaryParams)(headVaryParamsThenable) : null; 7986 const flightDatas = (0, _flightdatahelpers.normalizeFlightData)(flightData); 7987 if (typeof flightDatas === 'string') { 7988 return; 7989 } 7990 const navigationSeed = (0, _navigation.convertServerPatchToFullTree)(now, baseTree, flightDatas, renderedSearch, _bfcache.UnknownDynamicStaleTime); 7991 writeDynamicRenderResponseIntoCache(now, fetchStrategy, flightDatas, buildId, isResponsePartial, headVaryParams, staleAt, navigationSeed, null // spawnedEntries — no pre-created entries; will create or upsert 7992 ); 7993} 7994async function processRuntimePrefetchStream(now, runtimePrefetchStream, baseTree, renderedSearch) { 7995 const { stream, isPartial } = await stripIsPartialByte(runtimePrefetchStream); 7996 const serverData = await (0, _fetchserverresponse.createFromNextReadableStream)(stream, undefined, { 7997 allowPartialStream: true 7998 }); 7999 const headVaryParamsThenable = serverData.h; 8000 const headVaryParams = headVaryParamsThenable !== null ? (0, _varyparamsdecoding.readVaryParams)(headVaryParamsThenable) : null; 8001 const staleAt = await getStaleAt(now, serverData.s); 8002 const flightDatas = (0, _flightdatahelpers.normalizeFlightData)(serverData.f); 8003 if (typeof flightDatas === 'string') { 8004 return null; 8005 } 8006 const navigationSeed = (0, _navigation.convertServerPatchToFullTree)(now, baseTree, flightDatas, renderedSearch, _bfcache.UnknownDynamicStaleTime); 8007 return { 8008 flightDatas, 8009 navigationSeed, 8010 buildId: serverData.b, 8011 isResponsePartial: isPartial, 8012 headVaryParams, 8013 staleAt 8014 }; 8015} 8016async function stripIsPartialByte(stream) { 8017 // When there is no recognized marker byte, the fallback depends on whether 8018 // Cached Navigations is enabled. When enabled, dynamic navigation responses 8019 // don't have a marker but may contain dynamic holes, so they are treated as 8020 // partial. When disabled, unmarked responses are treated as non-partial. 8021 const defaultIsPartial = !!("TURBOPACK compile-time value", false); 8022 const reader = stream.getReader(); 8023 const { done, value } = await reader.read(); 8024 if (done || !value || value.byteLength === 0) { 8025 return { 8026 stream: new ReadableStream({ 8027 start: (c)=>c.close() 8028 }), 8029 isPartial: defaultIsPartial 8030 }; 8031 } 8032 const firstByte = value[0]; 8033 const hasMarker = firstByte === 0x23 || firstByte === 0x7e; 8034 const isPartial = hasMarker ? firstByte === 0x7e : defaultIsPartial; 8035 const remainder = hasMarker ? value.byteLength > 1 ? value.subarray(1) : null : value; 8036 return { 8037 isPartial, 8038 stream: new ReadableStream({ 8039 start (controller) { 8040 if (remainder) { 8041 controller.enqueue(remainder); 8042 } 8043 }, 8044 async pull (controller) { 8045 const result = await reader.read(); 8046 if (result.done) { 8047 controller.close(); 8048 } else { 8049 controller.enqueue(result.value); 8050 } 8051 } 8052 }) 8053 }; 8054} 8055if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 8056 Object.defineProperty(exports.default, '__esModule', { 8057 value: true 8058 });
8059 Object.assign(exports.default, exports); 8060 module.exports = exports.default; 8061} 8062}), 8063787288, ((__turbopack_context__, module, exports) => { 8064"use strict"; 8065 8066var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 8067'use client'; 8068"use strict"; 8069Object.defineProperty(exports, "__esModule", { 8070 value: true 8071}); 80720 && (module.exports = { 8073 createFetch: null, 8074 createFromNextReadableStream: null, 8075 decodeStaticStage: null, 8076 fetchServerResponse: null, 8077 processFetch: null, 8078 resolveStaticStageData: null 8079}); 8080function _export(target, all) { 8081 for(var name in all)Object.defineProperty(target, name, { 8082 enumerable: true, 8083 get: all[name] 8084 }); 8085} 8086_export(exports, { 8087 createFetch: function() { 8088 return createFetch; 8089 }, 8090 createFromNextReadableStream: function() { 8091 return createFromNextReadableStream; 8092 }, 8093 decodeStaticStage: function() { 8094 return decodeStaticStage; 8095 }, 8096 fetchServerResponse: function() { 8097 return fetchServerResponse; 8098 }, 8099 processFetch: function() { 8100 return processFetch; 8101 }, 8102 resolveStaticStageData: function() { 8103 return resolveStaticStageData; 8104 } 8105}); 8106const _client = __turbopack_context__.r(235326); 8107const _invarianterror = __turbopack_context__.r(312718); 8108const _approuterheaders = __turbopack_context__.r(621768); 8109const _appcallserver = __turbopack_context__.r(132120); 8110const _appfindsourcemapurl = __turbopack_context__.r(92245); 8111const _flightdatahelpers = __turbopack_context__.r(450590); 8112const _setcachebustingsearchparam = __turbopack_context__.r(288093); 8113const _routeparams = __turbopack_context__.r(33906); 8114const _deploymentid = __turbopack_context__.r(543369); 8115const _navigationbuildid = __turbopack_context__.r(732992); 8116const _constants = __turbopack_context__.r(663416); 8117const _cache = __turbopack_context__.r(620896); 8118const _bfcache = __turbopack_context__.r(179027); 8119const createFromReadableStream = _client.createFromReadableStream; 8120const createFromFetch = _client.createFromFetch; 8121let createDebugChannel; 8122if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8123; 8124function doMpaNavigation(url) { 8125 return (0, _routeparams.urlToUrlWithoutFlightMarker)(new URL(url, location.origin)).toString(); 8126} 8127let isPageUnloading = false; 8128if (typeof window !== 'undefined') { 8129 // Track when the page is unloading, e.g. due to reloading the page or 8130 // performing hard navigations. This allows us to suppress error logging when 8131 // the browser cancels in-flight requests during page unload. 8132 window.addEventListener('pagehide', ()=>{ 8133 isPageUnloading = true; 8134 }); 8135 // Reset the flag on pageshow, e.g. when navigating back and the JavaScript 8136 // execution context is restored by the browser. 8137 window.addEventListener('pageshow', ()=>{ 8138 isPageUnloading = false; 8139 }); 8140} 8141async function fetchServerResponse(url, options) { 8142 const { flightRouterState, nextUrl } = options; 8143 const headers = { 8144 // Enable flight response 8145 [_approuterheaders.RSC_HEADER]: '1', 8146 // Provide the current router state 8147 [_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER]: (0, _flightdatahelpers.prepareFlightRouterStateForRequest)(flightRouterState, options.isHmrRefresh) 8148 }; 8149 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8150 ; 8151 if (nextUrl) { 8152 headers[_approuterheaders.NEXT_URL] = nextUrl; 8153 } 8154 // In static export mode, we need to modify the URL to request the .txt file, 8155 // but we should preserve the original URL for the canonical URL and error handling. 8156 const originalUrl = url; 8157 try { 8158 var _res_headers_get, _flightResponse_d, _flightResponse_p, _flightResponsePromise__debugInfo; 8159 var _res_headers_get1; 8160 if ("TURBOPACK compile-time truthy", 1) { 8161 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8162 ; 8163 } 8164 // Typically, during a navigation, we decode the response using Flight's 8165 // `createFromFetch` API, which accepts a `fetch` promise. 8166 // TODO: Remove this check once the old PPR flag is removed 8167 const isLegacyPPR = ("TURBOPACK compile-time value", false) && !("TURBOPACK compile-time value", false); 8168 const shouldImmediatelyDecode = !isLegacyPPR; 8169 const res = await createFetch(url, headers, 'auto', shouldImmediatelyDecode); 8170 const responseUrl = (0, _routeparams.urlToUrlWithoutFlightMarker)(new URL(res.url)); 8171 const canonicalUrl = res.redirected ? responseUrl : originalUrl; 8172 const contentType = res.headers.get('content-type') || ''; 8173 const interception = !!((_res_headers_get1 = res.headers.get('vary')) === null || _res_headers_get1 === void 0 ? void 0 : _res_headers_get1.includes(_approuterheaders.NEXT_URL)); 8174 const postponed = !!res.headers.get(_approuterheaders.NEXT_DID_POSTPONE_HEADER); 8175 let isFlightResponse = contentType.startsWith(_approuterheaders.RSC_CONTENT_TYPE_HEADER); 8176 if ("TURBOPACK compile-time truthy", 1) { 8177 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8178 ; 8179 } 8180 // If fetch returns something different than flight response handle it like a mpa navigation 8181 // If the fetch was not 200, we also handle it like a mpa navigation 8182 if (!isFlightResponse || !res.ok || !res.body) { 8183 // in case the original URL came with a hash, preserve it before redirecting to the new URL 8184 if (url.hash) { 8185 responseUrl.hash = url.hash; 8186 } 8187 return doMpaNavigation(responseUrl.toString()); 8188 } 8189 // We may navigate to a page that requires a different Webpack runtime. 8190 // In prod, every page will have the same Webpack runtime. 8191 // In dev, the Webpack runtime is minimal for each page. 8192 // We need to ensure the Webpack runtime is updated before executing client-side JS of the new page. 8193 // TODO: This needs to happen in the Flight Client. 8194 // Or Webpack needs to include the runtime update in the Flight response as 8195 // a blocking script. 8196 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8197 ; 8198 let flightResponsePromise = res.flightResponsePromise; 8199 if (flightResponsePromise === null) { 8200 // Typically, `createFetch` would have already started decoding the 8201 // Flight response. If it hasn't, though, we need to decode it now. 8202 // TODO: This should only be reachable if legacy PPR is enabled (i.e. PPR 8203 // without Cache Components). Remove this branch once legacy PPR 8204 // is deleted. 8205 flightResponsePromise = createFromNextReadableStream(res.body, headers, {
8206 allowPartialStream: postponed 8207 }); 8208 } 8209 const [flightResponse, cacheData] = await Promise.all([ 8210 flightResponsePromise, 8211 res.cacheData 8212 ]); 8213 if (((_res_headers_get = res.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _res_headers_get !== void 0 ? _res_headers_get : flightResponse.b) !== (0, _navigationbuildid.getNavigationBuildId)()) { 8214 // The server build does not match the client build. 8215 return doMpaNavigation(res.url); 8216 } 8217 const normalizedFlightData = (0, _flightdatahelpers.normalizeFlightData)(flightResponse.f); 8218 if (typeof normalizedFlightData === 'string') { 8219 return doMpaNavigation(normalizedFlightData); 8220 } 8221 const staticStageData = cacheData !== null ? await resolveStaticStageData(cacheData, flightResponse, headers) : null; 8222 return { 8223 flightData: normalizedFlightData, 8224 canonicalUrl: canonicalUrl, 8225 // TODO: We should be able to read this from the rewrite header, not the 8226 // Flight response. Theoretically they should always agree, but there are 8227 // currently some cases where it's incorrect for interception routes. We 8228 // can always trust the value in the response body. However, per-segment 8229 // prefetch responses don't embed the value in the body; they rely on the 8230 // header alone. So we need to investigate why the header is sometimes 8231 // wrong for interception routes. 8232 renderedSearch: flightResponse.q, 8233 couldBeIntercepted: interception, 8234 supportsPerSegmentPrefetching: flightResponse.S, 8235 postponed, 8236 // The dynamicStaleTime is only present in the response body when 8237 // a page exports unstable_dynamicStaleTime and this is a dynamic render. 8238 // When absent (UnknownDynamicStaleTime), the client falls back to the 8239 // global DYNAMIC_STALETIME_MS. The value is in seconds. 8240 dynamicStaleTime: (_flightResponse_d = flightResponse.d) !== null && _flightResponse_d !== void 0 ? _flightResponse_d : _bfcache.UnknownDynamicStaleTime, 8241 staticStageData, 8242 runtimePrefetchStream: (_flightResponse_p = flightResponse.p) !== null && _flightResponse_p !== void 0 ? _flightResponse_p : null, 8243 responseHeaders: res.headers, 8244 debugInfo: (_flightResponsePromise__debugInfo = flightResponsePromise._debugInfo) !== null && _flightResponsePromise__debugInfo !== void 0 ? _flightResponsePromise__debugInfo : null 8245 }; 8246 } catch (err) { 8247 if (!isPageUnloading) { 8248 console.error("Failed to fetch RSC payload for ".concat(originalUrl, ". Falling back to browser navigation."), err); 8249 } 8250 // If fetch fails handle it like a mpa navigation 8251 // TODO-APP: Add a test for the case where a CORS request fails, e.g. external url redirect coming from the response. 8252 // See https://github.com/vercel/next.js/issues/43605#issuecomment-1451617521 for a reproduction. 8253 return originalUrl.toString(); 8254 } 8255} 8256async function processFetch(response) { 8257 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8258 ; 8259 return { 8260 response, 8261 cacheData: null 8262 }; 8263} 8264async function resolveStaticStageData(cacheData, flightResponse, headers) { 8265 const { isResponsePartial, responseBodyClone } = cacheData; 8266 if (responseBodyClone) { 8267 if (!isResponsePartial) { 8268 // Fully static — cache the entire decoded response as-is. 8269 responseBodyClone.cancel(); 8270 return { 8271 response: flightResponse, 8272 isResponsePartial: false 8273 }; 8274 } 8275 if (flightResponse.l !== undefined) { 8276 // Partially static — truncate the body clone at the byte boundary and 8277 // decode it. 8278 const response = await decodeStaticStage(responseBodyClone, flightResponse.l, headers); 8279 return { 8280 response, 8281 isResponsePartial: true 8282 }; 8283 } 8284 // No caching — cancel the unused clone. 8285 responseBodyClone.cancel(); 8286 } 8287 return null; 8288} 8289async function decodeStaticStage(responseBodyClone, staticStageByteLengthPromise, headers) { 8290 const staticStageByteLength = await staticStageByteLengthPromise; 8291 const truncatedStream = truncateStream(responseBodyClone, staticStageByteLength); 8292 return createFromNextReadableStream(truncatedStream, headers, {
8293 allowPartialStream: true 8294 }); 8295} 8296async function createFetch(url, headers, fetchPriority, shouldImmediatelyDecode, signal) { 8297 // TODO: In output: "export" mode, the headers do nothing. Omit them (and the 8298 // cache busting search param) from the request so they're 8299 // maximally cacheable. 8300 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8301 ; 8302 const deploymentId = (0, _deploymentid.getDeploymentId)(); 8303 if (deploymentId) { 8304 headers['x-deployment-id'] = deploymentId; 8305 } 8306 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8307 ; 8308 const fetchOptions = { 8309 // Backwards compat for older browsers. `same-origin` is the default in modern browsers. 8310 credentials: 'same-origin', 8311 headers, 8312 priority: fetchPriority || undefined, 8313 signal 8314 }; 8315 // `fetchUrl` is slightly different from `url` because we add a cache-busting 8316 // search param to it. This should not leak outside of this function, so we 8317 // track them separately. 8318 let fetchUrl = new URL(url); 8319 await (0, _setcachebustingsearchparam.setCacheBustingSearchParam)(fetchUrl, headers); 8320 let processed = fetch(fetchUrl, fetchOptions).then(processFetch); 8321 let fetchPromise = processed.then((param)=>{ 8322 let { response } = param; 8323 return response; 8324 }); 8325 // Immediately pass the fetch promise to the Flight client so that the debug 8326 // info includes the latency from the client to the server. The internal timer 8327 // in React starts as soon as `createFromFetch` is called. 8328 // 8329 // The only case where we don't do this is during a prefetch, because a 8330 // top-level prefetch response never blocks a navigation; if it hasn't already 8331 // been written into the cache by the time the navigation happens, the router 8332 // will go straight to a dynamic request. 8333 let flightResponsePromise = shouldImmediatelyDecode ? createFromNextFetch(fetchPromise, headers) : null; 8334 let browserResponse = await fetchPromise; 8335 // If the server responds with a redirect (e.g. 307), and the redirected 8336 // location does not contain the cache busting search param set in the 8337 // original request, the response is likely invalid — when following the 8338 // redirect, the browser forwards the request headers, but since the cache 8339 // busting search param is missing, the server will reject the request due to 8340 // a mismatch. 8341 // 8342 // Ideally, we would be able to intercept the redirect response and perform it 8343 // manually, instead of letting the browser automatically follow it, but this 8344 // is not allowed by the fetch API. 8345 // 8346 // So instead, we must "replay" the redirect by fetching the new location 8347 // again, but this time we'll append the cache busting search param to prevent 8348 // a mismatch. 8349 // 8350 // TODO: We can optimize Next.js's built-in middleware APIs by returning a 8351 // custom status code, to prevent the browser from automatically following it. 8352 // 8353 // This does not affect Server Action-based redirects; those are encoded 8354 // differently, as part of the Flight body. It only affects redirects that 8355 // occur in a middleware or a third-party proxy. 8356 let redirected = browserResponse.redirected; 8357 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 8358 ; 8359 // Remove the cache busting search param from the response URL, to prevent it 8360 // from leaking outside of this function. 8361 const responseUrl = new URL(browserResponse.url, fetchUrl); 8362 responseUrl.searchParams.delete(_approuterheaders.NEXT_RSC_UNION_QUERY); 8363 const rscResponse = { 8364 url: responseUrl.href, 8365 // This is true if any redirects occurred, either automatically by the 8366 // browser, or manually by us. So it's different from 8367 // `browserResponse.redirected`, which only tells us whether the browser 8368 // followed a redirect, and only for the last response in the chain. 8369 redirected, 8370 // These can be copied from the last browser response we received. We 8371 // intentionally only expose the subset of fields that are actually used 8372 // elsewhere in the codebase. 8373 ok: browserResponse.ok, 8374 headers: browserResponse.headers, 8375 body: browserResponse.body, 8376 status: browserResponse.status, 8377 // This is the exact promise returned by `createFromFetch`. It contains 8378 // debug information that we need to transfer to any derived promises that 8379 // are later rendered by React. 8380 flightResponsePromise: flightResponsePromise, 8381 cacheData: processed.then((param)=>{ 8382 let { cacheData } = param; 8383 return cacheData; 8384 }) 8385 }; 8386 return rscResponse; 8387} 8388function createFromNextReadableStream(flightStream, requestHeaders, options) { 8389 return createFromReadableStream(flightStream, { 8390 callServer: _appcallserver.callServer, 8391 findSourceMapURL: _appfindsourcemapurl.findSourceMapURL, 8392 debugChannel: createDebugChannel && createDebugChannel(requestHeaders),
8393 unstable_allowPartialStream: options === null || options === void 0 ? void 0 : options.allowPartialStream 8394 }); 8395} 8396function createFromNextFetch(promiseForResponse, requestHeaders) { 8397 return createFromFetch(promiseForResponse, { 8398 callServer: _appcallserver.callServer, 8399 findSourceMapURL: _appfindsourcemapurl.findSourceMapURL, 8400 debugChannel: createDebugChannel && createDebugChannel(requestHeaders) 8401 }); 8402} 8403function truncateStream(stream, byteLength) { 8404 const reader = stream.getReader(); 8405 let remaining = byteLength; 8406 return new ReadableStream({ 8407 async pull (controller) { 8408 if (remaining <= 0) { 8409 reader.cancel(); 8410 controller.close(); 8411 return; 8412 } 8413 const { done, value } = await reader.read(); 8414 if (done) { 8415 controller.close(); 8416 return; 8417 } 8418 if (value.byteLength <= remaining) { 8419 controller.enqueue(value); 8420 remaining -= value.byteLength; 8421 } else { 8422 controller.enqueue(value.subarray(0, remaining)); 8423 remaining = 0; 8424 reader.cancel(); 8425 controller.close(); 8426 } 8427 }, 8428 cancel () { 8429 reader.cancel(); 8430 } 8431 }); 8432} 8433if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 8434 Object.defineProperty(exports.default, '__esModule', { 8435 value: true 8436 }); 8437 Object.assign(exports.default, exports); 8438 module.exports = exports.default; 8439} 8440}), 8441548919, ((__turbopack_context__, module, exports) => { 8442"use strict"; 8443 8444Object.defineProperty(exports, "__esModule", { 8445 value: true 8446}); 8447Object.defineProperty(exports, "isNavigatingToNewRootLayout", { 8448 enumerable: true, 8449 get: function() { 8450 return isNavigatingToNewRootLayout; 8451 } 8452}); 8453const _approutertypes = __turbopack_context__.r(522744); 8454function isNavigatingToNewRootLayout(currentTree, nextTree) { 8455 var _currentTree_; 8456 // Compare segments 8457 const currentTreeSegment = currentTree[0]; 8458 const nextTreeSegment = nextTree.segment; 8459 // If any segment is different before we find the root layout, the root layout has changed. 8460 // E.g. /same/(group1)/layout.js -> /same/(group2)/layout.js 8461 // First segment is 'same' for both, keep looking. (group1) changed to (group2) before the root layout was found, it must have changed. 8462 if (Array.isArray(currentTreeSegment) && Array.isArray(nextTreeSegment)) { 8463 // Compare dynamic param name and type but ignore the value, different values would not affect the current root layout 8464 // /[name] - /slug1 and /slug2, both values (slug1 & slug2) still has the same layout /[name]/layout.js 8465 if (currentTreeSegment[0] !== nextTreeSegment[0] || currentTreeSegment[2] !== nextTreeSegment[2]) { 8466 return true; 8467 } 8468 } else if (currentTreeSegment !== nextTreeSegment) { 8469 return true; 8470 } 8471 // Current tree root layout found 8472 const currentIsRootLayout = (((_currentTree_ = currentTree[4]) !== null && _currentTree_ !== void 0 ? _currentTree_ : 0) & _approutertypes.PrefetchHint.IsRootLayout) !== 0; 8473 const nextIsRootLayout = (nextTree.prefetchHints & _approutertypes.PrefetchHint.IsRootLayout) !== 0; 8474 if (currentIsRootLayout) { 8475 // If the next tree doesn't have the root layout flag, it must have changed. 8476 return !nextIsRootLayout; 8477 } 8478 // Current tree didn't have its root layout here, must have changed. 8479 if (nextIsRootLayout) { 8480 return true; 8481 } 8482 const slots = nextTree.slots; 8483 const currentTreeChildren = currentTree[1]; 8484 if (slots !== null) { 8485 for(const slot in slots){ 8486 const nextTreeChild = slots[slot]; 8487 const currentTreeChild = currentTreeChildren[slot]; 8488 if (currentTreeChild === undefined || isNavigatingToNewRootLayout(currentTreeChild, nextTreeChild)) { 8489 return true; 8490 } 8491 } 8492 } 8493 return false;
8494} 8495if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 8496 Object.defineProperty(exports.default, '__esModule', { 8497 value: true 8498 }); 8499 Object.assign(exports.default, exports); 8500 module.exports = exports.default; 8501} 8502}), 8503494272, ((__turbopack_context__, module, exports) => { 8504"use strict"; 8505 8506Object.defineProperty(exports, "__esModule", { 8507 value: true 8508}); 85090 && (module.exports = { 8510 getLastCommittedTree: null, 8511 setLastCommittedTree: null 8512}); 8513function _export(target, all) { 8514 for(var name in all)Object.defineProperty(target, name, { 8515 enumerable: true, 8516 get: all[name] 8517 }); 8518} 8519_export(exports, { 8520 getLastCommittedTree: function() { 8521 return getLastCommittedTree; 8522 }, 8523 setLastCommittedTree: function() { 8524 return setLastCommittedTree; 8525 } 8526}); 8527// The tree from the last state that was committed to the browser history 8528// (i.e., the last state for which HistoryUpdater's useInsertionEffect ran). 8529// This lets the server-patch reducer distinguish between retrying a 8530// navigation that already pushed a history entry vs one whose transition 8531// suspended and never committed. 8532// 8533// Currently only used by the server-patch retry logic, but this module is a 8534// stepping stone toward a broader refactor of the navigation queue. The 8535// existing AppRouter action queue will eventually be replaced by a more 8536// reactive model that explicitly tracks pending vs committed navigation 8537// state. This file will likely evolve into (or be subsumed by) that new 8538// implementation. 8539let lastCommittedTree = null; 8540function getLastCommittedTree() { 8541 return lastCommittedTree; 8542} 8543function setLastCommittedTree(tree) { 8544 lastCommittedTree = tree; 8545} 8546if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 8547 Object.defineProperty(exports.default, '__esModule', { 8548 value: true 8549 }); 8550 Object.assign(exports.default, exports); 8551 module.exports = exports.default; 8552} 8553}), 8554595871, ((__turbopack_context__, module, exports) => { 8555"use strict"; 8556 8557var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 8558"use strict"; 8559Object.defineProperty(exports, "__esModule", { 8560 value: true 8561}); 85620 && (module.exports = { 8563 FreshnessPolicy: null, 8564 createInitialCacheNodeForHydration: null, 8565 isDeferredRsc: null, 8566 spawnDynamicRequests: null, 8567 startPPRNavigation: null 8568}); 8569function _export(target, all) { 8570 for(var name in all)Object.defineProperty(target, name, { 8571 enumerable: true, 8572 get: all[name] 8573 }); 8574} 8575_export(exports, { 8576 FreshnessPolicy: function() { 8577 return FreshnessPolicy; 8578 }, 8579 createInitialCacheNodeForHydration: function() { 8580 return createInitialCacheNodeForHydration; 8581 }, 8582 isDeferredRsc: function() { 8583 return isDeferredRsc; 8584 }, 8585 spawnDynamicRequests: function() { 8586 return spawnDynamicRequests; 8587 }, 8588 startPPRNavigation: function() { 8589 return startPPRNavigation; 8590 } 8591}); 8592const _approutertypes = __turbopack_context__.r(522744); 8593const _segment = __turbopack_context__.r(813258); 8594const _matchsegments = __turbopack_context__.r(756019); 8595const _createhreffromurl = __turbopack_context__.r(451191); 8596const _fetchserverresponse = __turbopack_context__.r(787288); 8597const _useactionqueue = __turbopack_context__.r(941538); 8598const _routerreducertypes = __turbopack_context__.r(388540); 8599const _isnavigatingtonewrootlayout = __turbopack_context__.r(548919); 8600const _committedstate = __turbopack_context__.r(494272); 8601const _navigation = __turbopack_context__.r(760355); 8602const _cache = __turbopack_context__.r(620896); 8603const _types = __turbopack_context__.r(509396); 8604const _optimisticroutes = __turbopack_context__.r(496167); 8605const _constants = __turbopack_context__.r(663416); 8606const _varypath = __turbopack_context__.r(856655); 8607const _bfcache = __turbopack_context__.r(179027); 8608var FreshnessPolicy = /*#__PURE__*/ function(FreshnessPolicy) { 8609 FreshnessPolicy[FreshnessPolicy["Default"] = 0] = "Default"; 8610 FreshnessPolicy[FreshnessPolicy["Hydration"] = 1] = "Hydration"; 8611 FreshnessPolicy[FreshnessPolicy["HistoryTraversal"] = 2] = "HistoryTraversal"; 8612 FreshnessPolicy[FreshnessPolicy["RefreshAll"] = 3] = "RefreshAll"; 8613 FreshnessPolicy[FreshnessPolicy["HMRRefresh"] = 4] = "HMRRefresh"; 8614 FreshnessPolicy[FreshnessPolicy["Gesture"] = 5] = "Gesture"; 8615 return FreshnessPolicy; 8616}({}); 8617const noop = ()=>{}; 8618function createInitialCacheNodeForHydration(navigatedAt, initialTree, seedData, seedHead, seedDynamicStaleAt) { 8619 // Create the initial cache node tree, using the data embedded into the 8620 // HTML document. 8621 const accumulation = { 8622 separateRefreshUrls: null, 8623 scrollRef: null 8624 }; 8625 const task = createCacheNodeOnNavigation(navigatedAt, initialTree, null, 1, seedData, seedHead, seedDynamicStaleAt, false, accumulation); 8626 return task; 8627} 8628function startPPRNavigation(navigatedAt, oldUrl, oldRenderedSearch, oldCacheNo
8628de, oldRouterState, newRouteTree, newMetadataVaryPath, freshness, seedData, seedHead, seedDynamicStaleAt, isSamePageNavigation, accumulation) { 8629 const didFindRootLayout = false; 8630 const parentNeedsDynamicRequest = false; 8631 const parentRefreshState = null; 8632 const oldRootRefreshState = { 8633 canonicalUrl: (0, _createhreffromurl.createHrefFromUrl)(oldUrl), 8634 renderedSearch: oldRenderedSearch 8635 }; 8636 return updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNode !== null ? oldCacheNode : undefined, oldRouterState, newRouteTree, newMetadataVaryPath, freshness, didFindRootLayout, seedData, seedHead, seedDynamicStaleAt, isSamePageNavigation, parentNeedsDynamicRequest, oldRootRefreshState, parentRefreshState, accumulation); 8637} 8638function updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNode, oldRouterState, newRouteTree, newMetadataVaryPath, freshness, didFindRootLayout, seedData, seedHead, seedDynamicStaleAt, isSamePageNavigation, parentNeedsDynamicRequest, oldRootRefreshState, parentRefreshState, accumulation) { 8639 // Check if this segment matches the one in the previous route. 8640 const oldSegment = oldRouterState[0]; 8641 const newSegment = createSegmentFromRouteTree(newRouteTree); 8642 if (!(0, _matchsegments.matchSegment)(newSegment, oldSegment)) { 8643 // This segment does not match the previous route. We're now entering the 8644 // new part of the target route. Switch to the "create" path. 8645 if (// highest-level layout in a route tree is referred to as the "root" 8646 // layout.) This could mean that we're navigating between two different 8647 // root layouts. When this happens, we perform a full-page (MPA-style) 8648 // navigation. 8649 // 8650 // However, the algorithm for deciding where to start rendering a route 8651 // (i.e. the one performed in order to reach this function) is stricter 8652 // than the one used to detect a change in the root layout. So just 8653 // because we're re-rendering a segment outside of the root layout does 8654 // not mean we should trigger a full-page navigation. 8655 // 8656 // Specifically, we handle dynamic parameters differently: two segments 8657 // are considered the same even if their parameter values are different. 8658 // 8659 // Refer to isNavigatingToNewRootLayout for details. 8660 // 8661 // Note that we only have to perform this extra traversal if we didn't 8662 // already discover a root layout in the part of the tree that is 8663 // unchanged. We also only need to compare the subtree that is not 8664 // shared. In the common case, this branch is skipped completely. 8665 !didFindRootLayout && (0, _isnavigatingtonewrootlayout.isNavigatingToNewRootLayout)(oldRouterState, newRouteTree) || // The global Not Found route (app/global-not-found.tsx) is a special 8666 // case, because it acts like a root layout, but in the router tree, it 8667 // is rendered in the same position as app/layout.tsx. 8668 // 8669 // Any navigation to the global Not Found route should trigger a 8670 // full-page navigation. 8671 // 8672 // TODO: We should probably model this by changing the key of the root 8673 // segment when this happens. Then the root layout check would work 8674 // as expected, without a special case. 8675 newSegment === _segment.NOT_FOUND_SEGMENT_KEY) { 8676 return null; 8677 } 8678 return createCacheNodeOnNavigation(navigatedAt, newRouteTree, newMetadataVaryPath, freshness, seedData, seedHead, seedDynamicStaleAt, parentNeedsDynamicRequest, accumulation); 8679 } 8680 const newSlots = newRouteTree.slots; 8681 const oldRouterStateChildren = oldRouterState[1]; 8682 const seedDataChildren = seedData !== null ? seedData[1] : null; 8683 // We're currently traversing the part of the tree that was also part of 8684 // the previous route. If we discover a root layout, then we don't need to 8685 // trigger an MPA navigation. 8686 const childDidFindRootLayout = didFindRootLayout || (newRouteTree.prefetchHints & _approutertypes.PrefetchHint.IsRootLayout) !== 0; 8687 let shouldRefreshDynamicData = false;
8688 switch(freshness){ 8689 case 0: 8690 case 2: 8691 case 1: 8692 case 5: 8693 shouldRefreshDynamicData = false; 8694 break; 8695 case 3: 8696 case 4: 8697 shouldRefreshDynamicData = true; 8698 break; 8699 default: 8700 freshness; 8701 break; 8702 } 8703 // TODO: We're not consistent about how we do this check. Some places 8704 // check if the segment starts with PAGE_SEGMENT_KEY, but most seem to 8705 // check if there any any children, which is why I'm doing it here. We 8706 // should probably encode an empty children set as `null` though. Either 8707 // way, we should update all the checks to be consistent. 8708 const isLeafSegment = newSlots === null; 8709 // Get the data for this segment. Since it was part of the previous route, 8710 // usually we just clone the data from the old CacheNode. However, during a 8711 // refresh or a revalidation, there won't be any existing CacheNode. So we 8712 // may need to consult the prefetch cache, like we would for a new segment. 8713 let newCacheNode; 8714 let needsDynamicRequest;
8715 if (oldCacheNode !== undefined && !shouldRefreshDynamicData && // During a same-page navigation, we always refetch the page segments 8716 !(isLeafSegment && isSamePageNavigation)) { 8717 // Reuse the existing CacheNode 8718 const dropPrefetchRsc = false; 8719 newCacheNode = reuseSharedCacheNode(dropPrefetchRsc, oldCacheNode); 8720 needsDynamicRequest = false; 8721 } else { 8722 // If this is part of a refresh, ignore the existing CacheNode and create a 8723 // new one. 8724 const seedRsc = seedData !== null ? seedData[0] : null; 8725 const result = createCacheNodeForSegment(navigatedAt, newRouteTree, seedRsc, newMetadataVaryPath, seedHead, freshness, seedDynamicStaleAt); 8726 newCacheNode = result.cacheNode; 8727 needsDynamicRequest = result.needsDynamicRequest; 8728 // Carry forward the old node's scrollRef. This preserves scroll 8729 // intent when a prior navigation's cache node is replaced by a 8730 // refresh before the scroll handler has had a chance to fire — 8731 // e.g. when router.push() and router.refresh() are called in the 8732 // same startTransition batch.
8733 if (oldCacheNode !== undefined) { 8734 newCacheNode.scrollRef = oldCacheNode.scrollRef; 8735 } 8736 } 8737 // During a refresh navigation, there's a special case that happens when 8738 // entering a "default" slot. The default slot may not be part of the 8739 // current route; it may have been reused from an older route. If so, 8740 // we need to fetch its data from the old route's URL rather than current 8741 // route's URL. Keep track of this as we traverse the tree. 8742 const maybeRefreshState = newRouteTree.refreshState; 8743 const refreshState = maybeRefreshState !== undefined && maybeRefreshState !== null ? maybeRefreshState : parentRefreshState; 8744 // If this segment itself needs to fetch new data from the server, then by 8745 // definition it is being refreshed. Track its refresh URL so we know which 8746 // URL to request the data from. 8747 if (needsDynamicRequest && refreshState !== null) { 8748 accumulateRefreshUrl(accumulation, refreshState); 8749 } 8750 // As we diff the trees, we may sometimes modify (copy-on-write, not mutate) 8751 // the Route Tree that was returned by the server — for example, in the case 8752 // of default parallel routes, we preserve the currently active segment. To 8753 // avoid mutating the original tree, we clone the router state children along 8754 // the return path. 8755 let patchedRouterStateChildren = {}; 8756 let taskChildren = null; 8757 // Most navigations require a request to fetch additional data from the 8758 // server, either because the data was not already prefetched, or because the 8759 // target route contains dynamic data that cannot be prefetched. 8760 // 8761 // However, if the target route is fully static, and it's already completely 8762 // loaded into the segment cache, then we can skip the server request. 8763 // 8764 // This starts off as `false`, and is set to `true` if any of the child 8765 // routes requires a dynamic request. 8766 let childNeedsDynamicRequest = false; 8767 // As we traverse the children, we'll construct a FlightRouterState that can 8768 // be sent to the server to request the dynamic data. If it turns out that 8769 // nothing in the subtree is dynamic (i.e. childNeedsDynamicRequest is false 8770 // at the end), then this will be discarded. 8771 // TODO: We can probably optimize the format of this data structure to only 8772 // include paths that are dynamic. Instead of reusing the 8773 // FlightRouterState type. 8774 let dynamicRequestTreeChildren = {}; 8775 let newCacheNodeSlots = null; 8776 if (newSlots !== null) { 8777 const oldCacheNodeSlots = oldCacheNode !== undefined ? oldCacheNode.slots : null; 8778 newCacheNode.slots = newCacheNodeSlots = {}; 8779 taskChildren = new Map(); 8780 for(let parallelRouteKey in newSlots){ 8781 let newRouteTreeChild = newSlots[parallelRouteKey]; 8782 const oldRouterStateChild = oldRouterStateChildren[parallelRouteKey]; 8783 if (oldRouterStateChild === undefined) { 8784 // This should never happen, but if it does, it suggests a malformed 8785 // server response. Trigger a full-page navigation. 8786 return null; 8787 } 8788 let seedDataChild = seedDataChildren !== null ? seedDataChildren[parallelRouteKey] : null; 8789 const oldSegmentChild = oldRouterStateChild[0]; 8790 let newSegmentChild = createSegmentFromRouteTree(newRouteTreeChild); 8791 let seedHeadChild = seedHead; 8792 if (// was stashed in the history entry as-is. 8793 freshness !== 2 && newSegmentChild === _segment.DEFAULT_SEGMENT_KEY && oldSegmentChild !== _segment.DEFAULT_SEGMENT_KEY) { 8794 // This is a "default" segment. These are never sent by the server during 8795 // a soft navigation; instead, the client reuses whatever segment was 8796 // already active in that slot on the previous route. 8797 newRouteTreeChild = reuseActiveSegmentInDefaultSlot(newRouteTree, parallelRouteKey, oldRootRefreshState, oldRouterStateChild); 8798 newSegmentChild = createSegmentFromRouteTree(newRouteTreeChild); 8799 // Since we're switching to a different route tree, these are no 8800 // longer valid, because they correspond to the outer tree. 8801 seedDataChild = null; 8802 seedHeadChild = null; 8803 }
8804 const oldCacheNodeChild = oldCacheNodeSlots !== null ? oldCacheNodeSlots[parallelRouteKey] : undefined; 8805 const taskChild = updateCacheNodeOnNavigation(navigatedAt, oldUrl, oldCacheNodeChild, oldRouterStateChild, newRouteTreeChild, newMetadataVaryPath, freshness, childDidFindRootLayout, seedDataChild !== null && seedDataChild !== void 0 ? seedDataChild : null, seedHeadChild, seedDynamicStaleAt, isSamePageNavigation, parentNeedsDynamicRequest || needsDynamicRequest, oldRootRefreshState, refreshState, accumulation); 8806 if (taskChild === null) { 8807 // One of the child tasks discovered a change to the root layout. 8808 // Immediately unwind from this recursive traversal. This will trigger a 8809 // full-page navigation. 8810 return null; 8811 } 8812 // Recursively propagate up the child tasks. 8813 taskChildren.set(parallelRouteKey, taskChild); 8814 newCacheNodeSlots[parallelRouteKey] = taskChild.node; 8815 // The child tree's route state may be different from the prefetched 8816 // route sent by the server. We need to clone it as we traverse back up 8817 // the tree. 8818 const taskChildRoute = taskChild.route; 8819 patchedRouterStateChildren[parallelRouteKey] = taskChildRoute; 8820 const dynamicRequestTreeChild = taskChild.dynamicRequestTree; 8821 if (dynamicRequestTreeChild !== null) { 8822 // Something in the child tree is dynamic. 8823 childNeedsDynamicRequest = true; 8824 dynamicRequestTreeChildren[parallelRouteKey] = dynamicRequestTreeChild; 8825 } else { 8826 dynamicRequestTreeChildren[parallelRouteKey] = taskChildRoute; 8827 } 8828 } 8829 } 8830 const newFlightRouterState = [ 8831 createSegmentFromRouteTree(newRouteTree), 8832 patchedRouterStateChildren, 8833 refreshState !== null ? [ 8834 refreshState.canonicalUrl, 8835 refreshState.renderedSearch 8836 ] : null, 8837 null, 8838 newRouteTree.prefetchHints 8839 ]; 8840 return { 8841 status: needsDynamicRequest ? 0 : 1, 8842 route: newFlightRouterState, 8843 node: newCacheNode, 8844 dynamicRequestTree: createDynamicRequestTree(newFlightRouterState, dynamicRequestTreeChildren, needsDynamicRequest, childNeedsDynamicRequest, parentNeedsDynamicRequest), 8845 refreshState, 8846 children: taskChildren 8847 }; 8848} 8849/** 8850 * Assigns a ScrollRef to a new leaf CacheNode so the scroll handler 8851 * knows to scroll to it after navigation. All leaves in the same 8852 * navigation share the same ScrollRef — the first segment to scroll 8853 * consumes it, preventing others from also scrolling. 8854 *
8855 * This is only called inside `createCacheNodeOnNavigation`, which only 8856 * runs when segments diverge from the previous route. So for a refresh 8857 * where the route structure stays the same, segments match, the update 8858 * path is taken, and this function is never called — no scroll ref is 8859 * assigned. A scroll ref is only assigned when the route actually 8860 * changed (e.g. a redirect, or a dynamic condition on the server that 8861 * produces a different route). 8862 * 8863 * Skipped during hydration (initial render should not scroll) and 8864 * history traversal (scroll restoration is handled separately). 8865 */ function accumulateScrollRef(freshness, cacheNode, accumulation) { 8866 switch(freshness){ 8867 case 0: 8868 case 5: 8869 case 3: 8870 case 4: 8871 if (accumulation.scrollRef === null) { 8872 accumulation.scrollRef = { 8873 current: true 8874 }; 8875 } 8876 cacheNode.scrollRef = accumulation.scrollRef; 8877 break; 8878 case 1: 8879 break; 8880 case 2: 8881 break; 8882 default: 8883 freshness; 8884 break; 8885 } 8886} 8887function createCacheNodeOnNavigation(navigatedAt, newRouteTree, newMetadataVaryPath, freshness, seedData, seedHead, seedDynamicStaleAt, parentNeedsDynamicRequest, accumulation) { 8888 // Same traversal as updateCacheNodeNavigation, but simpler. We switch to this 8889 // path once we reach the part of the tree that was not in the previous route. 8890 // We don't need to diff against the old tree, we just need to create a new 8891 // one. We also don't need to worry about any refresh-related logic. 8892 // 8893 // For the most part, this is a subset of updateCacheNodeOnNavigation, so any 8894 // change that happens in this function likely needs to be applied to that 8895 // one, too. However there are some places where the behavior intentionally 8896 // diverges, which is why we keep them separate. 8897 const newSegment = createSegmentFromRouteTree(newRouteTree); 8898 const newSlots = newRouteTree.slots; 8899 const seedDataChildren = seedData !== null ? seedData[1] : null; 8900 const seedRsc = seedData !== null ? seedData[0] : null; 8901 const result = createCacheNodeForSegment(navigatedAt, newRouteTree, seedRsc, newMetadataVaryPath, seedHead, freshness, seedDynamicStaleAt); 8902 const newCacheNode = result.cacheNode; 8903 const needsDynamicRequest = result.needsDynamicRequest; 8904 const isLeafSegment = newSlots === null; 8905 if (isLeafSegment) { 8906 accumulateScrollRef(freshness, newCacheNode, accumulation); 8907 } 8908 let patchedRouterStateChildren = {}; 8909 let taskChildren = null; 8910 let childNeedsDynamicRequest = false; 8911 let dynamicRequestTreeChildren = {}; 8912 let newCacheNodeSlots = null; 8913 if (newSlots !== null) { 8914 newCacheNode.slots = newCacheNodeSlots = {}; 8915 taskChildren = new Map(); 8916 for(let parallelRouteKey in newSlots){ 8917 const newRouteTreeChild = newSlots[parallelRouteKey]; 8918 const seedDataChild = seedDataChildren !== null ? seedDataChildren[parallelRouteKey] : null; 8919 const taskChild = createCacheNodeOnNavigation(navigatedAt, newRouteTreeChild, newMetadataVaryPath, freshness, seedDataChild !== null && seedDataChild !== void 0 ? seedDataChild : null, seedHead, seedDynamicStaleAt, parentNeedsDynamicRequest || needsDynamicRequest, accumulation); 8920 taskChildren.set(parallelRouteKey, taskChild); 8921 newCacheNodeSlots[parallelRouteKey] = taskChild.node; 8922 const taskChildRoute = taskChild.route; 8923 patchedRouterStateChildren[parallelRouteKey] = taskChildRoute; 8924 const dynamicRequestTreeChild = taskChild.dynamicRequestTree; 8925 if (dynamicRequestTreeChild !== null) { 8926 childNeedsDynamicRequest = true; 8927 dynamicRequestTreeChildren[parallelRouteKey] = dynamicRequestTreeChild; 8928 } else { 8929 dynamicRequestTreeChildren[parallelRouteKey] = taskChildRoute; 8930 } 8931 } 8932 } 8933 const newFlightRouterState = [ 8934 newSegment, 8935 patchedRouterStateChildren, 8936 null, 8937 null, 8938 newRouteTree.prefetchHints 8939 ]; 8940 return { 8941 status: needsDynamicRequest ? 0 : 1, 8942 route: newFlightRouterState, 8943 node: newCacheNode, 8944 dynamicRequestTree: createDynamicRequestTree(newFlightRouterState, dynamicRequestTreeChildren, needsDynamicRequest, childNeedsDynamicRequest, parentNeedsDynamicRequest), 8945 // This route is not part of the current tree, so there's no reason to 8946 // track the refresh URL. 8947 refreshState: null, 8948 children: taskChildren 8949 }; 8950} 8951function createSegmentFromRouteTree(newRouteTree) { 8952 if (newRouteTree.isPage) { 8953 // In a dynamic server response, the server embeds the search params into 8954 // the segment key, but in a static one it's omitted. The client handles 8955 // this inconsistency by adding the search params back right at the end. 8956 // 8957 // TODO: The only thing this is used for is to create a cache key for 8958 // ChildSegmentMap. But we already track the `renderedSearch` everywhere as 8959 // part of the varyPath. The plan is get rid of ChildSegmentMap and 8960 // store the page data in a CacheMap using the varyPath, like we do 8961 // for prefetches. Then we can remove it from the segment key. 8962 // 8963 // As an incremental step, we can grab the search params from the varyPath. 8964 const renderedSearch = (0, _varypath.getRenderedSearchFromVaryPath)(newRouteTree.varyPath); 8965 if (renderedSearch === null) { 8966 return _segment.PAGE_SEGMENT_KEY; 8967 } 8968 // This is based on equivalent logic in addSearchParamsIfPageSegment, used 8969 // on the server. 8970 const stringifiedQuery = JSON.stringify(Object.fromEntries(new URLSearchParams(renderedSearch))); 8971 return stringifiedQuery !== '{}' ? _segment.PAGE_SEGMENT_KEY + '?' + stringifiedQuery : _segment.PAGE_SEGMENT_KEY; 8972 } 8973 return newRouteTree.segment; 8974} 8975function patchRouterStateWithNewChildren(baseRouterState, newChildren) { 8976 const clone = [ 8977 baseRouterState[0], 8978 newChildren 8979 ]; 8980 // Based on equivalent logic in apply-router-state-patch-to-tree, but should 8981 // confirm whether we need to copy all of these fields. Not sure the server 8982 // ever sends, e.g. the refetch marker. 8983 if (2 in baseRouterState) { 8984 clone[2] = baseRouterState[2]; 8985 } 8986 if (3 in baseRouterState) { 8987 clone[3] = baseRouterState[3]; 8988 } 8989 if (4 in baseRouterState) { 8990 clone[4] = baseRouterState[4]; 8991 } 8992 return clone; 8993} 8994function createDynamicRequestTree(newRouterState, dynamicRequestTreeChildren, needsDynamicRequest, childNeedsDynamicRequest, parentNeedsDynamicRequest) { 8995 // Create a FlightRouterState that instructs the server how to render the 8996 // requested segment. 8997 // 8998 // Or, if neither this segment nor any of the children require a new data, 8999 // then we return `null` to skip the request. 9000 let dynamicRequestTree = null; 9001 if (needsDynamicRequest) { 9002 dynamicRequestTree = patchRouterStateWithNewChildren(newRouterState, dynamicRequestTreeChildren); 9003 // The "refetch" marker is set on the top-most segment that requires new 9004 // data. We can omit it if a parent was already marked. 9005 if (!parentNeedsDynamicRequest) { 9006 dynamicRequestTree[3] = 'refetch'; 9007 } 9008 } else if (childNeedsDynamicRequest) { 9009 // This segment does not request new data, but at least one of its 9010 // children does. 9011 dynamicRequestTree = patchRouterStateWithNewChildren(newRouterState, dynamicRequestTreeChildren); 9012 } else { 9013 dynamicRequestTree = null; 9014 } 9015 return dynamicRequestTree; 9016} 9017function accumulateRefreshUrl(accumulation, refreshState) { 9018 // This is a refresh navigation, and we're inside a "default" slot that's 9019 // not part of the current route; it was reused from an older route. In 9020 // order to get fresh data for this reused route, we need to issue a 9021 // separate request using the old route's URL. 9022 // 9023 // Track these extra URLs in the accumulated result. Later, we'll construct 9024 // an appropriate request for each unique URL in the final set. The reason 9025 // we don't do it immediately here is so we can deduplicate multiple 9026 // instances of the same URL into a single request. See 9027 // listenForDynamicRequest for more details. 9028 const refreshUrl = refreshState.canonicalUrl; 9029 const separateRefreshUrls = accumulation.separateRefreshUrls; 9030 if (separateRefreshUrls === null) { 9031 accumulation.separateRefreshUrls = new Set([ 9032 refreshUrl 9033 ]); 9034 } else { 9035 separateRefreshUrls.add(refreshUrl); 9036 } 9037} 9038function reuseActiveSegmentInDefaultSlot(parentRouteTree, parallelRouteKey, oldRootRefreshState, oldRouterState) { 9039 // This is a "default" segment. These are never sent by the server during a 9040 // soft navigation; instead, the client reuses whatever segment was already 9041 // active in that slot on the previous route. This means if we later need to 9042 // refresh the segment, it will have to be refetched from the previous route's 9043 // URL. We store it in the Flight Router State. 9044 let reusedUrl; 9045 let reusedRenderedSearch; 9046 const oldRefreshState = oldRouterState[2]; 9047 if (oldRefreshState !== undefined && oldRefreshState !== null) { 9048 // This segment was already reused from an even older route. Keep its 9049 // existing URL and refresh state. 9050 reusedUrl = oldRefreshState[0]; 9051 reusedRenderedSearch = oldRefreshState[1]; 9052 } else { 9053 // Since this route didn't already have a refresh state, it must have been 9054 // reachable from the root of the old route. So we use the refresh state 9055 // that represents the old route. 9056 reusedUrl = oldRootRefreshState.canonicalUrl; 9057 reusedRenderedSearch = oldRootRefreshState.renderedSearch; 9058 } 9059 const acc = { 9060 metadataVaryPath: null 9061 }; 9062 const reusedRouteTree = (0, _cache.convertReusedFlightRouterStateToRouteTree)(parentRouteTree, parallelRouteKey, oldRouterState, reusedRenderedSearch, acc); 9063 reusedRouteTree.refreshState = { 9064 canonicalUrl: reusedUrl, 9065 renderedSearch: reusedRenderedSearch 9066 }; 9067 return reusedRouteTree; 9068}
9069function reuseSharedCacheNode(dropPrefetchRsc, existingCacheNode) { 9070 // Clone the CacheNode that was already present in the previous tree. 9071 // Carry forward the scrollRef so scroll intent from a prior navigation 9072 // survives tree rebuilds (e.g. push + refresh in the same batch). 9073 return createCacheNode(existingCacheNode.rsc, dropPrefetchRsc ? null : existingCacheNode.prefetchRsc, existingCacheNode.head, dropPrefetchRsc ? null : existingCacheNode.prefetchHead, existingCacheNode.scrollRef); 9074} 9075function createCacheNodeForSegment(now, tree, seedRsc, metadataVaryPath, seedHead, freshness, dynamicStaleAt) { 9076 // Construct a new CacheNode using data from the BFCache, the client's 9077 // Segment Cache, or seeded from a server response. 9078 // 9079 // If there's a cache miss, or if we only have a partial hit, we'll render 9080 // the partial state immediately, and spawn a request to the server to fill 9081 // in the missing data. 9082 // 9083 // If the segment is fully cached on the client already, we can omit this 9084 // segment from the server request. 9085 // 9086 // If we already have a dynamic data response associated with this navigation, 9087 // as in the case of a Server Action-initiated redirect or refresh, we may 9088 // also be able to use that data without spawning a new request. (This is 9089 // referred to as the "seed" data.) 9090 const isPage = tree.isPage; 9091 // During certain kinds of navigations, we may be able to render from 9092 // the BFCache. 9093 switch(freshness){ 9094 case 0: 9095 { 9096 // Check BFCache during regular navigations. The entry's staleAt 9097 // determines whether it's still fresh. This is used when 9098 // staleTimes.dynamic is configured globally or when a page exports 9099 // unstable_dynamicStaleTime for per-page control. 9100 const bfcacheEntry = (0, _bfcache.readFromBFCacheDuringRegularNavigation)(now, tree.varyPath); 9101 if (bfcacheEntry !== null) { 9102 return { 9103 cacheNode: createCacheNode(bfcacheEntry.rsc, bfcacheEntry.prefetchRsc, bfcacheEntry.head, bfcacheEntry.prefetchHead), 9104 needsDynamicRequest: false 9105 }; 9106 } 9107 break; 9108 } 9109 case 1: 9110 { 9111 // This is not related to the BFCache but it is a special case. 9112 // 9113 // We should never spawn network requests during hydration. We must treat 9114 // the initial payload as authoritative, because the initial page load is 9115 // used as a last-ditch mechanism for recovering the app. 9116 // 9117 // This is also an important safety check because if this leaks into the 9118 // server rendering path (which theoretically it never should because the 9119 // server payload should be consistent), the server would hang because these 9120 // promises would never resolve. 9121 // 9122 // TODO: There is an existing case where the global "not found" boundary 9123 // triggers this path. But it does render correctly despite that. That's an 9124 // unusual render path so it's not surprising, but we should look into 9125 // modeling it in a more consistent way. See also the /_notFound special 9126 // case in updateCacheNodeOnNavigation. 9127 const rsc = seedRsc; 9128 const prefetchRsc = null; 9129 const head = isPage ? seedHead : null; 9130 const prefetchHead = null; 9131 (0, _bfcache.writeToBFCache)(now, tree.varyPath, rsc, prefetchRsc, head, prefetchHead, dynamicStaleAt); 9132 if (isPage && metadataVaryPath !== null) { 9133 (0, _bfcache.writeHeadToBFCache)(now, metadataVaryPath, head, prefetchHead, dynamicStaleAt); 9134 } 9135 return { 9136 cacheNode: createCacheNode(rsc, prefetchRsc, head, prefetchHead), 9137 needsDynamicRequest: false 9138 }; 9139 } 9140 case 2: 9141 const bfcacheEntry = (0, _bfcache.readFromBFCache)(tree.varyPath); 9142 if (bfcacheEntry !== null) { 9143 // Only show prefetched data if the dynamic data is still pending. This 9144 // avoids a flash back to the prefetch state in a case where it's highly 9145 // likely to have already streamed in. 9146 // 9147 // Tehnically, what we're actually checking is whether the dynamic 9148 // network response was received. But since it's a streaming response, 9149 // this does not mean that all the dynamic data has fully streamed in. 9150 // It just means that _some_ of the dynamic data was received. But as a 9151 // heuristic, we assume that the rest dynamic data will stream in 9152 // quickly, so it's still better to skip the prefetch state. 9153 const oldRsc = bfcacheEntry.rsc; 9154 const oldRscDidResolve = !isDeferredRsc(oldRsc) || oldRsc.status !== 'pending'; 9155 const dropPrefetchRsc = oldRscDidResolve; 9156 return { 9157 cacheNode: createCacheNode(bfcacheEntry.rsc, dropPrefetchRsc ? null : bfcacheEntry.prefetchRsc, bfcacheEntry.head, dropPrefetchRsc ? null : bfcacheEntry.prefetchHead), 9158 needsDynamicRequest: false 9159 }; 9160 } 9161 break; 9162 case 3: 9163 case 4: 9164 case 5: 9165 break; 9166 default: 9167 freshness; 9168 break; 9169 }
9170 let cachedRsc = null; 9171 let isCachedRscPartial = true; 9172 const segmentEntry = (0, _cache.readSegmentCacheEntry)(now, tree.varyPath); 9173 if (segmentEntry !== null) { 9174 switch(segmentEntry.status){ 9175 case _cache.EntryStatus.Fulfilled: 9176 { 9177 // Happy path: a cache hit 9178 cachedRsc = segmentEntry.rsc; 9179 isCachedRscPartial = segmentEntry.isPartial; 9180 break; 9181 } 9182 case _cache.EntryStatus.Pending: 9183 { 9184 // We haven't received data for this segment yet, but there's already 9185 // an in-progress request. Since it's extremely likely to arrive 9186 // before the dynamic data response, we might as well use it. 9187 const promiseForFulfilledEntry = (0, _cache.waitForSegmentCacheEntry)(segmentEntry); 9188 cachedRsc = promiseForFulfilledEntry.then((entry)=>entry !== null ? entry.rsc : null); 9189 // Because the request is still pending, we typically don't know yet 9190 // whether the response will be partial. We shouldn't skip this segment 9191 // during the dynamic navigation request. Otherwise, we might need to 9192 // do yet another request to fill in the remaining data, creating 9193 // a waterfall. 9194 // 9195 // The one exception is if this segment is being fetched with via 9196 // prefetch={true} (i.e. the "force stale" or "full" strategy). If so, 9197 // we can assume the response will be full. This field is set to `false` 9198 // for such segments. 9199 isCachedRscPartial = segmentEntry.isPartial; 9200 break; 9201 } 9202 case _cache.EntryStatus.Empty: 9203 case _cache.EntryStatus.Rejected: 9204 { 9205 break; 9206 } 9207 default: 9208 { 9209 segmentEntry; 9210 break; 9211 } 9212 } 9213 } 9214 // Now combine the cached data with the seed data to determine what we can 9215 // render immediately, versus what needs to stream in later. 9216 // A partial state to show immediately while we wait for the final data to 9217 // arrive. If `rsc` is already a complete value (not partial), or if we 9218 // don't have any useful partial state, this will be `null`. 9219 let prefetchRsc; 9220 // The final, resolved segment data. If the data is missing, this will be a 9221 // promise that resolves to the eventual data. A resolved value of `null` 9222 // means the data failed to load; the LayoutRouter will suspend indefinitely 9223 // until the router updates again (refer to finishNavigationTask). 9224 let rsc; 9225 let doesSegmentNeedDynamicRequest; 9226 if (seedRsc !== null) { 9227 // We already have a dynamic server response for this segment. 9228 if (isCachedRscPartial) { 9229 // The seed data may still be streaming in, so it's worth showing the 9230 // partial cached state in the meantime. 9231 prefetchRsc = cachedRsc; 9232 rsc = seedRsc; 9233 } else { 9234 // We already have a completely cached segment. Ignore the seed data, 9235 // which may still be streaming in. This shouldn't happen in the normal 9236 // case because the client will inform the server which segments are 9237 // already fully cached, and the server will skip rendering them. 9238 prefetchRsc = null;
9239 rsc = cachedRsc; 9240 } 9241 doesSegmentNeedDynamicRequest = false; 9242 } else { 9243 if (isCachedRscPartial) { 9244 // The cached data contains dynamic holes, or it's missing entirely. We'll 9245 // show the partial state immediately (if available), and stream in the 9246 // final data. 9247 // 9248 // Create a pending promise that we can later write to when the 9249 // data arrives from the server. 9250 prefetchRsc = cachedRsc; 9251 rsc = createDeferredRsc(); 9252 } else { 9253 // The data is fully cached. 9254 prefetchRsc = null; 9255 rsc = cachedRsc; 9256 } 9257 doesSegmentNeedDynamicRequest = isCachedRscPartial; 9258 } 9259 // If this is a page segment, we need to do the same for the head. This 9260 // follows analogous logic to the segment data above. 9261 // TODO: We don't need to store the head on the page segment's CacheNode; we 9262 // can lift it to the main state object. Then we can also delete 9263 // findHeadCache. 9264 let prefetchHead = null; 9265 let head = null; 9266 let doesHeadNeedDynamicRequest = isPage; 9267 if (isPage) { 9268 let cachedHead = null; 9269 let isCachedHeadPartial = true; 9270 if (metadataVaryPath !== null) { 9271 const metadataEntry = (0, _cache.readSegmentCacheEntry)(now, metadataVaryPath); 9272 if (metadataEntry !== null) { 9273 switch(metadataEntry.status){ 9274 case _cache.EntryStatus.Fulfilled: 9275 { 9276 cachedHead = metadataEntry.rsc; 9277 isCachedHeadPartial = metadataEntry.isPartial; 9278 break; 9279 } 9280 case _cache.EntryStatus.Pending: 9281 { 9282 cachedHead = (0, _cache.waitForSegmentCacheEntry)(metadataEntry).then((entry)=>entry !== null ? entry.rsc : null); 9283 isCachedHeadPartial = metadataEntry.isPartial; 9284 break; 9285 } 9286 case _cache.EntryStatus.Empty: 9287 case _cache.EntryStatus.Rejected: 9288 { 9289 break; 9290 } 9291 default: 9292 { 9293 metadataEntry; 9294 break; 9295 } 9296 } 9297 } 9298 } 9299 if (("TURBOPACK compile-time value", false) && isCachedHeadPartial) { 9300 // TODO: When optimistic routing is enabled, don't block on waiting for 9301 // the viewport to resolve. This is a temporary workaround until Vary 9302 // Params are tracked when rendering the metadata. We'll fix it before 9303 // this feature is stable. However, it's not a critical issue because 1) 9304 // it will stream in eventually anyway 2) metadata is wrapped in an 9305 // internal Suspense boundary, so is always non-blocking; this only 9306 // affects the viewport node, which is meant to blocking, however... 3) 9307 // before Segment Cache landed this wasn't always the case, anyway, so 9308 // it's unlikely that many people are relying on this behavior. Still, 9309 // will be fixed before stable. It's the very next step in the sequence of 9310 // work on this project. 9311 // 9312 // This line of code works because the App Router treats `null` as 9313 // "no renderable head available", rather than an empty head. React treats 9314 // an empty string as empty. 9315 cachedHead = ''; 9316 } 9317 if (seedHead !== null) { 9318 if (isCachedHeadPartial) { 9319 prefetchHead = cachedHead; 9320 head = seedHead; 9321 } else { 9322 prefetchHead = null; 9323 head = cachedHead; 9324 } 9325 doesHeadNeedDynamicRequest = false; 9326 } else { 9327 if (isCachedHeadPartial) { 9328 prefetchHead = cachedHead; 9329 head = createDeferredRsc(); 9330 } else { 9331 prefetchHead = null; 9332 head = cachedHead; 9333 } 9334 doesHeadNeedDynamicRequest = isCachedHeadPartial; 9335 } 9336 } 9337 // Now that we're creating a new segment, write its data to the BFCache. A 9338 // subsequent back/forward navigation will reuse this same data, until or 9339 // unless it's cleared by a refresh/revalidation. 9340 // 9341 // Skip BFCache writes for optimistic navigations since they are transient 9342 // and will be replaced by the canonical navigation. 9343 if (freshness !== 5) { 9344 (0, _bfcache.writeToBFCache)(now, tree.varyPath, rsc, prefetchRsc, head, prefetchHead, dynamicStaleAt); 9345 if (isPage && metadataVaryPath !== null) { 9346 (0, _bfcache.writeHeadToBFCache)(now, metadataVaryPath, head, prefetchHead, dynamicStaleAt); 9347 } 9348 } 9349 return { 9350 cacheNode: createCacheNode(rsc, prefetchRsc, head, prefetchHead), 9351 // TODO: We should store this field on the CacheNode itself. I think we can 9352 // probably unify NavigationTask, CacheNode, and DeferredRsc into a 9353 // single type. Or at least CacheNode and DeferredRsc. 9354 needsDynamicRequest: doesSegmentNeedDynamicRequest || doesHeadNeedDynamicRequest 9355 }; 9356} 9357function createCacheNode(rsc, prefetchRsc, head, prefetchHead) { 9358 let scrollRef = arguments.length > 4 && arguments[4] !== void 0 ? arguments[4] : null; 9359 return { 9360 rsc, 9361 prefetchRsc, 9362 head, 9363 prefetchHead, 9364 slots: null, 9365 scrollRef 9366 }; 9367} 9368// Represents whether the previuos navigation resulted in a route tree mismatch. 9369// A mismatch results in a refresh of the page. If there are two successive 9370// mismatches, we will fall back to an MPA navigation, to prevent a retry loop. 9371let previousNavigationDidMismatch = false;
9372function spawnDynamicRequests(task, primaryUrl, nextUrl, freshnessPolicy, accumulation, // prediction. Passed through so it can be marked as having a dynamic rewrite 9373// if the server returns a different pathname than expected (indicating 9374// dynamic rewrite behavior that varies by param value). 9375routeCacheEntry, // server-patch retry logic so it can inherit the intent if the original 9376// transition hasn't committed yet. 9377navigateType) { 9378 const dynamicRequestTree = task.dynamicRequestTree; 9379 if (dynamicRequestTree === null) { 9380 // This navigation was fully cached. There are no dynamic requests to spawn. 9381 previousNavigationDidMismatch = false; 9382 return; 9383 } 9384 // This is intentionally not an async function to discourage the caller from 9385 // awaiting the result. Any subsequent async operations spawned by this 9386 // function should result in a separate navigation task, rather than 9387 // block the original one. 9388 // 9389 // In this function we spawn (but do not await) all the network requests that 9390 // block the navigation, and collect the promises. The next function, 9391 // `finishNavigationTask`, can await the promises in any order without 9392 // accidentally introducing a network waterfall.
9393 const primaryRequestPromise = fetchMissingDynamicData(task, dynamicRequestTree, primaryUrl, nextUrl, freshnessPolicy, routeCacheEntry); 9394 const separateRefreshUrls = accumulation.separateRefreshUrls; 9395 let refreshRequestPromises = null; 9396 if (separateRefreshUrls !== null) { 9397 // There are multiple URLs that we need to request the data from. This 9398 // happens when a "default" parallel route slot is present in the tree, and 9399 // its data cannot be fetched from the current route. We need to split the 9400 // combined dynamic request tree into separate requests per URL. 9401 // TODO: Create a scoped dynamic request tree that omits anything that 9402 // is not relevant to the given URL. Without doing this, the server may 9403 // sometimes render more data than necessary; this is not a regression 9404 // compared to the pre-Segment Cache implementation, though, just an 9405 // optimization we can make in the future. 9406 // Construct a request tree for each additional refresh URL. This will 9407 // prune away everything except the parts of the tree that match the 9408 // given refresh URL. 9409 refreshRequestPromises = []; 9410 const canonicalUrl = (0, _createhreffromurl.createHrefFromUrl)(primaryUrl); 9411 for (const refreshUrl of separateRefreshUrls){ 9412 if (refreshUrl === canonicalUrl) { 9413 continue; 9414 } 9415 // TODO: Create a scoped dynamic request tree that omits anything that 9416 // is not relevant to the given URL. Without doing this, the server may 9417 // sometimes render more data than necessary; this is not a regression 9418 // compared to the pre-Segment Cache implementation, though, just an 9419 // optimization we can make in the future. 9420 // const scopedDynamicRequestTree = splitTaskByURL(task, refreshUrl) 9421 const scopedDynamicRequestTree = dynamicRequestTree; 9422 if (scopedDynamicRequestTree !== null) { 9423 refreshRequestPromises.push(fetchMissingDynamicData(task, scopedDynamicRequestTree, new URL(refreshUrl, location.origin), // time the refresh URL was set, not the current Next-Url. Need to 9424 // start tracking this alongside the refresh URL. In the meantime, 9425 // if a refresh fails due to a mismatch, it will trigger a 9426 // hard refresh. 9427 nextUrl, freshnessPolicy, routeCacheEntry)); 9428 } 9429 } 9430 } 9431 // Further async operations are moved into this separate function to 9432 // discourage sequential network requests. 9433 const voidPromise = finishNavigationTask(task, nextUrl, primaryRequestPromise, refreshRequestPromises, routeCacheEntry, navigateType); 9434 // `finishNavigationTask` is responsible for error handling, so we can attach 9435 // noop callbacks to this promise. 9436 voidPromise.then(noop, noop); 9437} 9438async function finishNavigationTask(task, nextUrl, primaryRequestPromise, refreshRequestPromises, routeCacheEntry, navigateType) { 9439 // Wait for all the requests to finish, or for the first one to fail. 9440 let exitStatus = await waitForRequestsToFinish(primaryRequestPromise, refreshRequestPromises); 9441 // Once the all the requests have finished, check the tree for any remaining 9442 // pending tasks. If anything is still pending, it means the server response 9443 // does not match the client, and we must refresh to get back to a consistent 9444 // state. We can skip this step if we already detected a mismatch during the 9445 // first phase; it doesn't matter in that case because we're going to refresh 9446 // the whole tree regardless. 9447 if (exitStatus === 0) { 9448 exitStatus = abortRemainingPendingTasks(task, null, null); 9449 } 9450 switch(exitStatus){ 9451 case 0: 9452 { 9453 // The task has completely finished. There's no missing data. Exit. 9454 previousNavigationDidMismatch = false; 9455 return; 9456 } 9457 case 1: 9458 { 9459 // Some data failed to finish loading. Trigger a soft retry. 9460 // TODO: As an extra precaution against soft retry loops, consider 9461 // tracking whether a navigation was itself triggered by a retry. If two 9462 // happen in a row, fall back to a hard retry. 9463 const isHardRetry = false;
9464 const primaryRequestResult = await primaryRequestPromise; 9465 dispatchRetryDueToTreeMismatch(isHardRetry, primaryRequestResult.url, nextUrl, primaryRequestResult.seed, task.route, routeCacheEntry, navigateType); 9466 return; 9467 } 9468 case 2: 9469 { 9470 // Some data failed to finish loading in a non-recoverable way, such as a 9471 // network error. Trigger an MPA navigation. 9472 // 9473 // Hard navigating/refreshing is how we prevent an infinite retry loop 9474 // caused by a network error — when the network fails, we fall back to the 9475 // browser behavior for offline navigations. In the future, Next.js may 9476 // introduce its own custom handling of offline navigations, but that 9477 // doesn't exist yet. 9478 const isHardRetry = true; 9479 const primaryRequestResult = await primaryRequestPromise; 9480 dispatchRetryDueToTreeMismatch(isHardRetry, primaryRequestResult.url, nextUrl, primaryRequestResult.seed, task.route, routeCacheEntry, navigateType); 9481 return; 9482 } 9483 default: 9484 { 9485 return exitStatus; 9486 } 9487 } 9488} 9489function waitForRequestsToFinish(primaryRequestPromise, refreshRequestPromises) { 9490 // Custom async combinator logic. This could be replaced by Promise.any but 9491 // we don't assume that's available. 9492 // 9493 // Each promise resolves once the server responsds and the data is written 9494 // into the CacheNode tree. Resolve the combined promise once all the 9495 // requests finish. 9496 // 9497 // Or, resolve as soon as one of the requests fails, without waiting for the 9498 // others to finish. 9499 return new Promise((resolve)=>{ 9500 const onFulfill = (result)=>{ 9501 if (result.exitStatus === 0) { 9502 remainingCount--; 9503 if (remainingCount === 0) { 9504 // All the requests finished successfully. 9505 resolve(0); 9506 } 9507 } else { 9508 // One of the requests failed. Exit with a failing status. 9509 // NOTE: It's possible for one of the requests to fail with SoftRetry 9510 // and a later one to fail with HardRetry. In this case, we choose to 9511 // retry immediately, rather than delay the retry until all the requests 9512 // finish. If it fails again, we will hard retry on the next 9513 // attempt, anyway. 9514 resolve(result.exitStatus); 9515 } 9516 }; 9517 // onReject shouldn't ever be called because fetchMissingDynamicData's 9518 // entire body is wrapped in a try/catch. This is just defensive. 9519 const onReject = ()=>resolve(2); 9520 // Attach the listeners to the promises. 9521 let remainingCount = 1; 9522 primaryRequestPromise.then(onFulfill, onReject); 9523 if (refreshRequestPromises !== null) { 9524 remainingCount += refreshRequestPromises.length; 9525 refreshRequestPromises.forEach((refreshRequestPromise)=>refreshRequestPromise.then(onFulfill, onReject)); 9526 } 9527 }); 9528} 9529function dispatchRetryDueToTreeMismatch(isHardRetry, retryUrl, retryNextUrl, seed, baseTree, // prediction. If the navigation results in a mismatch, we mark it as having 9530// a dynamic rewrite so future predictions bail out. 9531routeCacheEntry, originalNavigateType) { 9532 // If the navigation used a route prediction, mark it as having a dynamic 9533 // rewrite since it resulted in a mismatch. 9534 if (routeCacheEntry !== null) { 9535 (0, _cache.markRouteEntryAsDynamicRewrite)(routeCacheEntry); 9536 } else if (seed !== null) { 9537 // Even without a direct reference to the route cache entry, we can still 9538 // mark the route as having a dynamic rewrite by traversing the known route 9539 // tree. This handles cases where the navigation didn't originate from a 9540 // route prediction, but still needs to mark the pattern. 9541 const metadataVaryPath = seed.metadataVaryPath; 9542 if (metadataVaryPath !== null) { 9543 const now = Date.now(); 9544 (0, _optimisticroutes.discoverKnownRoute)(now, retryUrl.pathname, retryNextUrl, null, seed.routeTree, metadataVaryPath, false, (0, _createhreffromurl.createHrefFromUrl)(retryUrl), false, true // hasDynamicRewrite 9545 ); 9546 } 9547 } 9548 // Invalidate all route cache entries. Other entries may have been derived 9549 // from the template before we knew it had a dynamic rewrite. This also 9550 // triggers re-prefetching of visible links. 9551 (0, _cache.invalidateRouteCacheEntries)(retryNextUrl, baseTree); 9552 // If this is the second time in a row that a navigation resulted in a 9553 // mismatch, fall back to a hard (MPA) refresh. 9554 isHardRetry = isHardRetry || previousNavigationDidMismatch; 9555 previousNavigationDidMismatch = true; 9556 // If the original navigation hasn't committed to the browser history yet 9557 // (the transition suspended before React committed), inherit its push/replace 9558 // intent. Otherwise, the pushState already ran, so use 'replace' to avoid 9559 // creating a duplicate history entry. 9560 // 9561 // This works because React entangles the retry's state update with the 9562 // original pending transition — they commit together as a single batch, 9563 // so the navigate type from the retry is what HistoryUpdater ultimately sees. 9564 // 9565 // TODO: Ideally this check would happen right before we schedule the React 9566 // update (i.e., closer to where the action is dispatched into the queue), 9567 // not here where the action is constructed. But the current action queue 9568 // doesn't provide a natural place for that. Revisit when we refactor the 9569 // action queue into a more reactive navigation model. 9570 const lastCommitted = (0, _committedstate.getLastCommittedTree)(); 9571 const retryNavigateType = lastCommitted !== null && baseTree !== lastCommitted ? originalNavigateType : 'replace'; 9572 const retryAction = { 9573 type: _routerreducertypes.ACTION_SERVER_PATCH, 9574 previousTree: baseTree, 9575 url: retryUrl, 9576 nextUrl: retryNextUrl, 9577 seed, 9578 mpa: isHardRetry, 9579 navigateType: retryNavigateType 9580 }; 9581 (0, _useactionqueue.dispatchAppRouterAction)(retryAction); 9582} 9583async function fetchMissingDynamicData(task, dynamicRequestTree, url, nextUrl, freshnessPolicy, routeCacheEntry) { 9584 try { 9585 const result = await (0, _fetchserverresponse.fetchServerResponse)(url, { 9586 flightRouterState: dynamicRequestTree, 9587 nextUrl, 9588 isHmrRefresh: freshnessPolicy === 4 9589 }); 9590 if (typeof result === 'string') { 9591 // fetchServerResponse will return an href to indicate that the SPA 9592 // navigation failed. For example, if the server triggered a hard 9593 // redirect, or the fetch request errored. Initiate an MPA navigation 9594 // to the given href. 9595 return { 9596 exitStatus: 2, 9597 url: new URL(result, location.origin), 9598 seed: null 9599 }; 9600 } 9601 const now = Date.now(); 9602 const seed = (0, _navigation.convertServerPatchToFullTree)(now, task.route, result.flightData, result.renderedSearch, result.dynamicStaleTime);
9603 // If the navigation lock is active, wait for it to be released before 9604 // writing the dynamic data. This allows tests to assert on the prefetched 9605 // UI state. 9606 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 9607 ; 9608 if (routeCacheEntry !== null && result.staticStageData !== null) { 9609 const { response: staticStageResponse, isResponsePartial } = result.staticStageData; 9610 (0, _cache.getStaleAt)(now, staticStageResponse.s).then((staleAt)=>{ 9611 var _result_responseHeaders_get; 9612 const buildId = (_result_responseHeaders_get = result.responseHeaders.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _result_responseHeaders_get !== void 0 ? _result_responseHeaders_get : staticStageResponse.b; 9613 (0, _cache.writeStaticStageResponseIntoCache)(now, staticStageResponse.f, buildId, staticStageResponse.h, staleAt, dynamicRequestTree, result.renderedSearch, isResponsePartial); 9614 }).catch(()=>{ 9615 // The static stage processing failed. Not fatal — the navigation 9616 // completed normally, we just won't write into the cache. 9617 }); 9618 } 9619 if (routeCacheEntry !== null && result.runtimePrefetchStream !== null) { 9620 (0, _cache.processRuntimePrefetchStream)(now, result.runtimePrefetchStream, dynamicRequestTree, result.renderedSearch).then((processed)=>{ 9621 if (processed !== null) { 9622 (0, _cache.writeDynamicRenderResponseIntoCache)(now, _types.FetchStrategy.PPRRuntime, processed.flightDatas, processed.buildId, processed.isResponsePartial, processed.headVaryParams, processed.staleAt, processed.navigationSeed, null); 9623 } 9624 }).catch(()=>{ 9625 // The runtime prefetch cache write failed. Not fatal — the 9626 // navigation completed normally, we just won't cache runtime data. 9627 }); 9628 } 9629 // result.dynamicStaleTime is in seconds (from the server's `d` field). 9630 // Convert to an absolute timestamp using the centralized helper. 9631 const dynamicStaleAt = (0, _bfcache.computeDynamicStaleAt)(now, result.dynamicStaleTime); 9632 const didReceiveUnknownParallelRoute = writeDynamicDataIntoNavigationTask(task, seed.routeTree, seed.data, seed.head, dynamicStaleAt, result.debugInfo); 9633 return { 9634 exitStatus: didReceiveUnknownParallelRoute ? 1 : 0, 9635 url: new URL(result.canonicalUrl, location.origin), 9636 seed 9637 }; 9638 } catch (unused) { 9639 // This shouldn't happen because fetchServerResponse's entire body is 9640 // wrapped in a try/catch. If it does, though, it implies the server failed 9641 // to respond with any tree at all. So we must fall back to a hard retry. 9642 return { 9643 exitStatus: 2, 9644 url: url, 9645 seed: null 9646 }; 9647 } 9648} 9649function writeDynamicDataIntoNavigationTask(task, serverRouteTree, dynamicData, dynamicHead, dynamicStaleAt, debugInfo) { 9650 if (task.status === 0 && dynamicData !== null) { 9651 task.status = 1; 9652 finishPendingCacheNode(task.node, dynamicData, dynamicHead, debugInfo); 9653 // Update the BFCache entry's staleAt for this segment with the value 9654 // from the dynamic response. This applies the per-page 9655 // unstable_dynamicStaleTime if set, or the default DYNAMIC_STALETIME_MS. 9656 // We only update segments that received dynamic data — static segments 9657 // are unaffected. 9658 (0, _bfcache.updateBFCacheEntryStaleAt)(serverRouteTree.varyPath, dynamicStaleAt); 9659 } 9660 const taskChildren = task.children; 9661 const serverChildren = serverRouteTree.slots; 9662 const dynamicDataChildren = dynamicData !== null ? dynamicData[1] : null; 9663 // Detect whether the server sends a parallel route slot that the client 9664 // doesn't know about. 9665 let didReceiveUnknownParallelRoute = false; 9666 if (taskChildren !== null) { 9667 if (serverChildren !== null) { 9668 for(const parallelRouteKey in serverChildren){ 9669 const serverRouteTreeChild = serverChildren[parallelRouteKey]; 9670 const dynamicDataChild = dynamicDataChildren !== null ? dynamicDataChildren[parallelRouteKey] : null; 9671 const taskChild = taskChildren.get(parallelRouteKey); 9672 if (taskChild === undefined) { 9673 // The server sent a child segment that the client doesn't know about. 9674 // 9675 // When we receive an unknown parallel route, we must consider it a 9676 // mismatch. This is unlike the case where the segment itself 9677 // mismatches, because multiple routes can be active simultaneously. 9678 // But a given layout should never have a mismatching set of 9679 // child slots. 9680 // 9681 // Theoretically, this should only happen in development during an HMR 9682 // refresh, because the set of parallel routes for a layout does not 9683 // change over the lifetime of a build/deployment. In production, we 9684 // should have already mismatched on either the build id or the segment 9685 // path. But as an extra precaution, we validate in prod, too. 9686 didReceiveUnknownParallelRoute = true; 9687 } else { 9688 const taskSegment = taskChild.route[0]; 9689 const serverSegment = createSegmentFromRouteTree(serverRouteTreeChild); 9690 if ((0, _matchsegments.matchSegment)(serverSegment, taskSegment) && dynamicDataChild !== null && dynamicDataChild !== undefined) { 9691 // Found a match for this task. Keep traversing down the task tree. 9692 const childDidReceiveUnknownParallelRoute = writeDynamicDataIntoNavigationTask(taskChild, serverRouteTreeChild, dynamicDataChild, dynamicHead, dynamicStaleAt, debugInfo); 9693 if (childDidReceiveUnknownParallelRoute) { 9694 didReceiveUnknownParallelRoute = true; 9695 } 9696 } 9697 } 9698 } 9699 } else { 9700 if (serverChildren !== null) { 9701 // The server sent a child segment that the client doesn't know about. 9702 didReceiveUnknownParallelRoute = true; 9703 } 9704 } 9705 } 9706 return didReceiveUnknownParallelRoute; 9707} 9708function finishPendingCacheNode(cacheNode, dynamicData, dynamicHead, debugInfo) { 9709 // Writes a dynamic response into an existing Cache Node tree. This does _not_ 9710 // create a new tree, it updates the existing tree in-place. So it must follow 9711 // the Suspense rules of cache safety — it can resolve pending promises, but
9712 // it cannot overwrite existing data. It can add segments to the tree (because 9713 // a missing segment will cause the layout router to suspend). 9714 // but it cannot delete them. 9715 // 9716 // We must resolve every promise in the tree, or else it will suspend 9717 // indefinitely. If we did not receive data for a segment, we will resolve its 9718 // data promise to `null` to trigger a lazy fetch during render. 9719 // Use the dynamic data from the server to fulfill the deferred RSC promise 9720 // on the Cache Node. 9721 const rsc = cacheNode.rsc; 9722 const dynamicSegmentData = dynamicData[0]; 9723 if (dynamicSegmentData === null) { 9724 // This is an empty CacheNode; this particular server request did not 9725 // render this segment. There may be a separate pending request that will, 9726 // though, so we won't abort the task until all pending requests finish. 9727 return; 9728 } 9729 if (rsc === null) { 9730 // This is a lazy cache node. We can overwrite it. This is only safe 9731 // because we know that the LayoutRouter suspends if `rsc` is `null`. 9732 cacheNode.rsc = dynamicSegmentData; 9733 } else if (isDeferredRsc(rsc)) { 9734 // This is a deferred RSC promise. We can fulfill it with the data we just 9735 // received from the server. If it was already resolved by a different 9736 // navigation, then this does nothing because we can't overwrite data. 9737 rsc.resolve(dynamicSegmentData, debugInfo); 9738 } else { 9739 // This is not a deferred RSC promise, nor is it empty, so it must have 9740 // been populated by a different navigation. We must not overwrite it. 9741 } 9742 // Check if this is a leaf segment. If so, it will have a `head` property with 9743 // a pending promise that needs to be resolved with the dynamic head from 9744 // the server. 9745 const head = cacheNode.head; 9746 if (isDeferredRsc(head)) { 9747 head.resolve(dynamicHead, debugInfo); 9748 } 9749} 9750function abortRemainingPendingTasks(task, error, debugInfo) { 9751 let exitStatus; 9752 if (task.status === 0) { 9753 // The data for this segment is still missing. 9754 task.status = 2; 9755 abortPendingCacheNode(task.node, error, debugInfo); 9756 // If the server failed to fulfill the data for this segment, it implies 9757 // that the route tree received from the server mismatched the tree that 9758 // was previously prefetched. 9759 // 9760 // In an app with fully static routes and no proxy-driven redirects or 9761 // rewrites, this should never happen, because the route for a URL would 9762 // always be the same across multiple requests. So, this implies that some 9763 // runtime routing condition changed, likely in a proxy, without being 9764 // pushed to the client. 9765 // 9766 // When this happens, we treat this the same as a refresh(). The entire 9767 // tree will be re-rendered from the root. 9768 if (task.refreshState === null) { 9769 // Trigger a "soft" refresh. Essentially the same as calling `refresh()` 9770 // in a Server Action. 9771 exitStatus = 1; 9772 } else { 9773 // The mismatch was discovered inside an inactive parallel route. This 9774 // implies the inactive parallel route is no longer reachable at the URL 9775 // that originally rendered it. Fall back to an MPA refresh. 9776 // TODO: An alternative could be to trigger a soft refresh but to _not_ 9777 // re-use the inactive parallel routes this time. Similar to what would 9778 // happen if were to do a hard refrehs, but without the HTML page. 9779 exitStatus = 2; 9780 } 9781 } else { 9782 // This segment finished. (An error here is treated as Done because they are 9783 // surfaced to the application during render.) 9784 exitStatus = 0; 9785 } 9786 const taskChildren = task.children; 9787 if (taskChildren !== null) { 9788 for (const [, taskChild] of taskChildren){ 9789 const childExitStatus = abortRemainingPendingTasks(taskChild, error, debugInfo); 9790 // Propagate the exit status up the tree. The statuses are ordered by 9791 // their precedence. 9792 if (childExitStatus > exitStatus) { 9793 exitStatus = childExitStatus; 9794 } 9795 } 9796 } 9797 return exitStatus; 9798} 9799function abortPendingCacheNode(cacheNode, error, debugInfo) {
9800 const rsc = cacheNode.rsc; 9801 if (isDeferredRsc(rsc)) { 9802 if (error === null) { 9803 // This will trigger a lazy fetch during render. 9804 rsc.resolve(null, debugInfo); 9805 } else { 9806 // This will trigger an error during rendering. 9807 rsc.reject(error, debugInfo); 9808 } 9809 } 9810 // Check if this is a leaf segment. If so, it will have a `head` property with 9811 // a pending promise that needs to be resolved. If an error was provided, we 9812 // will not resolve it with an error, since this is rendered at the root of 9813 // the app. We want the segment to error, not the entire app. 9814 const head = cacheNode.head; 9815 if (isDeferredRsc(head)) { 9816 head.resolve(null, debugInfo); 9817 } 9818} 9819const DEFERRED = Symbol(); 9820function isDeferredRsc(value) { 9821 return value && typeof value === 'object' && value.tag === DEFERRED; 9822} 9823function createDeferredRsc() { 9824 // Create an unresolved promise that represents data derived from a Flight 9825 // response. The promise will be resolved later as soon as we start receiving 9826 // data from the server, i.e. as soon as the Flight client decodes and returns 9827 // the top-level response object. 9828 // The `_debugInfo` field contains profiling information. Promises that are 9829 // created by Flight already have this info added by React; for any derived 9830 // promise created by the router, we need to transfer the Flight debug info 9831 // onto the derived promise. 9832 // 9833 // The debug info represents the latency between the start of the navigation 9834 // and the start of rendering. (It does not represent the time it takes for 9835 // whole stream to finish.) 9836 const debugInfo = []; 9837 let resolve; 9838 let reject; 9839 const pendingRsc = new Promise((res, rej)=>{ 9840 resolve = res; 9841 reject = rej; 9842 }); 9843 pendingRsc.status = 'pending'; 9844 pendingRsc.resolve = (value, responseDebugInfo)=>{ 9845 if (pendingRsc.status === 'pending') { 9846 const fulfilledRsc = pendingRsc; 9847 fulfilledRsc.status = 'fulfilled'; 9848 fulfilledRsc.value = value; 9849 if (responseDebugInfo !== null) { 9850 // Transfer the debug info to the derived promise. 9851 debugInfo.push.apply(debugInfo, responseDebugInfo); 9852 } 9853 resolve(value); 9854 } 9855 }; 9856 pendingRsc.reject = (error, responseDebugInfo)=>{ 9857 if (pendingRsc.status === 'pending') { 9858 const rejectedRsc = pendingRsc; 9859 rejectedRsc.status = 'rejected'; 9860 rejectedRsc.reason = error; 9861 if (responseDebugInfo !== null) { 9862 // Transfer the debug info to the derived promise. 9863 debugInfo.push.apply(debugInfo, responseDebugInfo); 9864 } 9865 reject(error); 9866 } 9867 }; 9868 pendingRsc.tag = DEFERRED; 9869 pendingRsc._debugInfo = debugInfo; 9870 return pendingRsc; 9871} 9872/** 9873 * Helper for the Instant Navigation Testing API. Waits for the navigation lock 9874 * to be released before returning. The network request has already completed by 9875 * the time this is called, so this only delays writing the dynamic data. 9876 * 9877 * Not exposed in production builds by default. 9878 */ async function waitForNavigationLock() { 9879 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 9880 ; 9881} 9882if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 9883 Object.defineProperty(exports.default, '__esModule', { 9884 value: true 9885 }); 9886 Object.assign(exports.default, exports); 9887 module.exports = exports.default; 9888} 9889}), 9890203372, ((__turbopack_context__, module, exports) => { 9891"use strict"; 9892 9893/** 9894 * For a given page path, this function ensures that there is a leading slash. 9895 * If there is not a leading slash, one is added, otherwise it is noop. 9896 */ Object.defineProperty(exports, "__esModule", { 9897 value: true 9898}); 9899Object.defineProperty(exports, "ensureLeadingSlash", { 9900 enumerable: true, 9901 get: function() { 9902 return ensureLeadingSlash; 9903 } 9904}); 9905function ensureLeadingSlash(path) { 9906 return path.startsWith('/') ? path : "/".concat(path); 9907} 9908}),
9909174180, ((__turbopack_context__, module, exports) => { 9910"use strict"; 9911 9912Object.defineProperty(exports, "__esModule", { 9913 value: true 9914}); 99150 && (module.exports = { 9916 compareAppPaths: null, 9917 normalizeAppPath: null, 9918 normalizeRscURL: null 9919}); 9920function _export(target, all) { 9921 for(var name in all)Object.defineProperty(target, name, { 9922 enumerable: true, 9923 get: all[name] 9924 }); 9925} 9926_export(exports, { 9927 compareAppPaths: function() { 9928 return compareAppPaths; 9929 }, 9930 normalizeAppPath: function() { 9931 return normalizeAppPath; 9932 }, 9933 normalizeRscURL: function() { 9934 return normalizeRscURL; 9935 } 9936}); 9937const _ensureleadingslash = __turbopack_context__.r(203372); 9938const _segment = __turbopack_context__.r(813258); 9939function normalizeAppPath(route) { 9940 return (0, _ensureleadingslash.ensureLeadingSlash)(route.split('/').reduce((pathname, segment, index, segments)=>{ 9941 // Empty segments are ignored. 9942 if (!segment) { 9943 return pathname; 9944 } 9945 // Groups are ignored. 9946 if ((0, _segment.isGroupSegment)(segment)) { 9947 return pathname; 9948 } 9949 // Parallel segments are ignored. 9950 if (segment[0] === '@') { 9951 return pathname; 9952 } 9953 // The last segment (if it's a leaf) should be ignored. 9954 if ((segment === 'page' || segment === 'route') && index === segments.length - 1) { 9955 return pathname; 9956 } 9957 return "".concat(pathname, "/").concat(segment); 9958 }, '')); 9959} 9960function compareAppPaths(a, b) { 9961 const aHasSlot = a.includes('/@'); 9962 const bHasSlot = b.includes('/@'); 9963 if (aHasSlot && !bHasSlot) return -1; 9964 if (!aHasSlot && bHasSlot) return 1; 9965 return a.localeCompare(b); 9966} 9967function normalizeRscURL(url) { 9968 return url.replace(/\.rsc($|\?)/, '$1'); 9969} 9970}), 9971591463, ((__turbopack_context__, module, exports) => { 9972"use strict"; 9973 9974Object.defineProperty(exports, "__esModule", { 9975 value: true 9976}); 99770 && (module.exports = { 9978 INTERCEPTION_ROUTE_MARKERS: null, 9979 extractInterceptionRouteInformation: null, 9980 isInterceptionRouteAppPath: null 9981}); 9982function _export(target, all) { 9983 for(var name in all)Object.defineProperty(target, name, { 9984 enumerable: true, 9985 get: all[name] 9986 }); 9987} 9988_export(exports, { 9989 INTERCEPTION_ROUTE_MARKERS: function() { 9990 return INTERCEPTION_ROUTE_MARKERS; 9991 }, 9992 extractInterceptionRouteInformation: function() { 9993 return extractInterceptionRouteInformation; 9994 }, 9995 isInterceptionRouteAppPath: function() { 9996 return isInterceptionRouteAppPath; 9997 } 9998}); 9999const _apppaths = __turbopack_context__.r(174180); 10000const INTERCEPTION_ROUTE_MARKERS = [ 10001 '(..)(..)', 10002 '(.)', 10003 '(..)', 10004 '(...)' 10005]; 10006function isInterceptionRouteAppPath(path) { 10007 // TODO-APP: add more serious validation 10008 return path.split('/').find((segment)=>INTERCEPTION_ROUTE_MARKERS.find((m)=>segment.startsWith(m))) !== undefined; 10009} 10010function extractInterceptionRouteInformation(path) { 10011 let interceptingRoute; 10012 let marker; 10013 let interceptedRoute; 10014 for (const segment of path.split('/')){ 10015 marker = INTERCEPTION_ROUTE_MARKERS.find((m)=>segment.startsWith(m)); 10016 if (marker) { 10017 ; 10018 [interceptingRoute, interceptedRoute] = path.split(marker, 2); 10019 break; 10020 } 10021 } 10022 if (!interceptingRoute || !marker || !interceptedRoute) { 10023 throw Object.defineProperty(new Error("Invalid interception route: ".concat(path, ". Must be in the format /<intercepting route>/(..|...|..)(..)/<intercepted route>")), "__NEXT_ERROR_CODE", { 10024 value: "E269", 10025 enumerable: false, 10026 configurable: true 10027 }); 10028 } 10029 interceptingRoute = (0, _apppaths.normalizeAppPath)(interceptingRoute) // normalize the path, e.g. /(blog)/feed -> /feed 10030 ; 10031 switch(marker){ 10032 case '(.)': 10033 // (.) indicates that we should match with sibling routes, so we just need to append the intercepted route to the intercepting route 10034 if (interceptingRoute === '/') { 10035 interceptedRoute = "/".concat(interceptedRoute); 10036 } else { 10037 interceptedRoute = interceptingRoute + '/' + interceptedRoute; 10038 } 10039 break; 10040 case '(..)': 10041 // (..) indicates that we should match at one level up, so we need to remove the last segment of the intercepting route 10042 if (interceptingRoute === '/') { 10043 throw Object.defineProperty(new Error("Invalid interception route: ".concat(path, ". Cannot use (..) marker at the root level, use (.) instead.")), "__NEXT_ERROR_CODE", { 10044 value: "E207", 10045 enumerable: false, 10046 configurable: true 10047 }); 10048 } 10049 interceptedRoute = interceptingRoute.split('/').slice(0, -1).concat(interceptedRoute).join('/'); 10050 break; 10051 case '(...)': 10052 // (...) will match the route segment in the root directory, so we need to use the root directory to prepe
10052nd the intercepted route 10053 interceptedRoute = '/' + interceptedRoute; 10054 break; 10055 case '(..)(..)': 10056 // (..)(..) indicates that we should match at two levels up, so we need to remove the last two segments of the intercepting route 10057 const splitInterceptingRoute = interceptingRoute.split('/'); 10058 if (splitInterceptingRoute.length <= 2) { 10059 throw Object.defineProperty(new Error("Invalid interception route: ".concat(path, ". Cannot use (..)(..) marker at the root level or one level up.")), "__NEXT_ERROR_CODE", { 10060 value: "E486", 10061 enumerable: false, 10062 configurable: true 10063 }); 10064 } 10065 interceptedRoute = splitInterceptingRoute.slice(0, -2).concat(interceptedRoute).join('/'); 10066 break; 10067 default: 10068 throw Object.defineProperty(new Error('Invariant: unexpected marker'), "__NEXT_ERROR_CODE", { 10069 value: "E112", 10070 enumerable: false, 10071 configurable: true 10072 }); 10073 } 10074 return { 10075 interceptingRoute, 10076 interceptedRoute 10077 }; 10078} 10079}), 10080734727, ((__turbopack_context__, module, exports) => { 10081"use strict"; 10082 10083Object.defineProperty(exports, "__esModule", { 10084 value: true 10085}); 100860 && (module.exports = { 10087 computeChangedPath: null, 10088 extractPathFromFlightRouterState: null, 10089 extractSourcePageFromFlightRouterState: null, 10090 getSelectedParams: null 10091}); 10092function _export(target, all) { 10093 for(var name in all)Object.defineProperty(target, name, { 10094 enumerable: true, 10095 get: all[name] 10096 }); 10097} 10098_export(exports, { 10099 computeChangedPath: function() { 10100 return computeChangedPath; 10101 }, 10102 extractPathFromFlightRouterState: function() { 10103 return extractPathFromFlightRouterState; 10104 }, 10105 extractSourcePageFromFlightRouterState: function() { 10106 return extractSourcePageFromFlightRouterState; 10107 }, 10108 getSelectedParams: function() { 10109 return getSelectedParams; 10110 } 10111}); 10112const _interceptionroutes = __turbopack_context__.r(591463); 10113const _segment = __turbopack_context__.r(813258); 10114const _matchsegments = __turbopack_context__.r(756019); 10115const removeLeadingSlash = (segment)=>{ 10116 return segment[0] === '/' ? segment.slice(1) : segment; 10117}; 10118const segmentToPathname = (segment)=>{ 10119 if (typeof segment === 'string') { 10120 // 'children' is not a valid path -- it's technically a parallel route that corresponds with the current segment's page 10121 // if we don't skip it, then the computed pathname might be something like `/children` which doesn't make sense. 10122 if (segment === 'children') return ''; 10123 return segment; 10124 } 10125 return segment[1]; 10126}; 10127const segmentToSourcePagePathname = (segment)=>{ 10128 if (typeof segment === 'string') { 10129 if (segment === 'children') return ''; 10130 if (segment.startsWith(_segment.PAGE_SEGMENT_KEY)) return 'page'; 10131 return segment; 10132 } 10133 const [paramName, , dynamicParamType] = segment; 10134 switch(dynamicParamType){ 10135 case 'c': 10136 return "[...".concat(paramName, "]"); 10137 case 'ci(..)(..)': 10138 return "(..)(..)[...".concat(paramName, "]"); 10139 case 'ci(.)': 10140 return "(.)[...".concat(paramName, "]"); 10141 case 'ci(..)': 10142 return "(..)[...".concat(paramName, "]"); 10143 case 'ci(...)': 10144 return "(...)[...".concat(paramName, "]"); 10145 case 'oc': 10146 return "[[...".concat(paramName, "]]"); 10147 case 'd': 10148 return "[".concat(paramName, "]"); 10149 case 'di(..)(..)': 10150 return "(..)(..)[".concat(paramName, "]"); 10151 case 'di(.)': 10152 return "(.)[".concat(paramName, "]"); 10153 case 'di(..)': 10154 return "(..)[".concat(paramName, "]"); 10155 case 'di(...)': 10156 return "(...)[".concat(paramName, "]"); 10157 default: 10158 dynamicParamType; 10159 return "[".concat(paramName, "]"); 10160 } 10161}; 10162function normalizeSegments(segments) { 10163 return segments.reduce((acc, segment)=>{ 10164 segment = removeLeadingSlash(segment); 10165 if (segment === '' || (0, _segment.isGroupSegment)(segment)) { 10166 return acc; 10167 } 10168 return "".concat(acc, "/").concat(segment); 10169 }, '') || '/'; 10170} 10171function extractPathFromFlightRouterState(flightRouterState) { 10172 var _flightRouterState_; 10173 const segment = Array.isArray(flightRouterState[0]) ? flightRouterState[0][1] : flightRouterState[0]; 10174 if (segment === _segment.DEFAULT_SEGMENT_KEY || _interceptionroutes.INTERCEPTION_ROUTE_MARKERS.some((m)=>segment.startsWith(m))) return undefined; 10175 if (segment.startsWith(_segment.PAGE_SEGMENT_KEY)) return ''; 10176 const segments = [ 10177 segmentToPathname(segment) 10178 ]; 10179 const parallelRoutes = (_flightRouterState_ = flightRouterState[1]) !== null && _flightRouterState_ !== void 0 ? _flightRouterState_ : {}; 10180 const childrenPath = parallelRoutes.children ? extractPathFromFlightRouterState(parallelRoutes.children) : undefined; 10181 if (childrenPath !== undefined) { 10182 segments.push(childrenPath); 10183 } else { 10184 for (const [key, value] of Object.entries(parallelRoutes)){ 10185 if (key === 'children') continue; 10186 const childPath = extractPathFromFlightRouterState(value); 10187 if (childPath !== undefined) { 10188 segments.push(childPath); 10189 } 10190 } 10191 } 10192 return normalizeSegments(segments); 10193} 10194function extractSourcePageSegmentsFromFlightRouterState(flightRouterState) { 10195 var _flightRouterState_; 10196 const segment = segmentToSourcePagePathname(flightRouterState[0]); 10197 if (segment === _segment.DEFAULT_SEGMENT_KEY) { 10198 return undefined; 10199 } 10200 if (segment === 'page') { 10201 return [ 10202 segment 10203 ]; 10204 } 10205 const parallelRoutes = (_flightRouterState_ = flightRouterState[1]) !== null && _flightRouterState_ !== void 0 ? _flightRouterState_ : {}; 10206 const childrenPath = parallelRoutes.children ? extractSourcePageSegmentsFromFlightRouterState(parallelRoutes.children) : undefined; 10207 if (childrenPath !== undefined) { 10208 return segment === '' ? childrenPath : [ 10209 removeLeadingSlash(segment), 10210 ...childrenPath 10211 ]; 10212 } 10213 for (const [key, value] of Object.entries(parallelRoutes)){ 10214 if (key === 'children') continue; 10215 const childPath = extractSourcePageSegmentsFromFlightRouterState(value); 10216 if (childPath !== undefined) { 10217 return segment === '' ? childPath : [ 10218 removeLeadingSlash(segment), 10219 ...childPath 10220 ]; 10221 } 10222 } 10223 return undefined; 10224} 10225function extractSourcePageFromFlightRouterState(flightRouterState) { 10226 const sourcePageSegments = extractSourcePageSegmentsFromFlightRouterState(flightRouterState); 10227 return sourcePageSegments ? "/".concat(sourcePageSegments.join('/')) : undefined; 10228} 10229function computeChangedPathImpl(treeA, treeB) { 10230 const [segmentA, parallelRoutesA] = treeA; 10231 const [segmentB, parallelRoutesB] = treeB; 10232 const normalizedSegmentA = segmentToPathname(segmentA); 10233 const normalizedSegmentB = segmentToPathname(segmentB); 10234 if (_interceptionroutes.INTERCEPTION_ROUTE_MARKERS.some((m)=>normalizedSegmentA.startsWith(m) || normalizedSegmentB.startsWith(m))) { 10235 return ''; 10236 } 10237 if (!(0, _matchsegments.matchSegment)(segmentA, segmentB)) { 10238 var _extractPathFromFlightRouterState; 10239 // once we find where the tree changed, we compute the rest of the path by traversing the tree 10240 return (_extractPathFromFlightRouterState = extractPathFromFlightRouterState(treeB)) !== null && _extractPathFromFlightRouterState !== void 0 ? _extractPathFromFlightRouterState : ''; 10241 } 10242 for(const parallelRouterKey in parallelRoutesA){ 10243 if (parallelRoutesB[parallelRouterKey]) { 10244 const changedPath = computeChangedPathImpl(parallelRoutesA[parallelRouterKey], parallelRoutesB[parallelRouterKey]); 10245 if (changedPath !== null) { 10246 return "".concat(segmentToPathname(segmentB), "/").concat(changedPath); 10247 } 10248 } 10249 } 10250 return null; 10251} 10252function computeChangedPath(treeA, treeB) { 10253 const changedPath = computeChangedPathImpl(treeA, treeB); 10254 if (changedPath == null || changedPath === '/') { 10255 return changedPath; 10256 } 10257 // lightweight normalization to remove route groups 10258 return normalizeSegments(changedPath.split('/')); 10259} 10260function getSelectedParams(currentTree) { 10261 let params = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; 10262 const parallelRoutes = currentTree[1];
10263 for (const parallelRoute of Object.values(parallelRoutes)){ 10264 const segment = parallelRoute[0]; 10265 const isDynamicParameter = Array.isArray(segment); 10266 const segmentValue = isDynamicParameter ? segment[1] : segment; 10267 if (!segmentValue || segmentValue.startsWith(_segment.PAGE_SEGMENT_KEY)) continue; 10268 // Ensure catchAll and optional catchall are turned into an array 10269 const isCatchAll = isDynamicParameter && (segment[2] === 'c' || segment[2] === 'oc'); 10270 if (isCatchAll) { 10271 params[segment[0]] = segment[1].split('/'); 10272 } else if (isDynamicParameter) { 10273 params[segment[0]] = segment[1]; 10274 } 10275 params = getSelectedParams(parallelRoute, params); 10276 } 10277 return params; 10278} 10279if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 10280 Object.defineProperty(exports.default, '__esModule', { 10281 value: true 10282 }); 10283 Object.assign(exports.default, exports); 10284 module.exports = exports.default; 10285} 10286}), 10287948277, ((__turbopack_context__, module, exports) => { 10288"use strict"; 10289 10290// Adapted from React's sanitizeURL function found here: https://github.com/facebook/react/blob/b565373afd0cc1988497e1107106e851e8cfb261/packages/react-dom-bindings/src/shared/sanitizeURL.js 10291// A javascript: URL can contain leading C0 control or \u0020 SPACE, 10292// and any newline or tab are filtered out as if they're not part of the URL. 10293// https://url.spec.whatwg.org/#url-parsing 10294// Tab or newline are defined as \r\n\t: 10295// https://infra.spec.whatwg.org/#ascii-tab-or-newline 10296// A C0 control is a code point in the range \u0000 NULL to \u001F 10297// INFORMATION SEPARATOR ONE, inclusive: 10298// https://infra.spec.whatwg.org/#c0-control-or-space 10299Object.defineProperty(exports, "__esModule", { 10300 value: true 10301}); 10302Object.defineProperty(exports, "isJavaScriptURLString", { 10303 enumerable: true, 10304 get: function() { 10305 return isJavaScriptURLString; 10306 } 10307}); 10308const isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i; 10309function isJavaScriptURLString(url) { 10310 return isJavaScriptProtocol.test('' + url); 10311} 10312if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 10313 Object.defineProperty(exports.default, '__esModule', { 10314 value: true 10315 }); 10316 Object.assign(exports.default, exports); 10317 module.exports = exports.default; 10318} 10319}), 10320381400, ((__turbopack_context__, module, exports) => { 10321"use strict"; 10322 10323var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 10324/** 10325 * Navigation lock for the Instant Navigation Testing API. 10326 * 10327 * Manages the in-memory lock (a promise) that gates dynamic data writes 10328 * during instant navigation captures, and owns all cookie state 10329 * transitions (pending → captured-MPA, pending → captured-SPA). 10330 * 10331 * External actors (Playwright, devtools) set [0] to start a lock scope 10332 * and delete the cookie to end one. Next.js writes captured values. 10333 * The CookieStore handler distinguishes them by value: pending = external, 10334 * captured = self-write (ignored). 10335 */ "use strict"; 10336Object.defineProperty(exports, "__esModule", { 10337 value: true 10338}); 103390 && (module.exports = { 10340 isNavigationLocked: null, 10341 startListeningForInstantNavigationCookie: null, 10342 transitionToCapturedSPA: null, 10343 updateCapturedSPAToTree: null, 10344 waitForNavigationLockIfActive: null 10345}); 10346function _export(target, all) { 10347 for(var name in all)Object.defineProperty(target, name, { 10348 enumerable: true, 10349 get: all[name] 10350 }); 10351} 10352_export(exports, { 10353 isNavigationLocked: function() { 10354 return isNavigationLocked; 10355 }, 10356 startListeningForInstantNavigationCookie: function() { 10357 return startListeningForInstantNavigationCookie; 10358 }, 10359 transitionToCapturedSPA: function() { 10360 return transitionToCapturedSPA; 10361 }, 10362 updateCapturedSPAToTree: function() { 10363 return updateCapturedSPAToTree; 10364 }, 10365 waitForNavigationLockIfActive: function() { 10366 return waitForNavigationLockIfActive; 10367 } 10368}); 10369const _approuterheaders = __turbopack_context__.r(621768); 10370const _useactionqueue = __turbopack_context__.r(941538); 10371function parseCookieValue(raw) { 10372 try { 10373 const parsed = JSON.parse(raw); 10374 if (Array.isArray(parsed) && parsed.length >= 3) { 10375 const rawState = parsed[2]; 10376 return rawState === null ? 'mpa' : 'spa'; 10377 } 10378 } catch (unused) {} 10379 return 'pending'; 10380} 10381function writeCookieValue(value) { 10382 if (typeof cookieStore === 'undefined') { 10383 return; 10384 } 10385 // Read the existing cookie to preserve its attributes (domain, path), 10386 // then write back with the new value. This updates the same cookie 10387 // entry that the external actor created, regardless of how it was 10388 // scoped. 10389 cookieStore.get(_approuterheaders.NEXT_INSTANT_TEST_COOKIE).then((existing)=>{ 10390 if (existing) { 10391 var _existing_path; 10392 const options = { 10393 name: _approuterheaders.NEXT_INSTANT_TEST_COOKIE, 10394 value: JSON.stringify(value),
10395 path: (_existing_path = existing.path) !== null && _existing_path !== void 0 ? _existing_path : '/' 10396 }; 10397 if (existing.domain) { 10398 options.domain = existing.domain; 10399 } 10400 cookieStore.set(options); 10401 } 10402 }); 10403} 10404let lockState = null; 10405function acquireLock() { 10406 if (lockState !== null) { 10407 return; 10408 } 10409 let resolve; 10410 const promise = new Promise((r)=>{ 10411 resolve = r; 10412 }); 10413 lockState = { 10414 promise, 10415 resolve: resolve 10416 }; 10417} 10418function releaseLock() { 10419 if (lockState !== null) { 10420 lockState.resolve(); 10421 lockState = null; 10422 } 10423} 10424function startListeningForInstantNavigationCookie() { 10425 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 10426 ; 10427} 10428function transitionToCapturedSPA(fromTree, toTree) { 10429 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 10430 ; 10431} 10432function updateCapturedSPAToTree(fromTree, toTree) { 10433 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 10434 ; 10435} 10436function isNavigationLocked() { 10437 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 10438 ; 10439 return false; 10440} 10441async function waitForNavigationLockIfActive() { 10442 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 10443 ; 10444} 10445if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 10446 Object.defineProperty(exports.default, '__esModule', { 10447 value: true 10448 }); 10449 Object.assign(exports.default, exports); 10450 module.exports = exports.default; 10451} 10452}), 10453760355, ((__turbopack_context__, module, exports) => { 10454"use strict"; 10455 10456var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 10457"use strict"; 10458Object.defineProperty(exports, "__esModule", { 10459 value: true 10460}); 104610 && (module.exports = { 10462 completeHardNavigation: null, 10463 completeSoftNavigation: null, 10464 completeTraverseNavigation: null, 10465 convertServerPatchToFullTree: null, 10466 navigate: null, 10467 navigateToKnownRoute: null 10468}); 10469function _export(target, all) { 10470 for(var name in all)Object.defineProperty(target, name, { 10471 enumerable: true, 10472 get: all[name] 10473 }); 10474} 10475_export(exports, { 10476 completeHardNavigation: function() { 10477 return completeHardNavigation; 10478 }, 10479 completeSoftNavigation: function() { 10480 return completeSoftNavigation; 10481 }, 10482 completeTraverseNavigation: function() { 10483 return completeTraverseNavigation; 10484 }, 10485 convertServerPatchToFullTree: function() { 10486 return convertServerPatchToFullTree; 10487 }, 10488 navigate: function() { 10489 return navigate; 10490 }, 10491 navigateToKnownRoute: function() { 10492 return navigateToKnownRoute; 10493 } 10494}); 10495const _fetchserverresponse = __turbopack_context__.r(787288); 10496const _pprnavigations = __turbopack_context__.r(595871); 10497const _createhreffromurl = __turbopack_context__.r(451191); 10498const _constants = __turbopack_context__.r(663416); 10499const _cache = __turbopack_context__.r(620896); 10500const _optimisticroutes = __turbopack_context__.r(496167); 10501const _cachekey = __turbopack_context__.r(477048); 10502const _scheduler = __turbopack_context__.r(777709); 10503const _types = __turbopack_context__.r(509396); 10504const _links = __turbopack_context__.r(769688); 10505const _routerreducertypes = __turbopack_context__.r(388540); 10506const _computechangedpath = __turbopack_context__.r(734727); 10507const _javascripturl = __turbopack_context__.r(948277); 10508const _bfcache = __turbopack_context__.r(179027); 10509function navigate(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType) { 10510 // Instant Navigation Testing API: when the lock is active, ensure a 10511 // prefetch task has been initiated before proceeding with the navigation. 10512 // This guarantees that segment data requests are at least pending, even 10513 // for routes that already have a cached route tree. Without this, the 10514 // static shell might be incomplete because some segments were never 10515 // requested. 10516 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 10517 ; 10518 return navigateImpl(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType); 10519} 10520function navigateImpl(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType) { 10521 const now = Date.now(); 10522 const href = url.href; 10523 const cacheKey = (0, _cachekey.createCacheKey)(href, nextUrl); 10524 const route = (0, _cache.readRouteCacheEntry)(now, cacheKey); 10525 if (route !== null && route.status === _cache.EntryStatus.Fulfilled) { 10526 // We have a matching prefetch. 10527 return navigateUsingPrefetchedRouteTree(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType, route); 10528 } 10529 // There was no matching route tree in the cache. Let's see if we can 10530 // construct an "optimistic" route tree using the deprecated search-params 10531 // based matching. This is only used when the new optimisticRouting flag is 10532 // disabled. 10533 //
10534 // Do not construct an optimistic route tree if there was a cache hit, but 10535 // the entry has a rejected status, since it may have been rejected due to a 10536 // rewrite or redirect based on the search params. 10537 // 10538 // TODO: There are multiple reasons a prefetch might be rejected; we should 10539 // track them explicitly and choose what to do here based on that. 10540 if ("TURBOPACK compile-time truthy", 1) { 10541 if (route === null || route.status !== _cache.EntryStatus.Rejected) { 10542 const optimisticRoute = (0, _cache.deprecated_requestOptimisticRouteCacheEntry)(now, url, nextUrl); 10543 if (optimisticRoute !== null) { 10544 // We have an optimistic route tree. Proceed with the normal flow. 10545 return navigateUsingPrefetchedRouteTree(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType, optimisticRoute); 10546 } 10547 } 10548 } 10549 // There's no matching prefetch for this route in the cache. We must lazily 10550 // fetch it from the server before we can perform the navigation. 10551 // 10552 // TODO: If this is a gesture navigation, instead of performing a 10553 // dynamic request, we should do a runtime prefetch. 10554 return navigateToUnknownRoute(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType).catch(()=>{ 10555 // If the navigation fails, return the current state 10556 return state; 10557 }); 10558} 10559function navigateToKnownRoute(now, state, url, canonicalUrl, navigationSeed, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, freshnessPolicy, nextUrl, scrollBehavior, navigateType, debugInfo, // prediction. Passed through so it can be marked as having a dynamic rewrite 10560// if the server returns a different pathname (indicating dynamic rewrite 10561// behavior). 10562// 10563// When null, the navigation did not use route prediction - either because 10564// the route was already fully cached, or it's a navigation that doesn't 10565// involve prediction (refresh, history traversal, server action, etc.). 10566// In these cases, if a mismatch occurs, we still mark the route as having a 10567// dynamic rewrite by traversing the known route tree (see 10568// dispatchRetryDueToTreeMismatch). 10569routeCacheEntry) { 10570 // A version of navigate() that accepts the target route tree as an argument 10571 // rather than reading it from the prefetch cache. 10572 const accumulation = { 10573 separateRefreshUrls: null, 10574 scrollRef: null 10575 }; 10576 // We special case navigations to the exact same URL as the current location. 10577 // It's a common UI pattern for apps to refresh when you click a link to the 10578 // current page. So when this happens, we refresh the dynamic data in the page 10579 // segments. 10580 // 10581 // Note that this does not apply if the any part of the hash or search query 10582 // has changed. This might feel a bit weird but it makes more sense when you 10583 // consider that the way to trigger this behavior is to click the same link 10584 // multiple times. 10585 // 10586 // TODO: We should probably refresh the *entire* route when this case occurs, 10587 // not just the page segments. Essentially treating it the same as a refresh() 10588 // triggered by an action, which is the more explicit way of modeling the UI 10589 // pattern described above. 10590 // 10591 // Also note that this only refreshes the dynamic data, not static/ cached 10592 // data. If the page segment is fully static and prefetched, the request is 10593 // skipped. (This is also how refresh() works.) 10594 const isSamePageNavigation = url.href === currentUrl.href; 10595 const task = (0, _pprnavigations.startPPRNavigation)(now, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, navigationSeed.routeTree, navigationSeed.metadataVaryPath, freshnessPolicy, navigationSeed.data, navigationSeed.head, navigationSeed.dynamicStaleAt, isSamePageNavigation, accumulation); 10596 if (task !== null) { 10597 if (freshnessPolicy !== _pprnavigations.FreshnessPolicy.Gesture) { 10598 (0, _pprnavigations.spawnDynamicRequests)(task, url, nextUrl, freshnessPolicy, accumulation, routeCacheEntry, navigateType); 10599 } 10600 return completeSoftNavigation(state, url, nextUrl, task.route, task.node, navigationSeed.renderedSearch, canonicalUrl, navigateType, scrollBehavior, accumulation.scrollRef, debugInfo); 10601 } 10602 // Could not perform a SPA navigation. Revert to a full-page (MPA) navigation. 10603 return completeHardNavigation(state, url, navigateType); 10604} 10605function navigateUsingPrefetchedRouteTree(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType, route) { 10606 const routeTree = route.tree; 10607 const canonicalUrl = route.canonicalUrl + url.hash; 10608 const renderedSearch = route.renderedSearch; 10609 const prefetchSeed = { 10610 renderedSearch, 10611 routeTree, 10612 metadataVaryPath: route.metadata.varyPath, 10613 data: null, 10614 head: null, 10615 dynamicStaleAt: (0, _bfcache.computeDynamicStaleAt)(now, _bfcache.UnknownDynamicStaleTime) 10616 }; 10617 return navigateToKnownRoute(now, state, url, canonicalUrl, prefetchSeed, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, freshnessPolicy, nextUrl, scrollBehavior, navigateType, null, route); 10618} 10619// Used to request all the dynamic data for a route, rather than just a subset, 10620// e.g. during a refresh or a revalidation. Typically this gets constructed 10621// during the normal flow when diffing the route tree, but for an unprefetched 10622// navigation, where we don't know the structure of the target route, we use 10623// this instead. 10624const DynamicRequestTreeForEntireRoute = [ 10625 '', 10626 {}, 10627 null, 10628 'refetch' 10629]; 10630async function navigateToUnknownRoute(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType) {
10631 // Runs when a navigation happens but there's no cached prefetch we can use. 10632 // Don't bother to wait for a prefetch response; go straight to a full 10633 // navigation that contains both static and dynamic data in a single stream. 10634 // (This is unlike the old navigation implementation, which instead blocks 10635 // the dynamic request until a prefetch request is received.) 10636 // 10637 // To avoid duplication of logic, we're going to pretend that the tree 10638 // returned by the dynamic request is, in fact, a prefetch tree. Then we can 10639 // use the same server response to write the actual data into the CacheNode 10640 // tree. So it's the same flow as the "happy path" (prefetch, then 10641 // navigation), except we use a single server response for both stages. 10642 let dynamicRequestTree; 10643 switch(freshnessPolicy){ 10644 case _pprnavigations.FreshnessPolicy.Default: 10645 case _pprnavigations.FreshnessPolicy.HistoryTraversal: 10646 case _pprnavigations.FreshnessPolicy.Gesture: 10647 dynamicRequestTree = currentFlightRouterState; 10648 break; 10649 case _pprnavigations.FreshnessPolicy.Hydration: 10650 case _pprnavigations.FreshnessPolicy.RefreshAll: 10651 case _pprnavigations.FreshnessPolicy.HMRRefresh: 10652 dynamicRequestTree = DynamicRequestTreeForEntireRoute; 10653 break; 10654 default: 10655 freshnessPolicy; 10656 dynamicRequestTree = currentFlightRouterState; 10657 break; 10658 } 10659 const promiseForDynamicServerResponse = (0, _fetchserverresponse.fetchServerResponse)(url, { 10660 flightRouterState: dynamicRequestTree, 10661 nextUrl 10662 }); 10663 const result = await promiseForDynamicServerResponse; 10664 if (typeof result === 'string') { 10665 // This is an MPA navigation. 10666 const redirectUrl = new URL(result, location.origin); 10667 return completeHardNavigation(state, redirectUrl, navigateType); 10668 } 10669 const { flightData, canonicalUrl, renderedSearch, couldBeIntercepted, supportsPerSegmentPrefetching, dynamicStaleTime, staticStageData, runtimePrefetchStream, responseHeaders, debugInfo } = result; 10670 // Since the response format of dynamic requests and prefetches is slightly 10671 // different, we'll need to massage the data a bit. Create FlightRouterState 10672 // tree that simulates what we'd receive as the result of a prefetch. 10673 const navigationSeed = convertServerPatchToFullTree(now, currentFlightRouterState, flightData, renderedSearch, dynamicStaleTime); 10674 // Learn the route pattern so we can predict it for future navigations. 10675 // hasDynamicRewrite is false because this is a fresh navigation to an 10676 // unknown route - any rewrite detection happens during the traversal inside 10677 // discoverKnownRoute. The hasDynamicRewrite param is only set to true when 10678 // retrying after a tree mismatch (see dispatchRetryDueToTreeMismatch). 10679 const metadataVaryPath = navigationSeed.metadataVaryPath; 10680 if (metadataVaryPath !== null) { 10681 (0, _optimisticroutes.discoverKnownRoute)(now, url.pathname, nextUrl, null, navigationSeed.routeTree, metadataVaryPath, couldBeIntercepted, (0, _createhreffromurl.createHrefFromUrl)(canonicalUrl), supportsPerSegmentPrefetching, false // hasDynamicRewrite - not a retry, rewrite detection happens during traversal 10682 ); 10683 if (staticStageData !== null) { 10684 const { response: staticStageResponse, isResponsePartial } = staticStageData; 10685 // Write the static stage of the response into the segment cache so that 10686 // subsequent navigations can serve cached static segments instantly. 10687 (0, _cache.getStaleAt)(now, staticStageResponse.s).then((staleAt)=>{ 10688 var _responseHeaders_get; 10689 const buildId = (_responseHeaders_get = responseHeaders.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _responseHeaders_get !== void 0 ? _responseHeaders_get : staticStageResponse.b; 10690 (0, _cache.writeStaticStageResponseIntoCache)(now, staticStageResponse.f, buildId, staticStageResponse.h, staleAt, currentFlightRouterState, renderedSearch, isResponsePartial); 10691 }).catch(()=>{ 10692 // The static stage processing failed. Not fatal — the navigation 10693 // completed normally, we just won't write into the cache. 10694 }); 10695 } 10696 if (runtimePrefetchStream !== null) { 10697 (0, _cache.processRuntimePrefetchStream)(now, runtimePrefetchStream, currentFlightRouterState, renderedSearch).then((processed)=>{ 10698 if (processed !== null) { 10699 (0, _cache.writeDynamicRenderResponseIntoCache)(now, _types.FetchStrategy.PPRRuntime, processed.flightDatas, processed.buildId, processed.isResponsePartial, processed.headVaryParams, processed.staleAt, processed.navigationSeed, null); 10700 } 10701 }).catch(()=>{ 10702 // The runtime prefetch cache write failed. Not fatal — the
10703 // navigation completed normally, we just won't cache runtime data. 10704 }); 10705 } 10706 } 10707 return navigateToKnownRoute(now, state, url, (0, _createhreffromurl.createHrefFromUrl)(canonicalUrl), navigationSeed, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, freshnessPolicy, nextUrl, scrollBehavior, navigateType, debugInfo, // came directly from the server. If a mismatch occurs during dynamic data 10708 // fetch, the retry handler will traverse the known route tree to mark the 10709 // entry as having a dynamic rewrite. 10710 null); 10711} 10712function completeHardNavigation(state, url, navigateType) { 10713 if ((0, _javascripturl.isJavaScriptURLString)(url.href)) { 10714 console.error('Next.js has blocked a javascript: URL as a security precaution.'); 10715 return state; 10716 } 10717 const newState = { 10718 canonicalUrl: url.origin === location.origin ? (0, _createhreffromurl.createHrefFromUrl)(url) : url.href, 10719 pushRef: { 10720 pendingPush: navigateType === 'push', 10721 mpaNavigation: true, 10722 preserveCustomHistoryState: false 10723 }, 10724 // TODO: None of the rest of these values are consistent with the incoming 10725 // navigation. We rely on the fact that AppRouter will suspend and trigger 10726 // a hard navigation before it accesses any of these values. But instead 10727 // we should trigger the hard navigation and blocking any subsequent 10728 // router updates without updating React. 10729 renderedSearch: state.renderedSearch, 10730 focusAndScrollRef: state.focusAndScrollRef, 10731 cache: state.cache, 10732 tree: state.tree, 10733 nextUrl: state.nextUrl, 10734 previousNextUrl: state.previousNextUrl, 10735 debugInfo: null 10736 }; 10737 return newState; 10738} 10739function completeSoftNavigation(oldState, url, referringNextUrl, tree, cache, renderedSearch, canonicalUrl, navigateType, scrollBehavior, scrollRef, collectedDebugInfo) { 10740 // The "Next-Url" is a special representation of the URL that Next.js 10741 // uses to implement interception routes. 10742 // TODO: Get rid of this extra traversal by computing this during the
10743 // same traversal that computes the tree itself. We should also figure out 10744 // what is the minimum information needed for the server to correctly 10745 // intercept the route. 10746 const changedPath = (0, _computechangedpath.computeChangedPath)(oldState.tree, tree); 10747 const nextUrlForNewRoute = changedPath ? changedPath : oldState.nextUrl; 10748 // This value is stored on the state as `previousNextUrl`; the naming is 10749 // confusing. What it represents is the "Next-Url" header that was used to 10750 // fetch the incoming route. It's essentially the refererer URL, but in a 10751 // Next.js specific format. During refreshes, this is sent back to the server 10752 // instead of the current route's "Next-Url" so that the same interception 10753 // logic is applied as during the original navigation. 10754 const previousNextUrl = referringNextUrl; 10755 // Check if the only thing that changed was the hash fragment. 10756 const oldUrl = new URL(oldState.canonicalUrl, url); 10757 const onlyHashChange = // navigations are always same-origin. 10758 url.pathname === oldUrl.pathname && url.search === oldUrl.search && url.hash !== oldUrl.hash; 10759 // Determine whether and how the page should scroll after this 10760 // navigation. 10761 // 10762 // By default, we scroll to the segments that were navigated to — i.e. 10763 // segments in the new part of the route, as opposed to shared segments 10764 // that were already part of the previous route. All newly navigated 10765 // segments share a single ScrollRef. When they mount, the first one 10766 // to mount initiates the scroll. They share a ref so that only one 10767 // scroll happens per navigation. 10768 // 10769 // If a subsequent navigation produces new segments, those supersede 10770 // any pending scroll from the previous navigation by invalidating its 10771 // ScrollRef. If a navigation doesn't produce any new segments (e.g. 10772 // a refresh where the route structure didn't change), any pending 10773 // scrolls from previous navigations are unaffected. 10774 // 10775 // The branches below handle special cases layered on top of this 10776 // default model. 10777 let activeScrollRef; 10778 let forceScroll; 10779 if (scrollBehavior === _routerreducertypes.ScrollBehavior.NoScroll) { 10780 // The user explicitly opted out of scrolling (e.g. scroll={false} 10781 // on a Link or router.push). 10782 // 10783 // If this navigation created new scroll targets (scrollRef !== null), 10784 // neutralize them. If it didn't, any prior scroll targets carried 10785 // forward on the cache nodes via reuseSharedCacheNode remain active. 10786 if (scrollRef !== null) { 10787 scrollRef.current = false; 10788 } 10789 activeScrollRef = oldState.focusAndScrollRef.scrollRef; 10790 forceScroll = false; 10791 } else if (onlyHashChange) { 10792 // Hash-only navigations should scroll regardless of per-node state. 10793 // Create a fresh ref so the first segment to scroll consumes it. 10794 // 10795 // Invalidate any scroll ref from a prior navigation that hasn't 10796 // been consumed yet. 10797 const oldScrollRef = oldState.focusAndScrollRef.scrollRef; 10798 if (oldScrollRef !== null) { 10799 oldScrollRef.current = false; 10800 } 10801 // Also invalidate any per-node refs that were accumulated during 10802 // this navigation's tree construction — the hash-only ref 10803 // supersedes them. 10804 if (scrollRef !== null) { 10805 scrollRef.current = false; 10806 } 10807 activeScrollRef = { 10808 current: true 10809 }; 10810 forceScroll = true; 10811 } else { 10812 // Default case. Use the accumulated scrollRef (may be null if no 10813 // new segments were created). The handler checks per-node refs, so 10814 // unchanged parallel route slots won't scroll. 10815 activeScrollRef = scrollRef; 10816 // If this navigation created new scroll targets, invalidate any 10817 // pending scroll from a previous navigation. 10818 if (scrollRef !== null) { 10819 const oldScrollRef = oldState.focusAndScrollRef.scrollRef; 10820 if (oldScrollRef !== null) { 10821 oldScrollRef.current = false;
10822 } 10823 } 10824 forceScroll = false; 10825 } 10826 const newState = { 10827 canonicalUrl, 10828 renderedSearch, 10829 pushRef: { 10830 pendingPush: navigateType === 'push', 10831 mpaNavigation: false, 10832 preserveCustomHistoryState: false 10833 }, 10834 focusAndScrollRef: { 10835 scrollRef: activeScrollRef, 10836 forceScroll, 10837 onlyHashChange, 10838 hashFragment: // 10839 // Empty hash should trigger default behavior of scrolling layout into 10840 // view. #top is handled in layout-router. 10841 // 10842 // Refer to `ScrollAndFocusHandler` for details on how this is used. 10843 scrollBehavior !== _routerreducertypes.ScrollBehavior.NoScroll && url.hash !== '' ? decodeURIComponent(url.hash.slice(1)) : oldState.focusAndScrollRef.hashFragment 10844 }, 10845 cache, 10846 tree, 10847 nextUrl: nextUrlForNewRoute, 10848 previousNextUrl, 10849 debugInfo: collectedDebugInfo 10850 }; 10851 return newState; 10852} 10853function completeTraverseNavigation(state, url, renderedSearch, cache, tree, nextUrl) { 10854 return { 10855 // Set canonical url 10856 canonicalUrl: (0, _createhreffromurl.createHrefFromUrl)(url), 10857 renderedSearch, 10858 pushRef: { 10859 pendingPush: false, 10860 mpaNavigation: false, 10861 // Ensures that the custom history state that was set is preserved when applying this update. 10862 preserveCustomHistoryState: true 10863 }, 10864 focusAndScrollRef: state.focusAndScrollRef, 10865 cache, 10866 // Restore provided tree 10867 tree, 10868 nextUrl, 10869 // TODO: We need to restore previousNextUrl, too, which represents the 10870 // Next-Url that was used to fetch the data. Anywhere we fetch using the 10871 // canonical URL, there should be a corresponding Next-Url. 10872 previousNextUrl: null, 10873 debugInfo: null 10874 }; 10875} 10876function convertServerPatchToFullTree(now, currentTree, flightData, renderedSearch, dynamicStaleTimeSeconds) { 10877 // During a client navigation or prefetch, the server sends back only a patch 10878 // for the parts of the tree that have changed. 10879 // 10880 // This applies the patch to the base tree to create a full representation of 10881 // the resulting tree. 10882 // 10883 // The return type includes a full FlightRouterState tree and a full 10884 // CacheNodeSeedData tree. (Conceptually these are the same tree, and should 10885 // eventually be unified, but there's still lots of existing code that 10886 // operates on FlightRouterState trees alone without the CacheNodeSeedData.) 10887 // 10888 // TODO: This similar to what apply-router-state-patch-to-tree does. It 10889 // will eventually fully replace it. We should get rid of all the remaining 10890 // places where we iterate over the server patch format. This should also 10891 // eventually replace normalizeFlightData. 10892 let baseTree = currentTree; 10893 let baseData = null; 10894 let head = null; 10895 if (flightData !== null) { 10896 for (const { segmentPath, tree: treePatch, seedData: dataPatch, head: headPatch } of flightData){ 10897 const result = convertServerPatchToFullTreeImpl(baseTree, baseData, treePatch, dataPatch, segmentPath, renderedSearch, 0); 10898 baseTree = result.tree; 10899 baseData = result.data; 10900 // This is the same for all patches per response, so just pick an 10901 // arbitrary one 10902 head = headPatch; 10903 } 10904 } 10905 const finalFlightRouterState = baseTree; 10906 // Convert the final FlightRouterState into a RouteTree type. 10907 // 10908 // TODO: Eventually, FlightRouterState will evolve to being a transport format 10909 // only. The RouteTree type will become the main type used for dealing with 10910 // routes on the client, and we'll store it in the state directly. 10911 const acc = { 10912 metadataVaryPath: null 10913 }; 10914 const routeTree = (0, _cache.convertRootFlightRouterStateToRouteTree)(finalFlightRouterState, renderedSearch, acc); 10915 return { 10916 routeTree, 10917 metadataVaryPath: acc.metadataVaryPath, 10918 data: baseData, 10919 renderedSearch, 10920 head, 10921 dynamicStaleAt: (0, _bfcache.computeDynamicStaleAt)(now, dynamicStaleTimeSeconds) 10922 }; 10923} 10924function convertServerPatchToFullTreeImpl(baseRouterState, baseData, treePatch, dataPatch, segmentPath, renderedSearch, index) { 10925 if (index === segmentPath.length) { 10926 // We reached the part of the tree that we need to patch. 10927 return { 10928 tree: treePatch, 10929 data: dataPatch 10930 }; 10931 } 10932 // segmentPath represents the parent path of subtree. It's a repeating 10933 // pattern of parallel route key and segment: 10934 // 10935 // [string, Segment, string, Segment, string, Segment, ...] 10936 // 10937 // This path tells us which part of the base tree to apply the tree patch. 10938 // 10939 // NOTE: We receive the FlightRouterState patch in the same request as the 10940 // seed data patch. Therefore we don't need to worry about diffing the segment 10941 // values; we can assume the server sent us a correct result. 10942 const updatedParallelRouteKey = segmentPath[index]; 10943 // const segment: Segment = segmentPath[index + 1] <-- Not used, see note above 10944 const baseTreeChildren = baseRouterState[1]; 10945 const baseSeedDataChildren = baseData !== null ? baseData[1] : null; 10946 const newTreeChildren = {}; 10947 const newSeedDataChildren = {}; 10948 for(const parallelRouteKey in baseTreeChildren){ 10949 var _baseSeedDataChildren_parallelRouteKey; 10950 const childBaseRouterState = baseTreeChildren[parallelRouteKey]; 10951 const childBaseSeedData = baseSeedDataChildren !== null ? (_baseSeedDataChildren_parallelRouteKey = baseSeedDataChildren[parallelRouteKey]) !== null && _baseSeedDataChildren_parallelRouteKey !== void 0 ? _baseSeedDataChildren_parallelRouteKey : null : null; 10952 if (parallelRouteKey === updatedParallelRouteKey) { 10953 const result = convertServerPatchToFullTreeImpl(childBaseRouterState, childBaseSeedData, treePatch, dataPatch, segmentPath, renderedSearch, // the end of the segment path. 10954 index + 2); 10955 newTreeChildren[parallelRouteKey] = result.tree; 10956 newSeedDataChildren[parallelRouteKey] = result.data; 10957 } else { 10958 // This child is not being patched. Copy it over as-is. 10959 newTreeChildren[parallelRouteKey] = childBaseRouterState; 10960 newSeedDataChildren[parallelRouteKey] = childBaseSeedData; 10961 } 10962 }
10963 let clonedTree; 10964 let clonedSeedData; 10965 // Clone all the fields except the children. 10966 // Clone the FlightRouterState tree. Based on equivalent logic in 10967 // apply-router-state-patch-to-tree, but should confirm whether we need to 10968 // copy all of these fields. Not sure the server ever sends, e.g. the 10969 // refetch marker. 10970 clonedTree = [ 10971 baseRouterState[0], 10972 newTreeChildren 10973 ]; 10974 if (2 in baseRouterState) { 10975 const compressedRefreshState = baseRouterState[2]; 10976 if (compressedRefreshState !== undefined && compressedRefreshState !== null) { 10977 // Since this part of the tree was patched with new data, any parent 10978 // refresh states should be updated to reflect the new rendered search 10979 // value. (The refresh state acts like a "context provider".) All pages 10980 // within the same server response share the same renderedSearch value, 10981 // but the same RouteTree could be composed from multiple different 10982 // routes, and multiple responses. 10983 clonedTree[2] = [ 10984 compressedRefreshState[0], 10985 renderedSearch 10986 ]; 10987 } 10988 } 10989 if (3 in baseRouterState) { 10990 clonedTree[3] = baseRouterState[3]; 10991 } 10992 if (4 in baseRouterState) { 10993 clonedTree[4] = baseRouterState[4]; 10994 } 10995 // Clone the CacheNodeSeedData tree. 10996 const isEmptySeedDataPartial = true; 10997 clonedSeedData = [ 10998 null, 10999 newSeedDataChildren, 11000 null, 11001 isEmptySeedDataPartial, 11002 null 11003 ]; 11004 return { 11005 tree: clonedTree, 11006 data: clonedSeedData 11007 }; 11008} 11009/** 11010 * Instant Navigation Testing API: ensures a prefetch task has been initiated 11011 * and completed before proceeding with the navigation. This guarantees that 11012 * segment data requests are at least pending, even for routes whose route 11013 * tree is already cached. 11014 * 11015 * After the prefetch completes, delegates to the normal navigation flow. 11016 */ async function ensurePrefetchThenNavigate(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType) { 11017 const link = (0, _links.getLinkForCurrentNavigation)(); 11018 const fetchStrategy = link !== null ? link.fetchStrategy : _types.FetchStrategy.PPR; 11019 // Transition the cookie to captured-SPA immediately, before waiting 11020 // for the prefetch. This ensures the devtools panel can update its UI 11021 // right away, even if the prefetch takes time (e.g. dev compilation). 11022 // The "to" tree starts as null and is filled in after the prefetch 11023 // resolves and the navigation produces a new router state. 11024 const { transitionToCapturedSPA, updateCapturedSPAToTree } = __turbopack_context__.r(381400); 11025 transitionToCapturedSPA(currentFlightRouterState, null); 11026 const cacheKey = (0, _cachekey.createCacheKey)(url.href, nextUrl); 11027 await new Promise((resolve)=>{ 11028 (0, _scheduler.schedulePrefetchTask)(cacheKey, currentFlightRouterState, fetchStrategy, _types.PrefetchPriority.Default, null, resolve // _onComplete callback 11029 ); 11030 }); 11031 // Prefetch is complete. Proceed with the normal navigation flow, which 11032 // will now find the route in the cache. 11033 const result = await navigateImpl(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType); 11034 // Update the cookie with the resolved "to" tree so the devtools 11035 // panel can display both routes immediately. 11036 updateCapturedSPAToTree(currentFlightRouterState, result.tree); 11037 return result; 11038} 11039if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11040 Object.defineProperty(exports.default, '__esModule', { 11041 value: true 11042 }); 11043 Object.assign(exports.default, exports); 11044 module.exports = exports.default; 11045} 11046}), 11047754069, ((__turbopack_context__, module, exports) => { 11048"use strict"; 11049 11050var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 11051"use strict"; 11052Object.defineProperty(exports, "__esModule", { 11053 value: true 11054}); 110550 && (module.exports = { 11056 DYNAMIC_STALETIME_MS: null, 11057 STATIC_STALETIME_MS: null, 11058 navigateReducer: null 11059}); 11060function _export(target, all) { 11061 for(var name in all)Object.defineProperty(target, name, { 11062 enumerable: true, 11063 get: all[name] 11064 }); 11065} 11066_export(exports, { 11067 DYNAMIC_STALETIME_MS: function() { 11068 return DYNAMIC_STALETIME_MS; 11069 }, 11070 STATIC_STALETIME_MS: function() { 11071 return STATIC_STALETIME_MS; 11072 }, 11073 navigateReducer: function() { 11074 return navigateReducer; 11075 } 11076});
11077const _navigation = __turbopack_context__.r(760355); 11078const _cache = __turbopack_context__.r(620896); 11079const _pprnavigations = __turbopack_context__.r(595871); 11080const DYNAMIC_STALETIME_MS = Number(("TURBOPACK compile-time value", "0")) * 1000; 11081const STATIC_STALETIME_MS = (0, _cache.getStaleTimeMs)(Number(("TURBOPACK compile-time value", "300"))); 11082function navigateReducer(state, action) { 11083 const { url, isExternalUrl, navigateType, scrollBehavior } = action; 11084 if (isExternalUrl) { 11085 return (0, _navigation.completeHardNavigation)(state, url, navigateType); 11086 } 11087 // Handles case where `<meta http-equiv="refresh">` tag is present, 11088 // which will trigger an MPA navigation. 11089 if (document.getElementById('__next-page-redirect')) { 11090 return (0, _navigation.completeHardNavigation)(state, url, navigateType); 11091 } 11092 // Temporary glue code between the router reducer and the new navigation 11093 // implementation. Eventually we'll rewrite the router reducer to a 11094 // state machine. 11095 const currentUrl = new URL(state.canonicalUrl, location.origin); 11096 const currentRenderedSearch = state.renderedSearch; 11097 return (0, _navigation.navigate)(state, url, currentUrl, currentRenderedSearch, state.cache, state.tree, state.nextUrl, _pprnavigations.FreshnessPolicy.Default, scrollBehavior, navigateType); 11098} 11099if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11100 Object.defineProperty(exports.default, '__esModule', { 11101 value: true 11102 }); 11103 Object.assign(exports.default, exports); 11104 module.exports = exports.default; 11105} 11106}), 11107284356, ((__turbopack_context__, module, exports) => { 11108"use strict"; 11109 11110Object.defineProperty(exports, "__esModule", { 11111 value: true 11112}); 11113Object.defineProperty(exports, "hasInterceptionRouteInCurrentTree", { 11114 enumerable: true, 11115 get: function() { 11116 return hasInterceptionRouteInCurrentTree; 11117 } 11118}); 11119const _interceptionroutes = __turbopack_context__.r(591463); 11120function hasInterceptionRouteInCurrentTree(param) { 11121 let [segment, parallelRoutes] = param; 11122 // If we have a dynamic segment, it's marked as an interception route by the presence of the `i` suffix. 11123 if (Array.isArray(segment) && (segment[2] === 'di(..)(..)' || segment[2] === 'ci(..)(..)' || segment[2] === 'di(.)' || segment[2] === 'ci(.)' || segment[2] === 'di(..)' || segment[2] === 'ci(..)' || segment[2] === 'di(...)' || segment[2] === 'ci(...)')) { 11124 return true; 11125 } 11126 // If segment is not an array, apply the existing string-based check 11127 if (typeof segment === 'string' && (0, _interceptionroutes.isInterceptionRouteAppPath)(segment)) { 11128 return true; 11129 } 11130 // Iterate through parallelRoutes if they exist 11131 if (parallelRoutes) { 11132 for(const key in parallelRoutes){ 11133 if (hasInterceptionRouteInCurrentTree(parallelRoutes[key])) { 11134 return true; 11135 } 11136 } 11137 } 11138 return false; 11139} 11140if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11141 Object.defineProperty(exports.default, '__esModule', { 11142 value: true 11143 }); 11144 Object.assign(exports.default, exports); 11145 module.exports = exports.default; 11146} 11147}), 11148269845, ((__turbopack_context__, module, exports) => { 11149"use strict"; 11150 11151var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 11152"use strict"; 11153Object.defineProperty(exports, "__esModule", { 11154 value: true 11155}); 111560 && (module.exports = { 11157 refreshDynamicData: null, 11158 refreshReducer: null 11159}); 11160function _export(target, all) { 11161 for(var name in all)Object.defineProperty(target, name, { 11162 enumerable: true, 11163 get: all[name] 11164 }); 11165} 11166_export(exports, { 11167 refreshDynamicData: function() { 11168 return refreshDynamicData; 11169 }, 11170 refreshReducer: function() { 11171 return refreshReducer; 11172 } 11173}); 11174const _routerreducertypes = __turbopack_context__.r(388540);
11175const _navigation = __turbopack_context__.r(760355); 11176const _cache = __turbopack_context__.r(620896); 11177const _hasinterceptionrouteincurrenttree = __turbopack_context__.r(284356); 11178const _pprnavigations = __turbopack_context__.r(595871); 11179const _bfcache = __turbopack_context__.r(179027); 11180function refreshReducer(state, action) { 11181 // During a refresh, we invalidate the segment cache but not the route cache. 11182 // The route cache contains the tree structure (which segments exist at a 11183 // given URL) which doesn't change during a refresh. The segment cache 11184 // contains the actual RSC data which needs to be re-fetched. 11185 // 11186 // The Instant Navigation Testing API can bypass cache invalidation to 11187 // preserve prefetched data when refreshing after an MPA navigation. This is 11188 // only used for testing and is not exposed in production builds by default. 11189 const bypassCacheInvalidation = ("TURBOPACK compile-time value", false) && action.bypassCacheInvalidation; 11190 if ("TURBOPACK compile-time truthy", 1) { 11191 const currentNextUrl = state.nextUrl; 11192 const currentRouterState = state.tree; 11193 (0, _cache.invalidateSegmentCacheEntries)(currentNextUrl, currentRouterState); 11194 } 11195 return refreshDynamicData(state, _pprnavigations.FreshnessPolicy.RefreshAll); 11196} 11197function refreshDynamicData(state, freshnessPolicy) { 11198 // During a refresh, invalidate the BFCache, which may contain dynamic data. 11199 (0, _bfcache.invalidateBfCache)(); 11200 const currentNextUrl = state.nextUrl; 11201 // We always send the last next-url, not the current when performing a dynamic 11202 // request. This is because we update the next-url after a navigation, but we 11203 // want the same interception route to be matched that used the last next-url. 11204 const nextUrlForRefresh = (0, _hasinterceptionrouteincurrenttree.hasInterceptionRouteInCurrentTree)(state.tree) ? state.previousNextUrl || currentNextUrl : null; 11205 // A refresh is modeled as a navigation to the current URL, but where any 11206 // existing dynamic data (including in shared layouts) is re-fetched. 11207 const currentCanonicalUrl = state.canonicalUrl; 11208 const currentUrl = new URL(currentCanonicalUrl, location.origin); 11209 const currentRenderedSearch = state.renderedSearch; 11210 const currentFlightRouterState = state.tree; 11211 const scrollBehavior = _routerreducertypes.ScrollBehavior.NoScroll; 11212 // Create a NavigationSeed from the current FlightRouterState. 11213 // TODO: Eventually we will store this type directly on the state object 11214 // instead of reconstructing it on demand. Part of a larger series of 11215 // refactors to unify the various tree types that the client deals with. 11216 const now = Date.now(); 11217 // TODO: Store the dynamic stale time on the top-level state so it's known 11218 // during restores and refreshes. 11219 const refreshSeed = (0, _navigation.convertServerPatchToFullTree)(now, currentFlightRouterState, null, currentRenderedSearch, _bfcache.UnknownDynamicStaleTime); 11220 const navigateType = 'replace'; 11221 return (0, _navigation.navigateToKnownRoute)(now, state, currentUrl, currentCanonicalUrl, refreshSeed, currentUrl, currentRenderedSearch, state.cache, currentFlightRouterState, freshnessPolicy, nextUrlForRefresh, scrollBehavior, navigateType, null, // cache entry to mark as having a dynamic rewrite on mismatch. If a 11222 // mismatch occurs, the retry handler will traverse the known route tree 11223 // to find and mark the entry. 11224 null); 11225} 11226if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11227 Object.defineProperty(exports.default, '__esModule', { 11228 value: true 11229 }); 11230 Object.assign(exports.default, exports); 11231 module.exports = exports.default; 11232} 11233}), 11234891668, ((__turbopack_context__, module, exports) => { 11235"use strict"; 11236 11237Object.defineProperty(exports, "__esModule", { 11238 value: true 11239}); 11240Object.defineProperty(exports, "serverPatchReducer", { 11241 enumerable: true, 11242 get: function() { 11243 return serverPatchReducer; 11244 } 11245}); 11246const _createhreffromurl = __turbopack_context__.r(451191); 11247const _routerreducertypes = __turbopack_context__.r(388540);
11248const _navigation = __turbopack_context__.r(760355); 11249const _refreshreducer = __turbopack_context__.r(269845); 11250const _pprnavigations = __turbopack_context__.r(595871); 11251function serverPatchReducer(state, action) { 11252 // A "retry" is a navigation that happens due to a route mismatch. It's 11253 // similar to a refresh, because we will omit any existing dynamic data on 11254 // the page. But we seed the retry navigation with the exact tree that the 11255 // server just responded with. 11256 const retryMpa = action.mpa; 11257 const retryUrl = new URL(action.url, location.origin); 11258 const retrySeed = action.seed; 11259 const navigateType = action.navigateType; 11260 if (retryMpa || retrySeed === null) { 11261 // If the server did not send back data during the mismatch, fall back to 11262 // an MPA navigation. 11263 return (0, _navigation.completeHardNavigation)(state, retryUrl, navigateType); 11264 } 11265 const currentUrl = new URL(state.canonicalUrl, location.origin); 11266 const currentRenderedSearch = state.renderedSearch; 11267 if (action.previousTree !== state.tree) { 11268 // There was another, more recent navigation since the once that 11269 // mismatched. We can abort the retry, but we still need to refresh the 11270 // page to evict any stale dynamic data. 11271 return (0, _refreshreducer.refreshReducer)(state, { 11272 type: _routerreducertypes.ACTION_REFRESH 11273 }); 11274 } 11275 // There have been no new navigations since the mismatched one. Refresh, 11276 // using the tree we just received from the server. 11277 const retryCanonicalUrl = (0, _createhreffromurl.createHrefFromUrl)(retryUrl); 11278 const retryNextUrl = action.nextUrl; 11279 const scrollBehavior = _routerreducertypes.ScrollBehavior.Default; 11280 const now = Date.now(); 11281 return (0, _navigation.navigateToKnownRoute)(now, state, retryUrl, retryCanonicalUrl, retrySeed, currentUrl, currentRenderedSearch, state.cache, state.tree, _pprnavigations.FreshnessPolicy.RefreshAll, retryNextUrl, scrollBehavior, navigateType, null, // typically a retry after a previous mismatch, so the route was already 11282 // marked as having a dynamic rewrite when the mismatch was detected. 11283 null); 11284} 11285if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11286 Object.defineProperty(exports.default, '__esModule', { 11287 value: true 11288 }); 11289 Object.assign(exports.default, exports); 11290 module.exports = exports.default; 11291} 11292}), 1129373790, ((__turbopack_context__, module, exports) => { 11294"use strict"; 11295 11296Object.defineProperty(exports, "__esModule", { 11297 value: true 11298}); 11299Object.defineProperty(exports, "restoreReducer", { 11300 enumerable: true, 11301 get: function() { 11302 return restoreReducer; 11303 } 11304}); 11305const _computechangedpath = __turbopack_context__.r(734727); 11306const _pprnavigations = __turbopack_context__.r(595871); 11307const _navigation = __turbopack_context__.r(760355); 11308const _bfcache = __turbopack_context__.r(179027); 11309function restoreReducer(state, action) { 11310 var _ref; 11311 // This action is used to restore the router state from the history state. 11312 // However, it's possible that the history state no longer contains the `FlightRouterState`. 11313 // We will copy over the internal state on pushState/replaceState events, but if a history entry 11314 // occurred before hydration, or if the user navigated to a hash using a regular anchor link, 11315 // the history state will not contain the `FlightRouterState`. 11316 // In this case, we'll continue to use the existing tree so the router doesn't get into an invalid state. 11317 let treeToRestore; 11318 let renderedSearch; 11319 const historyState = action.historyState; 11320 if (historyState) { 11321 treeToRestore = historyState.tree; 11322 renderedSearch = historyState.renderedSearch; 11323 } else { 11324 treeToRestore = state.tree; 11325 renderedSearch = state.renderedSearch; 11326 } 11327 const currentUrl = new URL(state.canonicalUrl, location.origin); 11328 const restoredUrl = action.url; 11329 const restoredNextUrl = (_ref = (0, _computechangedpath.extractPathFromFlightRouterState)(treeToRestore)) !== null && _ref !== void 0 ? _ref : restoredUrl.pathname; 11330 const now = Date.now(); 11331 // TODO: Store the dynamic stale time on the top-level state so it's known 11332 // during restores and refreshes. 11333 const accumulation = { 11334 separateRefreshUrls: null, 11335 scrollRef: null 11336 }; 11337 const restoreSeed = (0, _navigation.convertServerPatchToFullTree)(now, treeToRestore, null, renderedSearch, _bfcache.UnknownDynamicStaleTime); 11338 const task = (0, _pprnavigations.startPPRNavigation)(now, currentUrl, state.renderedSearch, state.cache, state.tree, restoreSeed.routeTree, restoreSeed.metadataVaryPath, _pprnavigations.FreshnessPolicy.HistoryTraversal, null, null, restoreSeed.dynamicStaleAt, false, accumulation); 11339 if (task === null) { 11340 return (0, _navigation.completeHardNavigation)(state, restoredUrl, 'replace'); 11341 } 11342 (0, _pprnavigations.spawnDynamicRequests)(task, restoredUrl, restoredNextUrl, _pprnavigations.FreshnessPolicy.HistoryTraversal, accumulation, // cache entry to mark as having a dynamic rewrite on mismatch. If a 11343 // mismatch occurs, the retry handler will traverse the known route tree 11344 // to find and mark the entry. 11345 null, 'replace'); 11346 return (0, _navigation.completeTraverseNavigation)(state, restoredUrl, renderedSearch, task.node, task.route, restoredNextUrl); 11347} 11348if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11349 Object.defineProperty(exports.default, '__esModule', { 11350 value: true 11351 });
11352 Object.assign(exports.default, exports); 11353 module.exports = exports.default; 11354} 11355}), 11356486720, ((__turbopack_context__, module, exports) => { 11357"use strict"; 11358 11359Object.defineProperty(exports, "__esModule", { 11360 value: true 11361}); 11362Object.defineProperty(exports, "hmrRefreshReducer", { 11363 enumerable: true, 11364 get: function() { 11365 return hmrRefreshReducer; 11366 } 11367}); 11368const _refreshreducer = __turbopack_context__.r(269845); 11369const _pprnavigations = __turbopack_context__.r(595871); 11370function hmrRefreshReducer(state) { 11371 return (0, _refreshreducer.refreshDynamicData)(state, _pprnavigations.FreshnessPolicy.HMRRefresh); 11372} 11373if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11374 Object.defineProperty(exports.default, '__esModule', { 11375 value: true 11376 }); 11377 Object.assign(exports.default, exports); 11378 module.exports = exports.default; 11379} 11380}), 11381627801, ((__turbopack_context__, module, exports) => { 11382"use strict"; 11383 11384Object.defineProperty(exports, "__esModule", { 11385 value: true 11386}); 11387Object.defineProperty(exports, "assignLocation", { 11388 enumerable: true, 11389 get: function() { 11390 return assignLocation; 11391 } 11392}); 11393const _addbasepath = __turbopack_context__.r(405550); 11394function assignLocation(location, url) { 11395 if (location.startsWith('.')) { 11396 const urlBase = url.origin + url.pathname; 11397 return new URL(// new URL('./relative', 'https://example.com/subdir').href -> 'https://example.com/relative' 11398 // new URL('./relative', 'https://example.com/subdir/').href -> 'https://example.com/subdir/relative' 11399 (urlBase.endsWith('/') ? urlBase : urlBase + '/') + location); 11400 } 11401 return new URL((0, _addbasepath.addBasePath)(location), url.href); 11402} 11403if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11404 Object.defineProperty(exports.default, '__esModule', { 11405 value: true 11406 }); 11407 Object.assign(exports.default, exports); 11408 module.exports = exports.default; 11409} 11410}), 1141159084, ((__turbopack_context__, module, exports) => { 11412"use strict"; 11413 11414Object.defineProperty(exports, "__esModule", { 11415 value: true 11416}); 11417Object.defineProperty(exports, "pathHasPrefix", { 11418 enumerable: true, 11419 get: function() { 11420 return pathHasPrefix; 11421 } 11422}); 11423const _parsepath = __turbopack_context__.r(572463); 11424function pathHasPrefix(path, prefix) { 11425 if (typeof path !== 'string') { 11426 return false; 11427 } 11428 const { pathname } = (0, _parsepath.parsePath)(path); 11429 return pathname === prefix || pathname.startsWith(prefix + '/'); 11430} 11431}), 11432652817, ((__turbopack_context__, module, exports) => { 11433"use strict"; 11434 11435var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 11436"use strict"; 11437Object.defineProperty(exports, "__esModule", { 11438 value: true 11439}); 11440Object.defineProperty(exports, "hasBasePath", { 11441 enumerable: true, 11442 get: function() { 11443 return hasBasePath; 11444 } 11445}); 11446const _pathhasprefix = __turbopack_context__.r(59084); 11447const basePath = ("TURBOPACK compile-time value", "") || ''; 11448function hasBasePath(path) { 11449 return (0, _pathhasprefix.pathHasPrefix)(path, basePath); 11450} 11451if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11452 Object.defineProperty(exports.default, '__esModule', { 11453 value: true 11454 }); 11455 Object.assign(exports.default, exports); 11456 module.exports = exports.default; 11457} 11458}), 11459387250, ((__turbopack_context__, module, exports) => { 11460"use strict"; 11461 11462var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 11463"use strict"; 11464Object.defineProperty(exports, "__esModule", { 11465 value: true 11466}); 11467Object.defineProperty(exports, "removeBasePath", { 11468 enumerable: true, 11469 get: function() { 11470 return removeBasePath; 11471 } 11472}); 11473const _hasbasepath = __turbopack_context__.r(652817); 11474const basePath = ("TURBOPACK compile-time value", "") || ''; 11475function removeBasePath(path) { 11476 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 11477 ; 11478 // Can't trim the basePath if it has zero length! 11479 if (basePath.length === 0) return path; 11480 path = path.slice(basePath.length); 11481 if (!path.startsWith('/')) path = "/".concat(path); 11482 return path; 11483} 11484if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11485 Object.defineProperty(exports.default, '__esModule', { 11486 value: true 11487 });
11488 Object.assign(exports.default, exports); 11489 module.exports = exports.default; 11490} 11491}), 11492239747, ((__turbopack_context__, module, exports) => { 11493"use strict"; 11494 11495Object.defineProperty(exports, "__esModule", { 11496 value: true 11497}); 114980 && (module.exports = { 11499 SERVER_REFERENCE_ID_LENGTH: null, 11500 extractInfoFromServerReferenceId: null, 11501 mightBeServerReferenceId: null, 11502 omitUnusedArgs: null 11503}); 11504function _export(target, all) { 11505 for(var name in all)Object.defineProperty(target, name, { 11506 enumerable: true, 11507 get: all[name] 11508 }); 11509} 11510_export(exports, { 11511 SERVER_REFERENCE_ID_LENGTH: function() { 11512 return SERVER_REFERENCE_ID_LENGTH; 11513 }, 11514 extractInfoFromServerReferenceId: function() { 11515 return extractInfoFromServerReferenceId; 11516 }, 11517 mightBeServerReferenceId: function() { 11518 return mightBeServerReferenceId; 11519 }, 11520 omitUnusedArgs: function() { 11521 return omitUnusedArgs; 11522 } 11523}); 11524const SERVER_REFERENCE_ID_LENGTH = 42; 11525function mightBeServerReferenceId(id) { 11526 return id.length === SERVER_REFERENCE_ID_LENGTH; 11527} 11528function extractInfoFromServerReferenceId(id) { 11529 const infoByte = parseInt(id.slice(0, 2), 16); 11530 const typeBit = infoByte >> 7 & 0x1; 11531 const argMask = infoByte >> 1 & 0x3f; 11532 const restArgs = infoByte & 0x1; 11533 const usedArgs = Array(6); 11534 for(let index = 0; index < 6; index++){ 11535 const bitPosition = 5 - index; 11536 const bit = argMask >> bitPosition & 0x1; 11537 usedArgs[index] = bit === 1; 11538 } 11539 return { 11540 type: typeBit === 1 ? 'use-cache' : 'server-action', 11541 usedArgs: usedArgs, 11542 hasRestArgs: restArgs === 1 11543 }; 11544} 11545function omitUnusedArgs(args, info) { 11546 const filteredArgs = new Array(args.length); 11547 let length = 0; 11548 for(let index = 0; index < args.length; index++){ 11549 if (index < 6 && info.usedArgs[index] || // This assumes that the server reference info byte has the restArgs bit 11550 // set to 1 if there are more than 6 args. 11551 index >= 6 && info.hasRestArgs) { 11552 filteredArgs[index] = args[index]; 11553 length = index + 1; 11554 } 11555 } 11556 // Trim trailing unused args from the array. 11557 filteredArgs.length = length; 11558 return filteredArgs; 11559} 11560}), 11561339146, ((__turbopack_context__, module, exports) => { 11562"use strict"; 11563 11564Object.defineProperty(exports, "__esModule", { 11565 value: true 11566}); 115670 && (module.exports = { 11568 ActionDidNotRevalidate: null, 11569 ActionDidRevalidateDynamicOnly: null, 11570 ActionDidRevalidateStaticAndDynamic: null 11571}); 11572function _export(target, all) { 11573 for(var name in all)Object.defineProperty(target, name, { 11574 enumerable: true, 11575 get: all[name] 11576 }); 11577} 11578_export(exports, { 11579 ActionDidNotRevalidate: function() { 11580 return ActionDidNotRevalidate; 11581 }, 11582 ActionDidRevalidateDynamicOnly: function() { 11583 return ActionDidRevalidateDynamicOnly; 11584 }, 11585 ActionDidRevalidateStaticAndDynamic: function() { 11586 return ActionDidRevalidateStaticAndDynamic; 11587 } 11588}); 11589const ActionDidNotRevalidate = 0; 11590const ActionDidRevalidateStaticAndDynamic = 1; 11591const ActionDidRevalidateDynamicOnly = 2; 11592}), 11593745794, ((__turbopack_context__, module, exports) => { 11594"use strict"; 11595 11596var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 11597"use strict"; 11598Object.defineProperty(exports, "__esModule", { 11599 value: true 11600}); 11601Object.defineProperty(exports, "serverActionReducer", { 11602 enumerable: true, 11603 get: function() { 11604 return serverActionReducer; 11605 } 11606}); 11607const _appcallserver = __turbopack_context__.r(132120); 11608const _appfindsourcemapurl = __turbopack_context__.r(92245); 11609const _approuterheaders = __turbopack_context__.r(621768); 11610const _unrecognizedactionerror = __turbopack_context__.r(292838); 11611const _client = __turbopack_context__.r(235326); 11612const _routerreducertypes = __turbopack_context__.r(388540); 11613const _assignlocation = __turbopack_context__.r(627801); 11614const _createhreffromurl = __turbopack_context__.r(451191); 11615const _hasinterceptionrouteincurrenttree = __turbopack_context__.r(284356); 11616const _flightdatahelpers = __turbopack_context__.r(450590); 11617const _redirect = __turbopack_context__.r(124063); 11618const _removebasepath = __turbopack_context__.r(387250); 11619const _hasbasepath = __turbopack_context__.r(652817); 11620const _serverreferenceinfo = __turbopack_context__.r(239747); 11621const _cache = __turbopack_context__.r(620896); 11622const _scheduler = __turbopack_context__.r(777709); 11623const _deploymentid = __turbopack_context__.r(543369); 11624const _navigationbuildid = __turbopack_context__.r(732992); 11625const _constants = __turbopack_context__.r(663416);
11626const _navigation = __turbopack_context__.r(760355); 11627const _optimisticroutes = __turbopack_context__.r(496167); 11628const _actionrevalidationkind = __turbopack_context__.r(339146); 11629const _approuterutils = __turbopack_context__.r(657630); 11630const _pprnavigations = __turbopack_context__.r(595871); 11631const _fetchserverresponse = __turbopack_context__.r(787288); 11632const _bfcache = __turbopack_context__.r(179027); 11633const createFromFetch = _client.createFromFetch; 11634let createDebugChannel; 11635if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 11636; 11637async function fetchServerAction(state, nextUrl, param) { 11638 let { actionId, actionArgs } = param; 11639 const temporaryReferences = (0, _client.createTemporaryReferenceSet)(); 11640 const info = (0, _serverreferenceinfo.extractInfoFromServerReferenceId)(actionId); 11641 const usedArgs = (0, _serverreferenceinfo.omitUnusedArgs)(actionArgs, info); 11642 const body = await (0, _client.encodeReply)(usedArgs, { 11643 temporaryReferences 11644 }); 11645 const headers = { 11646 Accept: _approuterheaders.RSC_CONTENT_TYPE_HEADER, 11647 [_approuterheaders.ACTION_HEADER]: actionId, 11648 [_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER]: (0, _flightdatahelpers.prepareFlightRouterStateForRequest)(state.tree) 11649 }; 11650 const deploymentId = (0, _deploymentid.getDeploymentId)(); 11651 if (deploymentId) { 11652 headers['x-deployment-id'] = deploymentId; 11653 } 11654 if (nextUrl) { 11655 headers[_approuterheaders.NEXT_URL] = nextUrl; 11656 } 11657 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 11658 ; 11659 const res = await fetch(state.canonicalUrl, { 11660 method: 'POST', 11661 headers, 11662 body 11663 }); 11664 // Handle server actions that the server didn't recognize. 11665 const unrecognizedActionHeader = res.headers.get(_approuterheaders.NEXT_ACTION_NOT_FOUND_HEADER); 11666 if (unrecognizedActionHeader === '1') { 11667 throw Object.defineProperty(new _unrecognizedactionerror.UnrecognizedActionError('Server Action "'.concat(actionId, '" was not found on the server. \nRead more: https://nextjs.org/docs/messages/failed-to-find-server-action')), "__NEXT_ERROR_CODE", { 11668 value: "E715", 11669 enumerable: false, 11670 configurable: true 11671 }); 11672 } 11673 const redirectHeader = res.headers.get('x-action-redirect'); 11674 const [location1, _redirectType] = (redirectHeader === null || redirectHeader === void 0 ? void 0 : redirectHeader.split(';')) || []; 11675 let redirectType; 11676 switch(_redirectType){ 11677 case 'push': 11678 redirectType = 'push'; 11679 break; 11680 case 'replace': 11681 redirectType = 'replace'; 11682 break; 11683 default: 11684 redirectType = undefined; 11685 } 11686 const isPrerender = !!res.headers.get(_approuterheaders.NEXT_IS_PRERENDER_HEADER); 11687 let revalidationKind = _actionrevalidationkind.ActionDidNotRevalidate; 11688 try { 11689 const revalidationHeader = res.headers.get('x-action-revalidated'); 11690 if (revalidationHeader) { 11691 const parsedKind = JSON.parse(revalidationHeader); 11692 if (parsedKind === _actionrevalidationkind.ActionDidRevalidateStaticAndDynamic || parsedKind === _actionrevalidationkind.ActionDidRevalidateDynamicOnly) { 11693 revalidationKind = parsedKind; 11694 } 11695 } 11696 } catch (unused) {} 11697 const redirectLocation = location1 ? (0, _assignlocation.assignLocation)(location1, new URL(state.canonicalUrl, window.location.href)) : undefined; 11698 const contentType = res.headers.get('content-type'); 11699 const isRscResponse = !!(contentType && contentType.startsWith(_approuterheaders.RSC_CONTENT_TYPE_HEADER)); 11700 // Handle invalid server action responses. 11701 // A valid response must have `content-type: text/x-component`, unless it's an external redirect. 11702 // (external redirects have an 'x-action-redirect' header, but the body is an empty 'text/plain') 11703 if (!isRscResponse && !redirectLocation) { 11704 // The server can respond with a text/plain error message, but we'll fallback to something generic 11705 // if there isn't one. 11706 const message = res.status >= 400 && contentType === 'text/plain' ? await res.text() : 'An unexpected response was received from the server.'; 11707 throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", { 11708 value: "E394", 11709 enumerable: false, 11710 configurable: true 11711 }); 11712 } 11713 let actionResult; 11714 let actionFlightData; 11715 let actionFlightDataRenderedSearch;
11716 let couldBeIntercepted = false; 11717 if (isRscResponse) { 11718 var _res_headers_get; 11719 // Server action redirect responses carry the Flight data of the redirect 11720 // target, which may be prerendered with a completeness marker byte 11721 // prepended. Strip it before passing to Flight. 11722 const responsePromise = redirectLocation ? (0, _fetchserverresponse.processFetch)(res).then((param)=>{ 11723 let { response: r } = param; 11724 return r; 11725 }) : Promise.resolve(res); 11726 const response = await createFromFetch(responsePromise, { 11727 callServer: _appcallserver.callServer, 11728 findSourceMapURL: _appfindsourcemapurl.findSourceMapURL, 11729 temporaryReferences, 11730 debugChannel: createDebugChannel && createDebugChannel(headers) 11731 }); 11732 // An internal redirect can send an RSC response, but does not have a useful `actionResult`. 11733 actionResult = redirectLocation ? undefined : response.a; 11734 couldBeIntercepted = response.i; 11735 // Check if the response build ID matches the client build ID. 11736 // In a multi-zone setup, when a server action triggers a redirect, 11737 // the server pre-fetches the redirect target as RSC. If the redirect 11738 // target is served by a different Next.js zone (different build), the 11739 // pre-fetched RSC data will have a foreign build ID. We must discard 11740 // the flight data in that case so the redirect triggers an MPA 11741 // navigation (full page load) instead of trying to apply the foreign 11742 // RSC payload — which would result in a blank page. 11743 const responseBuildId = (_res_headers_get = res.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER)) !== null && _res_headers_get !== void 0 ? _res_headers_get : response.b; 11744 if (responseBuildId !== undefined && responseBuildId !== (0, _navigationbuildid.getNavigationBuildId)()) { 11745 // Build ID mismatch — discard the flight data. The redirect will 11746 // still be processed, and the absence of flight data will cause an 11747 // MPA navigation via completeHardNavigation(). 11748 } else { 11749 const maybeFlightData = (0, _flightdatahelpers.normalizeFlightData)(response.f); 11750 if (maybeFlightData !== '') { 11751 actionFlightData = maybeFlightData; 11752 actionFlightDataRenderedSearch = response.q; 11753 } 11754 } 11755 } else { 11756 // An external redirect doesn't contain RSC data. 11757 actionResult = undefined; 11758 actionFlightData = undefined; 11759 actionFlightDataRenderedSearch = undefined; 11760 } 11761 return { 11762 actionResult, 11763 actionFlightData, 11764 actionFlightDataRenderedSearch, 11765 redirectLocation, 11766 redirectType, 11767 revalidationKind, 11768 isPrerender, 11769 couldBeIntercepted 11770 }; 11771} 11772function serverActionReducer(state, action) { 11773 const { resolve, reject } = action; 11774 // only pass along the `nextUrl` param (used for interception routes) if the current route was intercepted. 11775 // If the route has been intercepted, the action should be as well. 11776 // Otherwise the server action might be intercepted with the wrong action id 11777 // (ie, one that corresponds with the intercepted route) 11778 const nextUrl = // performing a dynamic request. This is because we update 11779 // the next-url after a navigation, but we want the same 11780 // interception route to be matched that used the last 11781 // next-url. 11782 (state.previousNextUrl || state.nextUrl) && (0, _hasinterceptionrouteincurrenttree.hasInterceptionRouteInCurrentTree)(state.tree) ? state.previousNextUrl || state.nextUrl : null; 11783 return fetchServerAction(state, nextUrl, action).then(async (param)=>{ 11784 let { revalidationKind, actionResult, actionFlightData: flightData, actionFlightDataRenderedSearch: flightDataRenderedSearch, redirectLocation, redirectType, isPrerender, couldBeIntercepted } = param; 11785 if (revalidationKind !== _actionrevalidationkind.ActionDidNotRevalidate) { 11786 // There was either a revalidation or a refresh, or maybe both. 11787 // Evict the BFCache, which may contain dynamic data. 11788 (0, _bfcache.invalidateBfCache)(); 11789 // Store whether this action triggered any revalidation 11790 // The action queue will use this information to potentially 11791 // trigger a refresh action if the action was discarded 11792 // (ie, due to a navigation, before the action completed) 11793 action.didRevalidate = true; 11794 // If there was a revalidation, evict the prefetch cache. 11795 // TODO: Evict only segments with matching tags and/or paths. 11796 // TODO: We should only invalidate the route cache if cookies were 11797 // mutated, since route trees may vary based on cookies. For now we 11798 // invalidate both caches until we have a way to detect cookie 11799 // mutations on the client.
11800 if (revalidationKind === _actionrevalidationkind.ActionDidRevalidateStaticAndDynamic) { 11801 (0, _cache.invalidateEntirePrefetchCache)(nextUrl, state.tree); 11802 } 11803 // Start a cooldown before re-prefetching to allow CDN cache 11804 // propagation. 11805 (0, _scheduler.startRevalidationCooldown)(); 11806 } 11807 const navigateType = redirectType || 'push'; 11808 if (redirectLocation !== undefined) { 11809 // If the action triggered a redirect, the action promise will be rejected with 11810 // a redirect so that it's handled by RedirectBoundary as we won't have a valid 11811 // action result to resolve the promise with. This will effectively reset the state of 11812 // the component that called the action as the error boundary will remount the tree. 11813 // The status code doesn't matter here as the action handler will have already sent 11814 // a response with the correct status code. 11815 if ((0, _approuterutils.isExternalURL)(redirectLocation)) { 11816 // External redirect. Triggers an MPA navigation. 11817 const redirectHref = redirectLocation.href; 11818 const redirectError = createRedirectErrorForAction(redirectHref, navigateType); 11819 reject(redirectError); 11820 return (0, _navigation.completeHardNavigation)(state, redirectLocation, navigateType); 11821 } else { 11822 // Internal redirect. Triggers an SPA navigation. 11823 const redirectWithBasepath = (0, _createhreffromurl.createHrefFromUrl)(redirectLocation, false); 11824 const redirectHref = (0, _hasbasepath.hasBasePath)(redirectWithBasepath) ? (0, _removebasepath.removeBasePath)(redirectWithBasepath) : redirectWithBasepath; 11825 const redirectError = createRedirectErrorForAction(redirectHref, navigateType); 11826 reject(redirectError); 11827 } 11828 } else { 11829 // If there's no redirect, resolve the action with the result. 11830 resolve(actionResult); 11831 } 11832 // Check if we can bail out without updating any state. 11833 if (redirectLocation === undefined && // Did the action revalidate any data? 11834 revalidationKind === _actionrevalidationkind.ActionDidNotRevalidate && // Did the server render new data? 11835 flightData === undefined) { 11836 // The action did not trigger any revalidations or redirects. No 11837 // navigation is required. 11838 return state; 11839 } 11840 if (flightData === undefined && redirectLocation !== undefined) { 11841 // The server redirected, but did not send any Flight data. This implies 11842 // an external redirect. 11843 // TODO: We should refactor the action response type to be more explicit 11844 // about the various response types. 11845 return (0, _navigation.completeHardNavigation)(state, redirectLocation, navigateType); 11846 } 11847 if (typeof flightData === 'string') { 11848 // If the flight data is just a string, something earlier in the 11849 // response handling triggered an external redirect. 11850 return (0, _navigation.completeHardNavigation)(state, new URL(flightData, location.origin), navigateType); 11851 } 11852 // The action triggered a navigation — either a redirect, a revalidation, 11853 // or both. 11854 // If there was no redirect, then the target URL is the same as the 11855 // current URL. 11856 const currentUrl = new URL(state.canonicalUrl, location.origin); 11857 const currentRenderedSearch = state.renderedSearch; 11858 const redirectUrl = redirectLocation !== undefined ? redirectLocation : currentUrl; 11859 const currentFlightRouterState = state.tree; 11860 const scrollBehavior = _routerreducertypes.ScrollBehavior.Default; 11861 // If the action triggered a revalidation of the cache, we should also 11862 // refresh all the dynamic data. 11863 const freshnessPolicy = revalidationKind === _actionrevalidationkind.ActionDidNotRevalidate ? _pprnavigations.FreshnessPolicy.Default : _pprnavigations.FreshnessPolicy.RefreshAll; 11864 // The server may have sent back new data. If so, we will perform a 11865 // "seeded" navigation that uses the data from the response. 11866 // TODO: Currently the server always renders from the root in 11867 // response to a Server Action. In the case of a normal redirect 11868 // with no revalidation, it should skip over the shared layouts. 11869 if (flightData !== undefined && flightDataRenderedSearch !== undefined) { 11870 // The server sent back new route data as part of the response. We 11871 // will use this to render the new page. If this happens to be only a 11872 // subset of the data needed to render the new page, we'll initiate a 11873 // new fetch, like we would for a normal navigation. 11874 const redirectCanonicalUrl = (0, _createhreffromurl.createHrefFromUrl)(redirectUrl); 11875 const now = Date.now(); 11876 // TODO: Store the dynamic stale time on the top-level state so it's 11877 // known during restores and refreshes. 11878 const redirectSeed = (0, _navigation.convertServerPatchToFullTree)(now, currentFlightRouterState, flightData, flightDataRenderedSearch, _bfcache.UnknownDynamicStaleTime); 11879 // Learn the route pattern so we can predict it for future navigations. 11880 const metadataVaryPath = redirectSeed.metadataVaryPath; 11881 if (metadataVaryPath !== null) { 11882 (0, _optimisticroutes.discoverKnownRoute)(now, redirectUrl.pathname, nextUrl, null, redirectSeed.routeTree, metadataVaryPath, couldBeIntercepted, redirectCanonicalUrl, isPrerender, false // hasDynamicRewrite 11883 ); 11884 } 11885 return (0, _navigation.navigateToKnownRoute)(now, state, redirectUrl, redirectCanonicalUrl, redirectSeed, currentUrl, currentRenderedSearch, state.cache, currentFlightRouterState, freshnessPolicy, nextUrl, scrollBehavior, navigateType, null, // have the route tree from the server response. If a mismatch occurs 11886 // during dynamic data fetch, the retry handler will traverse the 11887 // known route tree to mark the entry as having a dynamic rewrite. 11888 null); 11889 } 11890 // The server did not send back new data. We'll perform a regular, non- 11891 // seeded navigation — effectively the same as <Link> or router.push(). 11892 return (0, _navigation.navigate)(state, redirectUrl, currentUrl, currentRenderedSearch, state.cache, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType); 11893 }, (e)=>{ 11894 // When the server action is rejected we don't update the state and instead call the reject handler of the promise. 11895 reject(e); 11896 return state; 11897 }); 11898} 11899function createRedirectErrorForAction(redirectHref, resolvedRedirectType) { 11900 const redirectError = (0, _redirect.getRedirectError)(redirectHref, resolvedRedirectType); 11901 redirectError.handled = true; 11902 return redirectError; 11903} 11904if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11905 Object.defineProperty(exports.default, '__esModule', { 11906 value: true 11907 });
11908 Object.assign(exports.default, exports); 11909 module.exports = exports.default; 11910} 11911}), 11912804924, ((__turbopack_context__, module, exports) => { 11913"use strict"; 11914 11915Object.defineProperty(exports, "__esModule", { 11916 value: true 11917}); 11918Object.defineProperty(exports, "reducer", { 11919 enumerable: true, 11920 get: function() { 11921 return reducer; 11922 } 11923}); 11924const _routerreducertypes = __turbopack_context__.r(388540); 11925const _navigatereducer = __turbopack_context__.r(754069); 11926const _serverpatchreducer = __turbopack_context__.r(891668); 11927const _restorereducer = __turbopack_context__.r(73790); 11928const _refreshreducer = __turbopack_context__.r(269845); 11929const _hmrrefreshreducer = __turbopack_context__.r(486720); 11930const _serveractionreducer = __turbopack_context__.r(745794); 11931/** 11932 * Reducer that handles the app-router state updates. 11933 */ function clientReducer(state, action) { 11934 switch(action.type){ 11935 case _routerreducertypes.ACTION_NAVIGATE: 11936 { 11937 return (0, _navigatereducer.navigateReducer)(state, action); 11938 } 11939 case _routerreducertypes.ACTION_SERVER_PATCH: 11940 { 11941 return (0, _serverpatchreducer.serverPatchReducer)(state, action); 11942 } 11943 case _routerreducertypes.ACTION_RESTORE: 11944 { 11945 return (0, _restorereducer.restoreReducer)(state, action); 11946 } 11947 case _routerreducertypes.ACTION_REFRESH: 11948 { 11949 return (0, _refreshreducer.refreshReducer)(state, action); 11950 } 11951 case _routerreducertypes.ACTION_HMR_REFRESH: 11952 { 11953 return (0, _hmrrefreshreducer.hmrRefreshReducer)(state); 11954 } 11955 case _routerreducertypes.ACTION_SERVER_ACTION: 11956 { 11957 return (0, _serveractionreducer.serverActionReducer)(state, action); 11958 } 11959 // This case should never be hit as dispatch is strongly typed. 11960 default: 11961 throw Object.defineProperty(new Error('Unknown action'), "__NEXT_ERROR_CODE", { 11962 value: "E295", 11963 enumerable: false, 11964 configurable: true 11965 }); 11966 } 11967} 11968function serverReducer(state, _action) { 11969 return state; 11970} 11971const reducer = typeof window === 'undefined' ? serverReducer : clientReducer; 11972if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 11973 Object.defineProperty(exports.default, '__esModule', { 11974 value: true 11975 }); 11976 Object.assign(exports.default, exports); 11977 module.exports = exports.default; 11978} 11979}), 11980401411, ((__turbopack_context__, module, exports) => { 11981"use strict"; 11982 11983Object.defineProperty(exports, "__esModule", { 11984 value: true 11985}); 11986Object.defineProperty(exports, "prefetch", { 11987 enumerable: true, 11988 get: function() { 11989 return prefetch; 11990 } 11991}); 11992const _approuterutils = __turbopack_context__.r(657630); 11993const _cachekey = __turbopack_context__.r(477048); 11994const _scheduler = __turbopack_context__.r(777709); 11995const _types = __turbopack_context__.r(509396); 11996function prefetch(href, nextUrl, treeAtTimeOfPrefetch, fetchStrategy, onInvalidate) { 11997 const url = (0, _approuterutils.createPrefetchURL)(href); 11998 if (url === null) { 11999 // This href should not be prefetched. 12000 return; 12001 } 12002 const cacheKey = (0, _cachekey.createCacheKey)(url.href, nextUrl); 12003 (0, _scheduler.schedulePrefetchTask)(cacheKey, treeAtTimeOfPrefetch, fetchStrategy, _types.PrefetchPriority.Default, onInvalidate); 12004} 12005if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 12006 Object.defineProperty(exports.default, '__esModule', { 12007 value: true 12008 }); 12009 Object.assign(exports.default, exports); 12010 module.exports = exports.default; 12011} 12012}), 12013699781, ((__turbopack_context__, module, exports) => { 12014"use strict"; 12015 12016var __TURBOPACK__imported__module__247167__ = /*#__PURE__*/ __turbopack_context__.i(247167); 12017"use strict"; 12018Object.defineProperty(exports, "__esModule", { 12019 value: true 12020}); 120210 && (module.exports = { 12022 createMutableActionQueue: null, 12023 dispatchNavigateAction: null, 12024 dispatchTraverseAction: null, 12025 getCurrentAppRouterState: null, 12026 publicAppRouterInstance: null 12027}); 12028function _export(target, all) { 12029 for(var name in all)Object.defineProperty(target, name, { 12030 enumerable: true, 12031 get: all[name] 12032 }); 12033} 12034_export(exports, { 12035 createMutableActionQueue: function() { 12036 return createMutableActionQueue; 12037 }, 12038 dispatchNavigateAction: function() {
12039 return dispatchNavigateAction; 12040 }, 12041 dispatchTraverseAction: function() { 12042 return dispatchTraverseAction; 12043 }, 12044 getCurrentAppRouterState: function() { 12045 return getCurrentAppRouterState; 12046 }, 12047 publicAppRouterInstance: function() { 12048 return publicAppRouterInstance; 12049 } 12050}); 12051const _routerreducertypes = __turbopack_context__.r(388540); 12052const _routerreducer = __turbopack_context__.r(804924); 12053const _react = __turbopack_context__.r(271645); 12054const _isthenable = __turbopack_context__.r(564245); 12055const _types = __turbopack_context__.r(509396); 12056const _prefetch = __turbopack_context__.r(401411); 12057const _navigation = __turbopack_context__.r(760355); 12058const _useactionqueue = __turbopack_context__.r(941538); 12059const _optimisticroutes = __turbopack_context__.r(496167); 12060const _pprnavigations = __turbopack_context__.r(595871); 12061const _addbasepath = __turbopack_context__.r(405550); 12062const _approuterutils = __turbopack_context__.r(657630); 12063const _links = __turbopack_context__.r(769688); 12064const _javascripturl = __turbopack_context__.r(948277); 12065function runRemainingActions(actionQueue, setState) { 12066 if (actionQueue.pending !== null) { 12067 actionQueue.pending = actionQueue.pending.next; 12068 if (actionQueue.pending !== null) { 12069 runAction({ 12070 actionQueue, 12071 action: actionQueue.pending, 12072 setState 12073 }); 12074 } 12075 } else { 12076 // Check for refresh when pending is already null 12077 // This handles the case where a discarded server action completes 12078 // after the navigation has already finished and the queue is empty 12079 if (actionQueue.needsRefresh) { 12080 actionQueue.needsRefresh = false; 12081 actionQueue.dispatch({ 12082 type: _routerreducertypes.ACTION_REFRESH 12083 }, setState); 12084 } 12085 } 12086} 12087async function runAction(param) { 12088 let { actionQueue, action, setState } = param; 12089 const prevState = actionQueue.state; 12090 actionQueue.pending = action; 12091 const payload = action.payload; 12092 const actionResult = actionQueue.action(prevState, payload); 12093 function handleResult(nextState) { 12094 // if we discarded this action, the state should also be discarded 12095 if (action.discarded) { 12096 // Check if the discarded server action revalidated data 12097 if (action.payload.type === _routerreducertypes.ACTION_SERVER_ACTION && action.payload.didRevalidate) { 12098 // The server action was discarded but it revalidated data, 12099 // mark that we need to refresh after all actions complete 12100 actionQueue.needsRefresh = true; 12101 } 12102 // Still need to run remaining actions even for discarded actions 12103 // to potentially trigger the refresh 12104 runRemainingActions(actionQueue, setState); 12105 return; 12106 } 12107 actionQueue.state = nextState; 12108 runRemainingActions(actionQueue, setState); 12109 action.resolve(nextState); 12110 } 12111 // if the action is a promise, set up a callback to resolve it 12112 if ((0, _isthenable.isThenable)(actionResult)) { 12113 actionResult.then(handleResult, (err)=>{ 12114 runRemainingActions(actionQueue, setState); 12115 action.reject(err); 12116 }); 12117 } else { 12118 handleResult(actionResult); 12119 } 12120} 12121function dispatchAction(actionQueue, payload, setState) { 12122 let resolvers = { 12123 resolve: setState, 12124 reject: ()=>{} 12125 }; 12126 // most of the action types are async with the exception of restore 12127 // it's important that restore is handled quickly since it's fired on the popstate event 12128 // and we don't want to add any delay on a back/forward nav 12129 // this only creates a promise for the async actions 12130 if (payload.type !== _routerreducertypes.ACTION_RESTORE) { 12131 // Create the promise and assign the resolvers to the object. 12132 const deferredPromise = new Promise((resolve, reject)=>{ 12133 resolvers = { 12134 resolve, 12135 reject 12136 }; 12137 }); 12138 (0, _react.startTransition)(()=>{ 12139 // we immediately notify React of the pending promise -- the resolver is attached to the action node 12140 // and will be called when the associated action promise resolves 12141 setState(deferredPromise); 12142 }); 12143 } 12144 const newAction = { 12145 payload, 12146 next: null, 12147 resolve: resolvers.resolve, 12148 reject: resolvers.reject 12149 }; 12150 // Check if the queue is empty 12151 if (actionQueue.pending === null) { 12152 // The queue is empty, so add the action and start it immediately 12153 // Mark this action as the last in the queue 12154 actionQueue.last = newAction; 12155 runAction({ 12156 actionQueue, 12157 action: newAction, 12158 setState 12159 }); 12160 } else if (payload.type === _routerreducertypes.ACTION_NAVIGATE || payload.type === _routerreducertypes.ACTION_RESTORE) { 12161 // Navigations (including back/forward) take priority over any pen
12161ding actions. 12162 // Mark the pending action as discarded (so the state is never applied) and start the navigation action immediately. 12163 actionQueue.pending.discarded = true; 12164 // The rest of the current queue should still execute after this navigation. 12165 // (Note that it can't contain any earlier navigations, because we always put those into `actionQueue.pending` by calling `runAction`) 12166 newAction.next = actionQueue.pending.next; 12167 runAction({ 12168 actionQueue, 12169 action: newAction, 12170 setState 12171 }); 12172 } else { 12173 // The queue is not empty, so add the action to the end of the queue 12174 // It will be started by runRemainingActions after the previous action finishes 12175 if (actionQueue.last !== null) { 12176 actionQueue.last.next = newAction; 12177 } 12178 actionQueue.last = newAction; 12179 } 12180} 12181let globalActionQueue = null; 12182function createMutableActionQueue(initialState, instrumentationHooks) { 12183 const actionQueue = { 12184 state: initialState, 12185 dispatch: (payload, setState)=>dispatchAction(actionQueue, payload, setState), 12186 action: async (state, action)=>{ 12187 const result = (0, _routerreducer.reducer)(state, action); 12188 return result; 12189 }, 12190 pending: null, 12191 last: null, 12192 onRouterTransitionStart: instrumentationHooks !== null && typeof instrumentationHooks.onRouterTransitionStart === 'function' ? instrumentationHooks.onRouterTransitionStart : null 12193 }; 12194 if (typeof window !== 'undefined') { 12195 // The action queue is lazily created on hydration, but after that point 12196 // it doesn't change. So we can store it in a global rather than pass 12197 // it around everywhere via props/context. 12198 if (globalActionQueue !== null) { 12199 throw Object.defineProperty(new Error('Internal Next.js Error: createMutableActionQueue was called more ' + 'than once'), "__NEXT_ERROR_CODE", { 12200 value: "E624", 12201 enumerable: false, 12202 configurable: true 12203 }); 12204 } 12205 globalActionQueue = actionQueue; 12206 } 12207 return actionQueue; 12208} 12209function getCurrentAppRouterState() { 12210 return globalActionQueue !== null ? globalActionQueue.state : null; 12211} 12212function getAppRouterActionQueue() { 12213 if (globalActionQueue === null) { 12214 throw Object.defineProperty(new Error('Internal Next.js error: Router action dispatched before initialization.'), "__NEXT_ERROR_CODE", { 12215 value: "E668", 12216 enumerable: false, 12217 configurable: true 12218 }); 12219 } 12220 return globalActionQueue; 12221} 12222function getProfilingHookForOnNavigationStart() { 12223 if (globalActionQueue !== null) { 12224 return globalActionQueue.onRouterTransitionStart; 12225 } 12226 return null; 12227} 12228function dispatchNavigateAction(href, navigateType, scrollBehavior, linkInstanceRef, transitionTypes) { 12229 // TODO: This stuff could just go into the reducer. Leaving as-is for now 12230 // since we're about to rewrite all the router reducer stuff anyway. 12231 if (transitionTypes) { 12232 for (const type of transitionTypes){ 12233 (0, _react.addTransitionType)(type); 12234 } 12235 } 12236 const url = new URL((0, _addbasepath.addBasePath)(href), location.href); 12237 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 12238 ; 12239 (0, _links.setLinkForCurrentNavigation)(linkInstanceRef); 12240 const onRouterTransitionStart = getProfilingHookForOnNavigationStart(); 12241 if (onRouterTransitionStart !== null) { 12242 onRouterTransitionStart(href, navigateType); 12243 } 12244 (0, _useactionqueue.dispatchAppRouterAction)({ 12245 type: _routerreducertypes.ACTION_NAVIGATE, 12246 url, 12247 isExternalUrl: (0, _approuterutils.isExternalURL)(url), 12248 locationSearch: location.search, 12249 scrollBehavior, 12250 navigateType 12251 }); 12252} 12253function dispatchTraverseAction(href, historyState) { 12254 const onRouterTransitionStart = getProfilingHookForOnNavigationStart(); 12255 if (onRouterTransitionStart !== null) { 12256 onRouterTransitionStart(href, 'traverse'); 12257 } 12258 (0, _useactionqueue.dispatchAppRouterAction)({ 12259 type: _routerreducertypes.ACTION_RESTORE, 12260 url: new URL(href), 12261 historyState 12262 }); 12263} 12264/** 12265 * (Experimental) Perform a gesture navigation. This dispatches through React's 12266 * useOptimistic instead of the main action queue, allowing the state to be 12267 * shown during a gesture transition and discarded when the canonical navigation 12268 * completes. 12269 * 12270 * Only available when experimental.gestureTransition is enabled. 12271 */ function gesturePush(href, options) { 12272 if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 12273 ; 12274} 12275const publicAppRouterInstance = { 12276 back: ()=>window.history.back(), 12277 forward: ()=>window.history.forward(), 12278 prefetch: // data in the router reducer state; it writes into a global mutable 12279 // cache. So we don't need to dispatch an action. 12280 (href, options)=>{ 12281 var _ref, _ref1; 12282 if ((0, _javascripturl.isJavaScriptURLString)(href)) { 12283 throw Object.defineProperty(new Error('Next.js has blocked a javascript: URL as a security precaution.'), "__NEXT_ERROR_CODE", { 12284 value: "E978", 12285 enumerable: false, 12286 configurable: true 12287 }); 12288 } 12289 const actionQueue = getAppRouterActionQueue(); 12290 const prefetchKind = (_ref = options === null || options === void 0 ? void 0 : options.kind) !== null && _ref !== void 0 ? _ref : _routerreducertypes.PrefetchKind.AUTO; 12291 // We don't currently offer a way to issue a runtime prefetch via `router.prefetch()`.
12292 // This will be possible when we update its API to not take a PrefetchKind. 12293 let fetchStrategy; 12294 switch(prefetchKind){ 12295 case _routerreducertypes.PrefetchKind.AUTO: 12296 { 12297 // We default to PPR. We'll discover whether or not the route supports it with the initial prefetch. 12298 fetchStrategy = _types.FetchStrategy.PPR; 12299 break; 12300 } 12301 case _routerreducertypes.PrefetchKind.FULL: 12302 { 12303 fetchStrategy = _types.FetchStrategy.Full; 12304 break; 12305 } 12306 default: 12307 { 12308 prefetchKind; 12309 // Despite typescript thinking that this can't happen, 12310 // we might get an unexpected value from user code. 12311 // We don't know what they want, but we know they want a prefetch, 12312 // so use the default. 12313 fetchStrategy = _types.FetchStrategy.PPR; 12314 } 12315 } 12316 (0, _prefetch.prefetch)(href, actionQueue.state.nextUrl, actionQueue.state.tree, fetchStrategy, (_ref1 = options === null || options === void 0 ? void 0 : options.onInvalidate) !== null && _ref1 !== void 0 ? _ref1 : null); 12317 }, 12318 replace: (href, options)=>{ 12319 if ((0, _javascripturl.isJavaScriptURLString)(href)) { 12320 throw Object.defineProperty(new Error('Next.js has blocked a javascript: URL as a security precaution.'), "__NEXT_ERROR_CODE", { 12321 value: "E978", 12322 enumerable: false, 12323 configurable: true 12324 }); 12325 } 12326 (0, _react.startTransition)(()=>{ 12327 dispatchNavigateAction(href, 'replace', (options === null || options === void 0 ? void 0 : options.scroll) === false ? _routerreducertypes.ScrollBehavior.NoScroll : _routerreducertypes.ScrollBehavior.Default, null, options === null || options === void 0 ? void 0 : options.transitionTypes); 12328 }); 12329 }, 12330 push: (href, options)=>{ 12331 if ((0, _javascripturl.isJavaScriptURLString)(href)) { 12332 throw Object.defineProperty(new Error('Next.js has blocked a javascript: URL as a security precaution.'), "__NEXT_ERROR_CODE", { 12333 value: "E978", 12334 enumerable: false, 12335 configurable: true 12336 }); 12337 } 12338 (0, _react.startTransition)(()=>{ 12339 dispatchNavigateAction(href, 'push', (options === null || options === void 0 ? void 0 : options.scroll) === false ? _routerreducertypes.ScrollBehavior.NoScroll : _routerreducertypes.ScrollBehavior.Default, null, options === null || options === void 0 ? void 0 : options.transitionTypes); 12340 }); 12341 }, 12342 refresh: ()=>{ 12343 (0, _react.startTransition)(()=>{ 12344 (0, _useactionqueue.dispatchAppRouterAction)({ 12345 type: _routerreducertypes.ACTION_REFRESH 12346 }); 12347 }); 12348 }, 12349 hmrRefresh: ()=>{ 12350 if ("TURBOPACK compile-time truthy", 1) { 12351 throw Object.defineProperty(new Error('hmrRefresh can only be used in development mode. Please use refresh instead.'), "__NEXT_ERROR_CODE", { 12352 value: "E485", 12353 enumerable: false, 12354 configurable: true 12355 }); 12356 } else //TURBOPACK unreachable 12357 ; 12358 } 12359}; 12360// Conditionally add experimental_gesturePush when gestureTransition is enabled 12361if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable 12362; 12363// Exists for debugging purposes. Don't use in application code. 12364if (typeof window !== 'undefined' && window.next) { 12365 window.next.router = publicAppRouterInstance; 12366} 12367if ((typeof exports.default === 'function' || typeof exports.default === 'object' && exports.default !== null) && typeof exports.default.__esModule === 'undefined') { 12368 Object.defineProperty(exports.default, '__esModule', { 12369 value: true 12370 }); 12371 Object.assign(exports.default, exports); 12372 module.exports = exports.default; 12373} 12374}), 12375]); 12376 12377//# debugId=095e860a-bcdb-ea77-2495-6325388fa85d
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.