@inertiajs/core 2.2.19 → 2.2.21

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,529 @@ 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
+ for (const [group, deferredProps] of Object.entries(pageResponse.deferredProps ?? {})) {
599
+ const remaining = deferredProps.filter((prop) => pageResponse.props[prop] === void 0);
600
+ if (remaining.length > 0) {
601
+ pageResponse.deferredProps[group] = remaining;
602
+ } else {
603
+ delete pageResponse.deferredProps[group];
604
+ }
605
+ }
606
+ const oncePropExpiresIn = this.getShortestOncePropTtl(pageResponse);
607
+ if (oncePropExpiresIn === null) {
608
+ return;
609
+ }
610
+ const prefetchExpiresIn = prefetched.expiresAt - Date.now();
611
+ const expiresIn = Math.min(prefetchExpiresIn, oncePropExpiresIn);
612
+ if (expiresIn > 0) {
613
+ this.scheduleForRemoval(prefetched.params, expiresIn);
614
+ } else {
615
+ this.remove(prefetched.params);
616
+ }
617
+ });
618
+ });
619
+ }
620
+ getShortestOncePropTtl(page2) {
621
+ const expiryTimestamps = Object.values(page2.onceProps ?? {}).map((onceProp) => onceProp.expiresAt).filter((expiresAt) => !!expiresAt);
622
+ if (expiryTimestamps.length === 0) {
623
+ return null;
624
+ }
625
+ return Math.min(...expiryTimestamps) - Date.now();
626
+ }
627
+ };
628
+ var prefetchedRequests = new PrefetchedRequests();
629
+
630
+ // src/scroll.ts
631
+ var Scroll = class {
632
+ static save() {
633
+ history.saveScrollPositions(
634
+ Array.from(this.regions()).map((region) => ({
635
+ top: region.scrollTop,
636
+ left: region.scrollLeft
637
+ }))
638
+ );
639
+ }
640
+ static regions() {
641
+ return document.querySelectorAll("[scroll-region]");
642
+ }
643
+ static reset() {
644
+ const anchorHash = typeof window !== "undefined" ? window.location.hash : null;
645
+ if (!anchorHash) {
646
+ window.scrollTo(0, 0);
647
+ }
648
+ this.regions().forEach((region) => {
649
+ if (typeof region.scrollTo === "function") {
650
+ region.scrollTo(0, 0);
651
+ } else {
652
+ region.scrollTop = 0;
653
+ region.scrollLeft = 0;
654
+ }
655
+ });
656
+ this.save();
657
+ this.scrollToAnchor();
658
+ }
659
+ static scrollToAnchor() {
660
+ const anchorHash = typeof window !== "undefined" ? window.location.hash : null;
661
+ if (anchorHash) {
662
+ setTimeout(() => {
663
+ const anchorElement = document.getElementById(anchorHash.slice(1));
664
+ anchorElement ? anchorElement.scrollIntoView() : window.scrollTo(0, 0);
665
+ });
666
+ }
667
+ }
668
+ static restore(scrollRegions) {
669
+ if (typeof window === "undefined") {
670
+ return;
671
+ }
672
+ window.requestAnimationFrame(() => {
673
+ this.restoreDocument();
674
+ this.restoreScrollRegions(scrollRegions);
675
+ });
676
+ }
677
+ static restoreScrollRegions(scrollRegions) {
678
+ if (typeof window === "undefined") {
679
+ return;
680
+ }
681
+ this.regions().forEach((region, index) => {
682
+ const scrollPosition = scrollRegions[index];
683
+ if (!scrollPosition) {
684
+ return;
685
+ }
686
+ if (typeof region.scrollTo === "function") {
687
+ region.scrollTo(scrollPosition.left, scrollPosition.top);
688
+ } else {
689
+ region.scrollTop = scrollPosition.top;
690
+ region.scrollLeft = scrollPosition.left;
691
+ }
692
+ });
693
+ }
694
+ static restoreDocument() {
695
+ const scrollPosition = history.getDocumentScrollPosition();
696
+ window.scrollTo(scrollPosition.left, scrollPosition.top);
697
+ }
698
+ static onScroll(event) {
699
+ const target = event.target;
700
+ if (typeof target.hasAttribute === "function" && target.hasAttribute("scroll-region")) {
701
+ this.save();
702
+ }
703
+ }
704
+ static onWindowScroll() {
705
+ history.saveDocumentScrollPosition({
706
+ top: window.scrollY,
707
+ left: window.scrollX
708
+ });
709
+ }
710
+ };
711
+
712
+ // src/url.ts
713
+ var qs = __toESM(require("qs"), 1);
714
+
715
+ // src/files.ts
716
+ var isFile = (value) => typeof File !== "undefined" && value instanceof File || value instanceof Blob || typeof FileList !== "undefined" && value instanceof FileList && value.length > 0;
717
+ function hasFiles(data) {
718
+ 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));
719
+ }
720
+
721
+ // src/formData.ts
722
+ var isFormData = (value) => value instanceof FormData;
723
+ function objectToFormData(source, form = new FormData(), parentKey = null, queryStringArrayFormat = "brackets") {
724
+ source = source || {};
725
+ for (const key in source) {
726
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
727
+ append(form, composeKey(parentKey, key, "indices"), source[key], queryStringArrayFormat);
728
+ }
729
+ }
730
+ return form;
731
+ }
732
+ function composeKey(parent, key, format) {
733
+ if (!parent) {
734
+ return key;
735
+ }
736
+ return format === "brackets" ? `${parent}[]` : `${parent}[${key}]`;
737
+ }
738
+ function append(form, key, value, format) {
739
+ if (Array.isArray(value)) {
740
+ return Array.from(value.keys()).forEach(
741
+ (index) => append(form, composeKey(key, index.toString(), format), value[index], format)
742
+ );
743
+ } else if (value instanceof Date) {
744
+ return form.append(key, value.toISOString());
745
+ } else if (value instanceof File) {
746
+ return form.append(key, value, value.name);
747
+ } else if (value instanceof Blob) {
748
+ return form.append(key, value);
749
+ } else if (typeof value === "boolean") {
750
+ return form.append(key, value ? "1" : "0");
751
+ } else if (typeof value === "string") {
752
+ return form.append(key, value);
753
+ } else if (typeof value === "number") {
754
+ return form.append(key, `${value}`);
755
+ } else if (value === null || value === void 0) {
756
+ return form.append(key, "");
757
+ }
758
+ objectToFormData(value, form, key, format);
759
+ }
760
+
761
+ // src/url.ts
762
+ function hrefToUrl(href) {
763
+ return new URL(href.toString(), typeof window === "undefined" ? void 0 : window.location.toString());
764
+ }
765
+ var transformUrlAndData = (href, data, method, forceFormData, queryStringArrayFormat) => {
766
+ let url = typeof href === "string" ? hrefToUrl(href) : href;
767
+ if ((hasFiles(data) || forceFormData) && !isFormData(data)) {
768
+ if (config.get("form.forceIndicesArrayFormatInFormData")) {
769
+ queryStringArrayFormat = "indices";
770
+ }
771
+ data = objectToFormData(data, new FormData(), null, queryStringArrayFormat);
772
+ }
773
+ if (isFormData(data)) {
774
+ return [url, data];
775
+ }
776
+ const [_href, _data] = mergeDataIntoQueryString(method, url, data, queryStringArrayFormat);
777
+ return [hrefToUrl(_href), _data];
778
+ };
779
+ function mergeDataIntoQueryString(method, href, data, qsArrayFormat = "brackets") {
780
+ const hasDataForQueryString = method === "get" && !isFormData(data) && Object.keys(data).length > 0;
781
+ const hasHost = urlHasProtocol(href.toString());
782
+ const hasAbsolutePath = hasHost || href.toString().startsWith("/") || href.toString() === "";
783
+ const hasRelativePath = !hasAbsolutePath && !href.toString().startsWith("#") && !href.toString().startsWith("?");
784
+ const hasRelativePathWithDotPrefix = /^[.]{1,2}([/]|$)/.test(href.toString());
785
+ const hasSearch = href.toString().includes("?") || hasDataForQueryString;
786
+ const hasHash = href.toString().includes("#");
787
+ const url = new URL(href.toString(), typeof window === "undefined" ? "http://localhost" : window.location.toString());
788
+ if (hasDataForQueryString) {
789
+ const parseOptions = { ignoreQueryPrefix: true, parseArrays: false };
790
+ url.search = qs.stringify(
791
+ { ...qs.parse(url.search, parseOptions), ...data },
792
+ {
793
+ encodeValuesOnly: true,
794
+ arrayFormat: qsArrayFormat
795
+ }
796
+ );
797
+ }
798
+ return [
799
+ [
800
+ hasHost ? `${url.protocol}//${url.host}` : "",
801
+ hasAbsolutePath ? url.pathname : "",
802
+ hasRelativePath ? url.pathname.substring(hasRelativePathWithDotPrefix ? 0 : 1) : "",
803
+ hasSearch ? url.search : "",
804
+ hasHash ? url.hash : ""
805
+ ].join(""),
806
+ hasDataForQueryString ? {} : data
807
+ ];
808
+ }
809
+ function urlWithoutHash(url) {
810
+ url = new URL(url.href);
811
+ url.hash = "";
812
+ return url;
813
+ }
814
+ var setHashIfSameUrl = (originUrl, destinationUrl) => {
815
+ if (originUrl.hash && !destinationUrl.hash && urlWithoutHash(originUrl).href === destinationUrl.href) {
816
+ destinationUrl.hash = originUrl.hash;
817
+ }
818
+ };
819
+ var isSameUrlWithoutHash = (url1, url2) => {
820
+ return urlWithoutHash(url1).href === urlWithoutHash(url2).href;
821
+ };
822
+ function isUrlMethodPair(href) {
823
+ return href !== null && typeof href === "object" && href !== void 0 && "url" in href && "method" in href;
824
+ }
825
+ function urlHasProtocol(url) {
826
+ return /^[a-z][a-z0-9+.-]*:\/\//i.test(url);
827
+ }
828
+ function urlToString(url, absolute) {
829
+ const urlObj = typeof url === "string" ? hrefToUrl(url) : url;
830
+ return absolute ? `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}${urlObj.search}${urlObj.hash}` : `${urlObj.pathname}${urlObj.search}${urlObj.hash}`;
831
+ }
832
+
833
+ // src/page.ts
834
+ var CurrentPage = class {
835
+ constructor() {
836
+ this.componentId = {};
837
+ this.listeners = [];
838
+ this.isFirstPageLoad = true;
839
+ this.cleared = false;
840
+ this.pendingDeferredProps = null;
841
+ }
842
+ init({
843
+ initialPage,
844
+ swapComponent,
845
+ resolveComponent
846
+ }) {
847
+ this.page = initialPage;
848
+ this.swapComponent = swapComponent;
849
+ this.resolveComponent = resolveComponent;
850
+ return this;
547
851
  }
548
852
  set(page2, {
549
853
  replace = false,
@@ -581,6 +885,9 @@ var CurrentPage = class {
581
885
  }
582
886
  this.page = page2;
583
887
  this.cleared = false;
888
+ if (this.hasOnceProps()) {
889
+ prefetchedRequests.updateCachedOncePropsFromCurrentPage();
890
+ }
584
891
  if (isNewComponent) {
585
892
  this.fireEventsFor("newComponent");
586
893
  }
@@ -629,6 +936,9 @@ var CurrentPage = class {
629
936
  get() {
630
937
  return this.page;
631
938
  }
939
+ hasOnceProps() {
940
+ return Object.keys(this.page.onceProps ?? {}).length > 0;
941
+ }
632
942
  merge(data) {
633
943
  this.page = { ...this.page, ...data };
634
944
  }
@@ -671,6 +981,18 @@ var CurrentPage = class {
671
981
  fireEventsFor(event) {
672
982
  this.listeners.filter((listener) => listener.event === event).forEach((listener) => listener.callback());
673
983
  }
984
+ mergeOncePropsIntoResponse(response, { force = false } = {}) {
985
+ Object.entries(response.onceProps ?? {}).forEach(([key, onceProp]) => {
986
+ const existingOnceProp = this.page.onceProps?.[key];
987
+ if (existingOnceProp === void 0) {
988
+ return;
989
+ }
990
+ if (force || response.props[onceProp.prop] === void 0) {
991
+ response.props[onceProp.prop] = this.page.props[existingOnceProp.prop];
992
+ response.onceProps[key].expiresAt = existingOnceProp.expiresAt;
993
+ }
994
+ });
995
+ }
674
996
  };
675
997
  var page = new CurrentPage();
676
998
 
@@ -754,7 +1076,7 @@ var History = class {
754
1076
  } catch {
755
1077
  return {
756
1078
  ...page2,
757
- props: (0, import_lodash_es2.cloneDeep)(page2.props)
1079
+ props: (0, import_lodash_es3.cloneDeep)(page2.props)
758
1080
  };
759
1081
  }
760
1082
  }
@@ -793,7 +1115,7 @@ var History = class {
793
1115
  if (!window.history.state?.page) {
794
1116
  return;
795
1117
  }
796
- if ((0, import_lodash_es2.isEqual)(this.getScrollRegions(), scrollRegions)) {
1118
+ if ((0, import_lodash_es3.isEqual)(this.getScrollRegions(), scrollRegions)) {
797
1119
  return;
798
1120
  }
799
1121
  return this.doReplaceState({
@@ -809,7 +1131,7 @@ var History = class {
809
1131
  if (!window.history.state?.page) {
810
1132
  return;
811
1133
  }
812
- if ((0, import_lodash_es2.isEqual)(this.getDocumentScrollPosition(), scrollRegion)) {
1134
+ if ((0, import_lodash_es3.isEqual)(this.getDocumentScrollPosition(), scrollRegion)) {
813
1135
  return;
814
1136
  }
815
1137
  return this.doReplaceState({
@@ -863,544 +1185,283 @@ var History = class {
863
1185
  doPushState(data, url) {
864
1186
  return Promise.resolve().then(() => window.history.pushState(data, "", url));
865
1187
  }
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
- }
1188
+ getState(key, defaultValue) {
1189
+ return this.current?.[key] ?? defaultValue;
1088
1190
  }
1089
- start() {
1090
- if (typeof window === "undefined") {
1091
- return;
1191
+ deleteState(key) {
1192
+ if (this.current[key] !== void 0) {
1193
+ delete this.current[key];
1194
+ this.replaceState(this.current);
1092
1195
  }
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);
1102
1196
  }
1103
- isInBackground(hidden) {
1104
- this.throttle = this.keepAlive ? false : hidden;
1105
- if (this.throttle) {
1106
- this.cbCount = 0;
1197
+ clearInitialState(key) {
1198
+ if (this.initialState && this.initialState[key] !== void 0) {
1199
+ delete this.initialState[key];
1107
1200
  }
1108
1201
  }
1109
- };
1110
-
1111
- // src/polls.ts
1112
- var Polls = class {
1113
- constructor() {
1114
- this.polls = [];
1115
- this.setupVisibilityListener();
1116
- }
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
- };
1202
+ hasAnyState() {
1203
+ return !!this.getAllState();
1124
1204
  }
1125
1205
  clear() {
1126
- this.polls.forEach((poll) => poll.stop());
1127
- this.polls = [];
1206
+ SessionStorage.remove(historySessionStorageKeys.key);
1207
+ SessionStorage.remove(historySessionStorageKeys.iv);
1128
1208
  }
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
- );
1209
+ setCurrent(page2) {
1210
+ this.current = page2;
1211
+ }
1212
+ isValidState(state) {
1213
+ return !!state.page;
1214
+ }
1215
+ getAllState() {
1216
+ return this.current;
1140
1217
  }
1141
1218
  };
1142
- var polls = new Polls();
1143
-
1144
- // src/prefetched.ts
1145
- var import_lodash_es3 = require("lodash-es");
1219
+ if (typeof window !== "undefined" && window.history.scrollRestoration) {
1220
+ window.history.scrollRestoration = "manual";
1221
+ }
1222
+ var history = new History();
1146
1223
 
1147
- // src/objectUtils.ts
1148
- var objectsAreEqual = (obj1, obj2, excludeKeys) => {
1149
- if (obj1 === obj2) {
1150
- return true;
1224
+ // src/eventHandler.ts
1225
+ var EventHandler = class {
1226
+ constructor() {
1227
+ this.internalListeners = [];
1151
1228
  }
1152
- for (const key in obj1) {
1153
- if (excludeKeys.includes(key)) {
1154
- continue;
1155
- }
1156
- if (obj1[key] === obj2[key]) {
1157
- continue;
1229
+ init() {
1230
+ if (typeof window !== "undefined") {
1231
+ window.addEventListener("popstate", this.handlePopstateEvent.bind(this));
1232
+ window.addEventListener("scroll", debounce(Scroll.onWindowScroll.bind(Scroll), 100), true);
1158
1233
  }
1159
- if (!compareValues(obj1[key], obj2[key])) {
1160
- return false;
1234
+ if (typeof document !== "undefined") {
1235
+ document.addEventListener("scroll", debounce(Scroll.onScroll.bind(Scroll), 100), true);
1161
1236
  }
1162
1237
  }
1163
- for (const key in obj2) {
1164
- if (excludeKeys.includes(key)) {
1165
- continue;
1166
- }
1167
- if (!(key in obj1)) {
1168
- return false;
1169
- }
1238
+ onGlobalEvent(type, callback) {
1239
+ const listener = ((event) => {
1240
+ const response = callback(event);
1241
+ if (event.cancelable && !event.defaultPrevented && response === false) {
1242
+ event.preventDefault();
1243
+ }
1244
+ });
1245
+ return this.registerListener(`inertia:${type}`, listener);
1170
1246
  }
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;
1247
+ on(event, callback) {
1248
+ this.internalListeners.push({ event, listener: callback });
1249
+ return () => {
1250
+ this.internalListeners = this.internalListeners.filter((listener) => listener.listener !== callback);
1251
+ };
1181
1252
  }
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;
1253
+ onMissingHistoryItem() {
1254
+ page.clear();
1255
+ this.fireInternalEvent("missingHistoryItem");
1195
1256
  }
1196
- for (const [unit, conversion] of Object.entries(conversionMap)) {
1197
- if (time.endsWith(unit)) {
1198
- return parseFloat(time) * conversion;
1257
+ fireInternalEvent(event, ...args) {
1258
+ this.internalListeners.filter((listener) => listener.event === event).forEach((listener) => listener.listener(...args));
1259
+ }
1260
+ registerListener(type, listener) {
1261
+ document.addEventListener(type, listener);
1262
+ return () => document.removeEventListener(type, listener);
1263
+ }
1264
+ handlePopstateEvent(event) {
1265
+ const state = event.state || null;
1266
+ if (state === null) {
1267
+ const url = hrefToUrl(page.get().url);
1268
+ url.hash = window.location.hash;
1269
+ history.replaceState({ ...page.get(), url: url.href });
1270
+ Scroll.reset();
1271
+ return;
1272
+ }
1273
+ if (!history.isValidState(state)) {
1274
+ return this.onMissingHistoryItem();
1199
1275
  }
1276
+ history.decrypt(state.page).then((data) => {
1277
+ if (page.get().version !== data.version) {
1278
+ this.onMissingHistoryItem();
1279
+ return;
1280
+ }
1281
+ router.cancelAll();
1282
+ page.setQuietly(data, { preserveState: false }).then(() => {
1283
+ Scroll.restore(history.getScrollRegions());
1284
+ fireNavigateEvent(page.get());
1285
+ });
1286
+ }).catch(() => {
1287
+ this.onMissingHistoryItem();
1288
+ });
1200
1289
  }
1201
- return parseInt(time);
1202
1290
  };
1291
+ var eventHandler = new EventHandler();
1203
1292
 
1204
- // src/prefetched.ts
1205
- var PrefetchedRequests = class {
1293
+ // src/navigationType.ts
1294
+ var NavigationType = class {
1206
1295
  constructor() {
1207
- this.cached = [];
1208
- this.inFlightRequests = [];
1209
- this.removalTimers = [];
1210
- this.currentUseId = null;
1296
+ this.type = this.resolveType();
1211
1297
  }
1212
- add(params, sendFunc, { cacheFor, cacheTags }) {
1213
- const inFlight = this.findInFlight(params);
1214
- if (inFlight) {
1215
- return Promise.resolve();
1298
+ resolveType() {
1299
+ if (typeof window === "undefined") {
1300
+ return "navigate";
1216
1301
  }
1217
- const existing = this.findCached(params);
1218
- if (!params.fresh && existing && existing.staleTimestamp > Date.now()) {
1219
- return Promise.resolve();
1302
+ if (window.performance && window.performance.getEntriesByType && window.performance.getEntriesByType("navigation").length > 0) {
1303
+ return window.performance.getEntriesByType("navigation")[0].type;
1220
1304
  }
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;
1305
+ return "navigate";
1306
+ }
1307
+ get() {
1308
+ return this.type;
1309
+ }
1310
+ isBackForward() {
1311
+ return this.type === "back_forward";
1272
1312
  }
1273
- removeAll() {
1274
- this.cached = [];
1275
- this.removalTimers.forEach((removalTimer) => {
1276
- clearTimeout(removalTimer.timer);
1277
- });
1278
- this.removalTimers = [];
1313
+ isReload() {
1314
+ return this.type === "reload";
1279
1315
  }
1280
- removeByTags(tags) {
1281
- this.cached = this.cached.filter((prefetched) => {
1282
- return !prefetched.tags.some((tag) => tags.includes(tag));
1283
- });
1316
+ };
1317
+ var navigationType = new NavigationType();
1318
+
1319
+ // src/initialVisit.ts
1320
+ var InitialVisit = class {
1321
+ static handle() {
1322
+ this.clearRememberedStateOnReload();
1323
+ const scenarios = [this.handleBackForward, this.handleLocation, this.handleDefault];
1324
+ scenarios.find((handler) => handler.bind(this)());
1284
1325
  }
1285
- remove(params) {
1286
- this.cached = this.cached.filter((prefetched) => {
1287
- return !this.paramsAreEqual(prefetched.params, params);
1288
- });
1289
- this.clearTimer(params);
1326
+ static clearRememberedStateOnReload() {
1327
+ if (navigationType.isReload()) {
1328
+ history.deleteState(history.rememberedState);
1329
+ history.clearInitialState(history.rememberedState);
1330
+ }
1290
1331
  }
1291
- removeFromInFlight(params) {
1292
- this.inFlightRequests = this.inFlightRequests.filter((prefetching) => {
1293
- return !this.paramsAreEqual(prefetching.params, params);
1332
+ static handleBackForward() {
1333
+ if (!navigationType.isBackForward() || !history.hasAnyState()) {
1334
+ return false;
1335
+ }
1336
+ const scrollRegions = history.getScrollRegions();
1337
+ history.decrypt().then((data) => {
1338
+ page.set(data, { preserveScroll: true, preserveState: true }).then(() => {
1339
+ Scroll.restore(scrollRegions);
1340
+ fireNavigateEvent(page.get());
1341
+ });
1342
+ }).catch(() => {
1343
+ eventHandler.onMissingHistoryItem();
1294
1344
  });
1345
+ return true;
1295
1346
  }
1296
- extractStaleValues(cacheFor) {
1297
- const [stale, expires] = this.cacheForToStaleAndExpires(cacheFor);
1298
- return [timeToMs(stale), timeToMs(expires)];
1299
- }
1300
- cacheForToStaleAndExpires(cacheFor) {
1301
- if (!Array.isArray(cacheFor)) {
1302
- return [cacheFor, cacheFor];
1347
+ /**
1348
+ * @link https://inertiajs.com/redirects#external-redirects
1349
+ */
1350
+ static handleLocation() {
1351
+ if (!SessionStorage.exists(SessionStorage.locationVisitKey)) {
1352
+ return false;
1303
1353
  }
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]];
1354
+ const locationVisit = SessionStorage.get(SessionStorage.locationVisitKey) || {};
1355
+ SessionStorage.remove(SessionStorage.locationVisitKey);
1356
+ if (typeof window !== "undefined") {
1357
+ page.setUrlHash(window.location.hash);
1311
1358
  }
1359
+ history.decrypt(page.get()).then(() => {
1360
+ const rememberedState = history.getState(history.rememberedState, {});
1361
+ const scrollRegions = history.getScrollRegions();
1362
+ page.remember(rememberedState);
1363
+ page.set(page.get(), {
1364
+ preserveScroll: locationVisit.preserveScroll,
1365
+ preserveState: true
1366
+ }).then(() => {
1367
+ if (locationVisit.preserveScroll) {
1368
+ Scroll.restore(scrollRegions);
1369
+ }
1370
+ fireNavigateEvent(page.get());
1371
+ });
1372
+ }).catch(() => {
1373
+ eventHandler.onMissingHistoryItem();
1374
+ });
1375
+ return true;
1312
1376
  }
1313
- clearTimer(params) {
1314
- const timer = this.removalTimers.find((removalTimer) => {
1315
- return this.paramsAreEqual(removalTimer.params, params);
1377
+ static handleDefault() {
1378
+ if (typeof window !== "undefined") {
1379
+ page.setUrlHash(window.location.hash);
1380
+ }
1381
+ page.set(page.get(), { preserveScroll: true, preserveState: true }).then(() => {
1382
+ if (navigationType.isReload()) {
1383
+ Scroll.restore(history.getScrollRegions());
1384
+ } else {
1385
+ Scroll.scrollToAnchor();
1386
+ }
1387
+ fireNavigateEvent(page.get());
1316
1388
  });
1317
- if (timer) {
1318
- clearTimeout(timer.timer);
1319
- this.removalTimers = this.removalTimers.filter((removalTimer) => removalTimer !== timer);
1389
+ }
1390
+ };
1391
+
1392
+ // src/poll.ts
1393
+ var Poll = class {
1394
+ constructor(interval, cb, options) {
1395
+ this.id = null;
1396
+ this.throttle = false;
1397
+ this.keepAlive = false;
1398
+ this.cbCount = 0;
1399
+ this.keepAlive = options.keepAlive ?? false;
1400
+ this.cb = cb;
1401
+ this.interval = interval;
1402
+ if (options.autoStart ?? true) {
1403
+ this.start();
1320
1404
  }
1321
1405
  }
1322
- scheduleForRemoval(params, expiresIn) {
1406
+ stop() {
1407
+ if (this.id) {
1408
+ clearInterval(this.id);
1409
+ }
1410
+ }
1411
+ start() {
1323
1412
  if (typeof window === "undefined") {
1324
1413
  return;
1325
1414
  }
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;
1415
+ this.stop();
1416
+ this.id = window.setInterval(() => {
1417
+ if (!this.throttle || this.cbCount % 10 === 0) {
1418
+ this.cb();
1344
1419
  }
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;
1420
+ if (this.throttle) {
1421
+ this.cbCount++;
1355
1422
  }
1356
- return !prefetched.singleUse;
1357
- });
1423
+ }, this.interval);
1358
1424
  }
1359
- findCached(params) {
1360
- return this.cached.find((prefetched) => {
1361
- return this.paramsAreEqual(prefetched.params, params);
1362
- }) || null;
1425
+ isInBackground(hidden) {
1426
+ this.throttle = this.keepAlive ? false : hidden;
1427
+ if (this.throttle) {
1428
+ this.cbCount = 0;
1429
+ }
1363
1430
  }
1364
- findInFlight(params) {
1365
- return this.inFlightRequests.find((prefetched) => {
1366
- return this.paramsAreEqual(prefetched.params, params);
1367
- }) || null;
1431
+ };
1432
+
1433
+ // src/polls.ts
1434
+ var Polls = class {
1435
+ constructor() {
1436
+ this.polls = [];
1437
+ this.setupVisibilityListener();
1368
1438
  }
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;
1439
+ add(interval, cb, options) {
1440
+ const poll = new Poll(interval, cb, options);
1441
+ this.polls.push(poll);
1442
+ return {
1443
+ stop: () => poll.stop(),
1444
+ start: () => poll.start()
1445
+ };
1375
1446
  }
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
- ]
1447
+ clear() {
1448
+ this.polls.forEach((poll) => poll.stop());
1449
+ this.polls = [];
1450
+ }
1451
+ setupVisibilityListener() {
1452
+ if (typeof document === "undefined") {
1453
+ return;
1454
+ }
1455
+ document.addEventListener(
1456
+ "visibilitychange",
1457
+ () => {
1458
+ this.polls.forEach((poll) => poll.isInBackground(document.hidden));
1459
+ },
1460
+ false
1400
1461
  );
1401
1462
  }
1402
1463
  };
1403
- var prefetchedRequests = new PrefetchedRequests();
1464
+ var polls = new Polls();
1404
1465
 
1405
1466
  // src/request.ts
1406
1467
  var import_axios = __toESM(require("axios"), 1);
@@ -1447,6 +1508,9 @@ var RequestParams = class _RequestParams {
1447
1508
  isPartial() {
1448
1509
  return this.params.only.length > 0 || this.params.except.length > 0 || this.params.reset.length > 0;
1449
1510
  }
1511
+ isDeferredPropsRequest() {
1512
+ return this.params.deferredProps === true;
1513
+ }
1450
1514
  onCancelToken(cb) {
1451
1515
  this.params.onCancelToken({
1452
1516
  cancel: cb
@@ -1705,6 +1769,9 @@ var Response = class _Response {
1705
1769
  mergeParams(params) {
1706
1770
  this.requestParams.merge(params);
1707
1771
  }
1772
+ getPageResponse() {
1773
+ return this.response.data = this.getDataFromResponse(this.response.data);
1774
+ }
1708
1775
  async handleNonInertiaResponse() {
1709
1776
  if (this.isLocationVisit()) {
1710
1777
  const locationUrl = hrefToUrl(this.getHeader("x-inertia-location"));
@@ -1755,11 +1822,12 @@ var Response = class _Response {
1755
1822
  }
1756
1823
  }
1757
1824
  async setPage() {
1758
- const pageResponse = this.getDataFromResponse(this.response.data);
1825
+ const pageResponse = this.getPageResponse();
1759
1826
  if (!this.shouldSetPage(pageResponse)) {
1760
1827
  return Promise.resolve();
1761
1828
  }
1762
1829
  this.mergeProps(pageResponse);
1830
+ page.mergeOncePropsIntoResponse(pageResponse);
1763
1831
  this.preserveEqualProps(pageResponse);
1764
1832
  await this.setRememberedState(pageResponse);
1765
1833
  this.requestParams.setPreserveOptions(pageResponse);
@@ -1864,12 +1932,24 @@ var Response = class _Response {
1864
1932
  pageResponse.props[prop] = deepMerge(currentProp, incomingProp, prop);
1865
1933
  });
1866
1934
  pageResponse.props = { ...page.get().props, ...pageResponse.props };
1935
+ if (this.requestParams.isDeferredPropsRequest()) {
1936
+ const currentErrors = page.get().props.errors;
1937
+ if (currentErrors && Object.keys(currentErrors).length > 0) {
1938
+ pageResponse.props.errors = currentErrors;
1939
+ }
1940
+ }
1867
1941
  if (page.get().scrollProps) {
1868
1942
  pageResponse.scrollProps = {
1869
1943
  ...page.get().scrollProps || {},
1870
1944
  ...pageResponse.scrollProps || {}
1871
1945
  };
1872
1946
  }
1947
+ if (page.hasOnceProps()) {
1948
+ pageResponse.onceProps = {
1949
+ ...page.get().onceProps || {},
1950
+ ...pageResponse.onceProps || {}
1951
+ };
1952
+ }
1873
1953
  }
1874
1954
  mergeOrMatchItems(existingItems, newItems, matchProp, matchPropsOn, shouldAppend = true) {
1875
1955
  const items = Array.isArray(existingItems) ? existingItems : [];
@@ -2026,8 +2106,18 @@ var Request = class _Request {
2026
2106
  "X-Requested-With": "XMLHttpRequest",
2027
2107
  "X-Inertia": true
2028
2108
  };
2029
- if (page.get().version) {
2030
- headers["X-Inertia-Version"] = page.get().version;
2109
+ const page2 = page.get();
2110
+ if (page2.version) {
2111
+ headers["X-Inertia-Version"] = page2.version;
2112
+ }
2113
+ const onceProps = Object.entries(page2.onceProps || {}).filter(([, onceProp]) => {
2114
+ if (page2.props[onceProp.prop] === void 0) {
2115
+ return false;
2116
+ }
2117
+ return !onceProp.expiresAt || onceProp.expiresAt > Date.now();
2118
+ }).map(([key]) => key);
2119
+ if (onceProps.length > 0) {
2120
+ headers["X-Inertia-Except-Once-Props"] = onceProps.join(",");
2031
2121
  }
2032
2122
  return headers;
2033
2123
  }
@@ -2078,6 +2168,7 @@ var Router = class {
2078
2168
  maxConcurrent: Infinity,
2079
2169
  interruptible: false
2080
2170
  });
2171
+ this.clientVisitQueue = new Queue();
2081
2172
  }
2082
2173
  init({
2083
2174
  initialPage,
@@ -2116,6 +2207,9 @@ var Router = class {
2116
2207
  return this.visit(url, { preserveState: true, ...options, method: "delete" });
2117
2208
  }
2118
2209
  reload(options = {}) {
2210
+ return this.doReload(options);
2211
+ }
2212
+ doReload(options = {}) {
2119
2213
  if (typeof window === "undefined") {
2120
2214
  return;
2121
2215
  }
@@ -2304,6 +2398,9 @@ var Router = class {
2304
2398
  this.clientVisit(params);
2305
2399
  }
2306
2400
  clientVisit(params, { replace = false } = {}) {
2401
+ this.clientVisitQueue.add(() => this.performClientVisit(params, { replace }));
2402
+ }
2403
+ performClientVisit(params, { replace = false } = {}) {
2307
2404
  const current = page.get();
2308
2405
  const props = typeof params.props === "function" ? params.props(current.props) : params.props ?? current.props;
2309
2406
  const { viewTransition, onError, onFinish, onSuccess, ...pageParams } = params;
@@ -2314,7 +2411,7 @@ var Router = class {
2314
2411
  };
2315
2412
  const preserveScroll = RequestParams.resolvePreserveOption(params.preserveScroll ?? false, page2);
2316
2413
  const preserveState = RequestParams.resolvePreserveOption(params.preserveState ?? false, page2);
2317
- page.set(page2, {
2414
+ return page.set(page2, {
2318
2415
  replace,
2319
2416
  preserveScroll,
2320
2417
  preserveState,
@@ -2322,10 +2419,11 @@ var Router = class {
2322
2419
  }).then(() => {
2323
2420
  const errors = page.get().props.errors || {};
2324
2421
  if (Object.keys(errors).length === 0) {
2325
- return onSuccess?.(page.get());
2422
+ onSuccess?.(page.get());
2423
+ return;
2326
2424
  }
2327
2425
  const scopedErrors = params.errorBag ? errors[params.errorBag || ""] || {} : errors;
2328
- return onError?.(scopedErrors);
2426
+ onError?.(scopedErrors);
2329
2427
  }).finally(() => onFinish?.(params));
2330
2428
  }
2331
2429
  getPrefetchParams(href, options) {
@@ -2421,7 +2519,7 @@ var Router = class {
2421
2519
  loadDeferredProps(deferred) {
2422
2520
  if (deferred) {
2423
2521
  Object.entries(deferred).forEach(([_, group]) => {
2424
- this.reload({ only: group });
2522
+ this.doReload({ only: group, deferredProps: true });
2425
2523
  });
2426
2524
  }
2427
2525
  }
@@ -2517,6 +2615,22 @@ var requestAnimationFrame = (cb, times = 1) => {
2517
2615
  }
2518
2616
  });
2519
2617
  };
2618
+ var getInitialPageFromDOM = (id, useScriptElement = false) => {
2619
+ if (typeof window === "undefined") {
2620
+ return null;
2621
+ }
2622
+ if (!useScriptElement) {
2623
+ const el = document.getElementById(id);
2624
+ if (el?.dataset.page) {
2625
+ return JSON.parse(el.dataset.page);
2626
+ }
2627
+ }
2628
+ const scriptEl = document.querySelector(`script[data-page="${id}"][type="application/json"]`);
2629
+ if (scriptEl?.textContent) {
2630
+ return JSON.parse(scriptEl.textContent);
2631
+ }
2632
+ return null;
2633
+ };
2520
2634
 
2521
2635
  // src/formObject.ts
2522
2636
  var import_lodash_es6 = require("lodash-es");