@remix-run/router 1.2.1 → 1.3.0-pre.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/CHANGELOG.md +12 -0
- package/dist/history.d.ts +6 -1
- package/dist/index.d.ts +1 -2
- package/dist/router.cjs.js +164 -83
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +2 -0
- package/dist/router.js +163 -84
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +164 -83
- package/dist/router.umd.js.map +1 -1
- package/dist/router.umd.min.js +2 -2
- package/dist/router.umd.min.js.map +1 -1
- package/dist/utils.d.ts +14 -7
- package/history.ts +33 -23
- package/index.ts +3 -3
- package/package.json +1 -1
- package/router.ts +77 -34
- package/utils.ts +88 -42
package/dist/router.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.
|
|
2
|
+
* @remix-run/router v1.3.0-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -98,6 +98,10 @@
|
|
|
98
98
|
return location;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
function createHref(to) {
|
|
102
|
+
return typeof to === "string" ? to : createPath(to);
|
|
103
|
+
}
|
|
104
|
+
|
|
101
105
|
let history = {
|
|
102
106
|
get index() {
|
|
103
107
|
return index;
|
|
@@ -111,8 +115,10 @@
|
|
|
111
115
|
return getCurrentLocation();
|
|
112
116
|
},
|
|
113
117
|
|
|
114
|
-
createHref
|
|
115
|
-
|
|
118
|
+
createHref,
|
|
119
|
+
|
|
120
|
+
createURL(to) {
|
|
121
|
+
return new URL(createHref(to), "http://localhost");
|
|
116
122
|
},
|
|
117
123
|
|
|
118
124
|
encodeLocation(to) {
|
|
@@ -391,15 +397,6 @@
|
|
|
391
397
|
|
|
392
398
|
return parsedPath;
|
|
393
399
|
}
|
|
394
|
-
function createClientSideURL(location) {
|
|
395
|
-
// window.location.origin is "null" (the literal string value) in Firefox
|
|
396
|
-
// under certain conditions, notably when serving from a local HTML file
|
|
397
|
-
// See https://bugzilla.mozilla.org/show_bug.cgi?id=878297
|
|
398
|
-
let base = typeof window !== "undefined" && typeof window.location !== "undefined" && window.location.origin !== "null" ? window.location.origin : window.location.href;
|
|
399
|
-
let href = typeof location === "string" ? location : createPath(location);
|
|
400
|
-
invariant(base, "No window.location.(origin|href) available to create URL for href: " + href);
|
|
401
|
-
return new URL(href, base);
|
|
402
|
-
}
|
|
403
400
|
|
|
404
401
|
function getUrlBasedHistory(getLocation, createHref, validateLocation, options) {
|
|
405
402
|
if (options === void 0) {
|
|
@@ -464,6 +461,16 @@
|
|
|
464
461
|
}
|
|
465
462
|
}
|
|
466
463
|
|
|
464
|
+
function createURL(to) {
|
|
465
|
+
// window.location.origin is "null" (the literal string value) in Firefox
|
|
466
|
+
// under certain conditions, notably when serving from a local HTML file
|
|
467
|
+
// See https://bugzilla.mozilla.org/show_bug.cgi?id=878297
|
|
468
|
+
let base = window.location.origin !== "null" ? window.location.origin : window.location.href;
|
|
469
|
+
let href = typeof to === "string" ? to : createPath(to);
|
|
470
|
+
invariant(base, "No window.location.(origin|href) available to create URL for href: " + href);
|
|
471
|
+
return new URL(href, base);
|
|
472
|
+
}
|
|
473
|
+
|
|
467
474
|
let history = {
|
|
468
475
|
get action() {
|
|
469
476
|
return action;
|
|
@@ -490,9 +497,11 @@
|
|
|
490
497
|
return createHref(window, to);
|
|
491
498
|
},
|
|
492
499
|
|
|
500
|
+
createURL,
|
|
501
|
+
|
|
493
502
|
encodeLocation(to) {
|
|
494
503
|
// Encode a Location the same way window.location would
|
|
495
|
-
let url =
|
|
504
|
+
let url = createURL(to);
|
|
496
505
|
return {
|
|
497
506
|
pathname: url.pathname,
|
|
498
507
|
search: url.search,
|
|
@@ -809,13 +818,32 @@
|
|
|
809
818
|
path = path.replace(/\*$/, "/*");
|
|
810
819
|
}
|
|
811
820
|
|
|
812
|
-
return path.replace(/^:(\w+)/g, (_, key) => {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
821
|
+
return path.replace(/^:(\w+)(\??)/g, (_, key, optional) => {
|
|
822
|
+
let param = params[key];
|
|
823
|
+
|
|
824
|
+
if (optional === "?") {
|
|
825
|
+
return param == null ? "" : param;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
if (param == null) {
|
|
829
|
+
invariant(false, "Missing \":" + key + "\" param");
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
return param;
|
|
833
|
+
}).replace(/\/:(\w+)(\??)/g, (_, key, optional) => {
|
|
834
|
+
let param = params[key];
|
|
835
|
+
|
|
836
|
+
if (optional === "?") {
|
|
837
|
+
return param == null ? "" : "/" + param;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if (param == null) {
|
|
841
|
+
invariant(false, "Missing \":" + key + "\" param");
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
return "/" + param;
|
|
845
|
+
}) // Remove any optional markers from optional static segments
|
|
846
|
+
.replace(/\?/g, "").replace(/(\/?)\*/, (_, prefix, __, str) => {
|
|
819
847
|
const star = "*";
|
|
820
848
|
|
|
821
849
|
if (params[star] == null) {
|
|
@@ -1162,9 +1190,10 @@
|
|
|
1162
1190
|
};
|
|
1163
1191
|
class AbortedDeferredError extends Error {}
|
|
1164
1192
|
class DeferredData {
|
|
1165
|
-
constructor(data) {
|
|
1166
|
-
this.
|
|
1167
|
-
this.
|
|
1193
|
+
constructor(data, responseInit) {
|
|
1194
|
+
this.pendingKeysSet = new Set();
|
|
1195
|
+
this.subscribers = new Set();
|
|
1196
|
+
this.deferredKeys = [];
|
|
1168
1197
|
invariant(data && typeof data === "object" && !Array.isArray(data), "defer() only accepts plain objects"); // Set up an AbortController + Promise we can race against to exit early
|
|
1169
1198
|
// cancellation
|
|
1170
1199
|
|
|
@@ -1183,6 +1212,7 @@
|
|
|
1183
1212
|
[key]: this.trackPromise(key, value)
|
|
1184
1213
|
});
|
|
1185
1214
|
}, {});
|
|
1215
|
+
this.init = responseInit;
|
|
1186
1216
|
}
|
|
1187
1217
|
|
|
1188
1218
|
trackPromise(key, value) {
|
|
@@ -1190,7 +1220,8 @@
|
|
|
1190
1220
|
return value;
|
|
1191
1221
|
}
|
|
1192
1222
|
|
|
1193
|
-
this.
|
|
1223
|
+
this.deferredKeys.push(key);
|
|
1224
|
+
this.pendingKeysSet.add(key); // We store a little wrapper promise that will be extended with
|
|
1194
1225
|
// _data/_error props upon resolve/reject
|
|
1195
1226
|
|
|
1196
1227
|
let promise = Promise.race([value, this.abortPromise]).then(data => this.onSettle(promise, key, null, data), error => this.onSettle(promise, key, error)); // Register rejection listeners to avoid uncaught promise rejections on
|
|
@@ -1212,39 +1243,41 @@
|
|
|
1212
1243
|
return Promise.reject(error);
|
|
1213
1244
|
}
|
|
1214
1245
|
|
|
1215
|
-
this.
|
|
1246
|
+
this.pendingKeysSet.delete(key);
|
|
1216
1247
|
|
|
1217
1248
|
if (this.done) {
|
|
1218
1249
|
// Nothing left to abort!
|
|
1219
1250
|
this.unlistenAbortSignal();
|
|
1220
1251
|
}
|
|
1221
1252
|
|
|
1222
|
-
const subscriber = this.subscriber;
|
|
1223
|
-
|
|
1224
1253
|
if (error) {
|
|
1225
1254
|
Object.defineProperty(promise, "_error", {
|
|
1226
1255
|
get: () => error
|
|
1227
1256
|
});
|
|
1228
|
-
|
|
1257
|
+
this.emit(false, key);
|
|
1229
1258
|
return Promise.reject(error);
|
|
1230
1259
|
}
|
|
1231
1260
|
|
|
1232
1261
|
Object.defineProperty(promise, "_data", {
|
|
1233
1262
|
get: () => data
|
|
1234
1263
|
});
|
|
1235
|
-
|
|
1264
|
+
this.emit(false, key);
|
|
1236
1265
|
return data;
|
|
1237
1266
|
}
|
|
1238
1267
|
|
|
1268
|
+
emit(aborted, settledKey) {
|
|
1269
|
+
this.subscribers.forEach(subscriber => subscriber(aborted, settledKey));
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1239
1272
|
subscribe(fn) {
|
|
1240
|
-
this.
|
|
1273
|
+
this.subscribers.add(fn);
|
|
1274
|
+
return () => this.subscribers.delete(fn);
|
|
1241
1275
|
}
|
|
1242
1276
|
|
|
1243
1277
|
cancel() {
|
|
1244
1278
|
this.controller.abort();
|
|
1245
|
-
this.
|
|
1246
|
-
|
|
1247
|
-
subscriber && subscriber(true);
|
|
1279
|
+
this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));
|
|
1280
|
+
this.emit(true);
|
|
1248
1281
|
}
|
|
1249
1282
|
|
|
1250
1283
|
async resolveData(signal) {
|
|
@@ -1269,7 +1302,7 @@
|
|
|
1269
1302
|
}
|
|
1270
1303
|
|
|
1271
1304
|
get done() {
|
|
1272
|
-
return this.
|
|
1305
|
+
return this.pendingKeysSet.size === 0;
|
|
1273
1306
|
}
|
|
1274
1307
|
|
|
1275
1308
|
get unwrappedData() {
|
|
@@ -1282,6 +1315,10 @@
|
|
|
1282
1315
|
}, {});
|
|
1283
1316
|
}
|
|
1284
1317
|
|
|
1318
|
+
get pendingKeys() {
|
|
1319
|
+
return Array.from(this.pendingKeysSet);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1285
1322
|
}
|
|
1286
1323
|
|
|
1287
1324
|
function isTrackedPromise(value) {
|
|
@@ -1300,9 +1337,16 @@
|
|
|
1300
1337
|
return value._data;
|
|
1301
1338
|
}
|
|
1302
1339
|
|
|
1303
|
-
function defer(data) {
|
|
1304
|
-
|
|
1305
|
-
|
|
1340
|
+
const defer = function defer(data, init) {
|
|
1341
|
+
if (init === void 0) {
|
|
1342
|
+
init = {};
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
let responseInit = typeof init === "number" ? {
|
|
1346
|
+
status: init
|
|
1347
|
+
} : init;
|
|
1348
|
+
return new DeferredData(data, responseInit);
|
|
1349
|
+
};
|
|
1306
1350
|
|
|
1307
1351
|
/**
|
|
1308
1352
|
* A redirect response. Sets the status code and the `Location` header.
|
|
@@ -1728,7 +1772,7 @@
|
|
|
1728
1772
|
|
|
1729
1773
|
|
|
1730
1774
|
pendingNavigationController = new AbortController();
|
|
1731
|
-
let request = createClientSideRequest(location, pendingNavigationController.signal, opts && opts.submission);
|
|
1775
|
+
let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission);
|
|
1732
1776
|
let pendingActionData;
|
|
1733
1777
|
let pendingError;
|
|
1734
1778
|
|
|
@@ -1869,7 +1913,9 @@
|
|
|
1869
1913
|
}
|
|
1870
1914
|
|
|
1871
1915
|
if (isDeferredResult(result)) {
|
|
1872
|
-
throw
|
|
1916
|
+
throw getInternalRouterError(400, {
|
|
1917
|
+
type: "defer-action"
|
|
1918
|
+
});
|
|
1873
1919
|
}
|
|
1874
1920
|
|
|
1875
1921
|
return {
|
|
@@ -1906,7 +1952,7 @@
|
|
|
1906
1952
|
formData: loadingNavigation.formData,
|
|
1907
1953
|
formEncType: loadingNavigation.formEncType
|
|
1908
1954
|
} : undefined;
|
|
1909
|
-
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches); // Cancel pending deferreds for no-longer-matched routes or routes we're
|
|
1955
|
+
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches); // Cancel pending deferreds for no-longer-matched routes or routes we're
|
|
1910
1956
|
// about to reload. Note that if this is an action reload we would have
|
|
1911
1957
|
// already cancelled all pending deferreds so this would be a no-op
|
|
1912
1958
|
|
|
@@ -2088,7 +2134,7 @@
|
|
|
2088
2134
|
}); // Call the action for the fetcher
|
|
2089
2135
|
|
|
2090
2136
|
let abortController = new AbortController();
|
|
2091
|
-
let fetchRequest = createClientSideRequest(path, abortController.signal, submission);
|
|
2137
|
+
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission);
|
|
2092
2138
|
fetchControllers.set(key, abortController);
|
|
2093
2139
|
let actionResult = await callLoaderOrAction("action", fetchRequest, match, requestMatches, router.basename);
|
|
2094
2140
|
|
|
@@ -2129,13 +2175,15 @@
|
|
|
2129
2175
|
}
|
|
2130
2176
|
|
|
2131
2177
|
if (isDeferredResult(actionResult)) {
|
|
2132
|
-
|
|
2178
|
+
throw getInternalRouterError(400, {
|
|
2179
|
+
type: "defer-action"
|
|
2180
|
+
});
|
|
2133
2181
|
} // Start the data load for current matches, or the next location if we're
|
|
2134
2182
|
// in the middle of a navigation
|
|
2135
2183
|
|
|
2136
2184
|
|
|
2137
2185
|
let nextLocation = state.navigation.location || state.location;
|
|
2138
|
-
let revalidationRequest = createClientSideRequest(nextLocation, abortController.signal);
|
|
2186
|
+
let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal);
|
|
2139
2187
|
let matches = state.navigation.state !== "idle" ? matchRoutes(dataRoutes, state.navigation.location, init.basename) : state.matches;
|
|
2140
2188
|
invariant(matches, "Didn't find any matches after fetcher action");
|
|
2141
2189
|
let loadId = ++incrementingLoadId;
|
|
@@ -2149,7 +2197,7 @@
|
|
|
2149
2197
|
});
|
|
2150
2198
|
|
|
2151
2199
|
state.fetchers.set(key, loadFetcher);
|
|
2152
|
-
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, {
|
|
2200
|
+
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, {
|
|
2153
2201
|
[match.route.id]: actionResult.data
|
|
2154
2202
|
}, undefined, // No need to send through errors since we short circuit above
|
|
2155
2203
|
fetchLoadMatches); // Put all revalidating fetchers into the loading state, except for the
|
|
@@ -2262,9 +2310,9 @@
|
|
|
2262
2310
|
}); // Call the loader for this fetcher route match
|
|
2263
2311
|
|
|
2264
2312
|
let abortController = new AbortController();
|
|
2265
|
-
let fetchRequest = createClientSideRequest(path, abortController.signal);
|
|
2313
|
+
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal);
|
|
2266
2314
|
fetchControllers.set(key, abortController);
|
|
2267
|
-
let result = await callLoaderOrAction("loader", fetchRequest, match, matches, router.basename); // Deferred isn't supported
|
|
2315
|
+
let result = await callLoaderOrAction("loader", fetchRequest, match, matches, router.basename); // Deferred isn't supported for fetcher loads, await everything and treat it
|
|
2268
2316
|
// as a normal load. resolveDeferredData will return undefined if this
|
|
2269
2317
|
// fetcher gets aborted, so we just leave result untouched and short circuit
|
|
2270
2318
|
// below if that happens
|
|
@@ -2364,7 +2412,7 @@
|
|
|
2364
2412
|
invariant(redirectLocation, "Expected a location on the redirect navigation"); // Check if this an external redirect that goes to a new origin
|
|
2365
2413
|
|
|
2366
2414
|
if (typeof ((_window = window) == null ? void 0 : _window.location) !== "undefined") {
|
|
2367
|
-
let newOrigin =
|
|
2415
|
+
let newOrigin = init.history.createURL(redirect.location).origin;
|
|
2368
2416
|
|
|
2369
2417
|
if (window.location.origin !== newOrigin) {
|
|
2370
2418
|
if (replace) {
|
|
@@ -2430,7 +2478,7 @@
|
|
|
2430
2478
|
// accordingly
|
|
2431
2479
|
let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(_ref8 => {
|
|
2432
2480
|
let [, href, match, fetchMatches] = _ref8;
|
|
2433
|
-
return callLoaderOrAction("loader", createClientSideRequest(href, request.signal), match, fetchMatches, router.basename);
|
|
2481
|
+
return callLoaderOrAction("loader", createClientSideRequest(init.history, href, request.signal), match, fetchMatches, router.basename);
|
|
2434
2482
|
})]);
|
|
2435
2483
|
let loaderResults = results.slice(0, matchesToLoad.length);
|
|
2436
2484
|
let fetcherResults = results.slice(matchesToLoad.length);
|
|
@@ -2639,6 +2687,7 @@
|
|
|
2639
2687
|
//#region createStaticHandler
|
|
2640
2688
|
////////////////////////////////////////////////////////////////////////////////
|
|
2641
2689
|
|
|
2690
|
+
const UNSAFE_DEFERRED_SYMBOL = Symbol("deferred");
|
|
2642
2691
|
function createStaticHandler(routes, opts) {
|
|
2643
2692
|
invariant(routes.length > 0, "You must provide a non-empty routes array to createStaticHandler");
|
|
2644
2693
|
let dataRoutes = convertRoutesToDataRoutes(routes);
|
|
@@ -2691,7 +2740,8 @@
|
|
|
2691
2740
|
},
|
|
2692
2741
|
statusCode: error.status,
|
|
2693
2742
|
loaderHeaders: {},
|
|
2694
|
-
actionHeaders: {}
|
|
2743
|
+
actionHeaders: {},
|
|
2744
|
+
activeDeferreds: null
|
|
2695
2745
|
};
|
|
2696
2746
|
} else if (!matches) {
|
|
2697
2747
|
let error = getInternalRouterError(404, {
|
|
@@ -2712,7 +2762,8 @@
|
|
|
2712
2762
|
},
|
|
2713
2763
|
statusCode: error.status,
|
|
2714
2764
|
loaderHeaders: {},
|
|
2715
|
-
actionHeaders: {}
|
|
2765
|
+
actionHeaders: {},
|
|
2766
|
+
activeDeferreds: null
|
|
2716
2767
|
};
|
|
2717
2768
|
}
|
|
2718
2769
|
|
|
@@ -2803,8 +2854,23 @@
|
|
|
2803
2854
|
} // Pick off the right state value to return
|
|
2804
2855
|
|
|
2805
2856
|
|
|
2806
|
-
|
|
2807
|
-
|
|
2857
|
+
if (result.actionData) {
|
|
2858
|
+
return Object.values(result.actionData)[0];
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2861
|
+
if (result.loaderData) {
|
|
2862
|
+
var _result$activeDeferre;
|
|
2863
|
+
|
|
2864
|
+
let data = Object.values(result.loaderData)[0];
|
|
2865
|
+
|
|
2866
|
+
if ((_result$activeDeferre = result.activeDeferreds) != null && _result$activeDeferre[match.route.id]) {
|
|
2867
|
+
data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id];
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2870
|
+
return data;
|
|
2871
|
+
}
|
|
2872
|
+
|
|
2873
|
+
return undefined;
|
|
2808
2874
|
}
|
|
2809
2875
|
|
|
2810
2876
|
async function queryImpl(request, location, matches, requestContext, routeMatch) {
|
|
@@ -2884,7 +2950,18 @@
|
|
|
2884
2950
|
}
|
|
2885
2951
|
|
|
2886
2952
|
if (isDeferredResult(result)) {
|
|
2887
|
-
|
|
2953
|
+
let error = getInternalRouterError(400, {
|
|
2954
|
+
type: "defer-action"
|
|
2955
|
+
});
|
|
2956
|
+
|
|
2957
|
+
if (isRouteRequest) {
|
|
2958
|
+
throw error;
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
result = {
|
|
2962
|
+
type: ResultType.error,
|
|
2963
|
+
error
|
|
2964
|
+
};
|
|
2888
2965
|
}
|
|
2889
2966
|
|
|
2890
2967
|
if (isRouteRequest) {
|
|
@@ -2905,7 +2982,8 @@
|
|
|
2905
2982
|
// return the raw Response or value
|
|
2906
2983
|
statusCode: 200,
|
|
2907
2984
|
loaderHeaders: {},
|
|
2908
|
-
actionHeaders: {}
|
|
2985
|
+
actionHeaders: {},
|
|
2986
|
+
activeDeferreds: null
|
|
2909
2987
|
};
|
|
2910
2988
|
}
|
|
2911
2989
|
|
|
@@ -2968,7 +3046,8 @@
|
|
|
2968
3046
|
}), {}),
|
|
2969
3047
|
errors: pendingActionError || null,
|
|
2970
3048
|
statusCode: 200,
|
|
2971
|
-
loaderHeaders: {}
|
|
3049
|
+
loaderHeaders: {},
|
|
3050
|
+
activeDeferreds: null
|
|
2972
3051
|
};
|
|
2973
3052
|
}
|
|
2974
3053
|
|
|
@@ -2977,27 +3056,21 @@
|
|
|
2977
3056
|
if (request.signal.aborted) {
|
|
2978
3057
|
let method = isRouteRequest ? "queryRoute" : "query";
|
|
2979
3058
|
throw new Error(method + "() call aborted");
|
|
2980
|
-
}
|
|
3059
|
+
} // Process and commit output from loaders
|
|
2981
3060
|
|
|
2982
|
-
let executedLoaders = new Set();
|
|
2983
|
-
results.forEach((result, i) => {
|
|
2984
|
-
executedLoaders.add(matchesToLoad[i].route.id); // Can't do anything with these without the Remix side of things, so just
|
|
2985
|
-
// cancel them for now
|
|
2986
3061
|
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
}
|
|
2990
|
-
}); // Process and commit output from loaders
|
|
2991
|
-
|
|
2992
|
-
let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError); // Add a null for any non-loader matches for proper revalidation on the client
|
|
3062
|
+
let activeDeferreds = new Map();
|
|
3063
|
+
let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError, activeDeferreds); // Add a null for any non-loader matches for proper revalidation on the client
|
|
2993
3064
|
|
|
3065
|
+
let executedLoaders = new Set(matchesToLoad.map(match => match.route.id));
|
|
2994
3066
|
matches.forEach(match => {
|
|
2995
3067
|
if (!executedLoaders.has(match.route.id)) {
|
|
2996
3068
|
context.loaderData[match.route.id] = null;
|
|
2997
3069
|
}
|
|
2998
3070
|
});
|
|
2999
3071
|
return _extends({}, context, {
|
|
3000
|
-
matches
|
|
3072
|
+
matches,
|
|
3073
|
+
activeDeferreds: activeDeferreds.size > 0 ? Object.fromEntries(activeDeferreds.entries()) : null
|
|
3001
3074
|
});
|
|
3002
3075
|
}
|
|
3003
3076
|
|
|
@@ -3116,13 +3189,13 @@
|
|
|
3116
3189
|
return boundaryMatches;
|
|
3117
3190
|
}
|
|
3118
3191
|
|
|
3119
|
-
function getMatchesToLoad(state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) {
|
|
3192
|
+
function getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) {
|
|
3120
3193
|
let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined; // Pick navigation matches that are net-new or qualify for revalidation
|
|
3121
3194
|
|
|
3122
3195
|
let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;
|
|
3123
3196
|
let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);
|
|
3124
3197
|
let navigationMatches = boundaryMatches.filter((match, index) => match.route.loader != null && (isNewLoader(state.loaderData, state.matches[index], match) || // If this route had a pending deferred cancelled it must be revalidated
|
|
3125
|
-
cancelledDeferredRoutes.some(id => id === match.route.id) || shouldRevalidateLoader(state.location, state.matches[index], submission, location, match, isRevalidationRequired, actionResult))); // Pick fetcher.loads that need to be revalidated
|
|
3198
|
+
cancelledDeferredRoutes.some(id => id === match.route.id) || shouldRevalidateLoader(history, state.location, state.matches[index], submission, location, match, isRevalidationRequired, actionResult))); // Pick fetcher.loads that need to be revalidated
|
|
3126
3199
|
|
|
3127
3200
|
let revalidatingFetchers = [];
|
|
3128
3201
|
fetchLoadMatches && fetchLoadMatches.forEach((_ref10, key) => {
|
|
@@ -3132,7 +3205,7 @@
|
|
|
3132
3205
|
if (cancelledFetcherLoads.includes(key)) {
|
|
3133
3206
|
revalidatingFetchers.push([key, href, match, fetchMatches]);
|
|
3134
3207
|
} else if (isRevalidationRequired) {
|
|
3135
|
-
let shouldRevalidate = shouldRevalidateLoader(href, match, submission, href, match, isRevalidationRequired, actionResult);
|
|
3208
|
+
let shouldRevalidate = shouldRevalidateLoader(history, href, match, submission, href, match, isRevalidationRequired, actionResult);
|
|
3136
3209
|
|
|
3137
3210
|
if (shouldRevalidate) {
|
|
3138
3211
|
revalidatingFetchers.push([key, href, match, fetchMatches]);
|
|
@@ -3162,10 +3235,10 @@
|
|
|
3162
3235
|
);
|
|
3163
3236
|
}
|
|
3164
3237
|
|
|
3165
|
-
function shouldRevalidateLoader(currentLocation, currentMatch, submission, location, match, isRevalidationRequired, actionResult) {
|
|
3166
|
-
let currentUrl =
|
|
3238
|
+
function shouldRevalidateLoader(history, currentLocation, currentMatch, submission, location, match, isRevalidationRequired, actionResult) {
|
|
3239
|
+
let currentUrl = history.createURL(currentLocation);
|
|
3167
3240
|
let currentParams = currentMatch.params;
|
|
3168
|
-
let nextUrl =
|
|
3241
|
+
let nextUrl = history.createURL(location);
|
|
3169
3242
|
let nextParams = match.params; // This is the default implementation as to when we revalidate. If the route
|
|
3170
3243
|
// provides it's own implementation, then we give them full control but
|
|
3171
3244
|
// provide this value so they can leverage it if needed after they check
|
|
@@ -3242,7 +3315,7 @@
|
|
|
3242
3315
|
if (redirectStatusCodes.has(status)) {
|
|
3243
3316
|
let location = result.headers.get("Location");
|
|
3244
3317
|
invariant(location, "Redirects returned/thrown from loaders/actions must have a Location header");
|
|
3245
|
-
let isAbsolute = /^[a-z
|
|
3318
|
+
let isAbsolute = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(location); // Support relative routing in internal redirects
|
|
3246
3319
|
|
|
3247
3320
|
if (!isAbsolute) {
|
|
3248
3321
|
let activeMatches = matches.slice(0, matches.indexOf(match) + 1);
|
|
@@ -3335,8 +3408,8 @@
|
|
|
3335
3408
|
// Request instance from the static handler (query/queryRoute)
|
|
3336
3409
|
|
|
3337
3410
|
|
|
3338
|
-
function createClientSideRequest(location, signal, submission) {
|
|
3339
|
-
let url =
|
|
3411
|
+
function createClientSideRequest(history, location, signal, submission) {
|
|
3412
|
+
let url = history.createURL(stripHashFromPath(location)).toString();
|
|
3340
3413
|
let init = {
|
|
3341
3414
|
signal
|
|
3342
3415
|
};
|
|
@@ -3409,13 +3482,16 @@
|
|
|
3409
3482
|
if (result.headers) {
|
|
3410
3483
|
loaderHeaders[id] = result.headers;
|
|
3411
3484
|
}
|
|
3412
|
-
} else if (isDeferredResult(result)) {
|
|
3413
|
-
activeDeferreds && activeDeferreds.set(id, result.deferredData);
|
|
3414
|
-
loaderData[id] = result.deferredData.data; // TODO: Add statusCode/headers once we wire up streaming in Remix
|
|
3415
3485
|
} else {
|
|
3416
|
-
|
|
3486
|
+
if (isDeferredResult(result)) {
|
|
3487
|
+
activeDeferreds.set(id, result.deferredData);
|
|
3488
|
+
loaderData[id] = result.deferredData.data;
|
|
3489
|
+
} else {
|
|
3490
|
+
loaderData[id] = result.data;
|
|
3491
|
+
} // Error status codes always override success status codes, but if all
|
|
3417
3492
|
// loaders are successful we take the deepest status code.
|
|
3418
3493
|
|
|
3494
|
+
|
|
3419
3495
|
if (result.statusCode != null && result.statusCode !== 200 && !foundError) {
|
|
3420
3496
|
statusCode = result.statusCode;
|
|
3421
3497
|
}
|
|
@@ -3465,11 +3541,11 @@
|
|
|
3465
3541
|
} else if (isRedirectResult(result)) {
|
|
3466
3542
|
// Should never get here, redirects should get processed above, but we
|
|
3467
3543
|
// keep this to type narrow to a success result in the else
|
|
3468
|
-
|
|
3544
|
+
invariant(false, "Unhandled fetcher revalidation redirect");
|
|
3469
3545
|
} else if (isDeferredResult(result)) {
|
|
3470
3546
|
// Should never get here, deferred data should be awaited for fetchers
|
|
3471
3547
|
// in resolveDeferredResults
|
|
3472
|
-
|
|
3548
|
+
invariant(false, "Unhandled fetcher deferred data");
|
|
3473
3549
|
} else {
|
|
3474
3550
|
let doneFetcher = {
|
|
3475
3551
|
state: "idle",
|
|
@@ -3541,7 +3617,8 @@
|
|
|
3541
3617
|
let {
|
|
3542
3618
|
pathname,
|
|
3543
3619
|
routeId,
|
|
3544
|
-
method
|
|
3620
|
+
method,
|
|
3621
|
+
type
|
|
3545
3622
|
} = _temp4 === void 0 ? {} : _temp4;
|
|
3546
3623
|
let statusText = "Unknown Server Error";
|
|
3547
3624
|
let errorMessage = "Unknown @remix-run/router error";
|
|
@@ -3551,6 +3628,8 @@
|
|
|
3551
3628
|
|
|
3552
3629
|
if (method && pathname && routeId) {
|
|
3553
3630
|
errorMessage = "You made a " + method + " request to \"" + pathname + "\" but " + ("did not provide a `loader` for route \"" + routeId + "\", ") + "so there is no way to handle the request.";
|
|
3631
|
+
} else if (type === "defer-action") {
|
|
3632
|
+
errorMessage = "defer() is not supported in actions";
|
|
3554
3633
|
} else {
|
|
3555
3634
|
errorMessage = "Cannot submit binary form data using GET";
|
|
3556
3635
|
}
|
|
@@ -3724,6 +3803,8 @@
|
|
|
3724
3803
|
exports.ErrorResponse = ErrorResponse;
|
|
3725
3804
|
exports.IDLE_FETCHER = IDLE_FETCHER;
|
|
3726
3805
|
exports.IDLE_NAVIGATION = IDLE_NAVIGATION;
|
|
3806
|
+
exports.UNSAFE_DEFERRED_SYMBOL = UNSAFE_DEFERRED_SYMBOL;
|
|
3807
|
+
exports.UNSAFE_DeferredData = DeferredData;
|
|
3727
3808
|
exports.UNSAFE_convertRoutesToDataRoutes = convertRoutesToDataRoutes;
|
|
3728
3809
|
exports.UNSAFE_getPathContributingMatches = getPathContributingMatches;
|
|
3729
3810
|
exports.createBrowserHistory = createBrowserHistory;
|