@inertiajs/core 3.1.0 → 3.2.0

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
@@ -281,6 +281,15 @@ import { cloneDeep } from "es-toolkit";
281
281
  import { get as get2 } from "es-toolkit/compat";
282
282
 
283
283
  // src/objectUtils.ts
284
+ var stripTopLevelUndefined = (obj) => {
285
+ const result = {};
286
+ for (const key of Object.keys(obj)) {
287
+ if (obj[key] !== void 0) {
288
+ result[key] = obj[key];
289
+ }
290
+ }
291
+ return result;
292
+ };
284
293
  var objectsAreEqual = (obj1, obj2, excludeKeys) => {
285
294
  if (obj1 === obj2) {
286
295
  return true;
@@ -1692,14 +1701,21 @@ var InitialVisit = class {
1692
1701
 
1693
1702
  // src/poll.ts
1694
1703
  var Poll = class {
1695
- id = null;
1704
+ intervalId = null;
1705
+ timeoutId = null;
1696
1706
  throttle = false;
1697
1707
  keepAlive = false;
1698
1708
  cb;
1699
1709
  interval;
1700
1710
  cbCount = 0;
1711
+ mode;
1712
+ inFlight = false;
1713
+ currentCancel = null;
1714
+ stopped = true;
1715
+ instanceId = 0;
1701
1716
  constructor(interval, cb, options) {
1702
1717
  this.keepAlive = options.keepAlive ?? false;
1718
+ this.mode = options.mode ?? "overlap";
1703
1719
  this.cb = cb;
1704
1720
  this.interval = interval;
1705
1721
  if (options.autoStart ?? true) {
@@ -1707,8 +1723,17 @@ var Poll = class {
1707
1723
  }
1708
1724
  }
1709
1725
  stop() {
1710
- if (this.id) {
1711
- clearInterval(this.id);
1726
+ this.stopped = true;
1727
+ this.instanceId++;
1728
+ this.inFlight = false;
1729
+ this.currentCancel = null;
1730
+ if (this.intervalId) {
1731
+ clearInterval(this.intervalId);
1732
+ this.intervalId = null;
1733
+ }
1734
+ if (this.timeoutId) {
1735
+ clearTimeout(this.timeoutId);
1736
+ this.timeoutId = null;
1712
1737
  }
1713
1738
  }
1714
1739
  start() {
@@ -1716,14 +1741,12 @@ var Poll = class {
1716
1741
  return;
1717
1742
  }
1718
1743
  this.stop();
1719
- this.id = window.setInterval(() => {
1720
- if (!this.throttle || this.cbCount % 10 === 0) {
1721
- this.cb();
1722
- }
1723
- if (this.throttle) {
1724
- this.cbCount++;
1725
- }
1726
- }, this.interval);
1744
+ this.stopped = false;
1745
+ if (this.mode === "rest") {
1746
+ this.scheduleNext();
1747
+ return;
1748
+ }
1749
+ this.intervalId = window.setInterval(() => this.tick(), this.interval);
1727
1750
  }
1728
1751
  isInBackground(hidden2) {
1729
1752
  this.throttle = this.keepAlive ? false : hidden2;
@@ -1731,6 +1754,50 @@ var Poll = class {
1731
1754
  this.cbCount = 0;
1732
1755
  }
1733
1756
  }
1757
+ scheduleNext() {
1758
+ if (this.stopped) {
1759
+ return;
1760
+ }
1761
+ this.timeoutId = window.setTimeout(() => {
1762
+ this.timeoutId = null;
1763
+ this.tick();
1764
+ }, this.interval);
1765
+ }
1766
+ tick() {
1767
+ if (!this.throttle || this.cbCount % 10 === 0) {
1768
+ this.fire();
1769
+ } else if (this.mode === "rest") {
1770
+ this.scheduleNext();
1771
+ }
1772
+ if (this.throttle) {
1773
+ this.cbCount++;
1774
+ }
1775
+ }
1776
+ fire() {
1777
+ if (this.inFlight && this.mode === "cancel") {
1778
+ this.currentCancel?.();
1779
+ }
1780
+ const instance = this.instanceId;
1781
+ this.cb({
1782
+ onStart: (cancel) => {
1783
+ if (instance !== this.instanceId) {
1784
+ return;
1785
+ }
1786
+ this.inFlight = true;
1787
+ this.currentCancel = cancel;
1788
+ },
1789
+ onFinish: () => {
1790
+ if (instance !== this.instanceId) {
1791
+ return;
1792
+ }
1793
+ this.inFlight = false;
1794
+ this.currentCancel = null;
1795
+ if (this.mode === "rest") {
1796
+ this.scheduleNext();
1797
+ }
1798
+ }
1799
+ });
1800
+ }
1734
1801
  };
1735
1802
 
1736
1803
  // src/polls.ts
@@ -1739,12 +1806,19 @@ var Polls = class {
1739
1806
  constructor() {
1740
1807
  this.setupVisibilityListener();
1741
1808
  }
1809
+ get count() {
1810
+ return this.polls.length;
1811
+ }
1742
1812
  add(interval, cb, options) {
1743
1813
  const poll = new Poll(interval, cb, options);
1744
1814
  this.polls.push(poll);
1745
1815
  return {
1746
1816
  stop: () => poll.stop(),
1747
- start: () => poll.start()
1817
+ start: () => poll.start(),
1818
+ destroy: () => {
1819
+ poll.stop();
1820
+ this.polls = this.polls.filter((p) => p !== poll);
1821
+ }
1748
1822
  };
1749
1823
  }
1750
1824
  clear() {
@@ -2919,9 +2993,23 @@ var Router = class {
2919
2993
  }
2920
2994
  return eventHandler.onGlobalEvent(type, callback);
2921
2995
  }
2996
+ once(type, callback) {
2997
+ if (typeof window === "undefined") {
2998
+ return () => {
2999
+ };
3000
+ }
3001
+ const remove2 = this.on(type, (event) => {
3002
+ remove2();
3003
+ return callback(event);
3004
+ });
3005
+ return remove2;
3006
+ }
2922
3007
  hasPendingOptimistic() {
2923
3008
  return this.asyncRequestStream.hasPendingOptimistic();
2924
3009
  }
3010
+ get activePolls() {
3011
+ return polls.count;
3012
+ }
2925
3013
  cancelAll({ async = true, prefetch = true, sync = true } = {}) {
2926
3014
  if (async) {
2927
3015
  this.asyncRequestStream.cancelInFlight({ prefetch });
@@ -2931,10 +3019,29 @@ var Router = class {
2931
3019
  }
2932
3020
  }
2933
3021
  poll(interval, requestOptions = {}, options = {}) {
2934
- return polls.add(interval, () => this.reload({ preserveErrors: true, ...requestOptions }), {
2935
- autoStart: options.autoStart ?? true,
2936
- keepAlive: options.keepAlive ?? false
2937
- });
3022
+ return polls.add(
3023
+ interval,
3024
+ ({ onStart, onFinish }) => {
3025
+ const resolved = typeof requestOptions === "function" ? requestOptions() : requestOptions;
3026
+ this.reload({
3027
+ preserveErrors: true,
3028
+ ...resolved,
3029
+ onCancelToken: (token) => {
3030
+ onStart(token.cancel);
3031
+ resolved.onCancelToken?.(token);
3032
+ },
3033
+ onFinish: (visit) => {
3034
+ onFinish();
3035
+ resolved.onFinish?.(visit);
3036
+ }
3037
+ });
3038
+ },
3039
+ {
3040
+ autoStart: options.autoStart ?? true,
3041
+ keepAlive: options.keepAlive ?? false,
3042
+ mode: options.mode
3043
+ }
3044
+ );
2938
3045
  }
2939
3046
  visit(href, options = {}) {
2940
3047
  options.optimistic = options.optimistic ?? this.pendingOptimisticCallback;
@@ -3250,8 +3357,8 @@ var Router = class {
3250
3357
  viewTransition: false,
3251
3358
  component: null,
3252
3359
  pageProps: null,
3253
- ...options,
3254
- ...configuredOptions
3360
+ ...stripTopLevelUndefined(options),
3361
+ ...stripTopLevelUndefined(configuredOptions)
3255
3362
  };
3256
3363
  const [url, _data] = transformUrlAndData(
3257
3364
  href,
@@ -3859,7 +3966,9 @@ var useInfiniteScrollData = (options) => {
3859
3966
  },
3860
3967
  onFinish: (visit) => {
3861
3968
  state.loading = false;
3862
- side === "next" ? options.onCompleteNextRequest(state.lastLoadedPage) : options.onCompletePreviousRequest(state.lastLoadedPage);
3969
+ const completed = visit.completed;
3970
+ const page3 = completed ? state.lastLoadedPage : null;
3971
+ side === "next" ? options.onCompleteNextRequest(page3, { page: page3, completed }) : options.onCompletePreviousRequest(page3, { page: page3, completed });
3863
3972
  reloadOptions.onFinish?.(visit);
3864
3973
  }
3865
3974
  });
@@ -4211,13 +4320,17 @@ function useInfiniteScroll(options) {
4211
4320
  // so they don't get confused with server-loaded content
4212
4321
  onBeforeUpdate: elementManager.processManuallyAddedElements,
4213
4322
  // After successful request, tag new server content
4214
- onCompletePreviousRequest: (loadedPage) => {
4215
- options.onCompletePreviousRequest();
4216
- requestAnimationFrame(() => elementManager.processServerLoadedElements(loadedPage), 2);
4323
+ onCompletePreviousRequest: (_, details) => {
4324
+ options.onCompletePreviousRequest(details);
4325
+ if (details.completed) {
4326
+ requestAnimationFrame(() => elementManager.processServerLoadedElements(details.page), 2);
4327
+ }
4217
4328
  },
4218
- onCompleteNextRequest: (loadedPage) => {
4219
- options.onCompleteNextRequest();
4220
- requestAnimationFrame(() => elementManager.processServerLoadedElements(loadedPage), 2);
4329
+ onCompleteNextRequest: (_, details) => {
4330
+ options.onCompleteNextRequest(details);
4331
+ if (details.completed) {
4332
+ requestAnimationFrame(() => elementManager.processServerLoadedElements(details.page), 2);
4333
+ }
4221
4334
  },
4222
4335
  onReset: options.onDataReset
4223
4336
  });