@inertiajs/core 3.0.0-beta.2 → 3.0.0-beta.4

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
@@ -1,8 +1,9 @@
1
1
  // src/router.ts
2
- import { cloneDeep as cloneDeep3, get as get7, isEqual as isEqual3, set as set5 } from "lodash-es";
2
+ import { cloneDeep as cloneDeep4, isEqual as isEqual3 } from "es-toolkit";
3
+ import { get as get7, set as set5 } from "es-toolkit/compat";
3
4
 
4
5
  // src/config.ts
5
- import { get, has, set } from "lodash-es";
6
+ import { get, has, set } from "es-toolkit/compat";
6
7
  var Config = class {
7
8
  constructor(defaults) {
8
9
  this.config = {};
@@ -43,7 +44,7 @@ var config = new Config({
43
44
  });
44
45
 
45
46
  // src/eventHandler.ts
46
- import { get as get4 } from "lodash-es";
47
+ import { get as get4 } from "es-toolkit/compat";
47
48
 
48
49
  // src/debounce.ts
49
50
  function debounce(fn, delay) {
@@ -99,10 +100,13 @@ var fireFlashEvent = (flash) => {
99
100
  };
100
101
 
101
102
  // src/history.ts
102
- import { cloneDeep as cloneDeep2, isEqual } from "lodash-es";
103
+ import { cloneDeep as cloneDeep3, isEqual } from "es-toolkit";
103
104
 
104
105
  // src/sessionStorage.ts
105
106
  var SessionStorage = class {
107
+ static {
108
+ this.locationVisitKey = "inertiaLocationVisit";
109
+ }
106
110
  static set(key, value) {
107
111
  if (typeof window !== "undefined") {
108
112
  window.sessionStorage.setItem(key, JSON.stringify(value));
@@ -146,7 +150,6 @@ var SessionStorage = class {
146
150
  }
147
151
  }
148
152
  };
149
- SessionStorage.locationVisitKey = "inertiaLocationVisit";
150
153
 
151
154
  // src/encryption.ts
152
155
  var encryptHistory = async (data) => {
@@ -271,10 +274,12 @@ var getKeyFromSessionStorage = async () => {
271
274
  };
272
275
 
273
276
  // src/page.ts
274
- import { get as get3, set as set3 } from "lodash-es";
277
+ import { cloneDeep as cloneDeep2 } from "es-toolkit";
278
+ import { get as get3, set as set3 } from "es-toolkit/compat";
275
279
 
276
280
  // src/prefetched.ts
277
- import { cloneDeep, get as get2 } from "lodash-es";
281
+ import { cloneDeep } from "es-toolkit";
282
+ import { get as get2 } from "es-toolkit/compat";
278
283
 
279
284
  // src/objectUtils.ts
280
285
  var objectsAreEqual = (obj1, obj2, excludeKeys) => {
@@ -976,9 +981,9 @@ function resolveUrlMethodPairComponent(pair) {
976
981
  if (!pair.component) {
977
982
  return null;
978
983
  }
979
- if (Array.isArray(pair.component)) {
984
+ if (typeof pair.component !== "string") {
980
985
  console.error(
981
- `The "component" property on the URL method pair received an array of components (${pair.component.join(", ")}), but only a single component string is supported for instant visits. Pass an explicit component name instead.`
986
+ `The "component" property on the URL method pair received multiple components (${Object.keys(pair.component).join(", ")}), but only a single component string is supported for instant visits. Use the withComponent() method to specify which component to use.`
982
987
  );
983
988
  return null;
984
989
  }
@@ -1001,6 +1006,9 @@ var CurrentPage = class {
1001
1006
  this.cleared = false;
1002
1007
  this.pendingDeferredProps = null;
1003
1008
  this.historyQuotaExceeded = false;
1009
+ this.optimisticBaseline = {};
1010
+ this.pendingOptimistics = [];
1011
+ this.optimisticCounter = 0;
1004
1012
  }
1005
1013
  init({
1006
1014
  initialPage,
@@ -1042,13 +1050,12 @@ var CurrentPage = class {
1042
1050
  if (componentId !== this.componentId) {
1043
1051
  return;
1044
1052
  }
1045
- page2.rememberedState ?? (page2.rememberedState = {});
1053
+ page2.rememberedState ??= {};
1046
1054
  const isServer3 = typeof window === "undefined";
1047
1055
  const location = !isServer3 ? window.location : new URL(page2.url);
1048
1056
  const scrollRegions = !isServer3 && preserveScroll ? Scroll.getScrollRegions() : [];
1049
1057
  replace = replace || isSameUrlWithoutHash(hrefToUrl(page2.url), location);
1050
1058
  const pageForHistory = { ...page2, flash: {} };
1051
- delete pageForHistory.optimisticUpdatedAt;
1052
1059
  return new Promise(
1053
1060
  (resolve) => replace ? history.replaceState(pageForHistory, resolve) : history.pushState(pageForHistory, resolve)
1054
1061
  ).then(() => {
@@ -1147,7 +1154,7 @@ var CurrentPage = class {
1147
1154
  viewTransition
1148
1155
  }) {
1149
1156
  const doSwap = () => this.swapComponent({ component, page: page2, preserveState });
1150
- if (!viewTransition || !document?.startViewTransition) {
1157
+ if (!viewTransition || !document?.startViewTransition || document.visibilityState === "hidden") {
1151
1158
  return doSwap();
1152
1159
  }
1153
1160
  const viewTransitionCallback = typeof viewTransition === "boolean" ? () => null : viewTransition;
@@ -1159,19 +1166,55 @@ var CurrentPage = class {
1159
1166
  resolve(component, page2) {
1160
1167
  return Promise.resolve(this.resolveComponent(component, page2));
1161
1168
  }
1162
- recordOptimisticUpdate(keys, updatedAt) {
1163
- if (!this.page.optimisticUpdatedAt) {
1164
- this.page.optimisticUpdatedAt = {};
1169
+ nextOptimisticId() {
1170
+ return ++this.optimisticCounter;
1171
+ }
1172
+ setBaseline(key, value) {
1173
+ if (!(key in this.optimisticBaseline)) {
1174
+ this.optimisticBaseline[key] = value;
1175
+ }
1176
+ }
1177
+ updateBaseline(key, value) {
1178
+ if (key in this.optimisticBaseline) {
1179
+ this.optimisticBaseline[key] = value;
1180
+ }
1181
+ }
1182
+ hasBaseline(key) {
1183
+ return key in this.optimisticBaseline;
1184
+ }
1185
+ registerOptimistic(id, callback) {
1186
+ this.pendingOptimistics.push({ id, callback });
1187
+ }
1188
+ unregisterOptimistic(id) {
1189
+ this.pendingOptimistics = this.pendingOptimistics.filter((entry) => entry.id !== id);
1190
+ }
1191
+ replayOptimistics() {
1192
+ const baselineKeys = Object.keys(this.optimisticBaseline);
1193
+ if (baselineKeys.length === 0) {
1194
+ return {};
1165
1195
  }
1166
- for (const key of keys) {
1167
- if (updatedAt > (this.page.optimisticUpdatedAt[key] || 0)) {
1168
- this.page.optimisticUpdatedAt[key] = updatedAt;
1196
+ const props = cloneDeep2(this.page.props);
1197
+ for (const key of baselineKeys) {
1198
+ props[key] = cloneDeep2(this.optimisticBaseline[key]);
1199
+ }
1200
+ for (const { callback } of this.pendingOptimistics) {
1201
+ const result = callback(cloneDeep2(props));
1202
+ if (result) {
1203
+ Object.assign(props, result);
1169
1204
  }
1170
1205
  }
1206
+ const replayedProps = {};
1207
+ for (const key of baselineKeys) {
1208
+ replayedProps[key] = props[key];
1209
+ }
1210
+ return replayedProps;
1211
+ }
1212
+ pendingOptimisticCount() {
1213
+ return this.pendingOptimistics.length;
1171
1214
  }
1172
- shouldPreserveOptimistic(key, updatedAt) {
1173
- const lastUpdatedAt = this.page.optimisticUpdatedAt?.[key];
1174
- return lastUpdatedAt !== void 0 && updatedAt < lastUpdatedAt;
1215
+ clearOptimisticState() {
1216
+ this.optimisticBaseline = {};
1217
+ this.pendingOptimistics = [];
1175
1218
  }
1176
1219
  isTheSame(page2) {
1177
1220
  return this.page.component === page2.component;
@@ -1211,9 +1254,9 @@ var Queue = class {
1211
1254
  return this.process();
1212
1255
  }
1213
1256
  process() {
1214
- this.processingPromise ?? (this.processingPromise = this.processNext().finally(() => {
1257
+ this.processingPromise ??= this.processNext().finally(() => {
1215
1258
  this.processingPromise = null;
1216
- }));
1259
+ });
1217
1260
  return this.processingPromise;
1218
1261
  }
1219
1262
  processNext() {
@@ -1280,7 +1323,7 @@ var History = class {
1280
1323
  } catch {
1281
1324
  return {
1282
1325
  ...page2,
1283
- props: cloneDeep2(page2.props)
1326
+ props: cloneDeep3(page2.props)
1284
1327
  };
1285
1328
  }
1286
1329
  }
@@ -1723,7 +1766,7 @@ var Polls = class {
1723
1766
  var polls = new Polls();
1724
1767
 
1725
1768
  // src/request.ts
1726
- import { get as get6 } from "lodash-es";
1769
+ import { get as get6 } from "es-toolkit/compat";
1727
1770
 
1728
1771
  // src/http.ts
1729
1772
  import { client as precognitionClient } from "laravel-precognition";
@@ -2113,7 +2156,8 @@ var RequestParams = class _RequestParams {
2113
2156
  };
2114
2157
 
2115
2158
  // src/response.ts
2116
- import { get as get5, isEqual as isEqual2, set as set4 } from "lodash-es";
2159
+ import { isEqual as isEqual2 } from "es-toolkit";
2160
+ import { get as get5, set as set4 } from "es-toolkit/compat";
2117
2161
 
2118
2162
  // src/dialog.ts
2119
2163
  var dialog_default = {
@@ -2231,7 +2275,6 @@ var Response = class _Response {
2231
2275
  }
2232
2276
  await history.processQueue();
2233
2277
  history.preserveUrl = this.requestParams.all().preserveUrl;
2234
- const previousFlash = page.get().flash;
2235
2278
  await this.setPage();
2236
2279
  const errors = page.get().props.errors || {};
2237
2280
  if (Object.keys(errors).length > 0) {
@@ -2244,7 +2287,7 @@ var Response = class _Response {
2244
2287
  router.flush(page.get().url);
2245
2288
  }
2246
2289
  const { flash } = page.get();
2247
- if (Object.keys(flash).length > 0 && (!this.requestParams.isPartial() || !isEqual2(flash, previousFlash))) {
2290
+ if (Object.keys(flash).length > 0 && !this.requestParams.isDeferredPropsRequest()) {
2248
2291
  fireFlashEvent(flash);
2249
2292
  this.requestParams.all().onFlash(flash);
2250
2293
  }
@@ -2383,16 +2426,15 @@ var Response = class _Response {
2383
2426
  return responseUrl.pathname + responseUrl.search + responseUrl.hash;
2384
2427
  }
2385
2428
  preserveOptimisticProps(pageResponse) {
2386
- const optimisticUpdatedAt = page.get().optimisticUpdatedAt;
2387
- if (!optimisticUpdatedAt || !router.hasPendingOptimistic()) {
2429
+ if (!router.hasPendingOptimistic()) {
2388
2430
  return;
2389
2431
  }
2390
2432
  for (const key of Object.keys(pageResponse.props)) {
2391
- if (key in optimisticUpdatedAt) {
2433
+ if (page.hasBaseline(key)) {
2434
+ page.updateBaseline(key, pageResponse.props[key]);
2392
2435
  pageResponse.props[key] = page.get().props[key];
2393
2436
  }
2394
2437
  }
2395
- pageResponse.optimisticUpdatedAt = { ...optimisticUpdatedAt };
2396
2438
  }
2397
2439
  preserveEqualProps(pageResponse) {
2398
2440
  if (pageResponse.component !== page.get().component) {
@@ -2715,7 +2757,7 @@ var RequestStream = class {
2715
2757
  }
2716
2758
  send(request) {
2717
2759
  this.requests.push(request);
2718
- request.send().then(() => {
2760
+ request.send().finally(() => {
2719
2761
  this.requests = this.requests.filter((r) => r !== request);
2720
2762
  });
2721
2763
  }
@@ -3004,7 +3046,7 @@ var Router = class {
3004
3046
  preserveState: true,
3005
3047
  props(currentProps) {
3006
3048
  const newValue = typeof value === "function" ? value(get7(currentProps, name), currentProps) : value;
3007
- return set5(cloneDeep3(currentProps), name, newValue);
3049
+ return set5(cloneDeep4(currentProps), name, newValue);
3008
3050
  },
3009
3051
  ...options || {}
3010
3052
  });
@@ -3102,7 +3144,7 @@ var Router = class {
3102
3144
  const sharedProps = Object.fromEntries(
3103
3145
  (current.sharedProps ?? []).filter((key) => key in current.props).map((key) => [key, current.props[key]])
3104
3146
  );
3105
- const resolvedPageProps = typeof visit.pageProps === "function" ? visit.pageProps(cloneDeep3(current.props), cloneDeep3(sharedProps)) : visit.pageProps;
3147
+ const resolvedPageProps = typeof visit.pageProps === "function" ? visit.pageProps(cloneDeep4(current.props), cloneDeep4(sharedProps)) : visit.pageProps;
3106
3148
  const intermediateProps = resolvedPageProps !== null ? { ...resolvedPageProps } : { ...sharedProps };
3107
3149
  const intermediatePage = {
3108
3150
  component: visit.component,
@@ -3144,7 +3186,7 @@ var Router = class {
3144
3186
  options.method = options.method ?? urlMethodPair.method;
3145
3187
  }
3146
3188
  const defaultVisitOptionsCallback = config.get("visitOptions");
3147
- const configuredOptions = defaultVisitOptionsCallback ? defaultVisitOptionsCallback(href.toString(), cloneDeep3(options)) || {} : {};
3189
+ const configuredOptions = defaultVisitOptionsCallback ? defaultVisitOptionsCallback(href.toString(), cloneDeep4(options)) || {} : {};
3148
3190
  const mergedOptions = {
3149
3191
  method: "get",
3150
3192
  data: {},
@@ -3211,21 +3253,25 @@ var Router = class {
3211
3253
  }
3212
3254
  applyOptimisticUpdate(optimistic, events) {
3213
3255
  const currentProps = page.get().props;
3214
- const optimisticProps = optimistic(cloneDeep3(currentProps));
3256
+ const optimisticProps = optimistic(cloneDeep4(currentProps));
3215
3257
  if (!optimisticProps) {
3216
3258
  return;
3217
3259
  }
3218
- const propsSnapshot = {};
3260
+ const changedKeys = [];
3219
3261
  for (const key of Object.keys(optimisticProps)) {
3220
3262
  if (!isEqual3(currentProps[key], optimisticProps[key])) {
3221
- propsSnapshot[key] = cloneDeep3(currentProps[key]);
3263
+ changedKeys.push(key);
3222
3264
  }
3223
3265
  }
3224
- if (Object.keys(propsSnapshot).length === 0) {
3266
+ if (changedKeys.length === 0) {
3225
3267
  return;
3226
3268
  }
3227
- const updatedAt = Date.now();
3228
- page.recordOptimisticUpdate(Object.keys(propsSnapshot), updatedAt);
3269
+ const id = page.nextOptimisticId();
3270
+ const component = page.get().component;
3271
+ for (const key of changedKeys) {
3272
+ page.setBaseline(key, cloneDeep4(currentProps[key]));
3273
+ }
3274
+ page.registerOptimistic(id, optimistic);
3229
3275
  page.setPropsQuietly({ ...currentProps, ...optimisticProps });
3230
3276
  let shouldRestore = true;
3231
3277
  const originalOnSuccess = events.onSuccess;
@@ -3235,17 +3281,16 @@ var Router = class {
3235
3281
  };
3236
3282
  const originalOnFinish = events.onFinish;
3237
3283
  events.onFinish = (visit) => {
3238
- if (shouldRestore) {
3239
- const propsToRestore = {};
3240
- for (const [key, value] of Object.entries(propsSnapshot)) {
3241
- if (!page.shouldPreserveOptimistic(key, updatedAt)) {
3242
- propsToRestore[key] = value;
3243
- }
3244
- }
3245
- if (Object.keys(propsToRestore).length > 0) {
3246
- page.setPropsQuietly({ ...page.get().props, ...propsToRestore });
3284
+ page.unregisterOptimistic(id);
3285
+ if (shouldRestore && page.get().component === component) {
3286
+ const replayedProps = page.replayOptimistics();
3287
+ if (Object.keys(replayedProps).length > 0) {
3288
+ page.setPropsQuietly({ ...page.get().props, ...replayedProps });
3247
3289
  }
3248
3290
  }
3291
+ if (page.pendingOptimisticCount() === 0) {
3292
+ page.clearOptimisticState();
3293
+ }
3249
3294
  return originalOnFinish(visit);
3250
3295
  };
3251
3296
  }
@@ -3469,7 +3514,7 @@ function axiosAdapter(instance) {
3469
3514
  }
3470
3515
 
3471
3516
  // src/formObject.ts
3472
- import { get as get8, set as set6 } from "lodash-es";
3517
+ import { get as get8, set as set6 } from "es-toolkit/compat";
3473
3518
  function undotKey(key) {
3474
3519
  if (!key.includes(".")) {
3475
3520
  return key;
@@ -4175,7 +4220,7 @@ function useInfiniteScroll(options) {
4175
4220
  }
4176
4221
 
4177
4222
  // src/layout.ts
4178
- import { isEqual as isEqual4 } from "lodash-es";
4223
+ import { isEqual as isEqual4 } from "es-toolkit";
4179
4224
  function createLayoutPropsStore() {
4180
4225
  let shared = {};
4181
4226
  let named = {};
@@ -4228,18 +4273,6 @@ function createLayoutPropsStore() {
4228
4273
  get: () => snapshot
4229
4274
  };
4230
4275
  }
4231
- function mergeLayoutProps(defaults, staticProps, dynamicProps) {
4232
- const result = { ...defaults };
4233
- for (const key of Object.keys(defaults)) {
4234
- if (key in staticProps && staticProps[key] !== void 0) {
4235
- result[key] = staticProps[key];
4236
- }
4237
- if (key in dynamicProps && dynamicProps[key] !== void 0) {
4238
- result[key] = dynamicProps[key];
4239
- }
4240
- }
4241
- return result;
4242
- }
4243
4276
  function isPlainObject(value) {
4244
4277
  return typeof value === "object" && value !== null && !Array.isArray(value);
4245
4278
  }
@@ -4870,7 +4903,6 @@ export {
4870
4903
  isSameUrlWithoutQueryOrHash,
4871
4904
  isUrlMethodPair,
4872
4905
  mergeDataIntoQueryString,
4873
- mergeLayoutProps,
4874
4906
  normalizeLayouts,
4875
4907
  objectToFormData,
4876
4908
  progress,