@inertiajs/core 2.2.19 → 2.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  config: () => config,
34
34
  createHeadManager: () => createHeadManager,
35
35
  formDataToObject: () => formDataToObject,
36
+ getInitialPageFromDOM: () => getInitialPageFromDOM,
36
37
  getScrollableParent: () => getScrollableParent,
37
38
  hideProgress: () => hide2,
38
39
  hrefToUrl: () => hrefToUrl,
@@ -93,7 +94,8 @@ var config = new Config({
93
94
  future: {
94
95
  preserveEqualProps: false,
95
96
  useDataInertiaHeadAttribute: false,
96
- useDialogForErrorModal: false
97
+ useDialogForErrorModal: false,
98
+ useScriptElementForInitialPage: false
97
99
  },
98
100
  prefetch: {
99
101
  cacheFor: 3e4,
@@ -152,7 +154,7 @@ var firePrefetchingEvent = (visit) => {
152
154
  };
153
155
 
154
156
  // src/history.ts
155
- var import_lodash_es2 = require("lodash-es");
157
+ var import_lodash_es3 = require("lodash-es");
156
158
 
157
159
  // src/sessionStorage.ts
158
160
  var SessionStorage = class {
@@ -323,227 +325,521 @@ var getKeyFromSessionStorage = async () => {
323
325
  return key;
324
326
  };
325
327
 
326
- // src/scroll.ts
327
- var Scroll = class {
328
- static save() {
329
- history.saveScrollPositions(
330
- Array.from(this.regions()).map((region) => ({
331
- top: region.scrollTop,
332
- left: region.scrollLeft
333
- }))
334
- );
335
- }
336
- static regions() {
337
- return document.querySelectorAll("[scroll-region]");
328
+ // src/prefetched.ts
329
+ var import_lodash_es2 = require("lodash-es");
330
+
331
+ // src/objectUtils.ts
332
+ var objectsAreEqual = (obj1, obj2, excludeKeys) => {
333
+ if (obj1 === obj2) {
334
+ return true;
338
335
  }
339
- static reset() {
340
- const anchorHash = typeof window !== "undefined" ? window.location.hash : null;
341
- if (!anchorHash) {
342
- window.scrollTo(0, 0);
336
+ for (const key in obj1) {
337
+ if (excludeKeys.includes(key)) {
338
+ continue;
343
339
  }
344
- this.regions().forEach((region) => {
345
- if (typeof region.scrollTo === "function") {
346
- region.scrollTo(0, 0);
347
- } else {
348
- region.scrollTop = 0;
349
- region.scrollLeft = 0;
350
- }
351
- });
352
- this.save();
353
- this.scrollToAnchor();
354
- }
355
- static scrollToAnchor() {
356
- const anchorHash = typeof window !== "undefined" ? window.location.hash : null;
357
- if (anchorHash) {
358
- setTimeout(() => {
359
- const anchorElement = document.getElementById(anchorHash.slice(1));
360
- anchorElement ? anchorElement.scrollIntoView() : window.scrollTo(0, 0);
361
- });
340
+ if (obj1[key] === obj2[key]) {
341
+ continue;
362
342
  }
363
- }
364
- static restore(scrollRegions) {
365
- if (typeof window === "undefined") {
366
- return;
343
+ if (!compareValues(obj1[key], obj2[key])) {
344
+ return false;
367
345
  }
368
- window.requestAnimationFrame(() => {
369
- this.restoreDocument();
370
- this.restoreScrollRegions(scrollRegions);
371
- });
372
346
  }
373
- static restoreScrollRegions(scrollRegions) {
374
- if (typeof window === "undefined") {
375
- return;
347
+ for (const key in obj2) {
348
+ if (excludeKeys.includes(key)) {
349
+ continue;
376
350
  }
377
- this.regions().forEach((region, index) => {
378
- const scrollPosition = scrollRegions[index];
379
- if (!scrollPosition) {
380
- return;
381
- }
382
- if (typeof region.scrollTo === "function") {
383
- region.scrollTo(scrollPosition.left, scrollPosition.top);
384
- } else {
385
- region.scrollTop = scrollPosition.top;
386
- region.scrollLeft = scrollPosition.left;
387
- }
388
- });
389
- }
390
- static restoreDocument() {
391
- const scrollPosition = history.getDocumentScrollPosition();
392
- window.scrollTo(scrollPosition.left, scrollPosition.top);
393
- }
394
- static onScroll(event) {
395
- const target = event.target;
396
- if (typeof target.hasAttribute === "function" && target.hasAttribute("scroll-region")) {
397
- this.save();
351
+ if (!(key in obj1)) {
352
+ return false;
398
353
  }
399
354
  }
400
- static onWindowScroll() {
401
- history.saveDocumentScrollPosition({
402
- top: window.scrollY,
403
- left: window.scrollX
404
- });
405
- }
355
+ return true;
406
356
  };
407
-
408
- // src/url.ts
409
- var qs = __toESM(require("qs"), 1);
410
-
411
- // src/files.ts
412
- var isFile = (value) => typeof File !== "undefined" && value instanceof File || value instanceof Blob || typeof FileList !== "undefined" && value instanceof FileList && value.length > 0;
413
- function hasFiles(data) {
414
- return isFile(data) || data instanceof FormData && Array.from(data.values()).some((value) => hasFiles(value)) || typeof data === "object" && data !== null && Object.values(data).some((value) => hasFiles(value));
415
- }
416
-
417
- // src/formData.ts
418
- var isFormData = (value) => value instanceof FormData;
419
- function objectToFormData(source, form = new FormData(), parentKey = null, queryStringArrayFormat = "brackets") {
420
- source = source || {};
421
- for (const key in source) {
422
- if (Object.prototype.hasOwnProperty.call(source, key)) {
423
- append(form, composeKey(parentKey, key, "indices"), source[key], queryStringArrayFormat);
424
- }
425
- }
426
- return form;
427
- }
428
- function composeKey(parent, key, format) {
429
- if (!parent) {
430
- return key;
431
- }
432
- return format === "brackets" ? `${parent}[]` : `${parent}[${key}]`;
433
- }
434
- function append(form, key, value, format) {
435
- if (Array.isArray(value)) {
436
- return Array.from(value.keys()).forEach(
437
- (index) => append(form, composeKey(key, index.toString(), format), value[index], format)
438
- );
439
- } else if (value instanceof Date) {
440
- return form.append(key, value.toISOString());
441
- } else if (value instanceof File) {
442
- return form.append(key, value, value.name);
443
- } else if (value instanceof Blob) {
444
- return form.append(key, value);
445
- } else if (typeof value === "boolean") {
446
- return form.append(key, value ? "1" : "0");
447
- } else if (typeof value === "string") {
448
- return form.append(key, value);
449
- } else if (typeof value === "number") {
450
- return form.append(key, `${value}`);
451
- } else if (value === null || value === void 0) {
452
- return form.append(key, "");
357
+ var compareValues = (value1, value2) => {
358
+ switch (typeof value1) {
359
+ case "object":
360
+ return objectsAreEqual(value1, value2, []);
361
+ case "function":
362
+ return value1.toString() === value2.toString();
363
+ default:
364
+ return value1 === value2;
453
365
  }
454
- objectToFormData(value, form, key, format);
455
- }
366
+ };
456
367
 
457
- // src/url.ts
458
- function hrefToUrl(href) {
459
- return new URL(href.toString(), typeof window === "undefined" ? void 0 : window.location.toString());
460
- }
461
- var transformUrlAndData = (href, data, method, forceFormData, queryStringArrayFormat) => {
462
- let url = typeof href === "string" ? hrefToUrl(href) : href;
463
- if ((hasFiles(data) || forceFormData) && !isFormData(data)) {
464
- if (config.get("form.forceIndicesArrayFormatInFormData")) {
465
- queryStringArrayFormat = "indices";
466
- }
467
- data = objectToFormData(data, new FormData(), null, queryStringArrayFormat);
468
- }
469
- if (isFormData(data)) {
470
- return [url, data];
471
- }
472
- const [_href, _data] = mergeDataIntoQueryString(method, url, data, queryStringArrayFormat);
473
- return [hrefToUrl(_href), _data];
368
+ // src/time.ts
369
+ var conversionMap = {
370
+ ms: 1,
371
+ s: 1e3,
372
+ m: 1e3 * 60,
373
+ h: 1e3 * 60 * 60,
374
+ d: 1e3 * 60 * 60 * 24
474
375
  };
475
- function mergeDataIntoQueryString(method, href, data, qsArrayFormat = "brackets") {
476
- const hasDataForQueryString = method === "get" && !isFormData(data) && Object.keys(data).length > 0;
477
- const hasHost = urlHasProtocol(href.toString());
478
- const hasAbsolutePath = hasHost || href.toString().startsWith("/") || href.toString() === "";
479
- const hasRelativePath = !hasAbsolutePath && !href.toString().startsWith("#") && !href.toString().startsWith("?");
480
- const hasRelativePathWithDotPrefix = /^[.]{1,2}([/]|$)/.test(href.toString());
481
- const hasSearch = href.toString().includes("?") || hasDataForQueryString;
482
- const hasHash = href.toString().includes("#");
483
- const url = new URL(href.toString(), typeof window === "undefined" ? "http://localhost" : window.location.toString());
484
- if (hasDataForQueryString) {
485
- const parseOptions = { ignoreQueryPrefix: true, parseArrays: false };
486
- url.search = qs.stringify(
487
- { ...qs.parse(url.search, parseOptions), ...data },
488
- {
489
- encodeValuesOnly: true,
490
- arrayFormat: qsArrayFormat
491
- }
492
- );
376
+ var timeToMs = (time) => {
377
+ if (typeof time === "number") {
378
+ return time;
493
379
  }
494
- return [
495
- [
496
- hasHost ? `${url.protocol}//${url.host}` : "",
497
- hasAbsolutePath ? url.pathname : "",
498
- hasRelativePath ? url.pathname.substring(hasRelativePathWithDotPrefix ? 0 : 1) : "",
499
- hasSearch ? url.search : "",
500
- hasHash ? url.hash : ""
501
- ].join(""),
502
- hasDataForQueryString ? {} : data
503
- ];
504
- }
505
- function urlWithoutHash(url) {
506
- url = new URL(url.href);
507
- url.hash = "";
508
- return url;
509
- }
510
- var setHashIfSameUrl = (originUrl, destinationUrl) => {
511
- if (originUrl.hash && !destinationUrl.hash && urlWithoutHash(originUrl).href === destinationUrl.href) {
512
- destinationUrl.hash = originUrl.hash;
380
+ for (const [unit, conversion] of Object.entries(conversionMap)) {
381
+ if (time.endsWith(unit)) {
382
+ return parseFloat(time) * conversion;
383
+ }
513
384
  }
385
+ return parseInt(time);
514
386
  };
515
- var isSameUrlWithoutHash = (url1, url2) => {
516
- return urlWithoutHash(url1).href === urlWithoutHash(url2).href;
517
- };
518
- function isUrlMethodPair(href) {
519
- return href !== null && typeof href === "object" && href !== void 0 && "url" in href && "method" in href;
520
- }
521
- function urlHasProtocol(url) {
522
- return /^[a-z][a-z0-9+.-]*:\/\//i.test(url);
523
- }
524
- function urlToString(url, absolute) {
525
- const urlObj = typeof url === "string" ? hrefToUrl(url) : url;
526
- return absolute ? `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}${urlObj.search}${urlObj.hash}` : `${urlObj.pathname}${urlObj.search}${urlObj.hash}`;
527
- }
528
387
 
529
- // src/page.ts
530
- var CurrentPage = class {
388
+ // src/prefetched.ts
389
+ var PrefetchedRequests = class {
531
390
  constructor() {
532
- this.componentId = {};
533
- this.listeners = [];
534
- this.isFirstPageLoad = true;
535
- this.cleared = false;
536
- this.pendingDeferredProps = null;
537
- }
538
- init({
539
- initialPage,
540
- swapComponent,
541
- resolveComponent
542
- }) {
543
- this.page = initialPage;
544
- this.swapComponent = swapComponent;
545
- this.resolveComponent = resolveComponent;
546
- return this;
391
+ this.cached = [];
392
+ this.inFlightRequests = [];
393
+ this.removalTimers = [];
394
+ this.currentUseId = null;
395
+ }
396
+ add(params, sendFunc, { cacheFor, cacheTags }) {
397
+ const inFlight = this.findInFlight(params);
398
+ if (inFlight) {
399
+ return Promise.resolve();
400
+ }
401
+ const existing = this.findCached(params);
402
+ if (!params.fresh && existing && existing.staleTimestamp > Date.now()) {
403
+ return Promise.resolve();
404
+ }
405
+ const [stale, prefetchExpiresIn] = this.extractStaleValues(cacheFor);
406
+ const promise = new Promise((resolve, reject) => {
407
+ sendFunc({
408
+ ...params,
409
+ onCancel: () => {
410
+ this.remove(params);
411
+ params.onCancel();
412
+ reject();
413
+ },
414
+ onError: (error) => {
415
+ this.remove(params);
416
+ params.onError(error);
417
+ reject();
418
+ },
419
+ onPrefetching(visitParams) {
420
+ params.onPrefetching(visitParams);
421
+ },
422
+ onPrefetched(response, visit) {
423
+ params.onPrefetched(response, visit);
424
+ },
425
+ onPrefetchResponse(response) {
426
+ resolve(response);
427
+ },
428
+ onPrefetchError(error) {
429
+ prefetchedRequests.removeFromInFlight(params);
430
+ reject(error);
431
+ }
432
+ });
433
+ }).then((response) => {
434
+ this.remove(params);
435
+ const pageResponse = response.getPageResponse();
436
+ page.mergeOncePropsIntoResponse(pageResponse);
437
+ this.cached.push({
438
+ params: { ...params },
439
+ staleTimestamp: Date.now() + stale,
440
+ expiresAt: Date.now() + prefetchExpiresIn,
441
+ response: promise,
442
+ singleUse: prefetchExpiresIn === 0,
443
+ timestamp: Date.now(),
444
+ inFlight: false,
445
+ tags: Array.isArray(cacheTags) ? cacheTags : [cacheTags]
446
+ });
447
+ const oncePropExpiresIn = this.getShortestOncePropTtl(pageResponse);
448
+ this.scheduleForRemoval(
449
+ params,
450
+ oncePropExpiresIn ? Math.min(prefetchExpiresIn, oncePropExpiresIn) : prefetchExpiresIn
451
+ );
452
+ this.removeFromInFlight(params);
453
+ response.handlePrefetch();
454
+ return response;
455
+ });
456
+ this.inFlightRequests.push({
457
+ params: { ...params },
458
+ response: promise,
459
+ staleTimestamp: null,
460
+ inFlight: true
461
+ });
462
+ return promise;
463
+ }
464
+ removeAll() {
465
+ this.cached = [];
466
+ this.removalTimers.forEach((removalTimer) => {
467
+ clearTimeout(removalTimer.timer);
468
+ });
469
+ this.removalTimers = [];
470
+ }
471
+ removeByTags(tags) {
472
+ this.cached = this.cached.filter((prefetched) => {
473
+ return !prefetched.tags.some((tag) => tags.includes(tag));
474
+ });
475
+ }
476
+ remove(params) {
477
+ this.cached = this.cached.filter((prefetched) => {
478
+ return !this.paramsAreEqual(prefetched.params, params);
479
+ });
480
+ this.clearTimer(params);
481
+ }
482
+ removeFromInFlight(params) {
483
+ this.inFlightRequests = this.inFlightRequests.filter((prefetching) => {
484
+ return !this.paramsAreEqual(prefetching.params, params);
485
+ });
486
+ }
487
+ extractStaleValues(cacheFor) {
488
+ const [stale, expires] = this.cacheForToStaleAndExpires(cacheFor);
489
+ return [timeToMs(stale), timeToMs(expires)];
490
+ }
491
+ cacheForToStaleAndExpires(cacheFor) {
492
+ if (!Array.isArray(cacheFor)) {
493
+ return [cacheFor, cacheFor];
494
+ }
495
+ switch (cacheFor.length) {
496
+ case 0:
497
+ return [0, 0];
498
+ case 1:
499
+ return [cacheFor[0], cacheFor[0]];
500
+ default:
501
+ return [cacheFor[0], cacheFor[1]];
502
+ }
503
+ }
504
+ clearTimer(params) {
505
+ const timer = this.removalTimers.find((removalTimer) => {
506
+ return this.paramsAreEqual(removalTimer.params, params);
507
+ });
508
+ if (timer) {
509
+ clearTimeout(timer.timer);
510
+ this.removalTimers = this.removalTimers.filter((removalTimer) => removalTimer !== timer);
511
+ }
512
+ }
513
+ scheduleForRemoval(params, expiresIn) {
514
+ if (typeof window === "undefined") {
515
+ return;
516
+ }
517
+ this.clearTimer(params);
518
+ if (expiresIn > 0) {
519
+ const timer = window.setTimeout(() => this.remove(params), expiresIn);
520
+ this.removalTimers.push({
521
+ params,
522
+ timer
523
+ });
524
+ }
525
+ }
526
+ get(params) {
527
+ return this.findCached(params) || this.findInFlight(params);
528
+ }
529
+ use(prefetched, params) {
530
+ const id = `${params.url.pathname}-${Date.now()}-${Math.random().toString(36).substring(7)}`;
531
+ this.currentUseId = id;
532
+ return prefetched.response.then((response) => {
533
+ if (this.currentUseId !== id) {
534
+ return;
535
+ }
536
+ response.mergeParams({ ...params, onPrefetched: () => {
537
+ } });
538
+ this.removeSingleUseItems(params);
539
+ return response.handle();
540
+ });
541
+ }
542
+ removeSingleUseItems(params) {
543
+ this.cached = this.cached.filter((prefetched) => {
544
+ if (!this.paramsAreEqual(prefetched.params, params)) {
545
+ return true;
546
+ }
547
+ return !prefetched.singleUse;
548
+ });
549
+ }
550
+ findCached(params) {
551
+ return this.cached.find((prefetched) => {
552
+ return this.paramsAreEqual(prefetched.params, params);
553
+ }) || null;
554
+ }
555
+ findInFlight(params) {
556
+ return this.inFlightRequests.find((prefetched) => {
557
+ return this.paramsAreEqual(prefetched.params, params);
558
+ }) || null;
559
+ }
560
+ withoutPurposePrefetchHeader(params) {
561
+ const newParams = (0, import_lodash_es2.cloneDeep)(params);
562
+ if (newParams.headers["Purpose"] === "prefetch") {
563
+ delete newParams.headers["Purpose"];
564
+ }
565
+ return newParams;
566
+ }
567
+ paramsAreEqual(params1, params2) {
568
+ return objectsAreEqual(
569
+ this.withoutPurposePrefetchHeader(params1),
570
+ this.withoutPurposePrefetchHeader(params2),
571
+ [
572
+ "showProgress",
573
+ "replace",
574
+ "prefetch",
575
+ "preserveScroll",
576
+ "preserveState",
577
+ "onBefore",
578
+ "onBeforeUpdate",
579
+ "onStart",
580
+ "onProgress",
581
+ "onFinish",
582
+ "onCancel",
583
+ "onSuccess",
584
+ "onError",
585
+ "onPrefetched",
586
+ "onCancelToken",
587
+ "onPrefetching",
588
+ "async",
589
+ "viewTransition"
590
+ ]
591
+ );
592
+ }
593
+ updateCachedOncePropsFromCurrentPage() {
594
+ this.cached.forEach((prefetched) => {
595
+ prefetched.response.then((response) => {
596
+ const pageResponse = response.getPageResponse();
597
+ page.mergeOncePropsIntoResponse(pageResponse, { force: true });
598
+ const oncePropExpiresIn = this.getShortestOncePropTtl(pageResponse);
599
+ if (oncePropExpiresIn === null) {
600
+ return;
601
+ }
602
+ const prefetchExpiresIn = prefetched.expiresAt - Date.now();
603
+ const expiresIn = Math.min(prefetchExpiresIn, oncePropExpiresIn);
604
+ if (expiresIn > 0) {
605
+ this.scheduleForRemoval(prefetched.params, expiresIn);
606
+ } else {
607
+ this.remove(prefetched.params);
608
+ }
609
+ });
610
+ });
611
+ }
612
+ getShortestOncePropTtl(page2) {
613
+ const expiryTimestamps = Object.values(page2.onceProps ?? {}).map((onceProp) => onceProp.expiresAt).filter((expiresAt) => !!expiresAt);
614
+ if (expiryTimestamps.length === 0) {
615
+ return null;
616
+ }
617
+ return Math.min(...expiryTimestamps) - Date.now();
618
+ }
619
+ };
620
+ var prefetchedRequests = new PrefetchedRequests();
621
+
622
+ // src/scroll.ts
623
+ var Scroll = class {
624
+ static save() {
625
+ history.saveScrollPositions(
626
+ Array.from(this.regions()).map((region) => ({
627
+ top: region.scrollTop,
628
+ left: region.scrollLeft
629
+ }))
630
+ );
631
+ }
632
+ static regions() {
633
+ return document.querySelectorAll("[scroll-region]");
634
+ }
635
+ static reset() {
636
+ const anchorHash = typeof window !== "undefined" ? window.location.hash : null;
637
+ if (!anchorHash) {
638
+ window.scrollTo(0, 0);
639
+ }
640
+ this.regions().forEach((region) => {
641
+ if (typeof region.scrollTo === "function") {
642
+ region.scrollTo(0, 0);
643
+ } else {
644
+ region.scrollTop = 0;
645
+ region.scrollLeft = 0;
646
+ }
647
+ });
648
+ this.save();
649
+ this.scrollToAnchor();
650
+ }
651
+ static scrollToAnchor() {
652
+ const anchorHash = typeof window !== "undefined" ? window.location.hash : null;
653
+ if (anchorHash) {
654
+ setTimeout(() => {
655
+ const anchorElement = document.getElementById(anchorHash.slice(1));
656
+ anchorElement ? anchorElement.scrollIntoView() : window.scrollTo(0, 0);
657
+ });
658
+ }
659
+ }
660
+ static restore(scrollRegions) {
661
+ if (typeof window === "undefined") {
662
+ return;
663
+ }
664
+ window.requestAnimationFrame(() => {
665
+ this.restoreDocument();
666
+ this.restoreScrollRegions(scrollRegions);
667
+ });
668
+ }
669
+ static restoreScrollRegions(scrollRegions) {
670
+ if (typeof window === "undefined") {
671
+ return;
672
+ }
673
+ this.regions().forEach((region, index) => {
674
+ const scrollPosition = scrollRegions[index];
675
+ if (!scrollPosition) {
676
+ return;
677
+ }
678
+ if (typeof region.scrollTo === "function") {
679
+ region.scrollTo(scrollPosition.left, scrollPosition.top);
680
+ } else {
681
+ region.scrollTop = scrollPosition.top;
682
+ region.scrollLeft = scrollPosition.left;
683
+ }
684
+ });
685
+ }
686
+ static restoreDocument() {
687
+ const scrollPosition = history.getDocumentScrollPosition();
688
+ window.scrollTo(scrollPosition.left, scrollPosition.top);
689
+ }
690
+ static onScroll(event) {
691
+ const target = event.target;
692
+ if (typeof target.hasAttribute === "function" && target.hasAttribute("scroll-region")) {
693
+ this.save();
694
+ }
695
+ }
696
+ static onWindowScroll() {
697
+ history.saveDocumentScrollPosition({
698
+ top: window.scrollY,
699
+ left: window.scrollX
700
+ });
701
+ }
702
+ };
703
+
704
+ // src/url.ts
705
+ var qs = __toESM(require("qs"), 1);
706
+
707
+ // src/files.ts
708
+ var isFile = (value) => typeof File !== "undefined" && value instanceof File || value instanceof Blob || typeof FileList !== "undefined" && value instanceof FileList && value.length > 0;
709
+ function hasFiles(data) {
710
+ return isFile(data) || data instanceof FormData && Array.from(data.values()).some((value) => hasFiles(value)) || typeof data === "object" && data !== null && Object.values(data).some((value) => hasFiles(value));
711
+ }
712
+
713
+ // src/formData.ts
714
+ var isFormData = (value) => value instanceof FormData;
715
+ function objectToFormData(source, form = new FormData(), parentKey = null, queryStringArrayFormat = "brackets") {
716
+ source = source || {};
717
+ for (const key in source) {
718
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
719
+ append(form, composeKey(parentKey, key, "indices"), source[key], queryStringArrayFormat);
720
+ }
721
+ }
722
+ return form;
723
+ }
724
+ function composeKey(parent, key, format) {
725
+ if (!parent) {
726
+ return key;
727
+ }
728
+ return format === "brackets" ? `${parent}[]` : `${parent}[${key}]`;
729
+ }
730
+ function append(form, key, value, format) {
731
+ if (Array.isArray(value)) {
732
+ return Array.from(value.keys()).forEach(
733
+ (index) => append(form, composeKey(key, index.toString(), format), value[index], format)
734
+ );
735
+ } else if (value instanceof Date) {
736
+ return form.append(key, value.toISOString());
737
+ } else if (value instanceof File) {
738
+ return form.append(key, value, value.name);
739
+ } else if (value instanceof Blob) {
740
+ return form.append(key, value);
741
+ } else if (typeof value === "boolean") {
742
+ return form.append(key, value ? "1" : "0");
743
+ } else if (typeof value === "string") {
744
+ return form.append(key, value);
745
+ } else if (typeof value === "number") {
746
+ return form.append(key, `${value}`);
747
+ } else if (value === null || value === void 0) {
748
+ return form.append(key, "");
749
+ }
750
+ objectToFormData(value, form, key, format);
751
+ }
752
+
753
+ // src/url.ts
754
+ function hrefToUrl(href) {
755
+ return new URL(href.toString(), typeof window === "undefined" ? void 0 : window.location.toString());
756
+ }
757
+ var transformUrlAndData = (href, data, method, forceFormData, queryStringArrayFormat) => {
758
+ let url = typeof href === "string" ? hrefToUrl(href) : href;
759
+ if ((hasFiles(data) || forceFormData) && !isFormData(data)) {
760
+ if (config.get("form.forceIndicesArrayFormatInFormData")) {
761
+ queryStringArrayFormat = "indices";
762
+ }
763
+ data = objectToFormData(data, new FormData(), null, queryStringArrayFormat);
764
+ }
765
+ if (isFormData(data)) {
766
+ return [url, data];
767
+ }
768
+ const [_href, _data] = mergeDataIntoQueryString(method, url, data, queryStringArrayFormat);
769
+ return [hrefToUrl(_href), _data];
770
+ };
771
+ function mergeDataIntoQueryString(method, href, data, qsArrayFormat = "brackets") {
772
+ const hasDataForQueryString = method === "get" && !isFormData(data) && Object.keys(data).length > 0;
773
+ const hasHost = urlHasProtocol(href.toString());
774
+ const hasAbsolutePath = hasHost || href.toString().startsWith("/") || href.toString() === "";
775
+ const hasRelativePath = !hasAbsolutePath && !href.toString().startsWith("#") && !href.toString().startsWith("?");
776
+ const hasRelativePathWithDotPrefix = /^[.]{1,2}([/]|$)/.test(href.toString());
777
+ const hasSearch = href.toString().includes("?") || hasDataForQueryString;
778
+ const hasHash = href.toString().includes("#");
779
+ const url = new URL(href.toString(), typeof window === "undefined" ? "http://localhost" : window.location.toString());
780
+ if (hasDataForQueryString) {
781
+ const parseOptions = { ignoreQueryPrefix: true, parseArrays: false };
782
+ url.search = qs.stringify(
783
+ { ...qs.parse(url.search, parseOptions), ...data },
784
+ {
785
+ encodeValuesOnly: true,
786
+ arrayFormat: qsArrayFormat
787
+ }
788
+ );
789
+ }
790
+ return [
791
+ [
792
+ hasHost ? `${url.protocol}//${url.host}` : "",
793
+ hasAbsolutePath ? url.pathname : "",
794
+ hasRelativePath ? url.pathname.substring(hasRelativePathWithDotPrefix ? 0 : 1) : "",
795
+ hasSearch ? url.search : "",
796
+ hasHash ? url.hash : ""
797
+ ].join(""),
798
+ hasDataForQueryString ? {} : data
799
+ ];
800
+ }
801
+ function urlWithoutHash(url) {
802
+ url = new URL(url.href);
803
+ url.hash = "";
804
+ return url;
805
+ }
806
+ var setHashIfSameUrl = (originUrl, destinationUrl) => {
807
+ if (originUrl.hash && !destinationUrl.hash && urlWithoutHash(originUrl).href === destinationUrl.href) {
808
+ destinationUrl.hash = originUrl.hash;
809
+ }
810
+ };
811
+ var isSameUrlWithoutHash = (url1, url2) => {
812
+ return urlWithoutHash(url1).href === urlWithoutHash(url2).href;
813
+ };
814
+ function isUrlMethodPair(href) {
815
+ return href !== null && typeof href === "object" && href !== void 0 && "url" in href && "method" in href;
816
+ }
817
+ function urlHasProtocol(url) {
818
+ return /^[a-z][a-z0-9+.-]*:\/\//i.test(url);
819
+ }
820
+ function urlToString(url, absolute) {
821
+ const urlObj = typeof url === "string" ? hrefToUrl(url) : url;
822
+ return absolute ? `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}${urlObj.search}${urlObj.hash}` : `${urlObj.pathname}${urlObj.search}${urlObj.hash}`;
823
+ }
824
+
825
+ // src/page.ts
826
+ var CurrentPage = class {
827
+ constructor() {
828
+ this.componentId = {};
829
+ this.listeners = [];
830
+ this.isFirstPageLoad = true;
831
+ this.cleared = false;
832
+ this.pendingDeferredProps = null;
833
+ }
834
+ init({
835
+ initialPage,
836
+ swapComponent,
837
+ resolveComponent
838
+ }) {
839
+ this.page = initialPage;
840
+ this.swapComponent = swapComponent;
841
+ this.resolveComponent = resolveComponent;
842
+ return this;
547
843
  }
548
844
  set(page2, {
549
845
  replace = false,
@@ -581,6 +877,9 @@ var CurrentPage = class {
581
877
  }
582
878
  this.page = page2;
583
879
  this.cleared = false;
880
+ if (this.hasOnceProps()) {
881
+ prefetchedRequests.updateCachedOncePropsFromCurrentPage();
882
+ }
584
883
  if (isNewComponent) {
585
884
  this.fireEventsFor("newComponent");
586
885
  }
@@ -629,6 +928,9 @@ var CurrentPage = class {
629
928
  get() {
630
929
  return this.page;
631
930
  }
931
+ hasOnceProps() {
932
+ return Object.keys(this.page.onceProps ?? {}).length > 0;
933
+ }
632
934
  merge(data) {
633
935
  this.page = { ...this.page, ...data };
634
936
  }
@@ -671,6 +973,18 @@ var CurrentPage = class {
671
973
  fireEventsFor(event) {
672
974
  this.listeners.filter((listener) => listener.event === event).forEach((listener) => listener.callback());
673
975
  }
976
+ mergeOncePropsIntoResponse(response, { force = false } = {}) {
977
+ Object.entries(response.onceProps ?? {}).forEach(([key, onceProp]) => {
978
+ const existingOnceProp = this.page.onceProps?.[key];
979
+ if (existingOnceProp === void 0) {
980
+ return;
981
+ }
982
+ if (force || response.props[onceProp.prop] === void 0) {
983
+ response.props[onceProp.prop] = this.page.props[existingOnceProp.prop];
984
+ response.onceProps[key].expiresAt = existingOnceProp.expiresAt;
985
+ }
986
+ });
987
+ }
674
988
  };
675
989
  var page = new CurrentPage();
676
990
 
@@ -754,7 +1068,7 @@ var History = class {
754
1068
  } catch {
755
1069
  return {
756
1070
  ...page2,
757
- props: (0, import_lodash_es2.cloneDeep)(page2.props)
1071
+ props: (0, import_lodash_es3.cloneDeep)(page2.props)
758
1072
  };
759
1073
  }
760
1074
  }
@@ -793,7 +1107,7 @@ var History = class {
793
1107
  if (!window.history.state?.page) {
794
1108
  return;
795
1109
  }
796
- if ((0, import_lodash_es2.isEqual)(this.getScrollRegions(), scrollRegions)) {
1110
+ if ((0, import_lodash_es3.isEqual)(this.getScrollRegions(), scrollRegions)) {
797
1111
  return;
798
1112
  }
799
1113
  return this.doReplaceState({
@@ -809,7 +1123,7 @@ var History = class {
809
1123
  if (!window.history.state?.page) {
810
1124
  return;
811
1125
  }
812
- if ((0, import_lodash_es2.isEqual)(this.getDocumentScrollPosition(), scrollRegion)) {
1126
+ if ((0, import_lodash_es3.isEqual)(this.getDocumentScrollPosition(), scrollRegion)) {
813
1127
  return;
814
1128
  }
815
1129
  return this.doReplaceState({
@@ -860,547 +1174,286 @@ var History = class {
860
1174
  )
861
1175
  );
862
1176
  }
863
- doPushState(data, url) {
864
- return Promise.resolve().then(() => window.history.pushState(data, "", url));
865
- }
866
- getState(key, defaultValue) {
867
- return this.current?.[key] ?? defaultValue;
868
- }
869
- deleteState(key) {
870
- if (this.current[key] !== void 0) {
871
- delete this.current[key];
872
- this.replaceState(this.current);
873
- }
874
- }
875
- clearInitialState(key) {
876
- if (this.initialState && this.initialState[key] !== void 0) {
877
- delete this.initialState[key];
878
- }
879
- }
880
- hasAnyState() {
881
- return !!this.getAllState();
882
- }
883
- clear() {
884
- SessionStorage.remove(historySessionStorageKeys.key);
885
- SessionStorage.remove(historySessionStorageKeys.iv);
886
- }
887
- setCurrent(page2) {
888
- this.current = page2;
889
- }
890
- isValidState(state) {
891
- return !!state.page;
892
- }
893
- getAllState() {
894
- return this.current;
895
- }
896
- };
897
- if (typeof window !== "undefined" && window.history.scrollRestoration) {
898
- window.history.scrollRestoration = "manual";
899
- }
900
- var history = new History();
901
-
902
- // src/eventHandler.ts
903
- var EventHandler = class {
904
- constructor() {
905
- this.internalListeners = [];
906
- }
907
- init() {
908
- if (typeof window !== "undefined") {
909
- window.addEventListener("popstate", this.handlePopstateEvent.bind(this));
910
- window.addEventListener("scroll", debounce(Scroll.onWindowScroll.bind(Scroll), 100), true);
911
- }
912
- if (typeof document !== "undefined") {
913
- document.addEventListener("scroll", debounce(Scroll.onScroll.bind(Scroll), 100), true);
914
- }
915
- }
916
- onGlobalEvent(type, callback) {
917
- const listener = ((event) => {
918
- const response = callback(event);
919
- if (event.cancelable && !event.defaultPrevented && response === false) {
920
- event.preventDefault();
921
- }
922
- });
923
- return this.registerListener(`inertia:${type}`, listener);
924
- }
925
- on(event, callback) {
926
- this.internalListeners.push({ event, listener: callback });
927
- return () => {
928
- this.internalListeners = this.internalListeners.filter((listener) => listener.listener !== callback);
929
- };
930
- }
931
- onMissingHistoryItem() {
932
- page.clear();
933
- this.fireInternalEvent("missingHistoryItem");
934
- }
935
- fireInternalEvent(event, ...args) {
936
- this.internalListeners.filter((listener) => listener.event === event).forEach((listener) => listener.listener(...args));
937
- }
938
- registerListener(type, listener) {
939
- document.addEventListener(type, listener);
940
- return () => document.removeEventListener(type, listener);
941
- }
942
- handlePopstateEvent(event) {
943
- const state = event.state || null;
944
- if (state === null) {
945
- const url = hrefToUrl(page.get().url);
946
- url.hash = window.location.hash;
947
- history.replaceState({ ...page.get(), url: url.href });
948
- Scroll.reset();
949
- return;
950
- }
951
- if (!history.isValidState(state)) {
952
- return this.onMissingHistoryItem();
953
- }
954
- history.decrypt(state.page).then((data) => {
955
- if (page.get().version !== data.version) {
956
- this.onMissingHistoryItem();
957
- return;
958
- }
959
- router.cancelAll();
960
- page.setQuietly(data, { preserveState: false }).then(() => {
961
- Scroll.restore(history.getScrollRegions());
962
- fireNavigateEvent(page.get());
963
- });
964
- }).catch(() => {
965
- this.onMissingHistoryItem();
966
- });
967
- }
968
- };
969
- var eventHandler = new EventHandler();
970
-
971
- // src/navigationType.ts
972
- var NavigationType = class {
973
- constructor() {
974
- this.type = this.resolveType();
975
- }
976
- resolveType() {
977
- if (typeof window === "undefined") {
978
- return "navigate";
979
- }
980
- if (window.performance && window.performance.getEntriesByType && window.performance.getEntriesByType("navigation").length > 0) {
981
- return window.performance.getEntriesByType("navigation")[0].type;
982
- }
983
- return "navigate";
984
- }
985
- get() {
986
- return this.type;
987
- }
988
- isBackForward() {
989
- return this.type === "back_forward";
990
- }
991
- isReload() {
992
- return this.type === "reload";
993
- }
994
- };
995
- var navigationType = new NavigationType();
996
-
997
- // src/initialVisit.ts
998
- var InitialVisit = class {
999
- static handle() {
1000
- this.clearRememberedStateOnReload();
1001
- const scenarios = [this.handleBackForward, this.handleLocation, this.handleDefault];
1002
- scenarios.find((handler) => handler.bind(this)());
1003
- }
1004
- static clearRememberedStateOnReload() {
1005
- if (navigationType.isReload()) {
1006
- history.deleteState(history.rememberedState);
1007
- history.clearInitialState(history.rememberedState);
1008
- }
1009
- }
1010
- static handleBackForward() {
1011
- if (!navigationType.isBackForward() || !history.hasAnyState()) {
1012
- return false;
1013
- }
1014
- const scrollRegions = history.getScrollRegions();
1015
- history.decrypt().then((data) => {
1016
- page.set(data, { preserveScroll: true, preserveState: true }).then(() => {
1017
- Scroll.restore(scrollRegions);
1018
- fireNavigateEvent(page.get());
1019
- });
1020
- }).catch(() => {
1021
- eventHandler.onMissingHistoryItem();
1022
- });
1023
- return true;
1024
- }
1025
- /**
1026
- * @link https://inertiajs.com/redirects#external-redirects
1027
- */
1028
- static handleLocation() {
1029
- if (!SessionStorage.exists(SessionStorage.locationVisitKey)) {
1030
- return false;
1031
- }
1032
- const locationVisit = SessionStorage.get(SessionStorage.locationVisitKey) || {};
1033
- SessionStorage.remove(SessionStorage.locationVisitKey);
1034
- if (typeof window !== "undefined") {
1035
- page.setUrlHash(window.location.hash);
1036
- }
1037
- history.decrypt(page.get()).then(() => {
1038
- const rememberedState = history.getState(history.rememberedState, {});
1039
- const scrollRegions = history.getScrollRegions();
1040
- page.remember(rememberedState);
1041
- page.set(page.get(), {
1042
- preserveScroll: locationVisit.preserveScroll,
1043
- preserveState: true
1044
- }).then(() => {
1045
- if (locationVisit.preserveScroll) {
1046
- Scroll.restore(scrollRegions);
1047
- }
1048
- fireNavigateEvent(page.get());
1049
- });
1050
- }).catch(() => {
1051
- eventHandler.onMissingHistoryItem();
1052
- });
1053
- return true;
1054
- }
1055
- static handleDefault() {
1056
- if (typeof window !== "undefined") {
1057
- page.setUrlHash(window.location.hash);
1058
- }
1059
- page.set(page.get(), { preserveScroll: true, preserveState: true }).then(() => {
1060
- if (navigationType.isReload()) {
1061
- Scroll.restore(history.getScrollRegions());
1062
- } else {
1063
- Scroll.scrollToAnchor();
1064
- }
1065
- fireNavigateEvent(page.get());
1066
- });
1067
- }
1068
- };
1069
-
1070
- // src/poll.ts
1071
- var Poll = class {
1072
- constructor(interval, cb, options) {
1073
- this.id = null;
1074
- this.throttle = false;
1075
- this.keepAlive = false;
1076
- this.cbCount = 0;
1077
- this.keepAlive = options.keepAlive ?? false;
1078
- this.cb = cb;
1079
- this.interval = interval;
1080
- if (options.autoStart ?? true) {
1081
- this.start();
1082
- }
1083
- }
1084
- stop() {
1085
- if (this.id) {
1086
- clearInterval(this.id);
1087
- }
1177
+ doPushState(data, url) {
1178
+ return Promise.resolve().then(() => window.history.pushState(data, "", url));
1088
1179
  }
1089
- start() {
1090
- if (typeof window === "undefined") {
1091
- return;
1092
- }
1093
- this.stop();
1094
- this.id = window.setInterval(() => {
1095
- if (!this.throttle || this.cbCount % 10 === 0) {
1096
- this.cb();
1097
- }
1098
- if (this.throttle) {
1099
- this.cbCount++;
1100
- }
1101
- }, this.interval);
1180
+ getState(key, defaultValue) {
1181
+ return this.current?.[key] ?? defaultValue;
1102
1182
  }
1103
- isInBackground(hidden) {
1104
- this.throttle = this.keepAlive ? false : hidden;
1105
- if (this.throttle) {
1106
- this.cbCount = 0;
1183
+ deleteState(key) {
1184
+ if (this.current[key] !== void 0) {
1185
+ delete this.current[key];
1186
+ this.replaceState(this.current);
1107
1187
  }
1108
1188
  }
1109
- };
1110
-
1111
- // src/polls.ts
1112
- var Polls = class {
1113
- constructor() {
1114
- this.polls = [];
1115
- this.setupVisibilityListener();
1189
+ clearInitialState(key) {
1190
+ if (this.initialState && this.initialState[key] !== void 0) {
1191
+ delete this.initialState[key];
1192
+ }
1116
1193
  }
1117
- add(interval, cb, options) {
1118
- const poll = new Poll(interval, cb, options);
1119
- this.polls.push(poll);
1120
- return {
1121
- stop: () => poll.stop(),
1122
- start: () => poll.start()
1123
- };
1194
+ hasAnyState() {
1195
+ return !!this.getAllState();
1124
1196
  }
1125
1197
  clear() {
1126
- this.polls.forEach((poll) => poll.stop());
1127
- this.polls = [];
1198
+ SessionStorage.remove(historySessionStorageKeys.key);
1199
+ SessionStorage.remove(historySessionStorageKeys.iv);
1128
1200
  }
1129
- setupVisibilityListener() {
1130
- if (typeof document === "undefined") {
1131
- return;
1132
- }
1133
- document.addEventListener(
1134
- "visibilitychange",
1135
- () => {
1136
- this.polls.forEach((poll) => poll.isInBackground(document.hidden));
1137
- },
1138
- false
1139
- );
1201
+ setCurrent(page2) {
1202
+ this.current = page2;
1203
+ }
1204
+ isValidState(state) {
1205
+ return !!state.page;
1206
+ }
1207
+ getAllState() {
1208
+ return this.current;
1140
1209
  }
1141
1210
  };
1142
- var polls = new Polls();
1143
-
1144
- // src/prefetched.ts
1145
- var import_lodash_es3 = require("lodash-es");
1211
+ if (typeof window !== "undefined" && window.history.scrollRestoration) {
1212
+ window.history.scrollRestoration = "manual";
1213
+ }
1214
+ var history = new History();
1146
1215
 
1147
- // src/objectUtils.ts
1148
- var objectsAreEqual = (obj1, obj2, excludeKeys) => {
1149
- if (obj1 === obj2) {
1150
- return true;
1216
+ // src/eventHandler.ts
1217
+ var EventHandler = class {
1218
+ constructor() {
1219
+ this.internalListeners = [];
1151
1220
  }
1152
- for (const key in obj1) {
1153
- if (excludeKeys.includes(key)) {
1154
- continue;
1155
- }
1156
- if (obj1[key] === obj2[key]) {
1157
- continue;
1221
+ init() {
1222
+ if (typeof window !== "undefined") {
1223
+ window.addEventListener("popstate", this.handlePopstateEvent.bind(this));
1224
+ window.addEventListener("scroll", debounce(Scroll.onWindowScroll.bind(Scroll), 100), true);
1158
1225
  }
1159
- if (!compareValues(obj1[key], obj2[key])) {
1160
- return false;
1226
+ if (typeof document !== "undefined") {
1227
+ document.addEventListener("scroll", debounce(Scroll.onScroll.bind(Scroll), 100), true);
1161
1228
  }
1162
1229
  }
1163
- for (const key in obj2) {
1164
- if (excludeKeys.includes(key)) {
1165
- continue;
1166
- }
1167
- if (!(key in obj1)) {
1168
- return false;
1169
- }
1230
+ onGlobalEvent(type, callback) {
1231
+ const listener = ((event) => {
1232
+ const response = callback(event);
1233
+ if (event.cancelable && !event.defaultPrevented && response === false) {
1234
+ event.preventDefault();
1235
+ }
1236
+ });
1237
+ return this.registerListener(`inertia:${type}`, listener);
1170
1238
  }
1171
- return true;
1172
- };
1173
- var compareValues = (value1, value2) => {
1174
- switch (typeof value1) {
1175
- case "object":
1176
- return objectsAreEqual(value1, value2, []);
1177
- case "function":
1178
- return value1.toString() === value2.toString();
1179
- default:
1180
- return value1 === value2;
1239
+ on(event, callback) {
1240
+ this.internalListeners.push({ event, listener: callback });
1241
+ return () => {
1242
+ this.internalListeners = this.internalListeners.filter((listener) => listener.listener !== callback);
1243
+ };
1181
1244
  }
1182
- };
1183
-
1184
- // src/time.ts
1185
- var conversionMap = {
1186
- ms: 1,
1187
- s: 1e3,
1188
- m: 1e3 * 60,
1189
- h: 1e3 * 60 * 60,
1190
- d: 1e3 * 60 * 60 * 24
1191
- };
1192
- var timeToMs = (time) => {
1193
- if (typeof time === "number") {
1194
- return time;
1245
+ onMissingHistoryItem() {
1246
+ page.clear();
1247
+ this.fireInternalEvent("missingHistoryItem");
1195
1248
  }
1196
- for (const [unit, conversion] of Object.entries(conversionMap)) {
1197
- if (time.endsWith(unit)) {
1198
- return parseFloat(time) * conversion;
1249
+ fireInternalEvent(event, ...args) {
1250
+ this.internalListeners.filter((listener) => listener.event === event).forEach((listener) => listener.listener(...args));
1251
+ }
1252
+ registerListener(type, listener) {
1253
+ document.addEventListener(type, listener);
1254
+ return () => document.removeEventListener(type, listener);
1255
+ }
1256
+ handlePopstateEvent(event) {
1257
+ const state = event.state || null;
1258
+ if (state === null) {
1259
+ const url = hrefToUrl(page.get().url);
1260
+ url.hash = window.location.hash;
1261
+ history.replaceState({ ...page.get(), url: url.href });
1262
+ Scroll.reset();
1263
+ return;
1264
+ }
1265
+ if (!history.isValidState(state)) {
1266
+ return this.onMissingHistoryItem();
1199
1267
  }
1268
+ history.decrypt(state.page).then((data) => {
1269
+ if (page.get().version !== data.version) {
1270
+ this.onMissingHistoryItem();
1271
+ return;
1272
+ }
1273
+ router.cancelAll();
1274
+ page.setQuietly(data, { preserveState: false }).then(() => {
1275
+ Scroll.restore(history.getScrollRegions());
1276
+ fireNavigateEvent(page.get());
1277
+ });
1278
+ }).catch(() => {
1279
+ this.onMissingHistoryItem();
1280
+ });
1200
1281
  }
1201
- return parseInt(time);
1202
1282
  };
1283
+ var eventHandler = new EventHandler();
1203
1284
 
1204
- // src/prefetched.ts
1205
- var PrefetchedRequests = class {
1285
+ // src/navigationType.ts
1286
+ var NavigationType = class {
1206
1287
  constructor() {
1207
- this.cached = [];
1208
- this.inFlightRequests = [];
1209
- this.removalTimers = [];
1210
- this.currentUseId = null;
1288
+ this.type = this.resolveType();
1211
1289
  }
1212
- add(params, sendFunc, { cacheFor, cacheTags }) {
1213
- const inFlight = this.findInFlight(params);
1214
- if (inFlight) {
1215
- return Promise.resolve();
1290
+ resolveType() {
1291
+ if (typeof window === "undefined") {
1292
+ return "navigate";
1216
1293
  }
1217
- const existing = this.findCached(params);
1218
- if (!params.fresh && existing && existing.staleTimestamp > Date.now()) {
1219
- return Promise.resolve();
1294
+ if (window.performance && window.performance.getEntriesByType && window.performance.getEntriesByType("navigation").length > 0) {
1295
+ return window.performance.getEntriesByType("navigation")[0].type;
1220
1296
  }
1221
- const [stale, expires] = this.extractStaleValues(cacheFor);
1222
- const promise = new Promise((resolve, reject) => {
1223
- sendFunc({
1224
- ...params,
1225
- onCancel: () => {
1226
- this.remove(params);
1227
- params.onCancel();
1228
- reject();
1229
- },
1230
- onError: (error) => {
1231
- this.remove(params);
1232
- params.onError(error);
1233
- reject();
1234
- },
1235
- onPrefetching(visitParams) {
1236
- params.onPrefetching(visitParams);
1237
- },
1238
- onPrefetched(response, visit) {
1239
- params.onPrefetched(response, visit);
1240
- },
1241
- onPrefetchResponse(response) {
1242
- resolve(response);
1243
- },
1244
- onPrefetchError(error) {
1245
- prefetchedRequests.removeFromInFlight(params);
1246
- reject(error);
1247
- }
1248
- });
1249
- }).then((response) => {
1250
- this.remove(params);
1251
- this.cached.push({
1252
- params: { ...params },
1253
- staleTimestamp: Date.now() + stale,
1254
- response: promise,
1255
- singleUse: expires === 0,
1256
- timestamp: Date.now(),
1257
- inFlight: false,
1258
- tags: Array.isArray(cacheTags) ? cacheTags : [cacheTags]
1259
- });
1260
- this.scheduleForRemoval(params, expires);
1261
- this.removeFromInFlight(params);
1262
- response.handlePrefetch();
1263
- return response;
1264
- });
1265
- this.inFlightRequests.push({
1266
- params: { ...params },
1267
- response: promise,
1268
- staleTimestamp: null,
1269
- inFlight: true
1270
- });
1271
- return promise;
1297
+ return "navigate";
1298
+ }
1299
+ get() {
1300
+ return this.type;
1272
1301
  }
1273
- removeAll() {
1274
- this.cached = [];
1275
- this.removalTimers.forEach((removalTimer) => {
1276
- clearTimeout(removalTimer.timer);
1277
- });
1278
- this.removalTimers = [];
1302
+ isBackForward() {
1303
+ return this.type === "back_forward";
1279
1304
  }
1280
- removeByTags(tags) {
1281
- this.cached = this.cached.filter((prefetched) => {
1282
- return !prefetched.tags.some((tag) => tags.includes(tag));
1283
- });
1305
+ isReload() {
1306
+ return this.type === "reload";
1284
1307
  }
1285
- remove(params) {
1286
- this.cached = this.cached.filter((prefetched) => {
1287
- return !this.paramsAreEqual(prefetched.params, params);
1288
- });
1289
- this.clearTimer(params);
1308
+ };
1309
+ var navigationType = new NavigationType();
1310
+
1311
+ // src/initialVisit.ts
1312
+ var InitialVisit = class {
1313
+ static handle() {
1314
+ this.clearRememberedStateOnReload();
1315
+ const scenarios = [this.handleBackForward, this.handleLocation, this.handleDefault];
1316
+ scenarios.find((handler) => handler.bind(this)());
1290
1317
  }
1291
- removeFromInFlight(params) {
1292
- this.inFlightRequests = this.inFlightRequests.filter((prefetching) => {
1293
- return !this.paramsAreEqual(prefetching.params, params);
1294
- });
1318
+ static clearRememberedStateOnReload() {
1319
+ if (navigationType.isReload()) {
1320
+ history.deleteState(history.rememberedState);
1321
+ history.clearInitialState(history.rememberedState);
1322
+ }
1295
1323
  }
1296
- extractStaleValues(cacheFor) {
1297
- const [stale, expires] = this.cacheForToStaleAndExpires(cacheFor);
1298
- return [timeToMs(stale), timeToMs(expires)];
1324
+ static handleBackForward() {
1325
+ if (!navigationType.isBackForward() || !history.hasAnyState()) {
1326
+ return false;
1327
+ }
1328
+ const scrollRegions = history.getScrollRegions();
1329
+ history.decrypt().then((data) => {
1330
+ page.set(data, { preserveScroll: true, preserveState: true }).then(() => {
1331
+ Scroll.restore(scrollRegions);
1332
+ fireNavigateEvent(page.get());
1333
+ });
1334
+ }).catch(() => {
1335
+ eventHandler.onMissingHistoryItem();
1336
+ });
1337
+ return true;
1299
1338
  }
1300
- cacheForToStaleAndExpires(cacheFor) {
1301
- if (!Array.isArray(cacheFor)) {
1302
- return [cacheFor, cacheFor];
1339
+ /**
1340
+ * @link https://inertiajs.com/redirects#external-redirects
1341
+ */
1342
+ static handleLocation() {
1343
+ if (!SessionStorage.exists(SessionStorage.locationVisitKey)) {
1344
+ return false;
1303
1345
  }
1304
- switch (cacheFor.length) {
1305
- case 0:
1306
- return [0, 0];
1307
- case 1:
1308
- return [cacheFor[0], cacheFor[0]];
1309
- default:
1310
- return [cacheFor[0], cacheFor[1]];
1346
+ const locationVisit = SessionStorage.get(SessionStorage.locationVisitKey) || {};
1347
+ SessionStorage.remove(SessionStorage.locationVisitKey);
1348
+ if (typeof window !== "undefined") {
1349
+ page.setUrlHash(window.location.hash);
1311
1350
  }
1351
+ history.decrypt(page.get()).then(() => {
1352
+ const rememberedState = history.getState(history.rememberedState, {});
1353
+ const scrollRegions = history.getScrollRegions();
1354
+ page.remember(rememberedState);
1355
+ page.set(page.get(), {
1356
+ preserveScroll: locationVisit.preserveScroll,
1357
+ preserveState: true
1358
+ }).then(() => {
1359
+ if (locationVisit.preserveScroll) {
1360
+ Scroll.restore(scrollRegions);
1361
+ }
1362
+ fireNavigateEvent(page.get());
1363
+ });
1364
+ }).catch(() => {
1365
+ eventHandler.onMissingHistoryItem();
1366
+ });
1367
+ return true;
1312
1368
  }
1313
- clearTimer(params) {
1314
- const timer = this.removalTimers.find((removalTimer) => {
1315
- return this.paramsAreEqual(removalTimer.params, params);
1369
+ static handleDefault() {
1370
+ if (typeof window !== "undefined") {
1371
+ page.setUrlHash(window.location.hash);
1372
+ }
1373
+ page.set(page.get(), { preserveScroll: true, preserveState: true }).then(() => {
1374
+ if (navigationType.isReload()) {
1375
+ Scroll.restore(history.getScrollRegions());
1376
+ } else {
1377
+ Scroll.scrollToAnchor();
1378
+ }
1379
+ fireNavigateEvent(page.get());
1316
1380
  });
1317
- if (timer) {
1318
- clearTimeout(timer.timer);
1319
- this.removalTimers = this.removalTimers.filter((removalTimer) => removalTimer !== timer);
1381
+ }
1382
+ };
1383
+
1384
+ // src/poll.ts
1385
+ var Poll = class {
1386
+ constructor(interval, cb, options) {
1387
+ this.id = null;
1388
+ this.throttle = false;
1389
+ this.keepAlive = false;
1390
+ this.cbCount = 0;
1391
+ this.keepAlive = options.keepAlive ?? false;
1392
+ this.cb = cb;
1393
+ this.interval = interval;
1394
+ if (options.autoStart ?? true) {
1395
+ this.start();
1320
1396
  }
1321
1397
  }
1322
- scheduleForRemoval(params, expiresIn) {
1398
+ stop() {
1399
+ if (this.id) {
1400
+ clearInterval(this.id);
1401
+ }
1402
+ }
1403
+ start() {
1323
1404
  if (typeof window === "undefined") {
1324
1405
  return;
1325
1406
  }
1326
- this.clearTimer(params);
1327
- if (expiresIn > 0) {
1328
- const timer = window.setTimeout(() => this.remove(params), expiresIn);
1329
- this.removalTimers.push({
1330
- params,
1331
- timer
1332
- });
1333
- }
1334
- }
1335
- get(params) {
1336
- return this.findCached(params) || this.findInFlight(params);
1337
- }
1338
- use(prefetched, params) {
1339
- const id = `${params.url.pathname}-${Date.now()}-${Math.random().toString(36).substring(7)}`;
1340
- this.currentUseId = id;
1341
- return prefetched.response.then((response) => {
1342
- if (this.currentUseId !== id) {
1343
- return;
1407
+ this.stop();
1408
+ this.id = window.setInterval(() => {
1409
+ if (!this.throttle || this.cbCount % 10 === 0) {
1410
+ this.cb();
1344
1411
  }
1345
- response.mergeParams({ ...params, onPrefetched: () => {
1346
- } });
1347
- this.removeSingleUseItems(params);
1348
- return response.handle();
1349
- });
1350
- }
1351
- removeSingleUseItems(params) {
1352
- this.cached = this.cached.filter((prefetched) => {
1353
- if (!this.paramsAreEqual(prefetched.params, params)) {
1354
- return true;
1412
+ if (this.throttle) {
1413
+ this.cbCount++;
1355
1414
  }
1356
- return !prefetched.singleUse;
1357
- });
1415
+ }, this.interval);
1358
1416
  }
1359
- findCached(params) {
1360
- return this.cached.find((prefetched) => {
1361
- return this.paramsAreEqual(prefetched.params, params);
1362
- }) || null;
1417
+ isInBackground(hidden) {
1418
+ this.throttle = this.keepAlive ? false : hidden;
1419
+ if (this.throttle) {
1420
+ this.cbCount = 0;
1421
+ }
1363
1422
  }
1364
- findInFlight(params) {
1365
- return this.inFlightRequests.find((prefetched) => {
1366
- return this.paramsAreEqual(prefetched.params, params);
1367
- }) || null;
1423
+ };
1424
+
1425
+ // src/polls.ts
1426
+ var Polls = class {
1427
+ constructor() {
1428
+ this.polls = [];
1429
+ this.setupVisibilityListener();
1368
1430
  }
1369
- withoutPurposePrefetchHeader(params) {
1370
- const newParams = (0, import_lodash_es3.cloneDeep)(params);
1371
- if (newParams.headers["Purpose"] === "prefetch") {
1372
- delete newParams.headers["Purpose"];
1373
- }
1374
- return newParams;
1431
+ add(interval, cb, options) {
1432
+ const poll = new Poll(interval, cb, options);
1433
+ this.polls.push(poll);
1434
+ return {
1435
+ stop: () => poll.stop(),
1436
+ start: () => poll.start()
1437
+ };
1375
1438
  }
1376
- paramsAreEqual(params1, params2) {
1377
- return objectsAreEqual(
1378
- this.withoutPurposePrefetchHeader(params1),
1379
- this.withoutPurposePrefetchHeader(params2),
1380
- [
1381
- "showProgress",
1382
- "replace",
1383
- "prefetch",
1384
- "preserveScroll",
1385
- "preserveState",
1386
- "onBefore",
1387
- "onBeforeUpdate",
1388
- "onStart",
1389
- "onProgress",
1390
- "onFinish",
1391
- "onCancel",
1392
- "onSuccess",
1393
- "onError",
1394
- "onPrefetched",
1395
- "onCancelToken",
1396
- "onPrefetching",
1397
- "async",
1398
- "viewTransition"
1399
- ]
1439
+ clear() {
1440
+ this.polls.forEach((poll) => poll.stop());
1441
+ this.polls = [];
1442
+ }
1443
+ setupVisibilityListener() {
1444
+ if (typeof document === "undefined") {
1445
+ return;
1446
+ }
1447
+ document.addEventListener(
1448
+ "visibilitychange",
1449
+ () => {
1450
+ this.polls.forEach((poll) => poll.isInBackground(document.hidden));
1451
+ },
1452
+ false
1400
1453
  );
1401
1454
  }
1402
1455
  };
1403
- var prefetchedRequests = new PrefetchedRequests();
1456
+ var polls = new Polls();
1404
1457
 
1405
1458
  // src/request.ts
1406
1459
  var import_axios = __toESM(require("axios"), 1);
@@ -1447,6 +1500,9 @@ var RequestParams = class _RequestParams {
1447
1500
  isPartial() {
1448
1501
  return this.params.only.length > 0 || this.params.except.length > 0 || this.params.reset.length > 0;
1449
1502
  }
1503
+ isDeferredPropsRequest() {
1504
+ return this.params.deferredProps === true;
1505
+ }
1450
1506
  onCancelToken(cb) {
1451
1507
  this.params.onCancelToken({
1452
1508
  cancel: cb
@@ -1705,6 +1761,9 @@ var Response = class _Response {
1705
1761
  mergeParams(params) {
1706
1762
  this.requestParams.merge(params);
1707
1763
  }
1764
+ getPageResponse() {
1765
+ return this.response.data = this.getDataFromResponse(this.response.data);
1766
+ }
1708
1767
  async handleNonInertiaResponse() {
1709
1768
  if (this.isLocationVisit()) {
1710
1769
  const locationUrl = hrefToUrl(this.getHeader("x-inertia-location"));
@@ -1755,11 +1814,12 @@ var Response = class _Response {
1755
1814
  }
1756
1815
  }
1757
1816
  async setPage() {
1758
- const pageResponse = this.getDataFromResponse(this.response.data);
1817
+ const pageResponse = this.getPageResponse();
1759
1818
  if (!this.shouldSetPage(pageResponse)) {
1760
1819
  return Promise.resolve();
1761
1820
  }
1762
1821
  this.mergeProps(pageResponse);
1822
+ page.mergeOncePropsIntoResponse(pageResponse);
1763
1823
  this.preserveEqualProps(pageResponse);
1764
1824
  await this.setRememberedState(pageResponse);
1765
1825
  this.requestParams.setPreserveOptions(pageResponse);
@@ -1864,6 +1924,12 @@ var Response = class _Response {
1864
1924
  pageResponse.props[prop] = deepMerge(currentProp, incomingProp, prop);
1865
1925
  });
1866
1926
  pageResponse.props = { ...page.get().props, ...pageResponse.props };
1927
+ if (this.requestParams.isDeferredPropsRequest()) {
1928
+ const currentErrors = page.get().props.errors;
1929
+ if (currentErrors && Object.keys(currentErrors).length > 0) {
1930
+ pageResponse.props.errors = currentErrors;
1931
+ }
1932
+ }
1867
1933
  if (page.get().scrollProps) {
1868
1934
  pageResponse.scrollProps = {
1869
1935
  ...page.get().scrollProps || {},
@@ -2026,8 +2092,13 @@ var Request = class _Request {
2026
2092
  "X-Requested-With": "XMLHttpRequest",
2027
2093
  "X-Inertia": true
2028
2094
  };
2029
- if (page.get().version) {
2030
- headers["X-Inertia-Version"] = page.get().version;
2095
+ const page2 = page.get();
2096
+ if (page2.version) {
2097
+ headers["X-Inertia-Version"] = page2.version;
2098
+ }
2099
+ const onceProps = Object.entries(page2.onceProps || {}).filter(([, onceProp]) => !onceProp.expiresAt || onceProp.expiresAt > Date.now()).map(([key]) => key);
2100
+ if (onceProps.length > 0) {
2101
+ headers["X-Inertia-Except-Once-Props"] = onceProps.join(",");
2031
2102
  }
2032
2103
  return headers;
2033
2104
  }
@@ -2078,6 +2149,7 @@ var Router = class {
2078
2149
  maxConcurrent: Infinity,
2079
2150
  interruptible: false
2080
2151
  });
2152
+ this.clientVisitQueue = new Queue();
2081
2153
  }
2082
2154
  init({
2083
2155
  initialPage,
@@ -2116,6 +2188,9 @@ var Router = class {
2116
2188
  return this.visit(url, { preserveState: true, ...options, method: "delete" });
2117
2189
  }
2118
2190
  reload(options = {}) {
2191
+ return this.doReload(options);
2192
+ }
2193
+ doReload(options = {}) {
2119
2194
  if (typeof window === "undefined") {
2120
2195
  return;
2121
2196
  }
@@ -2304,6 +2379,9 @@ var Router = class {
2304
2379
  this.clientVisit(params);
2305
2380
  }
2306
2381
  clientVisit(params, { replace = false } = {}) {
2382
+ this.clientVisitQueue.add(() => this.performClientVisit(params, { replace }));
2383
+ }
2384
+ performClientVisit(params, { replace = false } = {}) {
2307
2385
  const current = page.get();
2308
2386
  const props = typeof params.props === "function" ? params.props(current.props) : params.props ?? current.props;
2309
2387
  const { viewTransition, onError, onFinish, onSuccess, ...pageParams } = params;
@@ -2314,7 +2392,7 @@ var Router = class {
2314
2392
  };
2315
2393
  const preserveScroll = RequestParams.resolvePreserveOption(params.preserveScroll ?? false, page2);
2316
2394
  const preserveState = RequestParams.resolvePreserveOption(params.preserveState ?? false, page2);
2317
- page.set(page2, {
2395
+ return page.set(page2, {
2318
2396
  replace,
2319
2397
  preserveScroll,
2320
2398
  preserveState,
@@ -2322,10 +2400,11 @@ var Router = class {
2322
2400
  }).then(() => {
2323
2401
  const errors = page.get().props.errors || {};
2324
2402
  if (Object.keys(errors).length === 0) {
2325
- return onSuccess?.(page.get());
2403
+ onSuccess?.(page.get());
2404
+ return;
2326
2405
  }
2327
2406
  const scopedErrors = params.errorBag ? errors[params.errorBag || ""] || {} : errors;
2328
- return onError?.(scopedErrors);
2407
+ onError?.(scopedErrors);
2329
2408
  }).finally(() => onFinish?.(params));
2330
2409
  }
2331
2410
  getPrefetchParams(href, options) {
@@ -2421,7 +2500,7 @@ var Router = class {
2421
2500
  loadDeferredProps(deferred) {
2422
2501
  if (deferred) {
2423
2502
  Object.entries(deferred).forEach(([_, group]) => {
2424
- this.reload({ only: group });
2503
+ this.doReload({ only: group, deferredProps: true });
2425
2504
  });
2426
2505
  }
2427
2506
  }
@@ -2517,6 +2596,22 @@ var requestAnimationFrame = (cb, times = 1) => {
2517
2596
  }
2518
2597
  });
2519
2598
  };
2599
+ var getInitialPageFromDOM = (id, useScriptElement = false) => {
2600
+ if (typeof window === "undefined") {
2601
+ return null;
2602
+ }
2603
+ if (!useScriptElement) {
2604
+ const el = document.getElementById(id);
2605
+ if (el?.dataset.page) {
2606
+ return JSON.parse(el.dataset.page);
2607
+ }
2608
+ }
2609
+ const scriptEl = document.querySelector(`script[data-page="${id}"][type="application/json"]`);
2610
+ if (scriptEl?.textContent) {
2611
+ return JSON.parse(scriptEl.textContent);
2612
+ }
2613
+ return null;
2614
+ };
2520
2615
 
2521
2616
  // src/formObject.ts
2522
2617
  var import_lodash_es6 = require("lodash-es");